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)
57 //____________________________________________________________________
58 AliFMDDensityCalculator::AliFMDDensityCalculator(const char* title)
59 : TNamed("fmdDensityCalculator", title),
66 fUsePhiAcceptance(kPhiCorrectNch),
80 fRecalculateEta(false)
86 // name Name of object
88 fRingHistos.SetName(GetName());
89 fRingHistos.SetOwner();
90 fRingHistos.Add(new RingHistos(1, 'I'));
91 fRingHistos.Add(new RingHistos(2, 'I'));
92 fRingHistos.Add(new RingHistos(2, 'O'));
93 fRingHistos.Add(new RingHistos(3, 'I'));
94 fRingHistos.Add(new RingHistos(3, 'O'));
95 fSumOfWeights = new TH1D("sumOfWeights", "Sum of Landau weights",
97 fSumOfWeights->SetFillColor(kRed+1);
98 fSumOfWeights->SetXTitle("#sum_{i} a_{i} f_{i}(#Delta)");
99 fWeightedSum = new TH1D("weightedSum", "Weighted sum of Landau propability",
101 fWeightedSum->SetFillColor(kBlue+1);
102 fWeightedSum->SetXTitle("#sum_{i} i a_{i} f_{i}(#Delta)");
103 fCorrections = new TH1D("corrections", "Distribution of corrections",
105 fCorrections->SetFillColor(kBlue+1);
106 fCorrections->SetXTitle("correction");
108 fAccI = GenerateAcceptanceCorrection('I');
109 fAccO = GenerateAcceptanceCorrection('O');
111 fMaxWeights = new TH2D("maxWeights", "Maximum i of a_{i}'s to use",
113 fMaxWeights->SetXTitle("#eta");
114 fMaxWeights->SetDirectory(0);
116 fLowCuts = new TH2D("lowCuts", "Low cuts used", 1, 0, 1, 1, 0, 1);
117 fLowCuts->SetXTitle("#eta");
118 fLowCuts->SetDirectory(0);
122 //____________________________________________________________________
123 AliFMDDensityCalculator::AliFMDDensityCalculator(const
124 AliFMDDensityCalculator& o)
127 fSumOfWeights(o.fSumOfWeights),
128 fWeightedSum(o.fWeightedSum),
129 fCorrections(o.fCorrections),
130 fMaxParticles(o.fMaxParticles),
131 fUsePoisson(o.fUsePoisson),
132 fUsePhiAcceptance(o.fUsePhiAcceptance),
135 fFMD1iMax(o.fFMD1iMax),
136 fFMD2iMax(o.fFMD2iMax),
137 fFMD2oMax(o.fFMD2oMax),
138 fFMD3iMax(o.fFMD3iMax),
139 fFMD3oMax(o.fFMD3oMax),
140 fMaxWeights(o.fMaxWeights),
141 fLowCuts(o.fLowCuts),
142 fEtaLumping(o.fEtaLumping),
143 fPhiLumping(o.fPhiLumping),
146 fRecalculateEta(o.fRecalculateEta)
152 // o Object to copy from
154 TIter next(&o.fRingHistos);
156 while ((obj = next())) fRingHistos.Add(obj);
159 //____________________________________________________________________
160 AliFMDDensityCalculator::~AliFMDDensityCalculator()
165 fRingHistos.Delete();
168 //____________________________________________________________________
169 AliFMDDensityCalculator&
170 AliFMDDensityCalculator::operator=(const AliFMDDensityCalculator& o)
173 // Assignement operator
176 // o Object to assign from
179 // Reference to this object
181 if (&o == this) return *this;
182 TNamed::operator=(o);
185 fMaxParticles = o.fMaxParticles;
186 fUsePoisson = o.fUsePoisson;
187 fUsePhiAcceptance = o.fUsePhiAcceptance;
190 fFMD1iMax = o.fFMD1iMax;
191 fFMD2iMax = o.fFMD2iMax;
192 fFMD2oMax = o.fFMD2oMax;
193 fFMD3iMax = o.fFMD3iMax;
194 fFMD3oMax = o.fFMD3oMax;
195 fMaxWeights = o.fMaxWeights;
196 fLowCuts = o.fLowCuts;
197 fEtaLumping = o.fEtaLumping;
198 fPhiLumping = o.fPhiLumping;
200 fRecalculateEta = o.fRecalculateEta;
202 fRingHistos.Delete();
203 TIter next(&o.fRingHistos);
205 while ((obj = next())) fRingHistos.Add(obj);
210 //____________________________________________________________________
212 AliFMDDensityCalculator::Init(const TAxis& axis)
214 // Intialize this sub-algorithm
220 TIter next(&fRingHistos);
222 while ((o = static_cast<RingHistos*>(next()))) {
224 // o->fMultCut = fCuts.GetFixedCut(o->fDet, o->fRing);
225 // o->fPoisson.Init(o->fDet,o->fRing,fEtaLumping, fPhiLumping);
229 //____________________________________________________________________
230 AliFMDDensityCalculator::RingHistos*
231 AliFMDDensityCalculator::GetRingHistos(UShort_t d, Char_t r) const
234 // Get the ring histogram container
241 // Ring histogram container
245 case 1: idx = 0; break;
246 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
247 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
249 if (idx < 0 || idx >= fRingHistos.GetEntries()) {
250 AliWarning(Form("Index %d of FMD%d%c out of range", idx, d, r));
254 return static_cast<RingHistos*>(fRingHistos.At(idx));
257 //____________________________________________________________________
259 AliFMDDensityCalculator::GetMultCut(UShort_t d, Char_t r, Int_t ieta,
263 // Get the multiplicity cut. If the user has set fMultCut (via
264 // SetMultCut) then that value is used. If not, then the lower
265 // value of the fit range for the enery loss fits is returned.
268 // Lower cut on multiplicity
270 return fCuts.GetMultCut(d,r,ieta,errors);
273 //____________________________________________________________________
275 AliFMDDensityCalculator::GetMultCut(UShort_t d, Char_t r, Double_t eta,
279 // Get the multiplicity cut. If the user has set fMultCut (via
280 // SetMultCut) then that value is used. If not, then the lower
281 // value of the fit range for the enery loss fits is returned.
284 // Lower cut on multiplicity
286 return fCuts.GetMultCut(d,r,eta,errors);
289 //____________________________________________________________________
291 AliFMDDensityCalculator::Calculate(const AliESDFMD& fmd,
292 AliForwardUtil::Histos& hists,
299 // Do the calculations
302 // fmd AliESDFMD object (possibly) corrected for sharing
303 // hists Histogram cache
305 // lowFlux Low flux flag.
312 for (UShort_t d=1; d<=3; d++) {
313 UShort_t nr = (d == 1 ? 1 : 2);
314 for (UShort_t q=0; q<nr; q++) {
315 Char_t r = (q == 0 ? 'I' : 'O');
316 UShort_t ns= (q == 0 ? 20 : 40);
317 UShort_t nt= (q == 0 ? 512 : 256);
318 TH2D* h = hists.Get(d,r);
319 RingHistos* rh= GetRingHistos(d,r);
321 AliError(Form("No ring histogram found for FMD%d%c", d, r));
325 // rh->fPoisson.SetObject(d,r,vtxbin,cent);
326 rh->fPoisson.Reset(0);
327 // rh->ResetPoissonHistos(h, fEtaLumping, fPhiLumping);
329 for (UShort_t s=0; s<ns; s++) {
330 for (UShort_t t=0; t<nt; t++) {
332 Float_t mult = fmd.Multiplicity(d,r,s,t);
333 Float_t phi = fmd.Phi(d,r,s,t) / 180 * TMath::Pi();
334 Float_t eta = fmd.Eta(d,r,s,t);
338 eta = AliForwardUtil::GetEtaFromStrip(d,r,s,t,zvtx);
340 if (mult == AliESDFMD::kInvalidMult || mult > 20) {
341 rh->fPoisson.Fill(t , s, false);
342 rh->fEvsM->Fill(mult,0);
345 if (fUsePhiAcceptance == kPhiCorrectELoss)
346 mult *= AcceptanceCorrection(r,t);
349 if (eta != AliESDFMD::kInvalidEta) cut = GetMultCut(d, r, eta,false);
352 if (cut > 0 && mult > cut)
353 n = NParticles(mult,d,r,s,t,vtxbin,eta,lowFlux);
355 rh->fELoss->Fill(mult);
356 rh->fEvsN->Fill(mult,n);
357 rh->fEtaVsN->Fill(eta, n);
359 Double_t c = Correction(d,r,s,t,vtxbin,eta,lowFlux);
360 fCorrections->Fill(c);
362 rh->fEvsM->Fill(mult,n);
363 rh->fEtaVsM->Fill(eta, n);
364 rh->fCorr->Fill(eta, c);
366 Bool_t hit = (n > 0.9 && c > 0);
367 if (hit) rh->fELossUsed->Fill(mult);
368 rh->fPoisson.Fill(t,s,hit,1./c);
370 if (!fUsePoisson) rh->fDensity->Fill(eta,phi,n);
374 TH2D* hclone = static_cast<TH2D*>(h->Clone("hclone"));
375 if (!fUsePoisson) hclone->Reset();
376 if ( fUsePoisson) h->Reset();
378 TH2D* poisson = rh->fPoisson.Result();
379 for (Int_t t=0; t < poisson->GetNbinsX(); t++) {
380 for (Int_t s=0; s < poisson->GetNbinsY(); s++) {
382 Double_t poissonV = poisson->GetBinContent(t+1,s+1);
383 Double_t phi = fmd.Phi(d,r,s,t) / 180 * TMath::Pi();
384 Double_t eta = fmd.Eta(d,r,s,t);
386 eta = AliForwardUtil::GetEtaFromStrip(d,r,s,t,zvtx);
388 h->Fill(eta,phi,poissonV);
390 hclone->Fill(eta,phi,poissonV);
391 if (fUsePoisson) rh->fDensity->Fill(eta, phi, poissonV);
395 for (Int_t ieta=1; ieta <= h->GetNbinsX(); ieta++) {
396 for (Int_t iphi=1; iphi<= h->GetNbinsY(); iphi++) {
398 Double_t poissonV = 0; //h->GetBinContent(,s+1);
401 poissonV = h->GetBinContent(ieta,iphi);
402 eLossV = hclone->GetBinContent(ieta,iphi);
405 poissonV = hclone->GetBinContent(ieta,iphi);
406 eLossV = h->GetBinContent(ieta,iphi);
409 rh->fELossVsPoisson->Fill(eLossV, poissonV);
420 //_____________________________________________________________________
422 AliFMDDensityCalculator::FindMaxWeight(const AliFMDCorrELossFit* cor,
423 UShort_t d, Char_t r, Int_t iEta) const
426 // Find the max weight to use for FMD<i>dr</i> in eta bin @a iEta
434 AliFMDCorrELossFit::ELossFit* fit = cor->GetFit(d,r,iEta);
436 // AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f", d, r, eta));
439 return TMath::Min(Int_t(fMaxParticles), fit->FindMaxWeight());
442 //_____________________________________________________________________
444 AliFMDDensityCalculator::CacheMaxWeights()
447 // Find the max weights and cache them
449 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
450 AliFMDCorrELossFit* cor = fcm.GetELossFit();
451 const TAxis& eta = cor->GetEtaAxis();
453 Int_t nEta = eta.GetNbins();
460 fMaxWeights->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
461 fMaxWeights->GetYaxis()->SetBinLabel(1, "FMD1i");
462 fMaxWeights->GetYaxis()->SetBinLabel(2, "FMD2i");
463 fMaxWeights->GetYaxis()->SetBinLabel(3, "FMD2o");
464 fMaxWeights->GetYaxis()->SetBinLabel(4, "FMD3i");
465 fMaxWeights->GetYaxis()->SetBinLabel(5, "FMD3o");
467 AliInfo(Form("Get eta axis with %d bins from %f to %f",
468 nEta, eta.GetXmin(), eta.GetXmax()));
469 fLowCuts->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
470 fLowCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
471 fLowCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
472 fLowCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
473 fLowCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
474 fLowCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
476 for (Int_t i = 0; i < nEta; i++) {
478 w[0] = fFMD1iMax[i] = FindMaxWeight(cor, 1, 'I', i+1);
479 w[1] = fFMD2iMax[i] = FindMaxWeight(cor, 2, 'I', i+1);
480 w[2] = fFMD2oMax[i] = FindMaxWeight(cor, 2, 'O', i+1);
481 w[3] = fFMD3iMax[i] = FindMaxWeight(cor, 3, 'I', i+1);
482 w[4] = fFMD3oMax[i] = FindMaxWeight(cor, 3, 'O', i+1);
484 l[0] = GetMultCut(1, 'I', i+1, false);
485 l[1] = GetMultCut(2, 'I', i+1, false);
486 l[2] = GetMultCut(2, 'O', i+1, false);
487 l[3] = GetMultCut(3, 'I', i+1, false);
488 l[4] = GetMultCut(3, 'O', i+1, false);
489 for (Int_t j = 0; j < 5; j++) {
490 if (w[j] > 0) fMaxWeights->SetBinContent(i+1, j+1, w[j]);
491 if (l[j] > 0) fLowCuts->SetBinContent(i+1, j+1, l[j]);
496 //_____________________________________________________________________
498 AliFMDDensityCalculator::GetMaxWeight(UShort_t d, Char_t r, Int_t iEta) const
501 // Find the (cached) maximum weight for FMD<i>dr</i> in
502 // @f$\eta@f$ bin @a iEta
510 // max weight or <= 0 in case of problems
512 if (iEta < 0) return -1;
514 const TArrayI* max = 0;
516 case 1: max = &fFMD1iMax; break;
517 case 2: max = (r == 'I' || r == 'i' ? &fFMD2iMax : &fFMD2oMax); break;
518 case 3: max = (r == 'I' || r == 'i' ? &fFMD3iMax : &fFMD3oMax); break;
521 AliWarning(Form("No array for FMD%d%c", d, r));
525 if (iEta >= max->fN) {
526 AliWarning(Form("Eta bin %3d out of bounds [0,%d]",
531 AliDebug(30,Form("Max weight for FMD%d%c eta bin %3d: %d", d, r, iEta,
533 return max->At(iEta);
536 //_____________________________________________________________________
538 AliFMDDensityCalculator::GetMaxWeight(UShort_t d, Char_t r, Float_t eta) const
541 // Find the (cached) maximum weight for FMD<i>dr</i> iat
550 // max weight or <= 0 in case of problems
552 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
553 Int_t iEta = fcm.GetELossFit()->FindEtaBin(eta) -1;
555 return GetMaxWeight(d, r, iEta);
558 //_____________________________________________________________________
560 AliFMDDensityCalculator::NParticles(Float_t mult,
567 Bool_t lowFlux) const
570 // Get the number of particles corresponding to the signal mult
577 // t Strip (not used)
579 // eta Pseudo-rapidity
580 // lowFlux Low-flux flag
583 // The number of particles
585 // if (mult <= GetMultCut()) return 0;
586 if (lowFlux) return 1;
588 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
589 AliFMDCorrELossFit::ELossFit* fit = fcm.GetELossFit()->FindFit(d,r,eta);
591 AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f", d, r, eta));
595 Int_t m = GetMaxWeight(d,r,eta); // fit->FindMaxWeight();
597 AliWarning(Form("No good fits for FMD%d%c at eta=%f", d, r, eta));
601 UShort_t n = TMath::Min(fMaxParticles, UShort_t(m));
602 Double_t ret = fit->EvaluateWeighted(mult, n);
605 AliInfo(Form("FMD%d%c, eta=%7.4f, %8.5f -> %8.5f", d, r, eta, mult, ret));
608 fWeightedSum->Fill(ret);
609 fSumOfWeights->Fill(ret);
614 //_____________________________________________________________________
616 AliFMDDensityCalculator::Correction(UShort_t d,
622 Bool_t lowFlux) const
625 // Get the inverse correction factor. This consist of
627 // - acceptance correction (corners of sensors)
628 // - double hit correction (for low-flux events)
629 // - dead strip correction
635 // t Strip (not used)
637 // eta Pseudo-rapidity
638 // lowFlux Low-flux flag
643 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
645 Float_t correction = 1;
646 if (fUsePhiAcceptance == kPhiCorrectNch)
647 correction = AcceptanceCorrection(r,t);
650 if (fcm.GetDoubleHit())
651 dblHitCor = fcm.GetDoubleHit()->GetCorrection(d,r);
654 Double_t dblC = dblHitCor->GetBinContent(dblHitCor->FindBin(eta));
655 if (dblC > 0) correction *= dblC;
658 AliWarning(Form("Missing double hit correction for FMD%d%c",d,r));
664 //_____________________________________________________________________
666 AliFMDDensityCalculator::GenerateAcceptanceCorrection(Char_t r) const
669 // Generate the acceptance corrections
672 // r Ring to generate for
675 // Newly allocated histogram of acceptance corrections
677 const Double_t ic1[] = { 4.9895, 15.3560 };
678 const Double_t ic2[] = { 1.8007, 17.2000 };
679 const Double_t oc1[] = { 4.2231, 26.6638 };
680 const Double_t oc2[] = { 1.8357, 27.9500 };
681 const Double_t* c1 = (r == 'I' || r == 'i' ? ic1 : oc1);
682 const Double_t* c2 = (r == 'I' || r == 'i' ? ic2 : oc2);
683 Double_t minR = (r == 'I' || r == 'i' ? 4.5213 : 15.4);
684 Double_t maxR = (r == 'I' || r == 'i' ? 17.2 : 28.0);
685 Int_t nStrips = (r == 'I' || r == 'i' ? 512 : 256);
686 Int_t nSec = (r == 'I' || r == 'i' ? 20 : 40);
687 Float_t basearc = 2 * TMath::Pi() / nSec;
688 Double_t rad = maxR - minR;
689 Float_t segment = rad / nStrips;
690 Float_t cr = TMath::Sqrt(c1[0]*c1[0]+c1[1]*c1[1]);
692 // Numbers used to find end-point of strip.
693 // (See http://mathworld.wolfram.com/Circle-LineIntersection.html)
694 Float_t D = c1[0] * c2[1] - c1[1] * c2[0];
695 Float_t dx = c2[0] - c1[0];
696 Float_t dy = c2[1] - c1[1];
697 Float_t dr = TMath::Sqrt(dx*dx+dy*dy);
699 TH1D* ret = new TH1D(Form("acc%c", r),
700 Form("Acceptance correction for FMDx%c", r),
701 nStrips, -.5, nStrips-.5);
702 ret->SetXTitle("Strip");
703 ret->SetYTitle("#varphi acceptance");
704 ret->SetDirectory(0);
705 ret->SetFillColor(r == 'I' || r == 'i' ? kRed+1 : kBlue+1);
706 ret->SetFillStyle(3001);
708 for (Int_t t = 0; t < nStrips; t++) {
709 Float_t radius = minR + t * segment;
711 // If the radius of the strip is smaller than the radius corresponding
712 // to the first corner we have a full strip length
714 ret->SetBinContent(t+1, 1);
718 // Next, we should find the end-point of the strip - that is,
719 // the coordinates where the line from c1 to c2 intersects a circle
720 // with radius given by the strip.
721 // (See http://mathworld.wolfram.com/Circle-LineIntersection.html)
722 // Calculate the determinant
723 Float_t det = radius * radius * dr * dr - D*D;
726 // <0 means No intersection
727 // =0 means Exactly tangent
728 ret->SetBinContent(t+1, 1);
732 // Calculate end-point and the corresponding opening angle
733 Float_t x = (+D * dy + dx * TMath::Sqrt(det)) / dr / dr;
734 Float_t y = (-D * dx + dy * TMath::Sqrt(det)) / dr / dr;
735 Float_t th = TMath::ATan2(x, y);
737 ret->SetBinContent(t+1, th / basearc);
742 //_____________________________________________________________________
744 AliFMDDensityCalculator::AcceptanceCorrection(Char_t r, UShort_t t) const
747 // Get the acceptance correction for strip @a t in an ring of type @a r
750 // r Ring type ('I' or 'O')
754 // Inverse acceptance correction
756 TH1D* acc = (r == 'I' || r == 'i' ? fAccI : fAccO);
757 return acc->GetBinContent(t+1);
760 //____________________________________________________________________
762 AliFMDDensityCalculator::ScaleHistograms(const TList* dir, Int_t nEvents)
765 // Scale the histograms to the total number of events
768 // dir where to put the output
769 // nEvents Number of events
771 if (nEvents <= 0) return;
772 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
775 TIter next(&fRingHistos);
777 THStack* sums = new THStack("sums", "sums of ring signals");
778 while ((o = static_cast<RingHistos*>(next()))) {
779 o->ScaleHistograms(d, nEvents);
780 TH1D* sum = o->fDensity->ProjectionX(o->GetName(), 1,
781 o->fDensity->GetNbinsY(),"e");
782 sum->Scale(1., "width");
783 sum->SetTitle(o->GetName());
784 sum->SetDirectory(0);
785 sum->SetYTitle("#sum N_{ch,incl}");
791 //____________________________________________________________________
793 AliFMDDensityCalculator::DefineOutput(TList* dir)
796 // Output diagnostic histograms to directory
799 // dir List to write in
801 TList* d = new TList;
803 d->SetName(GetName());
805 d->Add(fWeightedSum);
806 d->Add(fSumOfWeights);
807 d->Add(fCorrections);
813 // TNamed* sigma = new TNamed("sigma",
814 // (fIncludeSigma ? "included" : "excluded"));
815 TNamed* maxP = new TNamed("maxParticle", Form("%d", fMaxParticles));
816 TNamed* method = new TNamed("method",
817 (fUsePoisson ? "Poisson" : "Energy loss"));
818 TNamed* phiA = new TNamed("phiAcceptance",
819 (fUsePhiAcceptance == 0 ? "disabled" :
820 fUsePhiAcceptance == 1 ? "particles" :
822 TNamed* etaL = new TNamed("etaLumping", Form("%d", fEtaLumping));
823 TNamed* phiL = new TNamed("phiLumping", Form("%d", fPhiLumping));
824 // TParameter<double>* nxi = new TParameter<double>("nXi", fNXi);
835 TIter next(&fRingHistos);
837 while ((o = static_cast<RingHistos*>(next()))) {
838 o->fPoisson.SetLumping(fEtaLumping, fPhiLumping);
842 //____________________________________________________________________
844 AliFMDDensityCalculator::Print(Option_t* option) const
852 char ind[gROOT->GetDirLevel()+3];
853 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
854 ind[gROOT->GetDirLevel()] = '\0';
855 std::cout << ind << ClassName() << ": " << GetName() << '\n'
857 << ind << " Max(particles): " << fMaxParticles << '\n'
858 << ind << " Poisson method: " << fUsePoisson << '\n'
859 << ind << " Use phi acceptance: " << fUsePhiAcceptance << '\n'
860 << ind << " Eta lumping: " << fEtaLumping << '\n'
861 << ind << " Phi lumping: " << fPhiLumping << '\n'
864 std::cout << ind << " Lower cut:" << std::endl;
868 if (opt.Contains("nomax")) return;
870 std::cout << ind << " Max weights:\n";
872 for (UShort_t d=1; d<=3; d++) {
873 UShort_t nr = (d == 1 ? 1 : 2);
874 for (UShort_t q=0; q<nr; q++) {
875 ind[gROOT->GetDirLevel()] = ' ';
876 ind[gROOT->GetDirLevel()+1] = '\0';
877 Char_t r = (q == 0 ? 'I' : 'O');
878 std::cout << ind << " FMD" << d << r << ":";
879 ind[gROOT->GetDirLevel()+1] = ' ';
880 ind[gROOT->GetDirLevel()+2] = '\0';
882 const TArrayI& a = (d == 1 ? fFMD1iMax :
883 (d == 2 ? (r == 'I' ? fFMD2iMax : fFMD2oMax) :
884 (r == 'I' ? fFMD3iMax : fFMD3oMax)));
886 for (Int_t i = 0; i < a.fN; i++) {
887 if (a.fArray[i] < 1) continue;
888 if (j % 6 == 0) std::cout << "\n " << ind;
890 std::cout << " " << std::setw(3) << i << ": " << a.fArray[i];
892 std::cout << std::endl;
897 //====================================================================
898 AliFMDDensityCalculator::RingHistos::RingHistos()
899 : AliForwardUtil::RingHistos(),
917 //____________________________________________________________________
918 AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
919 : AliForwardUtil::RingHistos(d,r),
939 fEvsN = new TH2D("elossVsNnocorr",
940 "#Delta E/#Delta E_{mip} vs uncorrected inclusive N_{ch}",
941 250, -.5, 24.5, 250, -.5, 24.5);
942 fEvsN->SetXTitle("#Delta E/#Delta E_{mip}");
943 fEvsN->SetYTitle("Inclusive N_{ch} (uncorrected)");
945 fEvsN->SetDirectory(0);
947 fEvsM = static_cast<TH2D*>(fEvsN->Clone("elossVsNcorr"));
948 fEvsM->SetTitle("#Delta E/#Delta E_{mip} vs corrected inclusive N_{ch}");
949 fEvsM->SetDirectory(0);
951 fEtaVsN = new TProfile("etaVsNnocorr",
952 "Average inclusive N_{ch} vs #eta (uncorrected)",
954 fEtaVsN->SetXTitle("#eta");
955 fEtaVsN->SetYTitle("#LT N_{ch,incl}#GT (uncorrected)");
956 fEtaVsN->SetDirectory(0);
957 fEtaVsN->SetLineColor(Color());
958 fEtaVsN->SetFillColor(Color());
960 fEtaVsM = static_cast<TProfile*>(fEtaVsN->Clone("etaVsNcorr"));
961 fEtaVsM->SetTitle("Average inclusive N_{ch} vs #eta (corrected)");
962 fEtaVsM->SetYTitle("#LT N_{ch,incl}#GT (corrected)");
963 fEtaVsM->SetDirectory(0);
966 fCorr = new TProfile("corr", "Average correction", 200, -4, 6);
967 fCorr->SetXTitle("#eta");
968 fCorr->SetYTitle("#LT correction#GT");
969 fCorr->SetDirectory(0);
970 fCorr->SetLineColor(Color());
971 fCorr->SetFillColor(Color());
973 fDensity = new TH2D("inclDensity", "Inclusive N_{ch} density",
974 200, -4, 6, (r == 'I' || r == 'i' ? 20 : 40),
976 fDensity->SetDirectory(0);
978 fDensity->SetMarkerColor(Color());
979 fDensity->SetXTitle("#eta");
980 fDensity->SetYTitle("#phi [radians]");
981 fDensity->SetZTitle("Inclusive N_{ch} density");
983 fELossVsPoisson = new TH2D("elossVsPoisson",
984 "N_{ch} from energy loss vs from Poission",
985 500, 0, 100, 500, 0, 100);
986 fELossVsPoisson->SetDirectory(0);
987 fELossVsPoisson->SetXTitle("N_{ch} from #DeltaE");
988 fELossVsPoisson->SetYTitle("N_{ch} from Poisson");
989 fELossVsPoisson->SetZTitle("Correlation");
991 fELoss = new TH1D("eloss", "#Delta/#Delta_{mip} in all strips",
993 fELoss->SetXTitle("#Delta/#Delta_{mip} (selected)");
994 fELoss->SetYTitle("P(#Delta/#Delta_{mip})");
995 fELoss->SetFillColor(Color()-2);
996 fELoss->SetFillStyle(3003);
997 fELoss->SetLineColor(kBlack);
998 fELoss->SetLineStyle(2);
999 fELoss->SetLineWidth(2);
1000 fELoss->SetDirectory(0);
1002 fELossUsed = static_cast<TH1D*>(fELoss->Clone("elossUsed"));
1003 fELossUsed->SetTitle("#Delta/#Delta_{mip} in used strips");
1004 fELossUsed->SetFillStyle(3002);
1005 fELossUsed->SetLineStyle(1);
1006 fELossUsed->SetDirectory(0);
1009 //____________________________________________________________________
1010 AliFMDDensityCalculator::RingHistos::RingHistos(const RingHistos& o)
1011 : AliForwardUtil::RingHistos(o),
1017 fDensity(o.fDensity),
1018 fELossVsPoisson(o.fELossVsPoisson),
1019 fPoisson(o.fPoisson),
1021 fELossUsed(o.fELossUsed),
1022 fMultCut(o.fMultCut)
1028 // o Object to copy from
1032 //____________________________________________________________________
1033 AliFMDDensityCalculator::RingHistos&
1034 AliFMDDensityCalculator::RingHistos::operator=(const RingHistos& o)
1037 // Assignment operator
1040 // o Object to assign from
1043 // Reference to this
1045 if (&o == this) return *this;
1046 AliForwardUtil::RingHistos::operator=(o);
1048 if (fEvsN) delete fEvsN;
1049 if (fEvsM) delete fEvsM;
1050 if (fEtaVsN) delete fEtaVsN;
1051 if (fEtaVsM) delete fEtaVsM;
1052 if (fCorr) delete fCorr;
1053 if (fDensity) delete fDensity;
1054 if (fELossVsPoisson) delete fELossVsPoisson;
1056 fEvsN = static_cast<TH2D*>(o.fEvsN->Clone());
1057 fEvsM = static_cast<TH2D*>(o.fEvsM->Clone());
1058 fEtaVsN = static_cast<TProfile*>(o.fEtaVsN->Clone());
1059 fEtaVsM = static_cast<TProfile*>(o.fEtaVsM->Clone());
1060 fCorr = static_cast<TProfile*>(o.fCorr->Clone());
1061 fDensity = static_cast<TH2D*>(o.fDensity->Clone());
1062 fELossVsPoisson = static_cast<TH2D*>(o.fELossVsPoisson->Clone());
1063 fPoisson = o.fPoisson;
1064 fELoss = static_cast<TH1D*>(o.fELoss->Clone());
1065 fELossUsed = static_cast<TH1D*>(o.fELossUsed->Clone());
1069 //____________________________________________________________________
1070 AliFMDDensityCalculator::RingHistos::~RingHistos()
1078 //____________________________________________________________________
1080 AliFMDDensityCalculator::RingHistos::Init(const TAxis& /*eAxis*/)
1082 fPoisson.Init(-1,-1);
1085 //____________________________________________________________________
1087 AliFMDDensityCalculator::RingHistos::Output(TList* dir)
1093 // dir Where to put it
1095 TList* d = DefineOutputList(dir);
1102 d->Add(fELossVsPoisson);
1104 fPoisson.GetOccupancy()->SetFillColor(Color());
1105 fPoisson.GetMean()->SetFillColor(Color());
1106 fPoisson.GetOccupancy()->SetFillColor(Color());
1110 Bool_t inner = (fRing == 'I' || fRing == 'i');
1111 Int_t nStr = inner ? 512 : 256;
1112 Int_t nSec = inner ? 20 : 40;
1113 TAxis x(nStr, -.5, nStr-.5);
1114 TAxis y(nSec, -.5, nSec-.5);
1115 x.SetTitle("strip");
1116 y.SetTitle("sector");
1117 fPoisson.Define(x, y);
1119 TParameter<double>* cut = new TParameter<double>("cut", fMultCut);
1123 //____________________________________________________________________
1125 AliFMDDensityCalculator::RingHistos::ScaleHistograms(TList* dir, Int_t nEvents)
1128 // Scale the histograms to the total number of events
1131 // dir Where the output is
1132 // nEvents Number of events
1134 TList* l = GetOutputList(dir);
1137 TH1* density = GetOutputHist(l,"inclDensity");
1138 if (density) density->Scale(1./nEvents);
1141 //____________________________________________________________________