]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/AliFMDDensityCalculator.cxx
Added scripts for Casper/Valentina style P(N_{ch}) analysis
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / AliFMDDensityCalculator.cxx
CommitLineData
7984e5f7 1// This class calculates the inclusive charged particle density
2// in each for the 5 FMD rings.
3//
7e4038b5 4#include "AliFMDDensityCalculator.h"
5#include <AliESDFMD.h>
6#include <TAxis.h>
7#include <TList.h>
8#include <TMath.h>
0bd4b00f 9#include "AliForwardCorrectionManager.h"
fb3430ac 10#include "AliFMDCorrDoubleHit.h"
11#include "AliFMDCorrELossFit.h"
7e4038b5 12#include "AliLog.h"
13#include <TH2D.h>
0bd4b00f 14#include <TProfile.h>
5bb5d1f6 15#include <THStack.h>
0bd4b00f 16#include <TROOT.h>
5ca83fee 17#include <TVector3.h>
1f7aa5c7 18#include <TStopwatch.h>
bfab35d9 19#include <TParameter.h>
0bd4b00f 20#include <iostream>
21#include <iomanip>
1f7aa5c7 22#include <cstring>
7e4038b5 23
24ClassImp(AliFMDDensityCalculator)
25#if 0
26; // For Emacs
27#endif
28
5ca83fee 29//____________________________________________________________________
30const char* AliFMDDensityCalculator::fgkFolderName = "fmdDensityCalculator";
31
7e4038b5 32//____________________________________________________________________
33AliFMDDensityCalculator::AliFMDDensityCalculator()
34 : TNamed(),
35 fRingHistos(),
dd497217 36 fSumOfWeights(0),
37 fWeightedSum(0),
ea3e5d95 38 fCorrections(0),
0bd4b00f 39 fMaxParticles(5),
9d05ffeb 40 fUsePoisson(false),
8411f7fe 41 fUsePhiAcceptance(kPhiCorrectNch),
0bd4b00f 42 fAccI(0),
43 fAccO(0),
1174780f 44 fFMD1iMax(0),
45 fFMD2iMax(0),
46 fFMD2oMax(0),
47 fFMD3iMax(0),
48 fFMD3oMax(0),
5bb5d1f6 49 fMaxWeights(0),
50 fLowCuts(0),
21d778b1 51 fEtaLumping(32),
52 fPhiLumping(4),
d2638bb7 53 fDebug(0),
6f4a5c0d 54 fCuts(),
5ca83fee 55 fRecalculateEta(false),
8449e3e0 56 fRecalculatePhi(false),
1f7aa5c7 57 fMinQuality(10),
58 fCache(),
59 fDoTiming(false),
60 fHTiming(0)
7984e5f7 61{
62 //
63 // Constructor
64 //
5ca83fee 65 DGUARD(fDebug, 3, "Default CTOR of FMD density calculator");
7984e5f7 66}
7e4038b5 67
68//____________________________________________________________________
69AliFMDDensityCalculator::AliFMDDensityCalculator(const char* title)
5ca83fee 70 : TNamed(fgkFolderName, title),
7e4038b5 71 fRingHistos(),
dd497217 72 fSumOfWeights(0),
73 fWeightedSum(0),
ea3e5d95 74 fCorrections(0),
0bd4b00f 75 fMaxParticles(5),
9d05ffeb 76 fUsePoisson(false),
8411f7fe 77 fUsePhiAcceptance(kPhiCorrectNch),
0bd4b00f 78 fAccI(0),
79 fAccO(0),
1174780f 80 fFMD1iMax(0),
81 fFMD2iMax(0),
82 fFMD2oMax(0),
83 fFMD3iMax(0),
84 fFMD3oMax(0),
5bb5d1f6 85 fMaxWeights(0),
86 fLowCuts(0),
21d778b1 87 fEtaLumping(32),
88 fPhiLumping(4),
d2638bb7 89 fDebug(0),
6f4a5c0d 90 fCuts(),
5ca83fee 91 fRecalculateEta(false),
8449e3e0 92 fRecalculatePhi(false),
1f7aa5c7 93 fMinQuality(10),
94 fCache(),
95 fDoTiming(false),
96 fHTiming(0)
7e4038b5 97{
7984e5f7 98 //
99 // Constructor
100 //
101 // Parameters:
102 // name Name of object
103 //
5ca83fee 104 DGUARD(fDebug, 3, "Named CTOR of FMD density calculator: %s", title);
7e4038b5 105 fRingHistos.SetName(GetName());
e308a636 106 fRingHistos.SetOwner();
7e4038b5 107 fRingHistos.Add(new RingHistos(1, 'I'));
108 fRingHistos.Add(new RingHistos(2, 'I'));
109 fRingHistos.Add(new RingHistos(2, 'O'));
110 fRingHistos.Add(new RingHistos(3, 'I'));
111 fRingHistos.Add(new RingHistos(3, 'O'));
dd497217 112 fSumOfWeights = new TH1D("sumOfWeights", "Sum of Landau weights",
113 200, 0, 20);
0bd4b00f 114 fSumOfWeights->SetFillColor(kRed+1);
115 fSumOfWeights->SetXTitle("#sum_{i} a_{i} f_{i}(#Delta)");
dd497217 116 fWeightedSum = new TH1D("weightedSum", "Weighted sum of Landau propability",
117 200, 0, 20);
0bd4b00f 118 fWeightedSum->SetFillColor(kBlue+1);
119 fWeightedSum->SetXTitle("#sum_{i} i a_{i} f_{i}(#Delta)");
dd497217 120 fCorrections = new TH1D("corrections", "Distribution of corrections",
121 100, 0, 10);
0bd4b00f 122 fCorrections->SetFillColor(kBlue+1);
123 fCorrections->SetXTitle("correction");
dd497217 124
0bd4b00f 125 fAccI = GenerateAcceptanceCorrection('I');
126 fAccO = GenerateAcceptanceCorrection('O');
5bb5d1f6 127
128 fMaxWeights = new TH2D("maxWeights", "Maximum i of a_{i}'s to use",
129 1, 0, 1, 1, 0, 1);
130 fMaxWeights->SetXTitle("#eta");
131 fMaxWeights->SetDirectory(0);
132
133 fLowCuts = new TH2D("lowCuts", "Low cuts used", 1, 0, 1, 1, 0, 1);
134 fLowCuts->SetXTitle("#eta");
135 fLowCuts->SetDirectory(0);
136
7e4038b5 137}
138
139//____________________________________________________________________
140AliFMDDensityCalculator::AliFMDDensityCalculator(const
141 AliFMDDensityCalculator& o)
142 : TNamed(o),
143 fRingHistos(),
dd497217 144 fSumOfWeights(o.fSumOfWeights),
145 fWeightedSum(o.fWeightedSum),
ea3e5d95 146 fCorrections(o.fCorrections),
0bd4b00f 147 fMaxParticles(o.fMaxParticles),
9d05ffeb 148 fUsePoisson(o.fUsePoisson),
5bb5d1f6 149 fUsePhiAcceptance(o.fUsePhiAcceptance),
0bd4b00f 150 fAccI(o.fAccI),
151 fAccO(o.fAccO),
1174780f 152 fFMD1iMax(o.fFMD1iMax),
153 fFMD2iMax(o.fFMD2iMax),
154 fFMD2oMax(o.fFMD2oMax),
155 fFMD3iMax(o.fFMD3iMax),
156 fFMD3oMax(o.fFMD3oMax),
5bb5d1f6 157 fMaxWeights(o.fMaxWeights),
158 fLowCuts(o.fLowCuts),
b6b35c77 159 fEtaLumping(o.fEtaLumping),
160 fPhiLumping(o.fPhiLumping),
d2638bb7 161 fDebug(o.fDebug),
6f4a5c0d 162 fCuts(o.fCuts),
5ca83fee 163 fRecalculateEta(o.fRecalculateEta),
8449e3e0 164 fRecalculatePhi(o.fRecalculatePhi),
1f7aa5c7 165 fMinQuality(o.fMinQuality),
166 fCache(o.fCache),
167 fDoTiming(o.fDoTiming),
168 fHTiming(o.fHTiming)
7e4038b5 169{
7984e5f7 170 //
171 // Copy constructor
172 //
173 // Parameters:
174 // o Object to copy from
175 //
5ca83fee 176 DGUARD(fDebug, 3, "Copy CTOR of FMD density calculator");
7e4038b5 177 TIter next(&o.fRingHistos);
178 TObject* obj = 0;
179 while ((obj = next())) fRingHistos.Add(obj);
180}
181
182//____________________________________________________________________
183AliFMDDensityCalculator::~AliFMDDensityCalculator()
184{
7984e5f7 185 //
186 // Destructor
187 //
6ab100ec 188 DGUARD(fDebug, 3, "DTOR of FMD density calculator");
36ffcf83 189 // fRingHistos.Delete();
7e4038b5 190}
191
192//____________________________________________________________________
193AliFMDDensityCalculator&
194AliFMDDensityCalculator::operator=(const AliFMDDensityCalculator& o)
195{
7984e5f7 196 //
197 // Assignement operator
198 //
199 // Parameters:
200 // o Object to assign from
201 //
202 // Return:
203 // Reference to this object
204 //
6ab100ec 205 DGUARD(fDebug, 3, "Assignment of FMD density calculator");
d015ecfe 206 if (&o == this) return *this;
ea3e5d95 207 TNamed::operator=(o);
7e4038b5 208
d2638bb7 209 fDebug = o.fDebug;
210 fMaxParticles = o.fMaxParticles;
211 fUsePoisson = o.fUsePoisson;
212 fUsePhiAcceptance = o.fUsePhiAcceptance;
213 fAccI = o.fAccI;
214 fAccO = o.fAccO;
215 fFMD1iMax = o.fFMD1iMax;
216 fFMD2iMax = o.fFMD2iMax;
217 fFMD2oMax = o.fFMD2oMax;
218 fFMD3iMax = o.fFMD3iMax;
219 fFMD3oMax = o.fFMD3oMax;
220 fMaxWeights = o.fMaxWeights;
221 fLowCuts = o.fLowCuts;
222 fEtaLumping = o.fEtaLumping;
223 fPhiLumping = o.fPhiLumping;
224 fCuts = o.fCuts;
6f4a5c0d 225 fRecalculateEta = o.fRecalculateEta;
5ca83fee 226 fRecalculatePhi = o.fRecalculatePhi;
8449e3e0 227 fMinQuality = o.fMinQuality;
1f7aa5c7 228 fCache = o.fCache;
229 fDoTiming = o.fDoTiming;
230 fHTiming = o.fHTiming;
d2638bb7 231
7e4038b5 232 fRingHistos.Delete();
233 TIter next(&o.fRingHistos);
234 TObject* obj = 0;
235 while ((obj = next())) fRingHistos.Add(obj);
236
237 return *this;
238}
239
1174780f 240//____________________________________________________________________
241void
5934a3e3 242AliFMDDensityCalculator::SetupForData(const TAxis& axis)
1174780f 243{
244 // Intialize this sub-algorithm
245 //
246 // Parameters:
5ca83fee 247 // etaAxis Eta axis
6ab100ec 248 DGUARD(fDebug, 1, "Initialize FMD density calculator");
e2ebf8c4 249 CacheMaxWeights(axis);
4077f3e8 250
1f7aa5c7 251 fCache.Init(axis);
252
9d05ffeb 253 TIter next(&fRingHistos);
254 RingHistos* o = 0;
d2638bb7 255 while ((o = static_cast<RingHistos*>(next()))) {
5934a3e3 256 o->SetupForData(axis);
e18cb8bd 257 // o->fMultCut = fCuts.GetFixedCut(o->fDet, o->fRing);
258 // o->fPoisson.Init(o->fDet,o->fRing,fEtaLumping, fPhiLumping);
d2638bb7 259 }
1174780f 260}
261
7e4038b5 262//____________________________________________________________________
263AliFMDDensityCalculator::RingHistos*
264AliFMDDensityCalculator::GetRingHistos(UShort_t d, Char_t r) const
265{
7984e5f7 266 //
267 // Get the ring histogram container
268 //
269 // Parameters:
270 // d Detector
271 // r Ring
272 //
273 // Return:
274 // Ring histogram container
275 //
7e4038b5 276 Int_t idx = -1;
277 switch (d) {
278 case 1: idx = 0; break;
279 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
280 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
281 }
e308a636 282 if (idx < 0 || idx >= fRingHistos.GetEntries()) {
283 AliWarning(Form("Index %d of FMD%d%c out of range", idx, d, r));
284 return 0;
285 }
7e4038b5 286
287 return static_cast<RingHistos*>(fRingHistos.At(idx));
288}
5bb5d1f6 289
0bd4b00f 290//____________________________________________________________________
291Double_t
5bb5d1f6 292AliFMDDensityCalculator::GetMultCut(UShort_t d, Char_t r, Int_t ieta,
293 Bool_t errors) const
0bd4b00f 294{
7984e5f7 295 //
296 // Get the multiplicity cut. If the user has set fMultCut (via
297 // SetMultCut) then that value is used. If not, then the lower
298 // value of the fit range for the enery loss fits is returned.
299 //
300 // Return:
301 // Lower cut on multiplicity
302 //
d2638bb7 303 return fCuts.GetMultCut(d,r,ieta,errors);
5bb5d1f6 304}
305
306//____________________________________________________________________
307Double_t
308AliFMDDensityCalculator::GetMultCut(UShort_t d, Char_t r, Double_t eta,
8e400b14 309 Bool_t errors) const
5bb5d1f6 310{
311 //
312 // Get the multiplicity cut. If the user has set fMultCut (via
313 // SetMultCut) then that value is used. If not, then the lower
314 // value of the fit range for the enery loss fits is returned.
315 //
316 // Return:
317 // Lower cut on multiplicity
318 //
d2638bb7 319 return fCuts.GetMultCut(d,r,eta,errors);
0bd4b00f 320}
321
7e4038b5 322//____________________________________________________________________
323Bool_t
324AliFMDDensityCalculator::Calculate(const AliESDFMD& fmd,
325 AliForwardUtil::Histos& hists,
21d778b1 326 Bool_t lowFlux,
b3d81bee 327 Double_t /*cent*/,
5ca83fee 328 const TVector3& ip)
7e4038b5 329{
7984e5f7 330 //
331 // Do the calculations
332 //
333 // Parameters:
334 // fmd AliESDFMD object (possibly) corrected for sharing
335 // hists Histogram cache
336 // vtxBin Vertex bin
337 // lowFlux Low flux flag.
338 //
339 // Return:
340 // true on successs
6ab100ec 341 DGUARD(fDebug, 1, "Calculate density in FMD density calculator");
5ca83fee 342
1f7aa5c7 343 TStopwatch timer;
344 TStopwatch totalT;
345
346 // First measurements of timing
347 // Re-calculation : fraction of sum 32.0% of total 18.1%
348 // N_{particle} : fraction of sum 15.2% of total 8.6%
349 // Correction : fraction of sum 26.4% of total 14.9%
350 // #phi acceptance : fraction of sum 0.2% of total 0.1%
351 // Copy to cache : fraction of sum 3.9% of total 2.2%
352 // Poisson calculation : fraction of sum 18.7% of total 10.6%
353 // Diagnostics : fraction of sum 3.7% of total 2.1%
354 Double_t reEtaTime = 0;
355 Double_t nPartTime = 0;
356 Double_t corrTime = 0;
357 Double_t rePhiTime = 0;
358 Double_t copyTime = 0;
359 Double_t poissonTime= 0;
360 Double_t diagTime = 0;
361 if (fDoTiming) totalT.Start(true);
362
363 Double_t etaCache[20*512]; // Same number of strips per ring
364 Double_t phiCache[20*512]; // whether it is inner our outer.
365 // We do not use TArrayD because we do not wont a bounds check
366 // TArrayD etaCache(20*512); // Same number of strips per ring
367 // TArrayD phiCache(20*512); // whether it is inner our outer.
368
5ca83fee 369 // --- Loop over detectors -----------------------------------------
7e4038b5 370 for (UShort_t d=1; d<=3; d++) {
371 UShort_t nr = (d == 1 ? 1 : 2);
372 for (UShort_t q=0; q<nr; q++) {
373 Char_t r = (q == 0 ? 'I' : 'O');
374 UShort_t ns= (q == 0 ? 20 : 40);
375 UShort_t nt= (q == 0 ? 512 : 256);
376 TH2D* h = hists.Get(d,r);
377 RingHistos* rh= GetRingHistos(d,r);
e308a636 378 if (!rh) {
379 AliError(Form("No ring histogram found for FMD%d%c", d, r));
380 fRingHistos.ls();
381 return false;
382 }
e18cb8bd 383 // rh->fPoisson.SetObject(d,r,vtxbin,cent);
d23503ee 384 rh->fPoisson.Reset(0);
5ca83fee 385 rh->fTotal->Reset();
386 rh->fGood->Reset();
821ffd28 387 // rh->ResetPoissonHistos(h, fEtaLumping, fPhiLumping);
1f7aa5c7 388
389 // Reset our eta cache
390 // for (Int_t i = 0; i < 20*512; i++)
391 // etaCache[i] = phiCache[i] = AliESDFMD::kInvalidEta;
392 memset(etaCache, 0, sizeof(Double_t)*20*512);
393 memset(phiCache, 0, sizeof(Double_t)*20*512);
394 // etaCache.Reset(AliESDFMD::kInvalidEta);
395 // phiCache.Reset(AliESDFMD::kInvalidEta);
396
5ca83fee 397 // --- Loop over sectors and strips ----------------------------
7e4038b5 398 for (UShort_t s=0; s<ns; s++) {
399 for (UShort_t t=0; t<nt; t++) {
3e4a0875 400
5ca83fee 401 Float_t mult = fmd.Multiplicity(d,r,s,t);
402 Float_t phi = fmd.Phi(d,r,s,t) * TMath::DegToRad();
403 Float_t eta = fmd.Eta(d,r,s,t);
404 Double_t oldPhi = phi;
405
406 // --- Re-calculate eta - needed for satelittes ------------
1f7aa5c7 407 if (fDoTiming) timer.Start(true);
408 if (eta == AliESDFMD::kInvalidEta || fRecalculateEta)
5ca83fee 409 eta = AliForwardUtil::GetEtaFromStrip(d,r,s,t,ip.Z());
1f7aa5c7 410 if (fDoTiming) reEtaTime += timer.CpuTime();
411 etaCache[s*nt+t] = eta;
5ca83fee 412
413 // --- Check this strip ------------------------------------
414 rh->fTotal->Fill(eta);
bfab35d9 415 if (mult == AliESDFMD::kInvalidMult) { // || mult > 20) {
8449e3e0 416 // Do not count invalid stuff
417 rh->fELoss->Fill(-1);
418 // rh->fEvsN->Fill(mult,-1);
419 // rh->fEvsM->Fill(mult,-1);
33b078ef 420 continue;
421 }
bfab35d9 422 if (mult > 20)
423 AliWarningF("Raw multiplicity of FMD%d%c[%02d,%03d] = %f > 20",
424 d, r, s, t, mult);
5ca83fee 425 // --- Automatic calculation of acceptance -----------------
426 rh->fGood->Fill(eta);
427
428 // --- If we asked to re-calculate phi for (x,y) IP --------
1f7aa5c7 429 if (fDoTiming) timer.Start(true);
5ca83fee 430 if (fRecalculatePhi) {
431 oldPhi = phi;
432 phi = AliForwardUtil::GetPhiFromStrip(r, t, phi, ip.X(), ip.Y());
433 }
1f7aa5c7 434 phiCache[s*nt+t] = phi;
435 if (fDoTiming) rePhiTime += timer.CpuTime();
5ca83fee 436
437 // --- Apply phi corner correction to eloss ----------------
8411f7fe 438 if (fUsePhiAcceptance == kPhiCorrectELoss)
0082a8fc 439 mult *= AcceptanceCorrection(r,t);
5bb5d1f6 440
5ca83fee 441 // --- Get the low multiplicity cut ------------------------
8e400b14 442 Double_t cut = 1024;
443 if (eta != AliESDFMD::kInvalidEta) cut = GetMultCut(d, r, eta,false);
bfab35d9 444 else AliWarningF("Eta for FMD%d%c[%02d,%03d] is invalid: %f",
445 d, r, s, t, eta);
8e400b14 446
5ca83fee 447 // --- Now caluculate Nch for this strip using fits --------
1f7aa5c7 448 if (fDoTiming) timer.Start(true);
5bb5d1f6 449 Double_t n = 0;
5ca83fee 450 if (cut > 0 && mult > cut) n = NParticles(mult,d,r,eta,lowFlux);
f7cfc454 451 rh->fELoss->Fill(mult);
8449e3e0 452 // rh->fEvsN->Fill(mult,n);
453 // rh->fEtaVsN->Fill(eta, n);
1f7aa5c7 454 if (fDoTiming) nPartTime += timer.CpuTime();
9fde7142 455
5ca83fee 456 // --- Calculate correction if needed ----------------------
1f7aa5c7 457 if (fDoTiming) timer.Start(true);
458 // Temporary stuff - remove Correction call
459 Double_t c = 1;
460 if (fUsePhiAcceptance == kPhiCorrectNch)
461 c = AcceptanceCorrection(r,t);
462 // Double_t c = Correction(d,r,t,eta,lowFlux);
463 if (fDoTiming) corrTime += timer.CpuTime();
dd497217 464 fCorrections->Fill(c);
7e4038b5 465 if (c > 0) n /= c;
8449e3e0 466 // rh->fEvsM->Fill(mult,n);
467 // rh->fEtaVsM->Fill(eta, n);
0bd4b00f 468 rh->fCorr->Fill(eta, c);
f7cfc454 469
5ca83fee 470 // --- Accumulate Poisson statistics -----------------------
821ffd28 471 Bool_t hit = (n > 0.9 && c > 0);
5ca83fee 472 if (hit) {
473 rh->fELossUsed->Fill(mult);
474 if (fRecalculatePhi) {
475 rh->fPhiBefore->Fill(oldPhi);
476 rh->fPhiAfter->Fill(phi);
477 }
478 }
21d778b1 479 rh->fPoisson.Fill(t,s,hit,1./c);
7e4038b5 480 h->Fill(eta,phi,n);
5ca83fee 481
482 // --- If we use ELoss fits, apply now ---------------------
5bb5d1f6 483 if (!fUsePoisson) rh->fDensity->Fill(eta,phi,n);
7e4038b5 484 } // for t
485 } // for s
5ca83fee 486
487 // --- Automatic acceptance - Calculate as an efficiency -------
1f7aa5c7 488 // This is very fast, so we do not bother to time it
5ca83fee 489 rh->fGood->Divide(rh->fGood, rh->fTotal, 1, 1, "B");
490
491 // --- Make a copy and reset as needed -------------------------
1f7aa5c7 492 if (fDoTiming) timer.Start(true);
493 TH2D* hclone = fCache.Get(d,r);
494 // hclone->Reset();
495 // TH2D* hclone = static_cast<TH2D*>(h->Clone("hclone"));
21d778b1 496 if (!fUsePoisson) hclone->Reset();
1f7aa5c7 497 else {
498 for (Int_t i = 0; i <= h->GetNbinsX()+1; i++) {
499 for (Int_t j = 0; j <= h->GetNbinsY()+1; j++) {
500 hclone->SetBinContent(i,j,h->GetBinContent(i,j));
501 hclone->SetBinError(i,j,h->GetBinError(i,j));
502 }
503 }
504 // hclone->Add(h);
505 h->Reset();
506 }
507 if (fDoTiming) copyTime += timer.CpuTime();
21d778b1 508
5ca83fee 509 // --- Store Poisson result ------------------------------------
1f7aa5c7 510 if (fDoTiming) timer.Start(true);
821ffd28 511 TH2D* poisson = rh->fPoisson.Result();
d23503ee 512 for (Int_t t=0; t < poisson->GetNbinsX(); t++) {
513 for (Int_t s=0; s < poisson->GetNbinsY(); s++) {
21d778b1 514
515 Double_t poissonV = poisson->GetBinContent(t+1,s+1);
1f7aa5c7 516 // Use cached eta - since the calls to GetEtaFromStrip and
517 // GetPhiFromStrip are _very_ expensive
518 Double_t phi = phiCache[s*nt+t];
519 Double_t eta = etaCache[s*nt+t];
520 // Double_t phi = fmd.Phi(d,r,s,t) * TMath::DegToRad();
521 // Double_t eta = fmd.Eta(d,r,s,t);
522 // if (fRecalculateEta)
523 // eta = AliForwardUtil::GetEtaFromStrip(d,r,s,t,ip.Z());
524 // if (fRecalculatePhi)
525 // phi = AliForwardUtil::GetPhiFromStrip(r, t, phi, ip.X(), ip.Y());
526 if (fUsePoisson) {
21d778b1 527 h->Fill(eta,phi,poissonV);
1f7aa5c7 528 rh->fDensity->Fill(eta, phi, poissonV);
529 }
21d778b1 530 else
531 hclone->Fill(eta,phi,poissonV);
21d778b1 532 }
533 }
1f7aa5c7 534 if (fDoTiming) poissonTime += timer.CpuTime();
21d778b1 535
5ca83fee 536 // --- Make diagnostics - eloss vs poisson ---------------------
1f7aa5c7 537 if (fDoTiming) timer.Start(true);
5ca83fee 538 Int_t nY = h->GetNbinsY();
21d778b1 539 for (Int_t ieta=1; ieta <= h->GetNbinsX(); ieta++) {
5ca83fee 540 // Set the overflow bin to contain the phi acceptance
541 Double_t phiAcc = rh->fGood->GetBinContent(ieta);
542 Double_t phiAccE = rh->fGood->GetBinError(ieta);
543 h->SetBinContent(ieta, nY+1, phiAcc);
544 h->SetBinError(ieta, nY+1, phiAccE);
545 Double_t eta = h->GetXaxis()->GetBinCenter(ieta);
546 rh->fPhiAcc->Fill(eta, ip.Z(), phiAcc);
5ca83fee 547 for (Int_t iphi=1; iphi<= nY; iphi++) {
e83d0620 548
21d778b1 549 Double_t poissonV = 0; //h->GetBinContent(,s+1);
550 Double_t eLossV = 0;
551 if(fUsePoisson) {
552 poissonV = h->GetBinContent(ieta,iphi);
553 eLossV = hclone->GetBinContent(ieta,iphi);
554 }
555 else {
556 poissonV = hclone->GetBinContent(ieta,iphi);
557 eLossV = h->GetBinContent(ieta,iphi);
558 }
7b03929c 559
9d05ffeb 560 rh->fELossVsPoisson->Fill(eLossV, poissonV);
5ca83fee 561 rh->fDiffELossPoisson->Fill(poissonV < 1e-12 ? 0 :
562 (eLossV - poissonV) / poissonV);
563
9d05ffeb 564 }
565 }
1f7aa5c7 566 if (fDoTiming) diagTime += timer.CpuTime();
567 // delete hclone;
21d778b1 568
7e4038b5 569 } // for q
570 } // for d
a7f31ad8 571
1f7aa5c7 572 if (fDoTiming) {
573 fHTiming->Fill(1,reEtaTime);
574 fHTiming->Fill(2,nPartTime);
575 fHTiming->Fill(3,corrTime);
576 fHTiming->Fill(4,rePhiTime);
577 fHTiming->Fill(5,copyTime);
578 fHTiming->Fill(6,poissonTime);
579 fHTiming->Fill(7,diagTime);
580 fHTiming->Fill(8,totalT.CpuTime());
581 }
582
7e4038b5 583 return kTRUE;
584}
585
1174780f 586//_____________________________________________________________________
587Int_t
fb3430ac 588AliFMDDensityCalculator::FindMaxWeight(const AliFMDCorrELossFit* cor,
1174780f 589 UShort_t d, Char_t r, Int_t iEta) const
590{
fb3430ac 591 //
592 // Find the max weight to use for FMD<i>dr</i> in eta bin @a iEta
593 //
594 // Parameters:
595 // cor Correction
596 // d Detector
597 // r Ring
598 // iEta Eta bin
599 //
241cca4d 600 DGUARD(fDebug, 10, "Find maximum weight in FMD density calculator");
f61b1745 601 if(!cor) return -1;
602
8449e3e0 603 AliFMDCorrELossFit::ELossFit* fit = cor->FindFit(d,r,iEta, -1);
1174780f 604 if (!fit) {
605 // AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f", d, r, eta));
606 return -1;
607 }
8449e3e0 608 return fit->FindMaxWeight(2*AliFMDCorrELossFit::ELossFit::fgMaxRelError,
609 AliFMDCorrELossFit::ELossFit::fgLeastWeight,
610 fMaxParticles);
1174780f 611}
612
613//_____________________________________________________________________
614void
e2ebf8c4 615AliFMDDensityCalculator::CacheMaxWeights(const TAxis& axis)
1174780f 616{
fb3430ac 617 //
618 // Find the max weights and cache them
619 //
6ab100ec 620 DGUARD(fDebug, 2, "Cache maximum weights in FMD density calculator");
1174780f 621 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
8449e3e0 622 const AliFMDCorrELossFit* cor = fcm.GetELossFit();
623 cor->CacheBins(fMinQuality);
a76fb27d 624
625 TAxis eta(axis.GetNbins(),
626 axis.GetXmin(),
627 axis.GetXmax());
628
f61b1745 629 if(cor)
630 eta.Set(cor->GetEtaAxis().GetNbins(),
631 cor->GetEtaAxis().GetXmin(),
632 cor->GetEtaAxis().GetXmax());
1174780f 633
634 Int_t nEta = eta.GetNbins();
635 fFMD1iMax.Set(nEta);
636 fFMD2iMax.Set(nEta);
637 fFMD2oMax.Set(nEta);
638 fFMD3iMax.Set(nEta);
639 fFMD3oMax.Set(nEta);
640
5bb5d1f6 641 fMaxWeights->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
642 fMaxWeights->GetYaxis()->SetBinLabel(1, "FMD1i");
643 fMaxWeights->GetYaxis()->SetBinLabel(2, "FMD2i");
644 fMaxWeights->GetYaxis()->SetBinLabel(3, "FMD2o");
645 fMaxWeights->GetYaxis()->SetBinLabel(4, "FMD3i");
646 fMaxWeights->GetYaxis()->SetBinLabel(5, "FMD3o");
647
648 AliInfo(Form("Get eta axis with %d bins from %f to %f",
649 nEta, eta.GetXmin(), eta.GetXmax()));
650 fLowCuts->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
651 fLowCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
652 fLowCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
653 fLowCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
654 fLowCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
655 fLowCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
656
1174780f 657 for (Int_t i = 0; i < nEta; i++) {
5bb5d1f6 658 Double_t w[5];
659 w[0] = fFMD1iMax[i] = FindMaxWeight(cor, 1, 'I', i+1);
660 w[1] = fFMD2iMax[i] = FindMaxWeight(cor, 2, 'I', i+1);
661 w[2] = fFMD2oMax[i] = FindMaxWeight(cor, 2, 'O', i+1);
662 w[3] = fFMD3iMax[i] = FindMaxWeight(cor, 3, 'I', i+1);
663 w[4] = fFMD3oMax[i] = FindMaxWeight(cor, 3, 'O', i+1);
664 Double_t l[5];
665 l[0] = GetMultCut(1, 'I', i+1, false);
666 l[1] = GetMultCut(2, 'I', i+1, false);
667 l[2] = GetMultCut(2, 'O', i+1, false);
668 l[3] = GetMultCut(3, 'I', i+1, false);
669 l[4] = GetMultCut(3, 'O', i+1, false);
670 for (Int_t j = 0; j < 5; j++) {
671 if (w[j] > 0) fMaxWeights->SetBinContent(i+1, j+1, w[j]);
672 if (l[j] > 0) fLowCuts->SetBinContent(i+1, j+1, l[j]);
673 }
1174780f 674 }
675}
676
677//_____________________________________________________________________
678Int_t
679AliFMDDensityCalculator::GetMaxWeight(UShort_t d, Char_t r, Int_t iEta) const
680{
fb3430ac 681 //
682 // Find the (cached) maximum weight for FMD<i>dr</i> in
683 // @f$\eta@f$ bin @a iEta
684 //
685 // Parameters:
686 // d Detector
687 // r Ring
688 // iEta Eta bin
689 //
690 // Return:
691 // max weight or <= 0 in case of problems
692 //
1174780f 693 if (iEta < 0) return -1;
694
695 const TArrayI* max = 0;
696 switch (d) {
697 case 1: max = &fFMD1iMax; break;
698 case 2: max = (r == 'I' || r == 'i' ? &fFMD2iMax : &fFMD2oMax); break;
699 case 3: max = (r == 'I' || r == 'i' ? &fFMD3iMax : &fFMD3oMax); break;
700 }
701 if (!max) {
702 AliWarning(Form("No array for FMD%d%c", d, r));
703 return -1;
704 }
705
706 if (iEta >= max->fN) {
707 AliWarning(Form("Eta bin %3d out of bounds [0,%d]",
708 iEta, max->fN-1));
709 return -1;
710 }
711
712 AliDebug(30,Form("Max weight for FMD%d%c eta bin %3d: %d", d, r, iEta,
713 max->At(iEta)));
714 return max->At(iEta);
715}
716
717//_____________________________________________________________________
718Int_t
719AliFMDDensityCalculator::GetMaxWeight(UShort_t d, Char_t r, Float_t eta) const
720{
fb3430ac 721 //
722 // Find the (cached) maximum weight for FMD<i>dr</i> iat
723 // @f$\eta@f$
724 //
725 // Parameters:
726 // d Detector
727 // r Ring
728 // eta Eta bin
729 //
730 // Return:
731 // max weight or <= 0 in case of problems
732 //
1174780f 733 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
734 Int_t iEta = fcm.GetELossFit()->FindEtaBin(eta) -1;
735
736 return GetMaxWeight(d, r, iEta);
737}
738
7e4038b5 739//_____________________________________________________________________
740Float_t
741AliFMDDensityCalculator::NParticles(Float_t mult,
742 UShort_t d,
743 Char_t r,
7e4038b5 744 Float_t eta,
745 Bool_t lowFlux) const
746{
7984e5f7 747 //
748 // Get the number of particles corresponding to the signal mult
749 //
750 // Parameters:
751 // mult Signal
752 // d Detector
753 // r Ring
754 // s Sector
755 // t Strip (not used)
756 // v Vertex bin
757 // eta Pseudo-rapidity
758 // lowFlux Low-flux flag
759 //
760 // Return:
761 // The number of particles
762 //
5bb5d1f6 763 // if (mult <= GetMultCut()) return 0;
6ab100ec 764 DGUARD(fDebug, 3, "Calculate Nch in FMD density calculator");
7e4038b5 765 if (lowFlux) return 1;
0bd4b00f 766
0bd4b00f 767 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
8449e3e0 768 AliFMDCorrELossFit::ELossFit* fit = fcm.GetELossFit()->FindFit(d,r,eta, -1);
0bd4b00f 769 if (!fit) {
8449e3e0 770 AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f qual=%d",
771 d, r, eta, fMinQuality));
0bd4b00f 772 return 0;
773 }
774
1174780f 775 Int_t m = GetMaxWeight(d,r,eta); // fit->FindMaxWeight();
0bd4b00f 776 if (m < 1) {
777 AliWarning(Form("No good fits for FMD%d%c at eta=%f", d, r, eta));
778 return 0;
779 }
79909b8b 780
0bd4b00f 781 UShort_t n = TMath::Min(fMaxParticles, UShort_t(m));
782 Double_t ret = fit->EvaluateWeighted(mult, n);
79909b8b 783
0bd4b00f 784 if (fDebug > 10) {
785 AliInfo(Form("FMD%d%c, eta=%7.4f, %8.5f -> %8.5f", d, r, eta, mult, ret));
786 }
79909b8b 787
0bd4b00f 788 fWeightedSum->Fill(ret);
789 fSumOfWeights->Fill(ret);
3e4a0875 790
0bd4b00f 791 return ret;
7e4038b5 792}
793
794//_____________________________________________________________________
795Float_t
0bd4b00f 796AliFMDDensityCalculator::Correction(UShort_t d,
797 Char_t r,
0bd4b00f 798 UShort_t t,
0bd4b00f 799 Float_t eta,
800 Bool_t lowFlux) const
7e4038b5 801{
7984e5f7 802 //
803 // Get the inverse correction factor. This consist of
804 //
805 // - acceptance correction (corners of sensors)
806 // - double hit correction (for low-flux events)
807 // - dead strip correction
808 //
809 // Parameters:
810 // d Detector
811 // r Ring
812 // s Sector
813 // t Strip (not used)
814 // v Vertex bin
815 // eta Pseudo-rapidity
816 // lowFlux Low-flux flag
817 //
818 // Return:
819 //
820 //
241cca4d 821 DGUARD(fDebug, 10, "Apply correction in FMD density calculator");
5bb5d1f6 822 Float_t correction = 1;
8411f7fe 823 if (fUsePhiAcceptance == kPhiCorrectNch)
824 correction = AcceptanceCorrection(r,t);
7e4038b5 825 if (lowFlux) {
1f7aa5c7 826 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
827
0bd4b00f 828 TH1D* dblHitCor = 0;
829 if (fcm.GetDoubleHit())
830 dblHitCor = fcm.GetDoubleHit()->GetCorrection(d,r);
831
7e4038b5 832 if (dblHitCor) {
0bd4b00f 833 Double_t dblC = dblHitCor->GetBinContent(dblHitCor->FindBin(eta));
834 if (dblC > 0) correction *= dblC;
7e4038b5 835 }
57522224 836 // else {
837 // AliWarning(Form("Missing double hit correction for FMD%d%c",d,r));
838 // }
7e4038b5 839 }
7e4038b5 840 return correction;
841}
842
0bd4b00f 843//_____________________________________________________________________
844TH1D*
845AliFMDDensityCalculator::GenerateAcceptanceCorrection(Char_t r) const
846{
7984e5f7 847 //
848 // Generate the acceptance corrections
849 //
850 // Parameters:
851 // r Ring to generate for
852 //
853 // Return:
854 // Newly allocated histogram of acceptance corrections
855 //
6ab100ec 856 DGUARD(fDebug, 3, "Make acceptance correction in FMD density calculator");
0bd4b00f 857 const Double_t ic1[] = { 4.9895, 15.3560 };
858 const Double_t ic2[] = { 1.8007, 17.2000 };
859 const Double_t oc1[] = { 4.2231, 26.6638 };
860 const Double_t oc2[] = { 1.8357, 27.9500 };
861 const Double_t* c1 = (r == 'I' || r == 'i' ? ic1 : oc1);
862 const Double_t* c2 = (r == 'I' || r == 'i' ? ic2 : oc2);
863 Double_t minR = (r == 'I' || r == 'i' ? 4.5213 : 15.4);
864 Double_t maxR = (r == 'I' || r == 'i' ? 17.2 : 28.0);
865 Int_t nStrips = (r == 'I' || r == 'i' ? 512 : 256);
866 Int_t nSec = (r == 'I' || r == 'i' ? 20 : 40);
867 Float_t basearc = 2 * TMath::Pi() / nSec;
868 Double_t rad = maxR - minR;
869 Float_t segment = rad / nStrips;
870 Float_t cr = TMath::Sqrt(c1[0]*c1[0]+c1[1]*c1[1]);
871
872 // Numbers used to find end-point of strip.
873 // (See http://mathworld.wolfram.com/Circle-LineIntersection.html)
874 Float_t D = c1[0] * c2[1] - c1[1] * c2[0];
875 Float_t dx = c2[0] - c1[0];
876 Float_t dy = c2[1] - c1[1];
877 Float_t dr = TMath::Sqrt(dx*dx+dy*dy);
878
879 TH1D* ret = new TH1D(Form("acc%c", r),
880 Form("Acceptance correction for FMDx%c", r),
881 nStrips, -.5, nStrips-.5);
882 ret->SetXTitle("Strip");
883 ret->SetYTitle("#varphi acceptance");
884 ret->SetDirectory(0);
885 ret->SetFillColor(r == 'I' || r == 'i' ? kRed+1 : kBlue+1);
886 ret->SetFillStyle(3001);
887
888 for (Int_t t = 0; t < nStrips; t++) {
889 Float_t radius = minR + t * segment;
890
891 // If the radius of the strip is smaller than the radius corresponding
892 // to the first corner we have a full strip length
893 if (radius <= cr) {
894 ret->SetBinContent(t+1, 1);
895 continue;
896 }
897
898 // Next, we should find the end-point of the strip - that is,
899 // the coordinates where the line from c1 to c2 intersects a circle
900 // with radius given by the strip.
901 // (See http://mathworld.wolfram.com/Circle-LineIntersection.html)
902 // Calculate the determinant
903 Float_t det = radius * radius * dr * dr - D*D;
904
905 if (det <= 0) {
906 // <0 means No intersection
907 // =0 means Exactly tangent
908 ret->SetBinContent(t+1, 1);
909 continue;
910 }
911
912 // Calculate end-point and the corresponding opening angle
913 Float_t x = (+D * dy + dx * TMath::Sqrt(det)) / dr / dr;
914 Float_t y = (-D * dx + dy * TMath::Sqrt(det)) / dr / dr;
915 Float_t th = TMath::ATan2(x, y);
916
917 ret->SetBinContent(t+1, th / basearc);
918 }
919 return ret;
920}
7e4038b5 921
922//_____________________________________________________________________
923Float_t
924AliFMDDensityCalculator::AcceptanceCorrection(Char_t r, UShort_t t) const
925{
7984e5f7 926 //
927 // Get the acceptance correction for strip @a t in an ring of type @a r
928 //
929 // Parameters:
930 // r Ring type ('I' or 'O')
931 // t Strip number
932 //
933 // Return:
934 // Inverse acceptance correction
935 //
0bd4b00f 936 TH1D* acc = (r == 'I' || r == 'i' ? fAccI : fAccO);
937 return acc->GetBinContent(t+1);
7e4038b5 938}
939
940//____________________________________________________________________
941void
5934a3e3 942AliFMDDensityCalculator::Terminate(const TList* dir, TList* output,
943 Int_t nEvents)
7e4038b5 944{
7984e5f7 945 //
946 // Scale the histograms to the total number of events
947 //
948 // Parameters:
949 // dir where to put the output
950 // nEvents Number of events
951 //
6ab100ec 952 DGUARD(fDebug, 1, "Scale histograms in FMD density calculator");
7e4038b5 953 if (nEvents <= 0) return;
9d99b0dd 954 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
955 if (!d) return;
7e4038b5 956
5934a3e3 957 TList* out = new TList;
958 out->SetName(d->GetName());
959 out->SetOwner();
960
7e4038b5 961 TIter next(&fRingHistos);
962 RingHistos* o = 0;
5bb5d1f6 963 THStack* sums = new THStack("sums", "sums of ring signals");
964 while ((o = static_cast<RingHistos*>(next()))) {
5934a3e3 965 o->Terminate(d, nEvents);
966 if (!o->fDensity) {
967 Warning("Terminate", "No density in %s", o->GetName());
968 continue;
969 }
5bb5d1f6 970 TH1D* sum = o->fDensity->ProjectionX(o->GetName(), 1,
971 o->fDensity->GetNbinsY(),"e");
972 sum->Scale(1., "width");
973 sum->SetTitle(o->GetName());
974 sum->SetDirectory(0);
975 sum->SetYTitle("#sum N_{ch,incl}");
976 sums->Add(sum);
977 }
5934a3e3 978 out->Add(sums);
979 output->Add(out);
7e4038b5 980}
981
982//____________________________________________________________________
983void
5934a3e3 984AliFMDDensityCalculator::CreateOutputObjects(TList* dir)
7e4038b5 985{
7984e5f7 986 //
987 // Output diagnostic histograms to directory
988 //
989 // Parameters:
990 // dir List to write in
991 //
6ab100ec 992 DGUARD(fDebug, 1, "Define output FMD density calculator");
7e4038b5 993 TList* d = new TList;
5bb5d1f6 994 d->SetOwner();
7e4038b5 995 d->SetName(GetName());
996 dir->Add(d);
dd497217 997 d->Add(fWeightedSum);
998 d->Add(fSumOfWeights);
999 d->Add(fCorrections);
0bd4b00f 1000 d->Add(fAccI);
1001 d->Add(fAccO);
5bb5d1f6 1002 d->Add(fMaxWeights);
1003 d->Add(fLowCuts);
0bd4b00f 1004
d2638bb7 1005 // TNamed* sigma = new TNamed("sigma",
1006 // (fIncludeSigma ? "included" : "excluded"));
241cca4d 1007 TObject* maxP = AliForwardUtil::MakeParameter("maxParticle", fMaxParticles);
1008 TObject* method = AliForwardUtil::MakeParameter("method", fUsePoisson);
1009 TObject* phiA = AliForwardUtil::MakeParameter("phiAcceptance",
1010 fUsePhiAcceptance);
1011 TObject* etaL = AliForwardUtil::MakeParameter("etaLumping", fEtaLumping);
1012 TObject* phiL = AliForwardUtil::MakeParameter("phiLumping", fPhiLumping);
5ca83fee 1013 TObject* reEt = AliForwardUtil::MakeParameter("recalcEta", fRecalculateEta);
1014 TObject* rePh = AliForwardUtil::MakeParameter("recalcPhi", fRecalculatePhi);
1015
bfab35d9 1016 TParameter<int>* nFiles = new TParameter<int>("nFiles", 1);
1017 nFiles->SetMergeMode('+');
1018
d2638bb7 1019 // d->Add(sigma);
f7cfc454 1020 d->Add(maxP);
1021 d->Add(method);
1022 d->Add(phiA);
1023 d->Add(etaL);
1024 d->Add(phiL);
5ca83fee 1025 d->Add(reEt);
1026 d->Add(rePh);
bfab35d9 1027 d->Add(nFiles);
d2638bb7 1028 // d->Add(nxi);
5ca83fee 1029 fCuts.Output(d,"lCuts");
f7cfc454 1030
7e4038b5 1031 TIter next(&fRingHistos);
1032 RingHistos* o = 0;
1033 while ((o = static_cast<RingHistos*>(next()))) {
e18cb8bd 1034 o->fPoisson.SetLumping(fEtaLumping, fPhiLumping);
5934a3e3 1035 o->CreateOutputObjects(d);
7e4038b5 1036 }
1f7aa5c7 1037
1038 if (!fDoTiming) return;
1039
1040 fHTiming = new TProfile("timing", "#LTt_{part}#GT", 8, .5, 8.5);
1041 fHTiming->SetDirectory(0);
1042 fHTiming->SetYTitle("#LTt_{part}#GT");
1043 fHTiming->SetXTitle("Part");
1044 fHTiming->SetFillColor(kRed+1);
1045 fHTiming->SetFillStyle(3001);
1046 fHTiming->SetMarkerStyle(20);
1047 fHTiming->SetMarkerColor(kBlack);
1048 fHTiming->SetLineColor(kBlack);
1049 fHTiming->SetStats(0);
1050 TAxis* xaxis = fHTiming->GetXaxis();
1051 xaxis->SetBinLabel(1, "Re-calculation of #eta");
1052 xaxis->SetBinLabel(2, "N_{particle}");
1053 xaxis->SetBinLabel(3, "Correction");
1054 xaxis->SetBinLabel(4, "Re-calculation of #phi");
1055 xaxis->SetBinLabel(5, "Copy to cache");
1056 xaxis->SetBinLabel(6, "Poisson calculation");
1057 xaxis->SetBinLabel(7, "Diagnostics");
1058 xaxis->SetBinLabel(8, "Total");
1059 d->Add(fHTiming);
7e4038b5 1060}
0bd4b00f 1061//____________________________________________________________________
1062void
1174780f 1063AliFMDDensityCalculator::Print(Option_t* option) const
0bd4b00f 1064{
7984e5f7 1065 //
1066 // Print information
1067 //
1068 // Parameters:
1069 // option Not used
1070 //
1174780f 1071 char ind[gROOT->GetDirLevel()+3];
0bd4b00f 1072 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
1073 ind[gROOT->GetDirLevel()] = '\0';
1f480471 1074 std::cout << ind << ClassName() << ": " << GetName() << '\n'
5bb5d1f6 1075 << std::boolalpha
1f480471 1076 << ind << " Max(particles): " << fMaxParticles << '\n'
5bb5d1f6 1077 << ind << " Poisson method: " << fUsePoisson << '\n'
1f480471 1078 << ind << " Eta lumping: " << fEtaLumping << '\n'
1079 << ind << " Phi lumping: " << fPhiLumping << '\n'
5ca83fee 1080 << ind << " Recalculate eta: " << fRecalculateEta << '\n'
1081 << ind << " Recalculate phi: " << fRecalculatePhi << '\n'
1082 << ind << " Use phi acceptance: "
5bb5d1f6 1083 << std::noboolalpha
1f480471 1084 << std::flush;
5ca83fee 1085 switch (fUsePhiAcceptance) {
1086 case kPhiNoCorrect: std::cout << "none\n"; break;
1087 case kPhiCorrectNch: std::cout << "correct Nch\n"; break;
1088 case kPhiCorrectELoss: std::cout << "correct energy loss\n"; break;
1089 }
d2638bb7 1090 std::cout << ind << " Lower cut:" << std::endl;
1091 fCuts.Print();
1174780f 1092 TString opt(option);
1093 opt.ToLower();
1094 if (opt.Contains("nomax")) return;
1095
1096 std::cout << ind << " Max weights:\n";
1097
1098 for (UShort_t d=1; d<=3; d++) {
1099 UShort_t nr = (d == 1 ? 1 : 2);
1100 for (UShort_t q=0; q<nr; q++) {
1101 ind[gROOT->GetDirLevel()] = ' ';
1102 ind[gROOT->GetDirLevel()+1] = '\0';
1103 Char_t r = (q == 0 ? 'I' : 'O');
1104 std::cout << ind << " FMD" << d << r << ":";
1105 ind[gROOT->GetDirLevel()+1] = ' ';
1106 ind[gROOT->GetDirLevel()+2] = '\0';
1107
1108 const TArrayI& a = (d == 1 ? fFMD1iMax :
1109 (d == 2 ? (r == 'I' ? fFMD2iMax : fFMD2oMax) :
1110 (r == 'I' ? fFMD3iMax : fFMD3oMax)));
1111 Int_t j = 0;
1112 for (Int_t i = 0; i < a.fN; i++) {
1113 if (a.fArray[i] < 1) continue;
1114 if (j % 6 == 0) std::cout << "\n " << ind;
1115 j++;
1116 std::cout << " " << std::setw(3) << i << ": " << a.fArray[i];
1117 }
1118 std::cout << std::endl;
1119 }
1120 }
0bd4b00f 1121}
7e4038b5 1122
1123//====================================================================
1124AliFMDDensityCalculator::RingHistos::RingHistos()
9d99b0dd 1125 : AliForwardUtil::RingHistos(),
5ca83fee 1126 fList(0),
8449e3e0 1127 // fEvsN(0),
1128 // fEvsM(0),
1129 // fEtaVsN(0),
1130 // fEtaVsM(0),
0bd4b00f 1131 fCorr(0),
9d05ffeb 1132 fDensity(0),
1133 fELossVsPoisson(0),
5ca83fee 1134 fDiffELossPoisson(0),
821ffd28 1135 fPoisson(),
f7cfc454 1136 fELoss(0),
1137 fELossUsed(0),
5ca83fee 1138 fMultCut(0),
1139 fTotal(0),
1140 fGood(0),
1141 fPhiAcc(0),
1142 fPhiBefore(0),
1143 fPhiAfter(0)
7984e5f7 1144{
1145 //
1146 // Default CTOR
1147 //
1148}
7e4038b5 1149
1150//____________________________________________________________________
1151AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
9d99b0dd 1152 : AliForwardUtil::RingHistos(d,r),
5ca83fee 1153 fList(0),
8449e3e0 1154 // fEvsN(0),
1155 // fEvsM(0),
1156 // fEtaVsN(0),
1157 // fEtaVsM(0),
0bd4b00f 1158 fCorr(0),
9d05ffeb 1159 fDensity(0),
1160 fELossVsPoisson(0),
5ca83fee 1161 fDiffELossPoisson(0),
821ffd28 1162 fPoisson("ignored"),
d2638bb7 1163 fELoss(0),
f7cfc454 1164 fELossUsed(0),
5ca83fee 1165 fMultCut(0),
1166 fTotal(0),
1167 fGood(0),
1168 fPhiAcc(0),
1169 fPhiBefore(0),
1170 fPhiAfter(0)
7e4038b5 1171{
7984e5f7 1172 //
1173 // Constructor
1174 //
1175 // Parameters:
1176 // d detector
1177 // r ring
1178 //
8449e3e0 1179#if 0
5bb5d1f6 1180 fEvsN = new TH2D("elossVsNnocorr",
1181 "#Delta E/#Delta E_{mip} vs uncorrected inclusive N_{ch}",
5ca83fee 1182 250, -.5, 24.5, 251, -1.5, 24.5);
7e4038b5 1183 fEvsN->SetXTitle("#Delta E/#Delta E_{mip}");
1184 fEvsN->SetYTitle("Inclusive N_{ch} (uncorrected)");
1185 fEvsN->Sumw2();
1186 fEvsN->SetDirectory(0);
5bb5d1f6 1187
1188 fEvsM = static_cast<TH2D*>(fEvsN->Clone("elossVsNcorr"));
1189 fEvsM->SetTitle("#Delta E/#Delta E_{mip} vs corrected inclusive N_{ch}");
7e4038b5 1190 fEvsM->SetDirectory(0);
1191
5bb5d1f6 1192 fEtaVsN = new TProfile("etaVsNnocorr",
1193 "Average inclusive N_{ch} vs #eta (uncorrected)",
1194 200, -4, 6);
0bd4b00f 1195 fEtaVsN->SetXTitle("#eta");
1196 fEtaVsN->SetYTitle("#LT N_{ch,incl}#GT (uncorrected)");
1197 fEtaVsN->SetDirectory(0);
1198 fEtaVsN->SetLineColor(Color());
1199 fEtaVsN->SetFillColor(Color());
5bb5d1f6 1200
1201 fEtaVsM = static_cast<TProfile*>(fEtaVsN->Clone("etaVsNcorr"));
1202 fEtaVsM->SetTitle("Average inclusive N_{ch} vs #eta (corrected)");
0bd4b00f 1203 fEtaVsM->SetYTitle("#LT N_{ch,incl}#GT (corrected)");
1204 fEtaVsM->SetDirectory(0);
8449e3e0 1205#endif
0bd4b00f 1206
5bb5d1f6 1207 fCorr = new TProfile("corr", "Average correction", 200, -4, 6);
0bd4b00f 1208 fCorr->SetXTitle("#eta");
1209 fCorr->SetYTitle("#LT correction#GT");
1210 fCorr->SetDirectory(0);
1211 fCorr->SetLineColor(Color());
1212 fCorr->SetFillColor(Color());
1213
5bb5d1f6 1214 fDensity = new TH2D("inclDensity", "Inclusive N_{ch} density",
7e4038b5 1215 200, -4, 6, (r == 'I' || r == 'i' ? 20 : 40),
1216 0, 2*TMath::Pi());
1217 fDensity->SetDirectory(0);
5ca83fee 1218 fDensity->Sumw2(); fDensity->SetMarkerColor(Color());
7e4038b5 1219 fDensity->SetXTitle("#eta");
1220 fDensity->SetYTitle("#phi [radians]");
1221 fDensity->SetZTitle("Inclusive N_{ch} density");
9d05ffeb 1222
5bb5d1f6 1223 fELossVsPoisson = new TH2D("elossVsPoisson",
1224 "N_{ch} from energy loss vs from Poission",
3e4a0875 1225 500, 0, 100, 500, 0, 100);
9d05ffeb 1226 fELossVsPoisson->SetDirectory(0);
1227 fELossVsPoisson->SetXTitle("N_{ch} from #DeltaE");
1228 fELossVsPoisson->SetYTitle("N_{ch} from Poisson");
1229 fELossVsPoisson->SetZTitle("Correlation");
1230
5ca83fee 1231 fDiffELossPoisson = new TH1D("diffElossPoisson",
1232 "(N_{ch,#DeltaE}-N_{ch,Poisson})/N_{ch,Poisson}",
1233 100, -1, 1);
1234 fDiffELossPoisson->SetDirectory(0);
1235 fDiffELossPoisson->SetXTitle(fDiffELossPoisson->GetTitle());
1236 fDiffELossPoisson->SetYTitle("Frequency");
1237 fDiffELossPoisson->SetMarkerColor(Color());
1238 fDiffELossPoisson->SetFillColor(Color());
bfab35d9 1239 fDiffELossPoisson->SetFillStyle(3001);
5ca83fee 1240 fDiffELossPoisson->Sumw2();
1241
f7cfc454 1242 fELoss = new TH1D("eloss", "#Delta/#Delta_{mip} in all strips",
8449e3e0 1243 640, -1, 15);
f7cfc454 1244 fELoss->SetXTitle("#Delta/#Delta_{mip} (selected)");
1245 fELoss->SetYTitle("P(#Delta/#Delta_{mip})");
1246 fELoss->SetFillColor(Color()-2);
1247 fELoss->SetFillStyle(3003);
1248 fELoss->SetLineColor(kBlack);
1249 fELoss->SetLineStyle(2);
1250 fELoss->SetLineWidth(2);
1251 fELoss->SetDirectory(0);
1252
1253 fELossUsed = static_cast<TH1D*>(fELoss->Clone("elossUsed"));
1254 fELossUsed->SetTitle("#Delta/#Delta_{mip} in used strips");
1255 fELossUsed->SetFillStyle(3002);
1256 fELossUsed->SetLineStyle(1);
1257 fELossUsed->SetDirectory(0);
5ca83fee 1258
1259 fPhiBefore = new TH1D("phiBefore", "#phi distribution (before recalc)",
1260 (r == 'I' || r == 'i' ? 20 : 40), 0, 2*TMath::Pi());
1261 fPhiBefore->SetDirectory(0);
1262 fPhiBefore->SetXTitle("#phi");
1263 fPhiBefore->SetYTitle("Events");
1264 fPhiBefore->SetMarkerColor(Color());
1265 fPhiBefore->SetLineColor(Color());
1266 fPhiBefore->SetFillColor(Color());
bfab35d9 1267 fPhiBefore->SetFillStyle(3001);
5ca83fee 1268 fPhiBefore->SetMarkerStyle(20);
1269
1270 fPhiAfter = static_cast<TH1D*>(fPhiBefore->Clone("phiAfter"));
1271 fPhiAfter->SetTitle("#phi distribution (after re-calc)");
1272 fPhiAfter->SetDirectory(0);
f7cfc454 1273
7e4038b5 1274}
1275//____________________________________________________________________
1276AliFMDDensityCalculator::RingHistos::RingHistos(const RingHistos& o)
5ca83fee 1277 : AliForwardUtil::RingHistos(o),
1278 fList(o.fList),
8449e3e0 1279 // fEvsN(o.fEvsN),
1280 // fEvsM(o.fEvsM),
1281 // fEtaVsN(o.fEtaVsN),
1282 // fEtaVsM(o.fEtaVsM),
0bd4b00f 1283 fCorr(o.fCorr),
9d05ffeb 1284 fDensity(o.fDensity),
1285 fELossVsPoisson(o.fELossVsPoisson),
5ca83fee 1286 fDiffELossPoisson(o.fDiffELossPoisson),
821ffd28 1287 fPoisson(o.fPoisson),
f7cfc454 1288 fELoss(o.fELoss),
1289 fELossUsed(o.fELossUsed),
5ca83fee 1290 fMultCut(o.fMultCut),
1291 fTotal(o.fTotal),
1292 fGood(o.fGood),
1293 fPhiAcc(o.fPhiAcc),
1294 fPhiBefore(o.fPhiBefore),
1295 fPhiAfter(o.fPhiAfter)
7984e5f7 1296{
1297 //
1298 // Copy constructor
1299 //
1300 // Parameters:
1301 // o Object to copy from
1302 //
1303}
7e4038b5 1304
1305//____________________________________________________________________
1306AliFMDDensityCalculator::RingHistos&
1307AliFMDDensityCalculator::RingHistos::operator=(const RingHistos& o)
1308{
7984e5f7 1309 //
1310 // Assignment operator
1311 //
1312 // Parameters:
1313 // o Object to assign from
1314 //
1315 // Return:
1316 // Reference to this
1317 //
d015ecfe 1318 if (&o == this) return *this;
9d99b0dd 1319 AliForwardUtil::RingHistos::operator=(o);
7e4038b5 1320
8449e3e0 1321 // if (fEvsN) delete fEvsN;
1322 // if (fEvsM) delete fEvsM;
1323 // if (fEtaVsN) delete fEtaVsN;
1324 // if (fEtaVsM) delete fEtaVsM;
5ca83fee 1325 if (fCorr) delete fCorr;
1326 if (fDensity) delete fDensity;
1327 if (fELossVsPoisson) delete fELossVsPoisson;
1328 if (fDiffELossPoisson) delete fDiffELossPoisson;
1329 if (fTotal) delete fTotal;
1330 if (fGood) delete fGood;
1331 if (fPhiAcc) delete fPhiAcc;
1332 if (fPhiBefore) delete fPhiBefore;
1333 if (fPhiAfter) delete fPhiAfter;
1334
8449e3e0 1335 // fEvsN = static_cast<TH2D*>(o.fEvsN->Clone());
1336 // fEvsM = static_cast<TH2D*>(o.fEvsM->Clone());
1337 // fEtaVsN = static_cast<TProfile*>(o.fEtaVsN->Clone());
1338 // fEtaVsM = static_cast<TProfile*>(o.fEtaVsM->Clone());
5ca83fee 1339 fCorr = static_cast<TProfile*>(o.fCorr->Clone());
1340 fDensity = static_cast<TH2D*>(o.fDensity->Clone());
1341 fELossVsPoisson = static_cast<TH2D*>(o.fELossVsPoisson->Clone());
1342 fDiffELossPoisson = static_cast<TH1D*>(o.fDiffELossPoisson->Clone());
1343 fPoisson = o.fPoisson;
1344 fELoss = static_cast<TH1D*>(o.fELoss->Clone());
1345 fELossUsed = static_cast<TH1D*>(o.fELossUsed->Clone());
1346 fTotal = static_cast<TH1D*>(o.fTotal->Clone());
1347 fGood = static_cast<TH1D*>(o.fGood->Clone());
1348 fPhiAcc = static_cast<TH2D*>(o.fPhiAcc->Clone());
1349 fPhiBefore = static_cast<TH1D*>(o.fPhiBefore->Clone());
1350 fPhiAfter = static_cast<TH1D*>(o.fPhiAfter->Clone());
7e4038b5 1351 return *this;
1352}
1353//____________________________________________________________________
1354AliFMDDensityCalculator::RingHistos::~RingHistos()
1355{
7984e5f7 1356 //
1357 // Destructor
1358 //
9d05ffeb 1359}
1360
e308a636 1361
1362//____________________________________________________________________
9d05ffeb 1363void
5934a3e3 1364AliFMDDensityCalculator::RingHistos::SetupForData(const TAxis& eAxis)
9d05ffeb 1365{
5ca83fee 1366 // Initialize
1367 // This is called on first event
e18cb8bd 1368 fPoisson.Init(-1,-1);
5ca83fee 1369 fTotal = new TH1D("total", "Total # of strips per #eta",
1370 eAxis.GetNbins(), eAxis.GetXmin(), eAxis.GetXmax());
1371 fTotal->SetDirectory(0);
1372 fTotal->SetXTitle("#eta");
1373 fTotal->SetYTitle("# of strips");
1374 fGood = static_cast<TH1D*>(fTotal->Clone("good"));
1375 fGood->SetTitle("# of good strips per #eta");
1376 fGood->SetDirectory(0);
1377
1378 fPhiAcc = new TH2D("phiAcc", "#phi acceptance vs Ip_{z}",
1379 eAxis.GetNbins(), eAxis.GetXmin(), eAxis.GetXmax(),
1380 10, -10, 10);
1381 fPhiAcc->SetXTitle("#eta");
1382 fPhiAcc->SetYTitle("v_{z} [cm]");
1383 fPhiAcc->SetZTitle("#phi acceptance");
1384 fPhiAcc->SetDirectory(0);
1385
1386 if (fList) fList->Add(fPhiAcc);
7e4038b5 1387}
1388
1389//____________________________________________________________________
1390void
5934a3e3 1391AliFMDDensityCalculator::RingHistos::CreateOutputObjects(TList* dir)
7e4038b5 1392{
7984e5f7 1393 //
5ca83fee 1394 // Make output. This is called as part of SlaveBegin
7984e5f7 1395 //
1396 // Parameters:
1397 // dir Where to put it
1398 //
9d99b0dd 1399 TList* d = DefineOutputList(dir);
8449e3e0 1400 // d->Add(fEvsN);
1401 // d->Add(fEvsM);
1402 // d->Add(fEtaVsN);
1403 // d->Add(fEtaVsM);
0bd4b00f 1404 d->Add(fCorr);
7e4038b5 1405 d->Add(fDensity);
9d05ffeb 1406 d->Add(fELossVsPoisson);
5ca83fee 1407 d->Add(fDiffELossPoisson);
821ffd28 1408 fPoisson.Output(d);
d23503ee 1409 fPoisson.GetOccupancy()->SetFillColor(Color());
1410 fPoisson.GetMean()->SetFillColor(Color());
1411 fPoisson.GetOccupancy()->SetFillColor(Color());
f7cfc454 1412 d->Add(fELoss);
1413 d->Add(fELossUsed);
5ca83fee 1414 d->Add(fPhiBefore);
1415 d->Add(fPhiAfter);
d23503ee 1416
1417 Bool_t inner = (fRing == 'I' || fRing == 'i');
1418 Int_t nStr = inner ? 512 : 256;
1419 Int_t nSec = inner ? 20 : 40;
1420 TAxis x(nStr, -.5, nStr-.5);
1421 TAxis y(nSec, -.5, nSec-.5);
1422 x.SetTitle("strip");
1423 y.SetTitle("sector");
1424 fPoisson.Define(x, y);
1425
241cca4d 1426 d->Add(AliForwardUtil::MakeParameter("cut", fMultCut));
5ca83fee 1427 fList = d;
9d99b0dd 1428}
1429
1430//____________________________________________________________________
1431void
5934a3e3 1432AliFMDDensityCalculator::RingHistos::Terminate(TList* dir, Int_t nEvents)
9d99b0dd 1433{
7984e5f7 1434 //
1435 // Scale the histograms to the total number of events
1436 //
1437 // Parameters:
1438 // dir Where the output is
1439 // nEvents Number of events
1440 //
9d99b0dd 1441 TList* l = GetOutputList(dir);
1442 if (!l) return;
1443
5934a3e3 1444 TH2D* density = static_cast<TH2D*>(GetOutputHist(l,"inclDensity"));
9d99b0dd 1445 if (density) density->Scale(1./nEvents);
5934a3e3 1446 fDensity = density;
7e4038b5 1447}
1448
1449//____________________________________________________________________
1450//
1451// EOF
1452//
1453
1454
1455