2 // Class to do the sharing correction. That is, a filter that merges
3 // adjacent strip signals presumably originating from a single particle
4 // that impinges on the detector in such a way that it deposite energy
5 // into two or more strips.
8 // - AliESDFMD object - from reconstruction
11 // - AliESDFMD object - copy of input, but with signals merged
14 // - AliFMDCorrELossFit
17 // - For each ring (FMD1i, FMD2i, FMD2o, FMD3i, FMD3o) the distribution of
18 // signals before and after the filter.
19 // - For each ring (see above), an array of distributions of number of
20 // hit strips for each vertex bin (if enabled - see Init method)
24 #include "AliFMDSharingFilter.h"
25 #include "AliFMDStripIndex.h"
26 #include <AliESDFMD.h>
31 #include "AliForwardCorrectionManager.h"
32 #include "AliFMDCorrELossFit.h"
36 #include <TParameter.h>
40 ClassImp(AliFMDSharingFilter)
42 ; // This is for Emacs
46 do { if (L>fDebug)break; std::cout << (M) << std::flush;} while(false)
48 do { if (L>fDebug)break; std::cout << (M) << std::endl;} while(false)
52 //____________________________________________________________________
53 AliFMDSharingFilter::AliFMDSharingFilter()
56 fCorrectAngles(kFALSE),
62 fZeroSharedHitsBelowThreshold(false),
65 fUseSimpleMerging(false),
66 fThreeStripSharing(true),
67 fMergingDisabled(false),
68 fIgnoreESDForAngleCorrection(false)
71 // Default Constructor - do not use
73 DGUARD(fDebug,1, "Default CTOR for AliFMDSharingFilter");
76 //____________________________________________________________________
77 AliFMDSharingFilter::AliFMDSharingFilter(const char* title)
78 : TNamed("fmdSharingFilter", title),
80 fCorrectAngles(kFALSE),
86 fZeroSharedHitsBelowThreshold(false),
89 fUseSimpleMerging(false),
90 fThreeStripSharing(true),
91 fMergingDisabled(false),
92 fIgnoreESDForAngleCorrection(false)
98 // title Title of object - not significant
100 DGUARD(fDebug,1, "Named CTOR for AliFMDSharingFilter: %s", title);
101 fRingHistos.SetName(GetName());
102 fRingHistos.SetOwner();
104 fRingHistos.Add(new RingHistos(1, 'I'));
105 fRingHistos.Add(new RingHistos(2, 'I'));
106 fRingHistos.Add(new RingHistos(2, 'O'));
107 fRingHistos.Add(new RingHistos(3, 'I'));
108 fRingHistos.Add(new RingHistos(3, 'O'));
110 fHCuts.Set(AliFMDMultCuts::kLandauSigmaWidth, 1);
111 fLCuts.Set(AliFMDMultCuts::kFixed, .15);
113 // fExtraDead.Reset(-1);
116 //____________________________________________________________________
117 AliFMDSharingFilter::~AliFMDSharingFilter()
122 DGUARD(fDebug,3, "DTOR for AliFMDSharingFilter");
123 // fRingHistos.Delete();
126 //____________________________________________________________________
127 AliFMDSharingFilter::RingHistos*
128 AliFMDSharingFilter::GetRingHistos(UShort_t d, Char_t r) const
131 // Get the ring histogram container
138 // Ring histogram container
142 case 1: idx = 0; break;
143 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
144 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
146 if (idx < 0 || idx >= fRingHistos.GetEntries()) return 0;
148 return static_cast<RingHistos*>(fRingHistos.At(idx));
151 //____________________________________________________________________
153 AliFMDSharingFilter::SetupForData(const TAxis& axis)
155 // Initialise - called on first event
156 DGUARD(fDebug,1, "Initialize for AliFMDSharingFilter");
157 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
158 const AliFMDCorrELossFit* fits = fcm.GetELossFit();
160 // Get the high cut. The high cut is defined as the
161 // most-probably-value peak found from the energy distributions, minus
162 // 2 times the width of the corresponding Landau.
164 TAxis eAxis(axis.GetNbins(),
168 eAxis.Set(fits->GetEtaAxis().GetNbins(),
169 fits->GetEtaAxis().GetXmin(),
170 fits->GetEtaAxis().GetXmax());
172 UShort_t nEta = eAxis.GetNbins();
174 fHighCuts->SetBins(nEta, eAxis.GetXmin(), eAxis.GetXmax(), 5, .5, 5.5);
175 fHighCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
176 fHighCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
177 fHighCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
178 fHighCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
179 fHighCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
181 fLowCuts->SetBins(nEta, eAxis.GetXmin(), eAxis.GetXmax(), 5, .5, 5.5);
182 fLowCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
183 fLowCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
184 fLowCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
185 fLowCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
186 fLowCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
188 // Cache our cuts in histograms
189 fLCuts.FillHistogram(fLowCuts);
190 fHCuts.FillHistogram(fHighCuts);
193 //____________________________________________________________________
194 #define ETA2COS(ETA) \
195 TMath::Cos(2*TMath::ATan(TMath::Exp(-TMath::Abs(ETA))))
198 AliFMDSharingFilter::Filter(const AliESDFMD& input,
204 // Filter the input AliESDFMD object
208 // lowFlux If this is a low-flux event
209 // output Output AliESDFMD object
212 // True on success, false otherwise
214 DGUARD(fDebug,1, "Filter event in AliFMDSharingFilter");
216 TIter next(&fRingHistos);
218 while ((o = static_cast<RingHistos*>(next()))) o->Clear();
224 for(UShort_t d = 1; d <= 3; d++) {
225 Int_t nRings = (d == 1 ? 1 : 2);
226 for (UShort_t q = 0; q < nRings; q++) {
227 Char_t r = (q == 0 ? 'I' : 'O');
228 UShort_t nsec = (q == 0 ? 20 : 40);
229 UShort_t nstr = (q == 0 ? 512 : 256);
230 RingHistos* histos = GetRingHistos(d, r);
232 for(UShort_t s = 0; s < nsec; s++) {
233 // `used' flags if the _current_ strip was used by _previous_
235 Bool_t used = kFALSE;
236 // `eTotal' contains the current sum of merged signals so far
237 Double_t eTotal = -1;
238 // Int_t nDistanceBefore = -1;
239 // Int_t nDistanceAfter = -1;
240 // `twoLow' flags if we saw two consequtive strips with a
241 // signal between the two cuts.
242 Bool_t twoLow = kFALSE;
243 Int_t nStripsAboveCut = 0;
245 for(UShort_t t = 0; t < nstr; t++) {
246 // nDistanceBefore++;
249 output.SetMultiplicity(d,r,s,t,0.);
250 Float_t mult = SignalInStrip(input,d,r,s,t);
251 Float_t multNext = (t<nstr-1) ? SignalInStrip(input,d,r,s,t+1) :0;
252 Float_t multNextNext = (t<nstr-2) ? SignalInStrip(input,d,r,s,t+2) :0;
253 if (multNext == AliESDFMD::kInvalidMult) multNext = 0;
254 if (multNextNext == AliESDFMD::kInvalidMult) multNextNext = 0;
255 if(!fThreeStripSharing) multNextNext = 0;
257 // Get the pseudo-rapidity
258 Double_t eta = input.Eta(d,r,s,t);
259 Double_t phi = input.Phi(d,r,s,t) * TMath::Pi() / 180.;
260 if (s == 0) output.SetEta(d,r,s,t,eta);
262 // Keep dead-channel information - either from the ESD (but
263 // see above for older data) or from the settings in the
264 // ForwardAODConfig.C file.
265 if (mult == AliESDFMD::kInvalidMult) {
266 output.SetMultiplicity(d,r,s,t,AliESDFMD::kInvalidMult);
267 histos->fBefore->Fill(-1);
268 mult = AliESDFMD::kInvalidMult;
271 Double_t lowCut = GetLowCut(d, r, eta);
272 Double_t highCut = GetHighCut(d, r, eta, false);
273 if (mult != AliESDFMD::kInvalidMult && mult > lowCut) {
274 // Always fill the ESD sum histogram
275 histos->fSumESD->Fill(eta, phi, mult);
278 // If no signal or dead strip, go on.
279 if (mult == AliESDFMD::kInvalidMult || mult == 0) {
280 if (mult == 0) histos->fSum->Fill(eta,phi,mult);
281 // Flush a possible signal
282 if (eTotal > 0 && t > 0)
283 output.SetMultiplicity(d,r,s,t-1,eTotal);
284 // Reset states so we do not try to merge over a dead strip.
289 histos->fNConsecutive->Fill(nStripsAboveCut);
290 if (mult == AliESDFMD::kInvalidMult)
291 // Why not fill immidiately here?
292 nStripsAboveCut = -1;
294 // Why not fill immidiately here?
299 // Fill the diagnostics histogram
300 histos->fBefore->Fill(mult);
302 Double_t mergedEnergy = mult;
303 // it seems to me that this logic could be condensed a bit
305 if(nStripsAboveCut < 1) {
307 histos->fNConsecutive->Fill(nStripsAboveCut);
314 histos->fNConsecutive->Fill(nStripsAboveCut);
318 if (!fMergingDisabled) {
324 // Fill in neighbor information
325 if (t < nstr-1) histos->fNeighborsBefore->Fill(mult,multNext);
327 Bool_t thisValid = mult > lowCut;
328 Bool_t nextValid = multNext > lowCut;
329 Bool_t thisSmall = mult < highCut;
330 Bool_t nextSmall = multNext < highCut;
332 // If this strips signal is above the high cut, reset distance
334 // histos->fDistanceBefore->Fill(nDistanceBefore);
335 // nDistanceBefore = -1;
338 // If the total signal in the past 1 or 2 strips are non-zero
341 // Here, we have already flagged one strip as a candidate
343 // If 3-strip merging is enabled, then check the next
344 // strip to see that it falls within cut, or if we have
346 if (fThreeStripSharing && nextValid && (nextSmall || twoLow)) {
347 eTotal = eTotal + multNext;
349 histos->fTriple->Fill(eTotal);
353 // Otherwise, we got a double hit before, and that
357 histos->fDouble->Fill(eTotal);
360 // Store energy loss and reset sum
365 // If we have no current sum
367 // Check if this is marked as used, and if so, continue
368 if (used) {used = kFALSE; continue; }
370 // If the signal is abvoe the cut, set current
371 if (thisValid) etot = mult;
373 // If the signal is abiove the cut, and so is the next
374 // signal and either of them are below the high cut,
375 if (thisValid && nextValid && (thisSmall || nextSmall)) {
377 // If this is below the high cut, and the next is too, then
378 // we have two low signals
379 if (thisSmall && nextSmall) twoLow = kTRUE;
381 // If this signal is bigger than the next, and the
382 // one after that is below the low-cut, then update
384 if (mult>multNext && multNextNext < lowCut) {
385 etot = mult + multNext;
387 histos->fDouble->Fill(etot);
390 // Otherwise, we may need to merge with a third strip
393 eTotal = mult + multNext;
396 // This is a signle hit
398 histos->fSingle->Fill(etot);
399 histos->fSinglePerStrip->Fill(etot,t);
402 } // else if (etotal >= 0)
405 // if (mergedEnergy > GetHighCut(d, r, eta ,false)) {
406 // histos->fDistanceAfter->Fill(nDistanceAfter);
407 // nDistanceAfter = -1;
409 //if(mult>0 && multNext >0)
410 // std::cout<<mult<<" "<<multNext<<" "<<mergedEnergy<<std::endl;
411 } // if (!fMergingDisabled)
414 mergedEnergy = AngleCorrect(mergedEnergy, eta);
415 // if (mergedEnergy > 0) histos->Incr();
418 histos->fNeighborsAfter->Fill(output.Multiplicity(d,r,s,t-1),
420 histos->fBeforeAfter->Fill(mult, mergedEnergy);
422 histos->fAfter->Fill(mergedEnergy);
423 histos->fSum->Fill(eta,phi,mergedEnergy);
425 output.SetMultiplicity(d,r,s,t,mergedEnergy);
427 histos->fNConsecutive->Fill(nStripsAboveCut); // fill the last sector
431 DMSG(fDebug, 3,"single=%9d, double=%9d, triple=%9d",
432 nSingle, nDouble, nTriple);
434 // while ((o = static_cast<RingHistos*>(next()))) o->Finish();
439 //_____________________________________________________________________
441 AliFMDSharingFilter::SignalInStrip(const AliESDFMD& input,
448 // Get the signal in a strip
460 Double_t mult = input.Multiplicity(d,r,s,t);
462 // - bad value (invalid or 0)
463 // - we want angle corrected and data is
464 // - we don't want angle corrected and data isn't
465 // just return read value
466 if (mult == AliESDFMD::kInvalidMult ||
468 (fCorrectAngles && (fIgnoreESDForAngleCorrection || input.IsAngleCorrected())) ||
469 (!fCorrectAngles && !fIgnoreESDForAngleCorrection && !input.IsAngleCorrected()))
472 // If we want angle corrected data, correct it,
473 // otherwise de-correct it
474 if (fCorrectAngles) mult = AngleCorrect(mult, input.Eta(d,r,s,t));
475 else mult = DeAngleCorrect(mult, input.Eta(d,r,s,t));
480 Double_t Rng2Cut(UShort_t d, Char_t r, Double_t eta, TH2* h) {
484 case 1: ybin = 1; break;
485 case 2: ybin = (r=='i' || r=='I') ? 2 : 3; break;
486 case 3: ybin = (r=='i' || r=='I') ? 4 : 5; break;
489 Int_t xbin = h->GetXaxis()->FindBin(eta);
490 if (xbin < 1 && xbin > h->GetXaxis()->GetNbins()) return ret;
491 ret = h->GetBinContent(xbin,ybin);
496 //_____________________________________________________________________
498 AliFMDSharingFilter::GetLowCut(UShort_t d, Char_t r, Double_t eta) const
501 // Get the low cut. Normally, the low cut is taken to be the lower
502 // value of the fit range used when generating the energy loss fits.
503 // However, if fLowCut is set (using SetLowCit) to a value greater
504 // than 0, then that value is used.
506 return Rng2Cut(d, r, eta, fLowCuts);
507 // return fLCuts.GetMultCut(d,r,eta,false);
510 //_____________________________________________________________________
512 AliFMDSharingFilter::GetHighCut(UShort_t d, Char_t r,
513 Double_t eta, Bool_t /*errors*/) const
516 // Get the high cut. The high cut is defined as the
517 // most-probably-value peak found from the energy distributions, minus
518 // 2 times the width of the corresponding Landau.
520 return Rng2Cut(d, r, eta, fHighCuts);
521 // return fHCuts.GetMultCut(d,r,eta,errors);
524 //____________________________________________________________________
526 AliFMDSharingFilter::AngleCorrect(Double_t mult, Double_t eta) const
529 // Angle correct the signal
532 // mult Angle Un-corrected Signal
533 // eta Pseudo-rapidity
536 // Angle corrected signal
538 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
539 if (eta < 0) theta -= TMath::Pi();
540 return mult * TMath::Cos(theta);
542 //____________________________________________________________________
544 AliFMDSharingFilter::DeAngleCorrect(Double_t mult, Double_t eta) const
547 // Angle de-correct the signal
550 // mult Angle corrected Signal
551 // eta Pseudo-rapidity
554 // Angle un-corrected signal
556 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
557 if (eta < 0) theta -= TMath::Pi();
558 return mult / TMath::Cos(theta);
561 //____________________________________________________________________
563 AliFMDSharingFilter::Terminate(const TList* dir, TList* output, Int_t nEvents)
566 // Scale the histograms to the total number of events
569 // dir Where the output is
570 // nEvents Number of events
572 DGUARD(fDebug,1, "Scale histograms in AliFMDSharingFilter");
573 if (nEvents <= 0) return;
574 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
577 TList* out = new TList;
578 out->SetName(d->GetName());
581 TParameter<int>* nFiles =
582 static_cast<TParameter<int>*>(d->FindObject("nFiles"));
584 TH2* lowCuts = static_cast<TH2*>(d->FindObject("lowCuts"));
585 TH2* highCuts = static_cast<TH2*>(d->FindObject("highCuts"));
586 if (lowCuts && nFiles) {
587 lowCuts->Scale(1. / nFiles->GetVal());
588 out->Add(lowCuts->Clone());
591 AliWarning("low cuts histogram not found in input list");
592 if (highCuts && nFiles) {
593 highCuts->Scale(1. / nFiles->GetVal());
594 out->Add(highCuts->Clone());
597 AliWarning("high cuts histogram not found in input list");
599 TIter next(&fRingHistos);
601 THStack* sums = new THStack("sums", "Sum of ring signals");
602 THStack* sumsESD = new THStack("sumsESD", "Sum of ring ESD signals");
603 while ((o = static_cast<RingHistos*>(next()))) {
604 o->Terminate(d, nEvents);
606 Warning("Terminate", "No sum histogram found for ring %s", o->GetName());
609 TH1D* sum = o->fSum->ProjectionX(o->GetName(), 1, o->fSum->GetNbinsY(),"e");
610 sum->Scale(1., "width");
611 sum->SetTitle(o->GetName());
612 sum->SetDirectory(0);
613 sum->SetYTitle("#sum_{c} #Delta/#Delta_{mip}");
616 sum = o->fSumESD->ProjectionX(o->GetName(), 1, o->fSumESD->GetNbinsY(),"e");
617 sum->Scale(1., "width");
618 sum->SetTitle(o->GetName());
619 sum->SetDirectory(0);
620 sum->SetYTitle("#sum_{s} #Delta/#Delta_{mip}");
628 //____________________________________________________________________
630 AliFMDSharingFilter::CreateOutputObjects(TList* dir)
633 // Define the output histograms. These are put in a sub list of the
634 // passed list. The histograms are merged before the parent task calls
635 // AliAnalysisTaskSE::Terminate
638 // dir Directory to add to
640 DGUARD(fDebug,1, "Define output in AliFMDSharingFilter");
641 TList* d = new TList;
642 d->SetName(GetName());
646 fSummed = new TH2I("operations", "Strip operations",
647 kMergedInto, kNone-.5, kMergedInto+.5,
648 51201, -.5, 51200.5);
649 fSummed->SetXTitle("Operation");
650 fSummed->SetYTitle("# of strips");
651 fSummed->SetZTitle("Events");
652 fSummed->GetXaxis()->SetBinLabel(kNone, "None");
653 fSummed->GetXaxis()->SetBinLabel(kCandidate, "Candidate");
654 fSummed->GetXaxis()->SetBinLabel(kMergedWithOther, "Merged w/other");
655 fSummed->GetXaxis()->SetBinLabel(kMergedInto, "Merged into");
656 fSummed->SetDirectory(0);
660 fHighCuts = new TH2D("highCuts", "High cuts used", 1,0,1, 1,0,1);
661 fHighCuts->SetXTitle("#eta");
662 fHighCuts->SetDirectory(0);
665 fLowCuts = new TH2D("lowCuts", "Low cuts used", 1,0,1, 1,0,1);
666 fLowCuts->SetXTitle("#eta");
667 fLowCuts->SetDirectory(0);
673 d->Add(AliForwardUtil::MakeParameter("angle", fCorrectAngles));
674 d->Add(AliForwardUtil::MakeParameter("lowSignal",
675 fZeroSharedHitsBelowThreshold));
676 d->Add(AliForwardUtil::MakeParameter("simple", fUseSimpleMerging));
677 d->Add(AliForwardUtil::MakeParameter("sumThree", fThreeStripSharing));
678 d->Add(AliForwardUtil::MakeParameter("disabled", fMergingDisabled));
679 TParameter<int>* nFiles = new TParameter<int>("nFiles", 1);
680 nFiles->SetMergeMode('+');
683 fLCuts.Output(d,"lCuts");
684 fHCuts.Output(d,"hCuts");
686 TIter next(&fRingHistos);
688 while ((o = static_cast<RingHistos*>(next()))) {
689 o->CreateOutputObjects(d);
692 #define PF(N,V,...) \
693 AliForwardUtil::PrintField(N,V, ## __VA_ARGS__)
694 #define PFB(N,FLAG) \
696 AliForwardUtil::PrintName(N); \
697 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
699 #define PFV(N,VALUE) \
701 AliForwardUtil::PrintName(N); \
702 std::cout << (VALUE) << std::endl; } while(false)
704 //____________________________________________________________________
706 AliFMDSharingFilter::Print(Option_t* /*option*/) const
714 AliForwardUtil::PrintTask(*this);
715 gROOT->IncreaseDirLevel();
717 PFB("Use corrected angles", fCorrectAngles);
718 PFB("Zero below threshold", fZeroSharedHitsBelowThreshold);
719 PFB("Use simple sharing", fUseSimpleMerging);
720 PFB("Allow 3 strip merging", fThreeStripSharing);
725 gROOT->DecreaseDirLevel();
728 //====================================================================
729 AliFMDSharingFilter::RingHistos::RingHistos()
730 : AliForwardUtil::RingHistos(),
737 // fDistanceBefore(0),
738 // fDistanceAfter(0),
755 //____________________________________________________________________
756 AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
757 : AliForwardUtil::RingHistos(d,r),
764 // fDistanceBefore(0),
765 // fDistanceAfter(0),
783 fBefore = new TH1D("esdEloss", Form("Energy loss in %s (reconstruction)",
784 GetName()), 640, -1, 15);
785 fBefore->SetXTitle("#Delta E/#Delta E_{mip}");
786 fBefore->SetYTitle("P(#Delta E/#Delta E_{mip})");
787 fBefore->SetFillColor(Color());
788 fBefore->SetFillStyle(3001);
789 fBefore->SetLineColor(kBlack);
790 fBefore->SetLineStyle(2);
791 fBefore->SetDirectory(0);
793 fAfter = static_cast<TH1D*>(fBefore->Clone("anaEloss"));
794 fAfter->SetTitle(Form("Energy loss in %s (sharing corrected)", GetName()));
795 fAfter->SetFillColor(Color()+2);
796 fAfter->SetLineStyle(1);
797 fAfter->SetDirectory(0);
799 fSingle = new TH1D("singleEloss", "Energy loss (single strips)",
801 fSingle->SetXTitle("#Delta/#Delta_{mip}");
802 fSingle->SetYTitle("P(#Delta/#Delta_{mip})");
803 fSingle->SetFillColor(Color());
804 fSingle->SetFillStyle(3001);
805 fSingle->SetLineColor(kBlack);
806 fSingle->SetLineStyle(2);
807 fSingle->SetDirectory(0);
809 fDouble = static_cast<TH1D*>(fSingle->Clone("doubleEloss"));
810 fDouble->SetTitle("Energy loss (two strips)");
811 fDouble->SetFillColor(Color()+1);
812 fDouble->SetDirectory(0);
814 fTriple = static_cast<TH1D*>(fSingle->Clone("tripleEloss"));
815 fTriple->SetTitle("Energy loss (three strips)");
816 fTriple->SetFillColor(Color()+2);
817 fTriple->SetDirectory(0);
819 //Int_t nBinsForInner = (r == 'I' ? 32 : 16);
820 Int_t nBinsForInner = (r == 'I' ? 512 : 256);
821 Int_t nStrips = (r == 'I' ? 512 : 256);
823 fSinglePerStrip = new TH2D("singlePerStrip", "SinglePerStrip",
824 600,0,15, nBinsForInner,0,nStrips);
825 fSinglePerStrip->SetXTitle("#Delta/#Delta_{mip}");
826 fSinglePerStrip->SetYTitle("Strip #");
827 fSinglePerStrip->SetZTitle("Counts");
828 fSinglePerStrip->SetDirectory(0);
831 fDistanceBefore = new TH1D("distanceBefore", "Distance before sharing",
832 nStrips , 0,nStrips );
833 fDistanceBefore->SetXTitle("Distance");
834 fDistanceBefore->SetYTitle("Counts");
835 fDistanceBefore->SetFillColor(kGreen+2);
836 fDistanceBefore->SetFillStyle(3001);
837 fDistanceBefore->SetLineColor(kBlack);
838 fDistanceBefore->SetLineStyle(2);
839 fDistanceBefore->SetDirectory(0);
841 fDistanceAfter = static_cast<TH1D*>(fDistanceBefore->Clone("distanceAfter"));
842 fDistanceAfter->SetTitle("Distance after sharing");
843 fDistanceAfter->SetFillColor(kGreen+1);
844 fDistanceAfter->SetDirectory(0);
849 Int_t n = int((max-min) / (max / 300));
850 fBeforeAfter = new TH2D("beforeAfter", "Before and after correlation",
851 n, min, max, n, min, max);
852 fBeforeAfter->SetXTitle("#Delta E/#Delta E_{mip} before");
853 fBeforeAfter->SetYTitle("#Delta E/#Delta E_{mip} after");
854 fBeforeAfter->SetZTitle("Correlation");
855 fBeforeAfter->SetDirectory(0);
857 fNeighborsBefore = static_cast<TH2D*>(fBeforeAfter->Clone("neighborsBefore"));
858 fNeighborsBefore->SetTitle("Correlation of neighbors before");
859 fNeighborsBefore->SetXTitle("#Delta E_{i}/#Delta E_{mip}");
860 fNeighborsBefore->SetYTitle("#Delta E_{i+1}/#Delta E_{mip}");
861 fNeighborsBefore->SetDirectory(0);
864 static_cast<TH2D*>(fNeighborsBefore->Clone("neighborsAfter"));
865 fNeighborsAfter->SetTitle("Correlation of neighbors after");
866 fNeighborsAfter->SetDirectory(0);
868 fSumESD = new TH2D("summedESD", "Summed ESD signal", 200, -4, 6,
869 NSector(), 0, 2*TMath::Pi());
870 fSumESD->SetDirectory(0);
872 fSumESD->SetMarkerColor(Color());
873 // fSum->SetFillColor(Color());
874 fSumESD->SetXTitle("#eta");
875 fSumESD->SetYTitle("#varphi [radians]");
876 fSumESD->SetZTitle("#sum_{strip} #Delta/#Delta_{mip}(#eta,#varphi) ");
878 fSum = static_cast<TH2D*>(fSumESD->Clone("summed"));
879 fSum->SetTitle("Summed cluster signal");
880 fSum->SetZTitle("#sum_{cluster} #Delta/#Delta_{mip}(#eta,#varphi) ");
881 fSum->SetDirectory(0);
883 // Perhaps we need to ensure that this histogram has enough range to
884 // accommondate all possible ranges - that is, from -1 to the number
885 // of strips in this ring(-type) - i.e., NStrips(). Perhaps the
886 // axis should be defined with increasin bin size - e.g.,
888 // -1.5,-.5,.5,1.5,...,100.5,128.5,192.5,...,NStrips()
890 fNConsecutive = new TH1D("nConsecutive","# consecutive strips above low cut",
892 fNConsecutive->SetXTitle("N_{strips}");
893 fNConsecutive->SetYTitle("N_{entries}");
894 fNConsecutive->SetFillColor(kYellow+2);
895 fNConsecutive->SetFillStyle(3001);
896 fNConsecutive->SetDirectory(0);
900 fHits = new TH1D("hits", "Number of hits", 200, 0, 200000);
901 fHits->SetDirectory(0);
902 fHits->SetXTitle("# of hits");
903 fHits->SetFillColor(kGreen+1);
906 //____________________________________________________________________
907 AliFMDSharingFilter::RingHistos::RingHistos(const RingHistos& o)
908 : AliForwardUtil::RingHistos(o),
914 fSinglePerStrip(o.fSinglePerStrip),
915 // fDistanceBefore(o.fDistanceBefore),
916 // fDistanceAfter(o.fDistanceAfter),
917 fBeforeAfter(o.fBeforeAfter),
918 fNeighborsBefore(o.fNeighborsBefore),
919 fNeighborsAfter(o.fNeighborsAfter),
920 fSumESD(o.fSumESD), //,
922 fNConsecutive(o.fNConsecutive)
931 // o Object to copy from
935 //____________________________________________________________________
936 AliFMDSharingFilter::RingHistos&
937 AliFMDSharingFilter::RingHistos::operator=(const RingHistos& o)
940 // Assignment operator
943 // o Object to assign from
948 if (&o == this) return *this;
949 AliForwardUtil::RingHistos::operator=(o);
953 if (fBefore) delete fBefore;
954 if (fAfter) delete fAfter;
955 if (fSingle) delete fSingle;
956 if (fDouble) delete fDouble;
957 if (fTriple) delete fTriple;
958 if (fSinglePerStrip) delete fSinglePerStrip;
959 if (fNConsecutive) delete fNConsecutive;
960 // if (fDistanceBefore) delete fDistanceBefore;
961 // if (fDistanceAfter) delete fDistanceAfter;
962 // if (fHits) delete fHits;
965 fBefore = static_cast<TH1D*>(o.fBefore->Clone());
966 fAfter = static_cast<TH1D*>(o.fAfter->Clone());
967 fSingle = static_cast<TH1D*>(o.fSingle->Clone());
968 fDouble = static_cast<TH1D*>(o.fDouble->Clone());
969 fTriple = static_cast<TH1D*>(o.fTriple->Clone());
970 fSinglePerStrip = static_cast<TH2D*>(o.fSinglePerStrip->Clone());
971 // fDistanceBefore = static_cast<TH1D*>(o.fDistanceBefore->Clone());
972 // fDistanceAfter = static_cast<TH1D*>(o.fDistanceAfter->Clone());
973 fBeforeAfter = static_cast<TH2D*>(o.fBeforeAfter->Clone());
974 fNeighborsBefore = static_cast<TH2D*>(o.fNeighborsBefore->Clone());
975 fNeighborsAfter = static_cast<TH2D*>(o.fNeighborsAfter->Clone());
976 // fHits = static_cast<TH1D*>(o.fHits->Clone());
977 fSumESD = static_cast<TH2D*>(o.fSumESD->Clone());
978 fSum = static_cast<TH2D*>(o.fSum->Clone());
979 fNConsecutive = static_cast<TH1D*>(o.fNConsecutive->Clone());
983 //____________________________________________________________________
984 AliFMDSharingFilter::RingHistos::~RingHistos()
991 //____________________________________________________________________
993 AliFMDSharingFilter::RingHistos::Finish()
999 // fHits->Fill(fNHits);
1002 //____________________________________________________________________
1004 AliFMDSharingFilter::RingHistos::Terminate(const TList* dir, Int_t nEvents)
1007 // Scale the histograms to the total number of events
1010 // nEvents Number of events
1011 // dir Where the output is
1013 TList* l = GetOutputList(dir);
1017 TH1D* before = static_cast<TH1D*>(l->FindObject("esdEloss"));
1018 TH1D* after = static_cast<TH1D*>(l->FindObject("anaEloss"));
1019 if (before) before->Scale(1./nEvents);
1020 if (after) after->Scale(1./nEvents);
1023 TH2D* summed = static_cast<TH2D*>(l->FindObject("summed"));
1024 if (summed) summed->Scale(1./nEvents);
1027 TH2D* summedESD = static_cast<TH2D*>(l->FindObject("summedESD"));
1028 if (summedESD) summedESD->Scale(1./nEvents);
1029 fSumESD = summedESD;
1031 TH1D* consecutive = static_cast<TH1D*>(l->FindObject("nConsecutive"));
1032 if (consecutive) consecutive->Scale(1./nEvents);
1033 fNConsecutive= consecutive;
1036 //____________________________________________________________________
1038 AliFMDSharingFilter::RingHistos::CreateOutputObjects(TList* dir)
1044 // dir where to store
1046 TList* d = DefineOutputList(dir);
1053 d->Add(fSinglePerStrip);
1054 // d->Add(fDistanceBefore);
1055 // d->Add(fDistanceAfter);
1056 d->Add(fBeforeAfter);
1057 d->Add(fNeighborsBefore);
1058 d->Add(fNeighborsAfter);
1062 d->Add(fNConsecutive);
1064 // Removed to avoid doubly adding the list which destroys
1069 //____________________________________________________________________