1 // This class calculates the inclusive charged particle density
2 // in each for the 5 FMD rings.
4 #include "AliFMDDensityCalculator.h"
9 #include "AliForwardCorrectionManager.h"
10 #include "AliFMDCorrDoubleHit.h"
11 #include "AliFMDCorrELossFit.h"
17 #include <TParameter.h>
21 ClassImp(AliFMDDensityCalculator)
26 //____________________________________________________________________
27 AliFMDDensityCalculator::AliFMDDensityCalculator()
35 fUsePhiAcceptance(kPhiCorrectNch),
49 fRecalculateEta(false)
54 DGUARD(fDebug, 0, "Default CTOR of FMD density calculator");
57 //____________________________________________________________________
58 AliFMDDensityCalculator::AliFMDDensityCalculator(const char* title)
59 : TNamed("fmdDensityCalculator", title),
66 fUsePhiAcceptance(kPhiCorrectNch),
80 fRecalculateEta(false)
86 // name Name of object
88 DGUARD(fDebug, 0, "Named CTOR of FMD density calculator: %s", title);
89 fRingHistos.SetName(GetName());
90 fRingHistos.SetOwner();
91 fRingHistos.Add(new RingHistos(1, 'I'));
92 fRingHistos.Add(new RingHistos(2, 'I'));
93 fRingHistos.Add(new RingHistos(2, 'O'));
94 fRingHistos.Add(new RingHistos(3, 'I'));
95 fRingHistos.Add(new RingHistos(3, 'O'));
96 fSumOfWeights = new TH1D("sumOfWeights", "Sum of Landau weights",
98 fSumOfWeights->SetFillColor(kRed+1);
99 fSumOfWeights->SetXTitle("#sum_{i} a_{i} f_{i}(#Delta)");
100 fWeightedSum = new TH1D("weightedSum", "Weighted sum of Landau propability",
102 fWeightedSum->SetFillColor(kBlue+1);
103 fWeightedSum->SetXTitle("#sum_{i} i a_{i} f_{i}(#Delta)");
104 fCorrections = new TH1D("corrections", "Distribution of corrections",
106 fCorrections->SetFillColor(kBlue+1);
107 fCorrections->SetXTitle("correction");
109 fAccI = GenerateAcceptanceCorrection('I');
110 fAccO = GenerateAcceptanceCorrection('O');
112 fMaxWeights = new TH2D("maxWeights", "Maximum i of a_{i}'s to use",
114 fMaxWeights->SetXTitle("#eta");
115 fMaxWeights->SetDirectory(0);
117 fLowCuts = new TH2D("lowCuts", "Low cuts used", 1, 0, 1, 1, 0, 1);
118 fLowCuts->SetXTitle("#eta");
119 fLowCuts->SetDirectory(0);
123 //____________________________________________________________________
124 AliFMDDensityCalculator::AliFMDDensityCalculator(const
125 AliFMDDensityCalculator& o)
128 fSumOfWeights(o.fSumOfWeights),
129 fWeightedSum(o.fWeightedSum),
130 fCorrections(o.fCorrections),
131 fMaxParticles(o.fMaxParticles),
132 fUsePoisson(o.fUsePoisson),
133 fUsePhiAcceptance(o.fUsePhiAcceptance),
136 fFMD1iMax(o.fFMD1iMax),
137 fFMD2iMax(o.fFMD2iMax),
138 fFMD2oMax(o.fFMD2oMax),
139 fFMD3iMax(o.fFMD3iMax),
140 fFMD3oMax(o.fFMD3oMax),
141 fMaxWeights(o.fMaxWeights),
142 fLowCuts(o.fLowCuts),
143 fEtaLumping(o.fEtaLumping),
144 fPhiLumping(o.fPhiLumping),
147 fRecalculateEta(o.fRecalculateEta)
153 // o Object to copy from
155 DGUARD(fDebug, 0, "Copy CTOR of FMD density calculator");
156 TIter next(&o.fRingHistos);
158 while ((obj = next())) fRingHistos.Add(obj);
161 //____________________________________________________________________
162 AliFMDDensityCalculator::~AliFMDDensityCalculator()
167 DGUARD(fDebug, 3, "DTOR of FMD density calculator");
168 fRingHistos.Delete();
171 //____________________________________________________________________
172 AliFMDDensityCalculator&
173 AliFMDDensityCalculator::operator=(const AliFMDDensityCalculator& o)
176 // Assignement operator
179 // o Object to assign from
182 // Reference to this object
184 DGUARD(fDebug, 3, "Assignment of FMD density calculator");
185 if (&o == this) return *this;
186 TNamed::operator=(o);
189 fMaxParticles = o.fMaxParticles;
190 fUsePoisson = o.fUsePoisson;
191 fUsePhiAcceptance = o.fUsePhiAcceptance;
194 fFMD1iMax = o.fFMD1iMax;
195 fFMD2iMax = o.fFMD2iMax;
196 fFMD2oMax = o.fFMD2oMax;
197 fFMD3iMax = o.fFMD3iMax;
198 fFMD3oMax = o.fFMD3oMax;
199 fMaxWeights = o.fMaxWeights;
200 fLowCuts = o.fLowCuts;
201 fEtaLumping = o.fEtaLumping;
202 fPhiLumping = o.fPhiLumping;
204 fRecalculateEta = o.fRecalculateEta;
206 fRingHistos.Delete();
207 TIter next(&o.fRingHistos);
209 while ((obj = next())) fRingHistos.Add(obj);
214 //____________________________________________________________________
216 AliFMDDensityCalculator::Init(const TAxis& axis)
218 // Intialize this sub-algorithm
222 DGUARD(fDebug, 1, "Initialize FMD density calculator");
225 TIter next(&fRingHistos);
227 while ((o = static_cast<RingHistos*>(next()))) {
229 // o->fMultCut = fCuts.GetFixedCut(o->fDet, o->fRing);
230 // o->fPoisson.Init(o->fDet,o->fRing,fEtaLumping, fPhiLumping);
234 //____________________________________________________________________
235 AliFMDDensityCalculator::RingHistos*
236 AliFMDDensityCalculator::GetRingHistos(UShort_t d, Char_t r) const
239 // Get the ring histogram container
246 // Ring histogram container
250 case 1: idx = 0; break;
251 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
252 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
254 if (idx < 0 || idx >= fRingHistos.GetEntries()) {
255 AliWarning(Form("Index %d of FMD%d%c out of range", idx, d, r));
259 return static_cast<RingHistos*>(fRingHistos.At(idx));
262 //____________________________________________________________________
264 AliFMDDensityCalculator::GetMultCut(UShort_t d, Char_t r, Int_t ieta,
268 // Get the multiplicity cut. If the user has set fMultCut (via
269 // SetMultCut) then that value is used. If not, then the lower
270 // value of the fit range for the enery loss fits is returned.
273 // Lower cut on multiplicity
275 return fCuts.GetMultCut(d,r,ieta,errors);
278 //____________________________________________________________________
280 AliFMDDensityCalculator::GetMultCut(UShort_t d, Char_t r, Double_t eta,
284 // Get the multiplicity cut. If the user has set fMultCut (via
285 // SetMultCut) then that value is used. If not, then the lower
286 // value of the fit range for the enery loss fits is returned.
289 // Lower cut on multiplicity
291 return fCuts.GetMultCut(d,r,eta,errors);
294 //____________________________________________________________________
296 AliFMDDensityCalculator::Calculate(const AliESDFMD& fmd,
297 AliForwardUtil::Histos& hists,
304 // Do the calculations
307 // fmd AliESDFMD object (possibly) corrected for sharing
308 // hists Histogram cache
310 // lowFlux Low flux flag.
314 DGUARD(fDebug, 1, "Calculate density in FMD density calculator");
316 for (UShort_t d=1; d<=3; d++) {
317 UShort_t nr = (d == 1 ? 1 : 2);
318 for (UShort_t q=0; q<nr; q++) {
319 Char_t r = (q == 0 ? 'I' : 'O');
320 UShort_t ns= (q == 0 ? 20 : 40);
321 UShort_t nt= (q == 0 ? 512 : 256);
322 TH2D* h = hists.Get(d,r);
323 RingHistos* rh= GetRingHistos(d,r);
325 AliError(Form("No ring histogram found for FMD%d%c", d, r));
329 // rh->fPoisson.SetObject(d,r,vtxbin,cent);
330 rh->fPoisson.Reset(0);
331 // rh->ResetPoissonHistos(h, fEtaLumping, fPhiLumping);
333 for (UShort_t s=0; s<ns; s++) {
334 for (UShort_t t=0; t<nt; t++) {
336 Float_t mult = fmd.Multiplicity(d,r,s,t);
337 Float_t phi = fmd.Phi(d,r,s,t) / 180 * TMath::Pi();
338 Float_t eta = fmd.Eta(d,r,s,t);
342 eta = AliForwardUtil::GetEtaFromStrip(d,r,s,t,zvtx);
344 if (mult == AliESDFMD::kInvalidMult || mult > 20) {
345 rh->fPoisson.Fill(t , s, false);
346 rh->fEvsM->Fill(mult,0);
349 if (fUsePhiAcceptance == kPhiCorrectELoss)
350 mult *= AcceptanceCorrection(r,t);
353 if (eta != AliESDFMD::kInvalidEta) cut = GetMultCut(d, r, eta,false);
356 if (cut > 0 && mult > cut)
357 n = NParticles(mult,d,r,s,t,vtxbin,eta,lowFlux);
359 rh->fELoss->Fill(mult);
360 rh->fEvsN->Fill(mult,n);
361 rh->fEtaVsN->Fill(eta, n);
363 Double_t c = Correction(d,r,s,t,vtxbin,eta,lowFlux);
364 fCorrections->Fill(c);
366 rh->fEvsM->Fill(mult,n);
367 rh->fEtaVsM->Fill(eta, n);
368 rh->fCorr->Fill(eta, c);
370 Bool_t hit = (n > 0.9 && c > 0);
371 if (hit) rh->fELossUsed->Fill(mult);
372 rh->fPoisson.Fill(t,s,hit,1./c);
374 if (!fUsePoisson) rh->fDensity->Fill(eta,phi,n);
378 TH2D* hclone = static_cast<TH2D*>(h->Clone("hclone"));
379 if (!fUsePoisson) hclone->Reset();
380 if ( fUsePoisson) h->Reset();
382 TH2D* poisson = rh->fPoisson.Result();
383 for (Int_t t=0; t < poisson->GetNbinsX(); t++) {
384 for (Int_t s=0; s < poisson->GetNbinsY(); s++) {
386 Double_t poissonV = poisson->GetBinContent(t+1,s+1);
387 Double_t phi = fmd.Phi(d,r,s,t) / 180 * TMath::Pi();
388 Double_t eta = fmd.Eta(d,r,s,t);
390 eta = AliForwardUtil::GetEtaFromStrip(d,r,s,t,zvtx);
392 h->Fill(eta,phi,poissonV);
394 hclone->Fill(eta,phi,poissonV);
395 if (fUsePoisson) rh->fDensity->Fill(eta, phi, poissonV);
399 for (Int_t ieta=1; ieta <= h->GetNbinsX(); ieta++) {
400 for (Int_t iphi=1; iphi<= h->GetNbinsY(); iphi++) {
402 Double_t poissonV = 0; //h->GetBinContent(,s+1);
405 poissonV = h->GetBinContent(ieta,iphi);
406 eLossV = hclone->GetBinContent(ieta,iphi);
409 poissonV = hclone->GetBinContent(ieta,iphi);
410 eLossV = h->GetBinContent(ieta,iphi);
413 rh->fELossVsPoisson->Fill(eLossV, poissonV);
424 //_____________________________________________________________________
426 AliFMDDensityCalculator::FindMaxWeight(const AliFMDCorrELossFit* cor,
427 UShort_t d, Char_t r, Int_t iEta) const
430 // Find the max weight to use for FMD<i>dr</i> in eta bin @a iEta
438 DGUARD(fDebug, 3, "Find maximum weight in FMD density calculator");
441 AliFMDCorrELossFit::ELossFit* fit = cor->GetFit(d,r,iEta);
443 // AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f", d, r, eta));
446 return TMath::Min(Int_t(fMaxParticles), fit->FindMaxWeight());
449 //_____________________________________________________________________
451 AliFMDDensityCalculator::CacheMaxWeights()
454 // Find the max weights and cache them
456 DGUARD(fDebug, 2, "Cache maximum weights in FMD density calculator");
457 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
458 AliFMDCorrELossFit* cor = fcm.GetELossFit();
461 eta.Set(cor->GetEtaAxis().GetNbins(),
462 cor->GetEtaAxis().GetXmin(),
463 cor->GetEtaAxis().GetXmax());
465 Int_t nEta = eta.GetNbins();
472 fMaxWeights->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
473 fMaxWeights->GetYaxis()->SetBinLabel(1, "FMD1i");
474 fMaxWeights->GetYaxis()->SetBinLabel(2, "FMD2i");
475 fMaxWeights->GetYaxis()->SetBinLabel(3, "FMD2o");
476 fMaxWeights->GetYaxis()->SetBinLabel(4, "FMD3i");
477 fMaxWeights->GetYaxis()->SetBinLabel(5, "FMD3o");
479 AliInfo(Form("Get eta axis with %d bins from %f to %f",
480 nEta, eta.GetXmin(), eta.GetXmax()));
481 fLowCuts->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
482 fLowCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
483 fLowCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
484 fLowCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
485 fLowCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
486 fLowCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
488 for (Int_t i = 0; i < nEta; i++) {
490 w[0] = fFMD1iMax[i] = FindMaxWeight(cor, 1, 'I', i+1);
491 w[1] = fFMD2iMax[i] = FindMaxWeight(cor, 2, 'I', i+1);
492 w[2] = fFMD2oMax[i] = FindMaxWeight(cor, 2, 'O', i+1);
493 w[3] = fFMD3iMax[i] = FindMaxWeight(cor, 3, 'I', i+1);
494 w[4] = fFMD3oMax[i] = FindMaxWeight(cor, 3, 'O', i+1);
496 l[0] = GetMultCut(1, 'I', i+1, false);
497 l[1] = GetMultCut(2, 'I', i+1, false);
498 l[2] = GetMultCut(2, 'O', i+1, false);
499 l[3] = GetMultCut(3, 'I', i+1, false);
500 l[4] = GetMultCut(3, 'O', i+1, false);
501 for (Int_t j = 0; j < 5; j++) {
502 if (w[j] > 0) fMaxWeights->SetBinContent(i+1, j+1, w[j]);
503 if (l[j] > 0) fLowCuts->SetBinContent(i+1, j+1, l[j]);
508 //_____________________________________________________________________
510 AliFMDDensityCalculator::GetMaxWeight(UShort_t d, Char_t r, Int_t iEta) const
513 // Find the (cached) maximum weight for FMD<i>dr</i> in
514 // @f$\eta@f$ bin @a iEta
522 // max weight or <= 0 in case of problems
524 if (iEta < 0) return -1;
526 const TArrayI* max = 0;
528 case 1: max = &fFMD1iMax; break;
529 case 2: max = (r == 'I' || r == 'i' ? &fFMD2iMax : &fFMD2oMax); break;
530 case 3: max = (r == 'I' || r == 'i' ? &fFMD3iMax : &fFMD3oMax); break;
533 AliWarning(Form("No array for FMD%d%c", d, r));
537 if (iEta >= max->fN) {
538 AliWarning(Form("Eta bin %3d out of bounds [0,%d]",
543 AliDebug(30,Form("Max weight for FMD%d%c eta bin %3d: %d", d, r, iEta,
545 return max->At(iEta);
548 //_____________________________________________________________________
550 AliFMDDensityCalculator::GetMaxWeight(UShort_t d, Char_t r, Float_t eta) const
553 // Find the (cached) maximum weight for FMD<i>dr</i> iat
562 // max weight or <= 0 in case of problems
564 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
565 Int_t iEta = fcm.GetELossFit()->FindEtaBin(eta) -1;
567 return GetMaxWeight(d, r, iEta);
570 //_____________________________________________________________________
572 AliFMDDensityCalculator::NParticles(Float_t mult,
579 Bool_t lowFlux) const
582 // Get the number of particles corresponding to the signal mult
589 // t Strip (not used)
591 // eta Pseudo-rapidity
592 // lowFlux Low-flux flag
595 // The number of particles
597 // if (mult <= GetMultCut()) return 0;
598 DGUARD(fDebug, 3, "Calculate Nch in FMD density calculator");
599 if (lowFlux) return 1;
601 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
602 AliFMDCorrELossFit::ELossFit* fit = fcm.GetELossFit()->FindFit(d,r,eta);
604 AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f", d, r, eta));
608 Int_t m = GetMaxWeight(d,r,eta); // fit->FindMaxWeight();
610 AliWarning(Form("No good fits for FMD%d%c at eta=%f", d, r, eta));
614 UShort_t n = TMath::Min(fMaxParticles, UShort_t(m));
615 Double_t ret = fit->EvaluateWeighted(mult, n);
618 AliInfo(Form("FMD%d%c, eta=%7.4f, %8.5f -> %8.5f", d, r, eta, mult, ret));
621 fWeightedSum->Fill(ret);
622 fSumOfWeights->Fill(ret);
627 //_____________________________________________________________________
629 AliFMDDensityCalculator::Correction(UShort_t d,
635 Bool_t lowFlux) const
638 // Get the inverse correction factor. This consist of
640 // - acceptance correction (corners of sensors)
641 // - double hit correction (for low-flux events)
642 // - dead strip correction
648 // t Strip (not used)
650 // eta Pseudo-rapidity
651 // lowFlux Low-flux flag
656 DGUARD(fDebug, 3, "Apply correction in FMD density calculator");
657 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
659 Float_t correction = 1;
660 if (fUsePhiAcceptance == kPhiCorrectNch)
661 correction = AcceptanceCorrection(r,t);
664 if (fcm.GetDoubleHit())
665 dblHitCor = fcm.GetDoubleHit()->GetCorrection(d,r);
668 Double_t dblC = dblHitCor->GetBinContent(dblHitCor->FindBin(eta));
669 if (dblC > 0) correction *= dblC;
672 AliWarning(Form("Missing double hit correction for FMD%d%c",d,r));
678 //_____________________________________________________________________
680 AliFMDDensityCalculator::GenerateAcceptanceCorrection(Char_t r) const
683 // Generate the acceptance corrections
686 // r Ring to generate for
689 // Newly allocated histogram of acceptance corrections
691 DGUARD(fDebug, 3, "Make acceptance correction in FMD density calculator");
692 const Double_t ic1[] = { 4.9895, 15.3560 };
693 const Double_t ic2[] = { 1.8007, 17.2000 };
694 const Double_t oc1[] = { 4.2231, 26.6638 };
695 const Double_t oc2[] = { 1.8357, 27.9500 };
696 const Double_t* c1 = (r == 'I' || r == 'i' ? ic1 : oc1);
697 const Double_t* c2 = (r == 'I' || r == 'i' ? ic2 : oc2);
698 Double_t minR = (r == 'I' || r == 'i' ? 4.5213 : 15.4);
699 Double_t maxR = (r == 'I' || r == 'i' ? 17.2 : 28.0);
700 Int_t nStrips = (r == 'I' || r == 'i' ? 512 : 256);
701 Int_t nSec = (r == 'I' || r == 'i' ? 20 : 40);
702 Float_t basearc = 2 * TMath::Pi() / nSec;
703 Double_t rad = maxR - minR;
704 Float_t segment = rad / nStrips;
705 Float_t cr = TMath::Sqrt(c1[0]*c1[0]+c1[1]*c1[1]);
707 // Numbers used to find end-point of strip.
708 // (See http://mathworld.wolfram.com/Circle-LineIntersection.html)
709 Float_t D = c1[0] * c2[1] - c1[1] * c2[0];
710 Float_t dx = c2[0] - c1[0];
711 Float_t dy = c2[1] - c1[1];
712 Float_t dr = TMath::Sqrt(dx*dx+dy*dy);
714 TH1D* ret = new TH1D(Form("acc%c", r),
715 Form("Acceptance correction for FMDx%c", r),
716 nStrips, -.5, nStrips-.5);
717 ret->SetXTitle("Strip");
718 ret->SetYTitle("#varphi acceptance");
719 ret->SetDirectory(0);
720 ret->SetFillColor(r == 'I' || r == 'i' ? kRed+1 : kBlue+1);
721 ret->SetFillStyle(3001);
723 for (Int_t t = 0; t < nStrips; t++) {
724 Float_t radius = minR + t * segment;
726 // If the radius of the strip is smaller than the radius corresponding
727 // to the first corner we have a full strip length
729 ret->SetBinContent(t+1, 1);
733 // Next, we should find the end-point of the strip - that is,
734 // the coordinates where the line from c1 to c2 intersects a circle
735 // with radius given by the strip.
736 // (See http://mathworld.wolfram.com/Circle-LineIntersection.html)
737 // Calculate the determinant
738 Float_t det = radius * radius * dr * dr - D*D;
741 // <0 means No intersection
742 // =0 means Exactly tangent
743 ret->SetBinContent(t+1, 1);
747 // Calculate end-point and the corresponding opening angle
748 Float_t x = (+D * dy + dx * TMath::Sqrt(det)) / dr / dr;
749 Float_t y = (-D * dx + dy * TMath::Sqrt(det)) / dr / dr;
750 Float_t th = TMath::ATan2(x, y);
752 ret->SetBinContent(t+1, th / basearc);
757 //_____________________________________________________________________
759 AliFMDDensityCalculator::AcceptanceCorrection(Char_t r, UShort_t t) const
762 // Get the acceptance correction for strip @a t in an ring of type @a r
765 // r Ring type ('I' or 'O')
769 // Inverse acceptance correction
771 TH1D* acc = (r == 'I' || r == 'i' ? fAccI : fAccO);
772 return acc->GetBinContent(t+1);
775 //____________________________________________________________________
777 AliFMDDensityCalculator::ScaleHistograms(const TList* dir, Int_t nEvents)
780 // Scale the histograms to the total number of events
783 // dir where to put the output
784 // nEvents Number of events
786 DGUARD(fDebug, 1, "Scale histograms in FMD density calculator");
787 if (nEvents <= 0) return;
788 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
791 TIter next(&fRingHistos);
793 THStack* sums = new THStack("sums", "sums of ring signals");
794 while ((o = static_cast<RingHistos*>(next()))) {
795 o->ScaleHistograms(d, nEvents);
796 TH1D* sum = o->fDensity->ProjectionX(o->GetName(), 1,
797 o->fDensity->GetNbinsY(),"e");
798 sum->Scale(1., "width");
799 sum->SetTitle(o->GetName());
800 sum->SetDirectory(0);
801 sum->SetYTitle("#sum N_{ch,incl}");
807 //____________________________________________________________________
809 AliFMDDensityCalculator::DefineOutput(TList* dir)
812 // Output diagnostic histograms to directory
815 // dir List to write in
817 DGUARD(fDebug, 1, "Define output FMD density calculator");
818 TList* d = new TList;
820 d->SetName(GetName());
822 d->Add(fWeightedSum);
823 d->Add(fSumOfWeights);
824 d->Add(fCorrections);
830 // TNamed* sigma = new TNamed("sigma",
831 // (fIncludeSigma ? "included" : "excluded"));
832 TNamed* maxP = new TNamed("maxParticle", Form("%d", fMaxParticles));
833 TNamed* method = new TNamed("method",
834 (fUsePoisson ? "Poisson" : "Energy loss"));
835 TNamed* phiA = new TNamed("phiAcceptance",
836 (fUsePhiAcceptance == 0 ? "disabled" :
837 fUsePhiAcceptance == 1 ? "particles" :
839 TNamed* etaL = new TNamed("etaLumping", Form("%d", fEtaLumping));
840 TNamed* phiL = new TNamed("phiLumping", Form("%d", fPhiLumping));
841 // TParameter<double>* nxi = new TParameter<double>("nXi", fNXi);
852 TIter next(&fRingHistos);
854 while ((o = static_cast<RingHistos*>(next()))) {
855 o->fPoisson.SetLumping(fEtaLumping, fPhiLumping);
859 //____________________________________________________________________
861 AliFMDDensityCalculator::Print(Option_t* option) const
869 char ind[gROOT->GetDirLevel()+3];
870 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
871 ind[gROOT->GetDirLevel()] = '\0';
872 std::cout << ind << ClassName() << ": " << GetName() << '\n'
874 << ind << " Max(particles): " << fMaxParticles << '\n'
875 << ind << " Poisson method: " << fUsePoisson << '\n'
876 << ind << " Use phi acceptance: " << fUsePhiAcceptance << '\n'
877 << ind << " Eta lumping: " << fEtaLumping << '\n'
878 << ind << " Phi lumping: " << fPhiLumping << '\n'
881 std::cout << ind << " Lower cut:" << std::endl;
885 if (opt.Contains("nomax")) return;
887 std::cout << ind << " Max weights:\n";
889 for (UShort_t d=1; d<=3; d++) {
890 UShort_t nr = (d == 1 ? 1 : 2);
891 for (UShort_t q=0; q<nr; q++) {
892 ind[gROOT->GetDirLevel()] = ' ';
893 ind[gROOT->GetDirLevel()+1] = '\0';
894 Char_t r = (q == 0 ? 'I' : 'O');
895 std::cout << ind << " FMD" << d << r << ":";
896 ind[gROOT->GetDirLevel()+1] = ' ';
897 ind[gROOT->GetDirLevel()+2] = '\0';
899 const TArrayI& a = (d == 1 ? fFMD1iMax :
900 (d == 2 ? (r == 'I' ? fFMD2iMax : fFMD2oMax) :
901 (r == 'I' ? fFMD3iMax : fFMD3oMax)));
903 for (Int_t i = 0; i < a.fN; i++) {
904 if (a.fArray[i] < 1) continue;
905 if (j % 6 == 0) std::cout << "\n " << ind;
907 std::cout << " " << std::setw(3) << i << ": " << a.fArray[i];
909 std::cout << std::endl;
914 //====================================================================
915 AliFMDDensityCalculator::RingHistos::RingHistos()
916 : AliForwardUtil::RingHistos(),
934 //____________________________________________________________________
935 AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
936 : AliForwardUtil::RingHistos(d,r),
956 fEvsN = new TH2D("elossVsNnocorr",
957 "#Delta E/#Delta E_{mip} vs uncorrected inclusive N_{ch}",
958 250, -.5, 24.5, 250, -.5, 24.5);
959 fEvsN->SetXTitle("#Delta E/#Delta E_{mip}");
960 fEvsN->SetYTitle("Inclusive N_{ch} (uncorrected)");
962 fEvsN->SetDirectory(0);
964 fEvsM = static_cast<TH2D*>(fEvsN->Clone("elossVsNcorr"));
965 fEvsM->SetTitle("#Delta E/#Delta E_{mip} vs corrected inclusive N_{ch}");
966 fEvsM->SetDirectory(0);
968 fEtaVsN = new TProfile("etaVsNnocorr",
969 "Average inclusive N_{ch} vs #eta (uncorrected)",
971 fEtaVsN->SetXTitle("#eta");
972 fEtaVsN->SetYTitle("#LT N_{ch,incl}#GT (uncorrected)");
973 fEtaVsN->SetDirectory(0);
974 fEtaVsN->SetLineColor(Color());
975 fEtaVsN->SetFillColor(Color());
977 fEtaVsM = static_cast<TProfile*>(fEtaVsN->Clone("etaVsNcorr"));
978 fEtaVsM->SetTitle("Average inclusive N_{ch} vs #eta (corrected)");
979 fEtaVsM->SetYTitle("#LT N_{ch,incl}#GT (corrected)");
980 fEtaVsM->SetDirectory(0);
983 fCorr = new TProfile("corr", "Average correction", 200, -4, 6);
984 fCorr->SetXTitle("#eta");
985 fCorr->SetYTitle("#LT correction#GT");
986 fCorr->SetDirectory(0);
987 fCorr->SetLineColor(Color());
988 fCorr->SetFillColor(Color());
990 fDensity = new TH2D("inclDensity", "Inclusive N_{ch} density",
991 200, -4, 6, (r == 'I' || r == 'i' ? 20 : 40),
993 fDensity->SetDirectory(0);
995 fDensity->SetMarkerColor(Color());
996 fDensity->SetXTitle("#eta");
997 fDensity->SetYTitle("#phi [radians]");
998 fDensity->SetZTitle("Inclusive N_{ch} density");
1000 fELossVsPoisson = new TH2D("elossVsPoisson",
1001 "N_{ch} from energy loss vs from Poission",
1002 500, 0, 100, 500, 0, 100);
1003 fELossVsPoisson->SetDirectory(0);
1004 fELossVsPoisson->SetXTitle("N_{ch} from #DeltaE");
1005 fELossVsPoisson->SetYTitle("N_{ch} from Poisson");
1006 fELossVsPoisson->SetZTitle("Correlation");
1008 fELoss = new TH1D("eloss", "#Delta/#Delta_{mip} in all strips",
1010 fELoss->SetXTitle("#Delta/#Delta_{mip} (selected)");
1011 fELoss->SetYTitle("P(#Delta/#Delta_{mip})");
1012 fELoss->SetFillColor(Color()-2);
1013 fELoss->SetFillStyle(3003);
1014 fELoss->SetLineColor(kBlack);
1015 fELoss->SetLineStyle(2);
1016 fELoss->SetLineWidth(2);
1017 fELoss->SetDirectory(0);
1019 fELossUsed = static_cast<TH1D*>(fELoss->Clone("elossUsed"));
1020 fELossUsed->SetTitle("#Delta/#Delta_{mip} in used strips");
1021 fELossUsed->SetFillStyle(3002);
1022 fELossUsed->SetLineStyle(1);
1023 fELossUsed->SetDirectory(0);
1026 //____________________________________________________________________
1027 AliFMDDensityCalculator::RingHistos::RingHistos(const RingHistos& o)
1028 : AliForwardUtil::RingHistos(o),
1034 fDensity(o.fDensity),
1035 fELossVsPoisson(o.fELossVsPoisson),
1036 fPoisson(o.fPoisson),
1038 fELossUsed(o.fELossUsed),
1039 fMultCut(o.fMultCut)
1045 // o Object to copy from
1049 //____________________________________________________________________
1050 AliFMDDensityCalculator::RingHistos&
1051 AliFMDDensityCalculator::RingHistos::operator=(const RingHistos& o)
1054 // Assignment operator
1057 // o Object to assign from
1060 // Reference to this
1062 if (&o == this) return *this;
1063 AliForwardUtil::RingHistos::operator=(o);
1065 if (fEvsN) delete fEvsN;
1066 if (fEvsM) delete fEvsM;
1067 if (fEtaVsN) delete fEtaVsN;
1068 if (fEtaVsM) delete fEtaVsM;
1069 if (fCorr) delete fCorr;
1070 if (fDensity) delete fDensity;
1071 if (fELossVsPoisson) delete fELossVsPoisson;
1073 fEvsN = static_cast<TH2D*>(o.fEvsN->Clone());
1074 fEvsM = static_cast<TH2D*>(o.fEvsM->Clone());
1075 fEtaVsN = static_cast<TProfile*>(o.fEtaVsN->Clone());
1076 fEtaVsM = static_cast<TProfile*>(o.fEtaVsM->Clone());
1077 fCorr = static_cast<TProfile*>(o.fCorr->Clone());
1078 fDensity = static_cast<TH2D*>(o.fDensity->Clone());
1079 fELossVsPoisson = static_cast<TH2D*>(o.fELossVsPoisson->Clone());
1080 fPoisson = o.fPoisson;
1081 fELoss = static_cast<TH1D*>(o.fELoss->Clone());
1082 fELossUsed = static_cast<TH1D*>(o.fELossUsed->Clone());
1086 //____________________________________________________________________
1087 AliFMDDensityCalculator::RingHistos::~RingHistos()
1095 //____________________________________________________________________
1097 AliFMDDensityCalculator::RingHistos::Init(const TAxis& /*eAxis*/)
1099 fPoisson.Init(-1,-1);
1102 //____________________________________________________________________
1104 AliFMDDensityCalculator::RingHistos::Output(TList* dir)
1110 // dir Where to put it
1112 TList* d = DefineOutputList(dir);
1119 d->Add(fELossVsPoisson);
1121 fPoisson.GetOccupancy()->SetFillColor(Color());
1122 fPoisson.GetMean()->SetFillColor(Color());
1123 fPoisson.GetOccupancy()->SetFillColor(Color());
1127 Bool_t inner = (fRing == 'I' || fRing == 'i');
1128 Int_t nStr = inner ? 512 : 256;
1129 Int_t nSec = inner ? 20 : 40;
1130 TAxis x(nStr, -.5, nStr-.5);
1131 TAxis y(nSec, -.5, nSec-.5);
1132 x.SetTitle("strip");
1133 y.SetTitle("sector");
1134 fPoisson.Define(x, y);
1136 TParameter<double>* cut = new TParameter<double>("cut", fMultCut);
1140 //____________________________________________________________________
1142 AliFMDDensityCalculator::RingHistos::ScaleHistograms(TList* dir, Int_t nEvents)
1145 // Scale the histograms to the total number of events
1148 // dir Where the output is
1149 // nEvents Number of events
1151 TList* l = GetOutputList(dir);
1154 TH1* density = GetOutputHist(l,"inclDensity");
1155 if (density) density->Scale(1./nEvents);
1158 //____________________________________________________________________