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),
56 //____________________________________________________________________
57 AliFMDDensityCalculator::AliFMDDensityCalculator(const char* title)
58 : TNamed("fmdDensityCalculator", title),
65 fUsePhiAcceptance(kPhiCorrectNch),
84 // name Name of object
86 fRingHistos.SetName(GetName());
87 fRingHistos.SetOwner();
88 fRingHistos.Add(new RingHistos(1, 'I'));
89 fRingHistos.Add(new RingHistos(2, 'I'));
90 fRingHistos.Add(new RingHistos(2, 'O'));
91 fRingHistos.Add(new RingHistos(3, 'I'));
92 fRingHistos.Add(new RingHistos(3, 'O'));
93 fSumOfWeights = new TH1D("sumOfWeights", "Sum of Landau weights",
95 fSumOfWeights->SetFillColor(kRed+1);
96 fSumOfWeights->SetXTitle("#sum_{i} a_{i} f_{i}(#Delta)");
97 fWeightedSum = new TH1D("weightedSum", "Weighted sum of Landau propability",
99 fWeightedSum->SetFillColor(kBlue+1);
100 fWeightedSum->SetXTitle("#sum_{i} i a_{i} f_{i}(#Delta)");
101 fCorrections = new TH1D("corrections", "Distribution of corrections",
103 fCorrections->SetFillColor(kBlue+1);
104 fCorrections->SetXTitle("correction");
106 fAccI = GenerateAcceptanceCorrection('I');
107 fAccO = GenerateAcceptanceCorrection('O');
109 fMaxWeights = new TH2D("maxWeights", "Maximum i of a_{i}'s to use",
111 fMaxWeights->SetXTitle("#eta");
112 fMaxWeights->SetDirectory(0);
114 fLowCuts = new TH2D("lowCuts", "Low cuts used", 1, 0, 1, 1, 0, 1);
115 fLowCuts->SetXTitle("#eta");
116 fLowCuts->SetDirectory(0);
120 //____________________________________________________________________
121 AliFMDDensityCalculator::AliFMDDensityCalculator(const
122 AliFMDDensityCalculator& o)
125 fSumOfWeights(o.fSumOfWeights),
126 fWeightedSum(o.fWeightedSum),
127 fCorrections(o.fCorrections),
128 fMaxParticles(o.fMaxParticles),
129 fUsePoisson(o.fUsePoisson),
130 fUsePhiAcceptance(o.fUsePhiAcceptance),
133 fFMD1iMax(o.fFMD1iMax),
134 fFMD2iMax(o.fFMD2iMax),
135 fFMD2oMax(o.fFMD2oMax),
136 fFMD3iMax(o.fFMD3iMax),
137 fFMD3oMax(o.fFMD3oMax),
138 fMaxWeights(o.fMaxWeights),
139 fLowCuts(o.fLowCuts),
140 fEtaLumping(o.fEtaLumping),
141 fPhiLumping(o.fPhiLumping),
149 // o Object to copy from
151 TIter next(&o.fRingHistos);
153 while ((obj = next())) fRingHistos.Add(obj);
156 //____________________________________________________________________
157 AliFMDDensityCalculator::~AliFMDDensityCalculator()
162 fRingHistos.Delete();
165 //____________________________________________________________________
166 AliFMDDensityCalculator&
167 AliFMDDensityCalculator::operator=(const AliFMDDensityCalculator& o)
170 // Assignement operator
173 // o Object to assign from
176 // Reference to this object
178 if (&o == this) return *this;
179 TNamed::operator=(o);
182 fMaxParticles = o.fMaxParticles;
183 fUsePoisson = o.fUsePoisson;
184 fUsePhiAcceptance = o.fUsePhiAcceptance;
187 fFMD1iMax = o.fFMD1iMax;
188 fFMD2iMax = o.fFMD2iMax;
189 fFMD2oMax = o.fFMD2oMax;
190 fFMD3iMax = o.fFMD3iMax;
191 fFMD3oMax = o.fFMD3oMax;
192 fMaxWeights = o.fMaxWeights;
193 fLowCuts = o.fLowCuts;
194 fEtaLumping = o.fEtaLumping;
195 fPhiLumping = o.fPhiLumping;
198 fRingHistos.Delete();
199 TIter next(&o.fRingHistos);
201 while ((obj = next())) fRingHistos.Add(obj);
206 //____________________________________________________________________
208 AliFMDDensityCalculator::Init(const TAxis& axis)
210 // Intialize this sub-algorithm
216 TIter next(&fRingHistos);
218 while ((o = static_cast<RingHistos*>(next()))) {
220 // o->fMultCut = fCuts.GetFixedCut(o->fDet, o->fRing);
221 // o->fPoisson.Init(o->fDet,o->fRing,fEtaLumping, fPhiLumping);
225 //____________________________________________________________________
226 AliFMDDensityCalculator::RingHistos*
227 AliFMDDensityCalculator::GetRingHistos(UShort_t d, Char_t r) const
230 // Get the ring histogram container
237 // Ring histogram container
241 case 1: idx = 0; break;
242 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
243 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
245 if (idx < 0 || idx >= fRingHistos.GetEntries()) {
246 AliWarning(Form("Index %d of FMD%d%c out of range", idx, d, r));
250 return static_cast<RingHistos*>(fRingHistos.At(idx));
253 //____________________________________________________________________
255 AliFMDDensityCalculator::GetMultCut(UShort_t d, Char_t r, Int_t ieta,
259 // Get the multiplicity cut. If the user has set fMultCut (via
260 // SetMultCut) then that value is used. If not, then the lower
261 // value of the fit range for the enery loss fits is returned.
264 // Lower cut on multiplicity
266 return fCuts.GetMultCut(d,r,ieta,errors);
269 //____________________________________________________________________
271 AliFMDDensityCalculator::GetMultCut(UShort_t d, Char_t r, Double_t eta,
275 // Get the multiplicity cut. If the user has set fMultCut (via
276 // SetMultCut) then that value is used. If not, then the lower
277 // value of the fit range for the enery loss fits is returned.
280 // Lower cut on multiplicity
282 return fCuts.GetMultCut(d,r,eta,errors);
285 //____________________________________________________________________
287 AliFMDDensityCalculator::Calculate(const AliESDFMD& fmd,
288 AliForwardUtil::Histos& hists,
294 // Do the calculations
297 // fmd AliESDFMD object (possibly) corrected for sharing
298 // hists Histogram cache
300 // lowFlux Low flux flag.
307 for (UShort_t d=1; d<=3; d++) {
308 UShort_t nr = (d == 1 ? 1 : 2);
309 for (UShort_t q=0; q<nr; q++) {
310 Char_t r = (q == 0 ? 'I' : 'O');
311 UShort_t ns= (q == 0 ? 20 : 40);
312 UShort_t nt= (q == 0 ? 512 : 256);
313 TH2D* h = hists.Get(d,r);
314 RingHistos* rh= GetRingHistos(d,r);
316 AliError(Form("No ring histogram found for FMD%d%c", d, r));
320 // rh->fPoisson.SetObject(d,r,vtxbin,cent);
321 rh->fPoisson.Reset(0);
322 // rh->ResetPoissonHistos(h, fEtaLumping, fPhiLumping);
324 for (UShort_t s=0; s<ns; s++) {
325 for (UShort_t t=0; t<nt; t++) {
327 Float_t mult = fmd.Multiplicity(d,r,s,t);
328 Float_t phi = fmd.Phi(d,r,s,t) / 180 * TMath::Pi();
329 Float_t eta = fmd.Eta(d,r,s,t);
331 if (mult == AliESDFMD::kInvalidMult || mult > 20) {
332 rh->fPoisson.Fill(t , s, false);
333 rh->fEvsM->Fill(mult,0);
336 if (fUsePhiAcceptance == kPhiCorrectELoss)
337 mult *= AcceptanceCorrection(r,t);
340 if (eta != AliESDFMD::kInvalidEta) cut = GetMultCut(d, r, eta,false);
343 if (cut > 0 && mult > cut)
344 n = NParticles(mult,d,r,s,t,vtxbin,eta,lowFlux);
346 rh->fELoss->Fill(mult);
347 rh->fEvsN->Fill(mult,n);
348 rh->fEtaVsN->Fill(eta, n);
350 Double_t c = Correction(d,r,s,t,vtxbin,eta,lowFlux);
351 fCorrections->Fill(c);
353 rh->fEvsM->Fill(mult,n);
354 rh->fEtaVsM->Fill(eta, n);
355 rh->fCorr->Fill(eta, c);
357 Bool_t hit = (n > 0.9 && c > 0);
358 if (hit) rh->fELossUsed->Fill(mult);
359 rh->fPoisson.Fill(t,s,hit,1./c);
361 if (!fUsePoisson) rh->fDensity->Fill(eta,phi,n);
365 TH2D* hclone = static_cast<TH2D*>(h->Clone("hclone"));
366 if (!fUsePoisson) hclone->Reset();
367 if ( fUsePoisson) h->Reset();
369 TH2D* poisson = rh->fPoisson.Result();
370 for (Int_t t=0; t < poisson->GetNbinsX(); t++) {
371 for (Int_t s=0; s < poisson->GetNbinsY(); s++) {
373 Double_t poissonV = poisson->GetBinContent(t+1,s+1);
374 Double_t phi = fmd.Phi(d,r,s,t) / 180 * TMath::Pi();
375 Double_t eta = fmd.Eta(d,r,s,t);
377 h->Fill(eta,phi,poissonV);
379 hclone->Fill(eta,phi,poissonV);
380 rh->fDensity->Fill(eta, phi, poissonV);
384 for (Int_t ieta=1; ieta <= h->GetNbinsX(); ieta++) {
385 for (Int_t iphi=1; iphi<= h->GetNbinsY(); iphi++) {
387 Double_t poissonV = 0; //h->GetBinContent(,s+1);
390 poissonV = h->GetBinContent(ieta,iphi);
391 eLossV = hclone->GetBinContent(ieta,iphi);
394 poissonV = hclone->GetBinContent(ieta,iphi);
395 eLossV = h->GetBinContent(ieta,iphi);
398 rh->fELossVsPoisson->Fill(eLossV, poissonV);
409 //_____________________________________________________________________
411 AliFMDDensityCalculator::FindMaxWeight(const AliFMDCorrELossFit* cor,
412 UShort_t d, Char_t r, Int_t iEta) const
415 // Find the max weight to use for FMD<i>dr</i> in eta bin @a iEta
423 AliFMDCorrELossFit::ELossFit* fit = cor->GetFit(d,r,iEta);
425 // AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f", d, r, eta));
428 return TMath::Min(Int_t(fMaxParticles), fit->FindMaxWeight());
431 //_____________________________________________________________________
433 AliFMDDensityCalculator::CacheMaxWeights()
436 // Find the max weights and cache them
438 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
439 AliFMDCorrELossFit* cor = fcm.GetELossFit();
440 const TAxis& eta = cor->GetEtaAxis();
442 Int_t nEta = eta.GetNbins();
449 fMaxWeights->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
450 fMaxWeights->GetYaxis()->SetBinLabel(1, "FMD1i");
451 fMaxWeights->GetYaxis()->SetBinLabel(2, "FMD2i");
452 fMaxWeights->GetYaxis()->SetBinLabel(3, "FMD2o");
453 fMaxWeights->GetYaxis()->SetBinLabel(4, "FMD3i");
454 fMaxWeights->GetYaxis()->SetBinLabel(5, "FMD3o");
456 AliInfo(Form("Get eta axis with %d bins from %f to %f",
457 nEta, eta.GetXmin(), eta.GetXmax()));
458 fLowCuts->SetBins(nEta, eta.GetXmin(), eta.GetXmax(), 5, .5, 5.5);
459 fLowCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
460 fLowCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
461 fLowCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
462 fLowCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
463 fLowCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
465 for (Int_t i = 0; i < nEta; i++) {
467 w[0] = fFMD1iMax[i] = FindMaxWeight(cor, 1, 'I', i+1);
468 w[1] = fFMD2iMax[i] = FindMaxWeight(cor, 2, 'I', i+1);
469 w[2] = fFMD2oMax[i] = FindMaxWeight(cor, 2, 'O', i+1);
470 w[3] = fFMD3iMax[i] = FindMaxWeight(cor, 3, 'I', i+1);
471 w[4] = fFMD3oMax[i] = FindMaxWeight(cor, 3, 'O', i+1);
473 l[0] = GetMultCut(1, 'I', i+1, false);
474 l[1] = GetMultCut(2, 'I', i+1, false);
475 l[2] = GetMultCut(2, 'O', i+1, false);
476 l[3] = GetMultCut(3, 'I', i+1, false);
477 l[4] = GetMultCut(3, 'O', i+1, false);
478 for (Int_t j = 0; j < 5; j++) {
479 if (w[j] > 0) fMaxWeights->SetBinContent(i+1, j+1, w[j]);
480 if (l[j] > 0) fLowCuts->SetBinContent(i+1, j+1, l[j]);
485 //_____________________________________________________________________
487 AliFMDDensityCalculator::GetMaxWeight(UShort_t d, Char_t r, Int_t iEta) const
490 // Find the (cached) maximum weight for FMD<i>dr</i> in
491 // @f$\eta@f$ bin @a iEta
499 // max weight or <= 0 in case of problems
501 if (iEta < 0) return -1;
503 const TArrayI* max = 0;
505 case 1: max = &fFMD1iMax; break;
506 case 2: max = (r == 'I' || r == 'i' ? &fFMD2iMax : &fFMD2oMax); break;
507 case 3: max = (r == 'I' || r == 'i' ? &fFMD3iMax : &fFMD3oMax); break;
510 AliWarning(Form("No array for FMD%d%c", d, r));
514 if (iEta >= max->fN) {
515 AliWarning(Form("Eta bin %3d out of bounds [0,%d]",
520 AliDebug(30,Form("Max weight for FMD%d%c eta bin %3d: %d", d, r, iEta,
522 return max->At(iEta);
525 //_____________________________________________________________________
527 AliFMDDensityCalculator::GetMaxWeight(UShort_t d, Char_t r, Float_t eta) const
530 // Find the (cached) maximum weight for FMD<i>dr</i> iat
539 // max weight or <= 0 in case of problems
541 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
542 Int_t iEta = fcm.GetELossFit()->FindEtaBin(eta) -1;
544 return GetMaxWeight(d, r, iEta);
547 //_____________________________________________________________________
549 AliFMDDensityCalculator::NParticles(Float_t mult,
556 Bool_t lowFlux) const
559 // Get the number of particles corresponding to the signal mult
566 // t Strip (not used)
568 // eta Pseudo-rapidity
569 // lowFlux Low-flux flag
572 // The number of particles
574 // if (mult <= GetMultCut()) return 0;
575 if (lowFlux) return 1;
577 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
578 AliFMDCorrELossFit::ELossFit* fit = fcm.GetELossFit()->FindFit(d,r,eta);
580 AliWarning(Form("No energy loss fit for FMD%d%c at eta=%f", d, r, eta));
584 Int_t m = GetMaxWeight(d,r,eta); // fit->FindMaxWeight();
586 AliWarning(Form("No good fits for FMD%d%c at eta=%f", d, r, eta));
590 UShort_t n = TMath::Min(fMaxParticles, UShort_t(m));
591 Double_t ret = fit->EvaluateWeighted(mult, n);
594 AliInfo(Form("FMD%d%c, eta=%7.4f, %8.5f -> %8.5f", d, r, eta, mult, ret));
597 fWeightedSum->Fill(ret);
598 fSumOfWeights->Fill(ret);
603 //_____________________________________________________________________
605 AliFMDDensityCalculator::Correction(UShort_t d,
611 Bool_t lowFlux) const
614 // Get the inverse correction factor. This consist of
616 // - acceptance correction (corners of sensors)
617 // - double hit correction (for low-flux events)
618 // - dead strip correction
624 // t Strip (not used)
626 // eta Pseudo-rapidity
627 // lowFlux Low-flux flag
632 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
634 Float_t correction = 1;
635 if (fUsePhiAcceptance == kPhiCorrectNch)
636 correction = AcceptanceCorrection(r,t);
639 if (fcm.GetDoubleHit())
640 dblHitCor = fcm.GetDoubleHit()->GetCorrection(d,r);
643 Double_t dblC = dblHitCor->GetBinContent(dblHitCor->FindBin(eta));
644 if (dblC > 0) correction *= dblC;
647 AliWarning(Form("Missing double hit correction for FMD%d%c",d,r));
653 //_____________________________________________________________________
655 AliFMDDensityCalculator::GenerateAcceptanceCorrection(Char_t r) const
658 // Generate the acceptance corrections
661 // r Ring to generate for
664 // Newly allocated histogram of acceptance corrections
666 const Double_t ic1[] = { 4.9895, 15.3560 };
667 const Double_t ic2[] = { 1.8007, 17.2000 };
668 const Double_t oc1[] = { 4.2231, 26.6638 };
669 const Double_t oc2[] = { 1.8357, 27.9500 };
670 const Double_t* c1 = (r == 'I' || r == 'i' ? ic1 : oc1);
671 const Double_t* c2 = (r == 'I' || r == 'i' ? ic2 : oc2);
672 Double_t minR = (r == 'I' || r == 'i' ? 4.5213 : 15.4);
673 Double_t maxR = (r == 'I' || r == 'i' ? 17.2 : 28.0);
674 Int_t nStrips = (r == 'I' || r == 'i' ? 512 : 256);
675 Int_t nSec = (r == 'I' || r == 'i' ? 20 : 40);
676 Float_t basearc = 2 * TMath::Pi() / nSec;
677 Double_t rad = maxR - minR;
678 Float_t segment = rad / nStrips;
679 Float_t cr = TMath::Sqrt(c1[0]*c1[0]+c1[1]*c1[1]);
681 // Numbers used to find end-point of strip.
682 // (See http://mathworld.wolfram.com/Circle-LineIntersection.html)
683 Float_t D = c1[0] * c2[1] - c1[1] * c2[0];
684 Float_t dx = c2[0] - c1[0];
685 Float_t dy = c2[1] - c1[1];
686 Float_t dr = TMath::Sqrt(dx*dx+dy*dy);
688 TH1D* ret = new TH1D(Form("acc%c", r),
689 Form("Acceptance correction for FMDx%c", r),
690 nStrips, -.5, nStrips-.5);
691 ret->SetXTitle("Strip");
692 ret->SetYTitle("#varphi acceptance");
693 ret->SetDirectory(0);
694 ret->SetFillColor(r == 'I' || r == 'i' ? kRed+1 : kBlue+1);
695 ret->SetFillStyle(3001);
697 for (Int_t t = 0; t < nStrips; t++) {
698 Float_t radius = minR + t * segment;
700 // If the radius of the strip is smaller than the radius corresponding
701 // to the first corner we have a full strip length
703 ret->SetBinContent(t+1, 1);
707 // Next, we should find the end-point of the strip - that is,
708 // the coordinates where the line from c1 to c2 intersects a circle
709 // with radius given by the strip.
710 // (See http://mathworld.wolfram.com/Circle-LineIntersection.html)
711 // Calculate the determinant
712 Float_t det = radius * radius * dr * dr - D*D;
715 // <0 means No intersection
716 // =0 means Exactly tangent
717 ret->SetBinContent(t+1, 1);
721 // Calculate end-point and the corresponding opening angle
722 Float_t x = (+D * dy + dx * TMath::Sqrt(det)) / dr / dr;
723 Float_t y = (-D * dx + dy * TMath::Sqrt(det)) / dr / dr;
724 Float_t th = TMath::ATan2(x, y);
726 ret->SetBinContent(t+1, th / basearc);
731 //_____________________________________________________________________
733 AliFMDDensityCalculator::AcceptanceCorrection(Char_t r, UShort_t t) const
736 // Get the acceptance correction for strip @a t in an ring of type @a r
739 // r Ring type ('I' or 'O')
743 // Inverse acceptance correction
745 TH1D* acc = (r == 'I' || r == 'i' ? fAccI : fAccO);
746 return acc->GetBinContent(t+1);
749 //____________________________________________________________________
751 AliFMDDensityCalculator::ScaleHistograms(const TList* dir, Int_t nEvents)
754 // Scale the histograms to the total number of events
757 // dir where to put the output
758 // nEvents Number of events
760 if (nEvents <= 0) return;
761 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
764 TIter next(&fRingHistos);
766 THStack* sums = new THStack("sums", "sums of ring signals");
767 while ((o = static_cast<RingHistos*>(next()))) {
768 o->ScaleHistograms(d, nEvents);
769 TH1D* sum = o->fDensity->ProjectionX(o->GetName(), 1,
770 o->fDensity->GetNbinsY(),"e");
771 sum->Scale(1., "width");
772 sum->SetTitle(o->GetName());
773 sum->SetDirectory(0);
774 sum->SetYTitle("#sum N_{ch,incl}");
780 //____________________________________________________________________
782 AliFMDDensityCalculator::DefineOutput(TList* dir)
785 // Output diagnostic histograms to directory
788 // dir List to write in
790 TList* d = new TList;
792 d->SetName(GetName());
794 d->Add(fWeightedSum);
795 d->Add(fSumOfWeights);
796 d->Add(fCorrections);
802 // TNamed* sigma = new TNamed("sigma",
803 // (fIncludeSigma ? "included" : "excluded"));
804 TNamed* maxP = new TNamed("maxParticle", Form("%d", fMaxParticles));
805 TNamed* method = new TNamed("method",
806 (fUsePoisson ? "Poisson" : "Energy loss"));
807 TNamed* phiA = new TNamed("phiAcceptance",
808 (fUsePhiAcceptance == 0 ? "disabled" :
809 fUsePhiAcceptance == 1 ? "particles" :
811 TNamed* etaL = new TNamed("etaLumping", Form("%d", fEtaLumping));
812 TNamed* phiL = new TNamed("phiLumping", Form("%d", fPhiLumping));
813 // TParameter<double>* nxi = new TParameter<double>("nXi", fNXi);
824 TIter next(&fRingHistos);
826 while ((o = static_cast<RingHistos*>(next()))) {
827 o->fPoisson.SetLumping(fEtaLumping, fPhiLumping);
831 //____________________________________________________________________
833 AliFMDDensityCalculator::Print(Option_t* option) const
841 char ind[gROOT->GetDirLevel()+3];
842 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
843 ind[gROOT->GetDirLevel()] = '\0';
844 std::cout << ind << ClassName() << ": " << GetName() << '\n'
846 << ind << " Max(particles): " << fMaxParticles << '\n'
847 << ind << " Poisson method: " << fUsePoisson << '\n'
848 << ind << " Use phi acceptance: " << fUsePhiAcceptance << '\n'
849 << ind << " Eta lumping: " << fEtaLumping << '\n'
850 << ind << " Phi lumping: " << fPhiLumping << '\n'
853 std::cout << ind << " Lower cut:" << std::endl;
857 if (opt.Contains("nomax")) return;
859 std::cout << ind << " Max weights:\n";
861 for (UShort_t d=1; d<=3; d++) {
862 UShort_t nr = (d == 1 ? 1 : 2);
863 for (UShort_t q=0; q<nr; q++) {
864 ind[gROOT->GetDirLevel()] = ' ';
865 ind[gROOT->GetDirLevel()+1] = '\0';
866 Char_t r = (q == 0 ? 'I' : 'O');
867 std::cout << ind << " FMD" << d << r << ":";
868 ind[gROOT->GetDirLevel()+1] = ' ';
869 ind[gROOT->GetDirLevel()+2] = '\0';
871 const TArrayI& a = (d == 1 ? fFMD1iMax :
872 (d == 2 ? (r == 'I' ? fFMD2iMax : fFMD2oMax) :
873 (r == 'I' ? fFMD3iMax : fFMD3oMax)));
875 for (Int_t i = 0; i < a.fN; i++) {
876 if (a.fArray[i] < 1) continue;
877 if (j % 6 == 0) std::cout << "\n " << ind;
879 std::cout << " " << std::setw(3) << i << ": " << a.fArray[i];
881 std::cout << std::endl;
886 //====================================================================
887 AliFMDDensityCalculator::RingHistos::RingHistos()
888 : AliForwardUtil::RingHistos(),
906 //____________________________________________________________________
907 AliFMDDensityCalculator::RingHistos::RingHistos(UShort_t d, Char_t r)
908 : AliForwardUtil::RingHistos(d,r),
928 fEvsN = new TH2D("elossVsNnocorr",
929 "#Delta E/#Delta E_{mip} vs uncorrected inclusive N_{ch}",
930 250, -.5, 24.5, 250, -.5, 24.5);
931 fEvsN->SetXTitle("#Delta E/#Delta E_{mip}");
932 fEvsN->SetYTitle("Inclusive N_{ch} (uncorrected)");
934 fEvsN->SetDirectory(0);
936 fEvsM = static_cast<TH2D*>(fEvsN->Clone("elossVsNcorr"));
937 fEvsM->SetTitle("#Delta E/#Delta E_{mip} vs corrected inclusive N_{ch}");
938 fEvsM->SetDirectory(0);
940 fEtaVsN = new TProfile("etaVsNnocorr",
941 "Average inclusive N_{ch} vs #eta (uncorrected)",
943 fEtaVsN->SetXTitle("#eta");
944 fEtaVsN->SetYTitle("#LT N_{ch,incl}#GT (uncorrected)");
945 fEtaVsN->SetDirectory(0);
946 fEtaVsN->SetLineColor(Color());
947 fEtaVsN->SetFillColor(Color());
949 fEtaVsM = static_cast<TProfile*>(fEtaVsN->Clone("etaVsNcorr"));
950 fEtaVsM->SetTitle("Average inclusive N_{ch} vs #eta (corrected)");
951 fEtaVsM->SetYTitle("#LT N_{ch,incl}#GT (corrected)");
952 fEtaVsM->SetDirectory(0);
955 fCorr = new TProfile("corr", "Average correction", 200, -4, 6);
956 fCorr->SetXTitle("#eta");
957 fCorr->SetYTitle("#LT correction#GT");
958 fCorr->SetDirectory(0);
959 fCorr->SetLineColor(Color());
960 fCorr->SetFillColor(Color());
962 fDensity = new TH2D("inclDensity", "Inclusive N_{ch} density",
963 200, -4, 6, (r == 'I' || r == 'i' ? 20 : 40),
965 fDensity->SetDirectory(0);
967 fDensity->SetMarkerColor(Color());
968 fDensity->SetXTitle("#eta");
969 fDensity->SetYTitle("#phi [radians]");
970 fDensity->SetZTitle("Inclusive N_{ch} density");
972 fELossVsPoisson = new TH2D("elossVsPoisson",
973 "N_{ch} from energy loss vs from Poission",
974 500, 0, 100, 500, 0, 100);
975 fELossVsPoisson->SetDirectory(0);
976 fELossVsPoisson->SetXTitle("N_{ch} from #DeltaE");
977 fELossVsPoisson->SetYTitle("N_{ch} from Poisson");
978 fELossVsPoisson->SetZTitle("Correlation");
980 fELoss = new TH1D("eloss", "#Delta/#Delta_{mip} in all strips",
982 fELoss->SetXTitle("#Delta/#Delta_{mip} (selected)");
983 fELoss->SetYTitle("P(#Delta/#Delta_{mip})");
984 fELoss->SetFillColor(Color()-2);
985 fELoss->SetFillStyle(3003);
986 fELoss->SetLineColor(kBlack);
987 fELoss->SetLineStyle(2);
988 fELoss->SetLineWidth(2);
989 fELoss->SetDirectory(0);
991 fELossUsed = static_cast<TH1D*>(fELoss->Clone("elossUsed"));
992 fELossUsed->SetTitle("#Delta/#Delta_{mip} in used strips");
993 fELossUsed->SetFillStyle(3002);
994 fELossUsed->SetLineStyle(1);
995 fELossUsed->SetDirectory(0);
998 //____________________________________________________________________
999 AliFMDDensityCalculator::RingHistos::RingHistos(const RingHistos& o)
1000 : AliForwardUtil::RingHistos(o),
1006 fDensity(o.fDensity),
1007 fELossVsPoisson(o.fELossVsPoisson),
1008 fPoisson(o.fPoisson),
1010 fELossUsed(o.fELossUsed),
1011 fMultCut(o.fMultCut)
1017 // o Object to copy from
1021 //____________________________________________________________________
1022 AliFMDDensityCalculator::RingHistos&
1023 AliFMDDensityCalculator::RingHistos::operator=(const RingHistos& o)
1026 // Assignment operator
1029 // o Object to assign from
1032 // Reference to this
1034 if (&o == this) return *this;
1035 AliForwardUtil::RingHistos::operator=(o);
1037 if (fEvsN) delete fEvsN;
1038 if (fEvsM) delete fEvsM;
1039 if (fEtaVsN) delete fEtaVsN;
1040 if (fEtaVsM) delete fEtaVsM;
1041 if (fCorr) delete fCorr;
1042 if (fDensity) delete fDensity;
1043 if (fELossVsPoisson) delete fELossVsPoisson;
1045 fEvsN = static_cast<TH2D*>(o.fEvsN->Clone());
1046 fEvsM = static_cast<TH2D*>(o.fEvsM->Clone());
1047 fEtaVsN = static_cast<TProfile*>(o.fEtaVsN->Clone());
1048 fEtaVsM = static_cast<TProfile*>(o.fEtaVsM->Clone());
1049 fCorr = static_cast<TProfile*>(o.fCorr->Clone());
1050 fDensity = static_cast<TH2D*>(o.fDensity->Clone());
1051 fELossVsPoisson = static_cast<TH2D*>(o.fELossVsPoisson->Clone());
1052 fPoisson = o.fPoisson;
1053 fELoss = static_cast<TH1D*>(o.fELoss->Clone());
1054 fELossUsed = static_cast<TH1D*>(o.fELossUsed->Clone());
1058 //____________________________________________________________________
1059 AliFMDDensityCalculator::RingHistos::~RingHistos()
1067 //____________________________________________________________________
1069 AliFMDDensityCalculator::RingHistos::Init(const TAxis& /*eAxis*/)
1071 fPoisson.Init(-1,-1);
1074 //____________________________________________________________________
1076 AliFMDDensityCalculator::RingHistos::Output(TList* dir)
1082 // dir Where to put it
1084 TList* d = DefineOutputList(dir);
1091 d->Add(fELossVsPoisson);
1093 fPoisson.GetOccupancy()->SetFillColor(Color());
1094 fPoisson.GetMean()->SetFillColor(Color());
1095 fPoisson.GetOccupancy()->SetFillColor(Color());
1099 Bool_t inner = (fRing == 'I' || fRing == 'i');
1100 Int_t nStr = inner ? 512 : 256;
1101 Int_t nSec = inner ? 20 : 40;
1102 TAxis x(nStr, -.5, nStr-.5);
1103 TAxis y(nSec, -.5, nSec-.5);
1104 x.SetTitle("strip");
1105 y.SetTitle("sector");
1106 fPoisson.Define(x, y);
1108 TParameter<double>* cut = new TParameter<double>("cut", fMultCut);
1112 //____________________________________________________________________
1114 AliFMDDensityCalculator::RingHistos::ScaleHistograms(TList* dir, Int_t nEvents)
1117 // Scale the histograms to the total number of events
1120 // dir Where the output is
1121 // nEvents Number of events
1123 TList* l = GetOutputList(dir);
1126 TH1* density = GetOutputHist(l,"inclDensity");
1127 if (density) density->Scale(1./nEvents);
1130 //____________________________________________________________________