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 <AliESDFMD.h>
30 #include "AliForwardCorrectionManager.h"
31 #include "AliFMDCorrELossFit.h"
38 ClassImp(AliFMDSharingFilter)
40 ; // This is for Emacs
44 do { if (L>fDebug)break; std::cout << (M) << std::flush;} while(false)
46 do { if (L>fDebug)break; std::cout << (M) << std::endl;} while(false)
50 //____________________________________________________________________
51 AliFMDSharingFilter::AliFMDSharingFilter()
55 fCorrectAngles(kFALSE),
64 // Default Constructor - do not use
68 //____________________________________________________________________
69 AliFMDSharingFilter::AliFMDSharingFilter(const char* title)
70 : TNamed("fmdSharingFilter", title),
73 fCorrectAngles(kFALSE),
85 // title Title of object - not significant
87 fRingHistos.Add(new RingHistos(1, 'I'));
88 fRingHistos.Add(new RingHistos(2, 'I'));
89 fRingHistos.Add(new RingHistos(2, 'O'));
90 fRingHistos.Add(new RingHistos(3, 'I'));
91 fRingHistos.Add(new RingHistos(3, 'O'));
94 //____________________________________________________________________
95 AliFMDSharingFilter::AliFMDSharingFilter(const AliFMDSharingFilter& o)
99 fCorrectAngles(o.fCorrectAngles),
101 fIncludeSigma(o.fIncludeSigma),
103 fHighCuts(o.fHighCuts),
111 // o Object to copy from
113 TIter next(&o.fRingHistos);
115 while ((obj = next())) fRingHistos.Add(obj);
118 //____________________________________________________________________
119 AliFMDSharingFilter::~AliFMDSharingFilter()
124 fRingHistos.Delete();
127 //____________________________________________________________________
129 AliFMDSharingFilter::operator=(const AliFMDSharingFilter& o)
132 // Assignment operator
135 // o Object to assign from
140 TNamed::operator=(o);
143 fCorrectAngles = o.fCorrectAngles;
148 fHighCuts = o.fHighCuts;
149 fIncludeSigma = o.fIncludeSigma;
151 fRingHistos.Delete();
152 TIter next(&o.fRingHistos);
154 while ((obj = next())) fRingHistos.Add(obj);
159 //____________________________________________________________________
160 AliFMDSharingFilter::RingHistos*
161 AliFMDSharingFilter::GetRingHistos(UShort_t d, Char_t r) const
164 // Get the ring histogram container
171 // Ring histogram container
175 case 1: idx = 0; break;
176 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
177 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
179 if (idx < 0 || idx >= fRingHistos.GetEntries()) return 0;
181 return static_cast<RingHistos*>(fRingHistos.At(idx));
184 //____________________________________________________________________
186 AliFMDSharingFilter::Init()
189 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
191 // Get the high cut. The high cut is defined as the
192 // most-probably-value peak found from the energy distributions, minus
193 // 2 times the width of the corresponding Landau.
194 AliFMDCorrELossFit* fits = fcm.GetELossFit();
195 const TAxis& eAxis = fits->GetEtaAxis();
197 UShort_t nEta = eAxis.GetNbins();
198 fHighCuts->SetBins(nEta, eAxis.GetXmin(), eAxis.GetXmax(), 5, .5, 5.5);
199 fHighCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
200 fHighCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
201 fHighCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
202 fHighCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
203 fHighCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
206 for (UShort_t d = 1; d <= 3; d++) {
207 UShort_t nr = (d == 1 ? 1 : 2);
208 for (UShort_t q = 0; q < nr; q++) {
209 Char_t r = (q == 0 ? 'I' : 'O');
211 for (UShort_t e = 1; e <= nEta; e++) {
212 Double_t eta = eAxis.GetBinCenter(e);
213 Double_t cut = GetHighCut(d, r, eta, false);
214 if (cut <= 0) continue;
215 fHighCuts->SetBinContent(e, ybin, cut);
221 //____________________________________________________________________
223 AliFMDSharingFilter::Filter(const AliESDFMD& input,
228 // Filter the input AliESDFMD object
232 // lowFlux If this is a low-flux event
233 // output Output AliESDFMD object
236 // True on success, false otherwise
239 TIter next(&fRingHistos);
241 while ((o = static_cast<RingHistos*>(next())))
244 if (fOper) fOper->Reset(0);
246 Int_t nCandidate = 0;
252 for(UShort_t d = 1; d <= 3; d++) {
253 Int_t nRings = (d == 1 ? 1 : 2);
254 for (UShort_t q = 0; q < nRings; q++) {
255 Char_t r = (q == 0 ? 'I' : 'O');
256 UShort_t nsec = (q == 0 ? 20 : 40);
257 UShort_t nstr = (q == 0 ? 512 : 256);
258 RingHistos* histos = GetRingHistos(d, r);
260 for(UShort_t s = 0; s < nsec; s++) {
261 for (UShort_t t = 0; t < nstr; t++) status[t] = kCandidate;
262 #ifdef USE_OLDER_MERGING
263 Bool_t usedThis = kFALSE;
264 Bool_t usedPrev = kFALSE;
266 for(UShort_t t = 0; t < nstr; t++) {
267 output.SetMultiplicity(d,r,s,t,0.);
268 Float_t mult = SignalInStrip(input,d,r,s,t);
269 // Get the pseudo-rapidity
270 Double_t eta = input.Eta(d,r,s,t);
271 Double_t phi = input.Phi(d,r,s,t) * TMath::Pi() / 180.;
272 if (s == 0) output.SetEta(d,r,s,t,eta);
274 // Keep dead-channel information.
275 if(mult == AliESDFMD::kInvalidMult)
276 output.SetMultiplicity(d,r,s,t,AliESDFMD::kInvalidMult);
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);
285 // Fill the diagnostics histogram
286 histos->fBefore->Fill(mult);
288 // Get next and previous signal - if any
291 Status prevStatus = (t == 0 ? kNone : status[t-1]);
292 Status thisStatus = status[t];
293 Status nextStatus = (t == nstr-1 ? kNone : status[t+1]);
295 prevE = SignalInStrip(input,d,r,s,t-1);
296 if (prevE == AliESDFMD::kInvalidMult) prevE = 0;
299 nextE = SignalInStrip(input,d,r,s,t+1);
300 if (nextE == AliESDFMD::kInvalidMult) nextE = 0;
302 if (t != 0) histos->fNeighborsBefore->Fill(prevE, mult);
304 #ifdef USE_OLDER_MERGING
305 Double_t mergedEnergy = MultiplicityOfStrip(mult,eta,prevE,nextE,
308 status[t] = (usedPrev ? kMergedWithOther : kNone);
309 if (t != nstr - 1) status[t] = (usedThis ? kMergedWithOther : kNone);
311 Double_t mergedEnergy = MultiplicityOfStrip(mult, prevE, nextE,
317 if (t != 0) status[t-1] = prevStatus;
318 if (t != nstr-1) status[t+1] = nextStatus;
319 status[t] = thisStatus;
322 // If we're processing on non-angle corrected data, we
323 // should do the angle correction here
325 mergedEnergy = AngleCorrect(mergedEnergy, eta);
326 if (mergedEnergy > 0) histos->Incr();
329 histos->fNeighborsAfter->Fill(output.Multiplicity(d,r,s,t-1),
331 histos->fBeforeAfter->Fill(mult, mergedEnergy);
332 histos->fAfter->Fill(mergedEnergy);
333 histos->fSum->Fill(eta,phi,mergedEnergy);
335 output.SetMultiplicity(d,r,s,t,mergedEnergy);
337 for (UShort_t t = 0; t < nstr; t++) {
338 if (fOper) fOper->operator()(d, r, s, t) = status[t];
340 case kNone: nNone++; break;
341 case kCandidate: nCandidate++; break;
342 case kMergedWithOther: nMerged++; break;
343 case kMergedInto: nSummed++; break;
349 fSummed->Fill(kNone, nNone);
350 fSummed->Fill(kCandidate, nCandidate);
351 fSummed->Fill(kMergedWithOther, nMerged);
352 fSummed->Fill(kMergedInto, nSummed);
354 DBGL(1, Form("none=%9d, candidate=%9d, merged=%9d, summed=%9d",
355 nNone, nCandidate, nMerged, nSummed));
357 while ((o = static_cast<RingHistos*>(next())))
363 //_____________________________________________________________________
365 AliFMDSharingFilter::SignalInStrip(const AliESDFMD& input,
372 // Get the signal in a strip
384 Double_t mult = input.Multiplicity(d,r,s,t);
386 // - bad value (invalid or 0)
387 // - we want angle corrected and data is
388 // - we don't want angle corrected and data isn't
389 // just return read value
390 if (mult == AliESDFMD::kInvalidMult ||
392 (fCorrectAngles && input.IsAngleCorrected()) ||
393 (!fCorrectAngles && !input.IsAngleCorrected()))
396 // If we want angle corrected data, correct it,
397 // otherwise de-correct it
398 if (fCorrectAngles) mult = AngleCorrect(mult, input.Eta(d,r,s,t));
399 else mult = DeAngleCorrect(mult, input.Eta(d,r,s,t));
402 //_____________________________________________________________________
404 AliFMDSharingFilter::GetLowCut(UShort_t, Char_t, Double_t) const
407 // Get the low cut. Normally, the low cut is taken to be the lower
408 // value of the fit range used when generating the energy loss fits.
409 // However, if fLowCut is set (using SetLowCit) to a value greater
410 // than 0, then that value is used.
412 if (fLowCut > 0) return fLowCut;
413 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
414 AliFMDCorrELossFit* fits = fcm.GetELossFit();
415 return fits->GetLowCut();
418 //_____________________________________________________________________
420 AliFMDSharingFilter::GetHighCut(UShort_t d, Char_t r,
421 Double_t eta, Bool_t errors) const
424 // Get the high cut. The high cut is defined as the
425 // most-probably-value peak found from the energy distributions, minus
426 // 2 times the width of the corresponding Landau.
428 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
431 // Get the high cut. The high cut is defined as the
432 // most-probably-value peak found from the energy distributions, minus
433 // 2 times the width of the corresponding Landau.
434 AliFMDCorrELossFit* fits = fcm.GetELossFit();
436 return fits->GetLowerBound(d, r, eta, fNXi, errors, fIncludeSigma);
439 //_____________________________________________________________________
441 const char* status2String(AliFMDSharingFilter::Status s)
444 case AliFMDSharingFilter::kNone: return "none ";
445 case AliFMDSharingFilter::kCandidate: return "candidate";
446 case AliFMDSharingFilter::kMergedWithOther: return "merged ";
447 case AliFMDSharingFilter::kMergedInto: return "summed ";
453 //_____________________________________________________________________
455 AliFMDSharingFilter::MultiplicityOfStrip(Double_t thisE,
466 Status& nextStatus) const
468 Double_t lowCut = GetLowCut(d, r, eta);
470 DBG(3,Form("FMD%d%c[%2d,%3d]: this=%9f(%s), prev=%9f(%s), next=%9f(%s)",
472 thisE, status2String(thisStatus),
473 prevE, status2String(prevStatus),
474 nextE, status2String(nextStatus)));
476 // If below cut, then modify zero signal and make sure the next
477 // strip is considered a candidate.
478 if (thisE < lowCut || thisE > 20) {
480 DBGL(3,Form(" %9f<%9f || %9f>20, 0'ed", thisE, lowCut, thisE));
481 if (prevStatus == kCandidate) prevStatus = kNone;
484 // It this strip was merged with the previous strip, then
485 // make the next strip a candidate and zero the value in this strip.
486 if (thisStatus == kMergedWithOther) {
487 DBGL(3,Form(" Merged with other, 0'ed"));
491 // Get the upper cut on the sharing
492 Double_t highCut = GetHighCut(d, r, eta ,false);
498 // Only for low-flux events
500 // If this is smaller than the next, and the next is larger
501 // then the cut, mark both as candidates for sharing.
502 // They should be be merged on the next iteration
503 if (thisE < nextE && nextE > highCut) {
504 thisStatus = kCandidate;
505 nextStatus = kCandidate;
510 // Variable to sum signal in
511 Double_t totalE = thisE;
513 // If the previous signal was between the two cuts, and is still
514 // marked as a candidate , then merge it in here.
515 if (prevStatus == kCandidate && prevE > lowCut && prevE < highCut) {
517 prevStatus = kMergedWithOther;
518 DBG(3, Form(" Prev candidate %9f<%9f<%9f->%9f",
519 lowCut, prevE, highCut, totalE));
522 // If the next signal is between the two cuts, then merge it here
523 if (nextE > lowCut && nextE < highCut) {
525 nextStatus = kMergedWithOther;
526 DBG(3, Form(" Next %9f<%9f<%9f->%9f", lowCut, nextE, highCut,totalE));
529 // If the signal is bigger than the high-cut, then return the value
530 if (totalE > highCut) {
532 thisStatus = kMergedInto;
535 DBGL(3, Form(" %9f>%f9 (was %9f) -> %9f %s",
536 totalE, highCut, thisE, totalE,status2String(thisStatus)));
540 // This is below cut, so flag next as a candidate
541 DBG(3, Form(" %9f<=%9f, next candidate", totalE, highCut));
542 nextStatus = kCandidate;
545 // If the total signal is smaller than low cut then zero this and kill this
546 if (totalE < lowCut) {
547 DBGL(3, Form(" %9f<%9f (was %9f), zeroed", totalE, lowCut, thisE));
552 // If total signal not above high cut or lower than low cut,
553 // mark this as a candidate for merging into the next, and zero signal
554 DBGL(3, Form(" %9f<%9f<%9f (was %9f), zeroed, candidate",
555 lowCut, totalE, highCut, thisE));
556 thisStatus = kCandidate;
560 //_____________________________________________________________________
562 AliFMDSharingFilter::MultiplicityOfStrip(Double_t mult,
572 Bool_t& usedThis) const
575 // The actual algorithm
578 // mult The unfiltered signal in the strip
579 // eta Psuedo rapidity
580 // prevE Previous strip signal (or 0)
581 // nextE Next strip signal (or 0)
582 // lowFlux Whether this is a low flux event
587 // usedPrev Whether the previous strip was used in sharing or not
588 // usedThis Wether this strip was used in sharing or not.
591 // The filtered signal in the strip
594 // IF the multiplicity is very large, or below the cut, reject it, and
595 // flag it as candidate for sharing
596 Double_t lowCut = GetLowCut(d,r,eta);
597 if(mult > 12 || mult < lowCut) {
603 // If this was shared with the previous signal, return 0 and mark it as
604 // not a candiate for sharing
611 //analyse and perform sharing on one strip
614 Double_t highCut = GetHighCut(d, r, eta, false);
621 // If this signal is smaller than the next, and the next signal is smaller
622 // than then the high cut, and it's a low-flux event, then mark this and
623 // the next signal as candidates for sharing
625 // This is the test if the signal is the smaller of two possibly
635 Double_t totalE = mult;
637 // If the previous signal was larger than the low cut, and
638 // the previous was smaller than high cut, and the previous signal
639 // isn't marked as used, then add it's energy to this signal
640 if (prevE > lowCut &&
645 // If the next signal is larger than the low cut, and
646 // the next signal is smaller than the high cut, then add the next signal
647 // to this, and marked the next signal as used
648 if(nextE > lowCut && nextE < highCut ) {
653 // If we're processing on non-angle corrected data, we should do the
654 // angle correction here
655 // if (!fCorrectAngles)
656 // totalE = AngleCorrect(totalE, eta);
658 // Fill post processing histogram
659 // if(totalE > fLowCut)
660 // GetRingHistos(d,r)->fAfter->Fill(totalE);
663 Double_t mergedEnergy = 0;
666 // If we have a signal, then this is used (sharedPrev=true) and
667 // the signal is set to the result
668 mergedEnergy = totalE;
672 // If we do not have a signal (too low), then this is not shared,
673 // and the next strip is not shared either
680 //____________________________________________________________________
682 AliFMDSharingFilter::AngleCorrect(Double_t mult, Double_t eta) const
685 // Angle correct the signal
688 // mult Angle Un-corrected Signal
689 // eta Pseudo-rapidity
692 // Angle corrected signal
694 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
695 if (eta < 0) theta -= TMath::Pi();
696 return mult * TMath::Cos(theta);
698 //____________________________________________________________________
700 AliFMDSharingFilter::DeAngleCorrect(Double_t mult, Double_t eta) const
703 // Angle de-correct the signal
706 // mult Angle corrected Signal
707 // eta Pseudo-rapidity
710 // Angle un-corrected signal
712 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
713 if (eta < 0) theta -= TMath::Pi();
714 return mult / TMath::Cos(theta);
717 //____________________________________________________________________
719 AliFMDSharingFilter::ScaleHistograms(const TList* dir, Int_t nEvents)
722 // Scale the histograms to the total number of events
725 // dir Where the output is
726 // nEvents Number of events
728 if (nEvents <= 0) return;
729 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
732 TIter next(&fRingHistos);
734 THStack* sums = new THStack("sums", "Sum of ring signals");
735 while ((o = static_cast<RingHistos*>(next()))) {
736 o->ScaleHistograms(d, nEvents);
737 TH1D* sum = o->fSum->ProjectionX(o->GetName(), 1, o->fSum->GetNbinsY(),"e");
738 sum->Scale(1., "width");
739 sum->SetTitle(o->GetName());
740 sum->SetDirectory(0);
741 sum->SetYTitle("#sum #Delta/#Delta_{mip}");
747 //____________________________________________________________________
749 AliFMDSharingFilter::DefineOutput(TList* dir)
752 // Define the output histograms. These are put in a sub list of the
753 // passed list. The histograms are merged before the parent task calls
754 // AliAnalysisTaskSE::Terminate
757 // dir Directory to add to
759 TList* d = new TList;
760 d->SetName(GetName());
763 fSummed = new TH2I("operations", "Strip operations",
764 kMergedInto, kNone-.5, kMergedInto+.5,
765 51201, -.5, 51200.5);
766 fSummed->SetXTitle("Operation");
767 fSummed->SetYTitle("# of strips");
768 fSummed->SetZTitle("Events");
769 fSummed->GetXaxis()->SetBinLabel(kNone, "None");
770 fSummed->GetXaxis()->SetBinLabel(kCandidate, "Candidate");
771 fSummed->GetXaxis()->SetBinLabel(kMergedWithOther, "Merged w/other");
772 fSummed->GetXaxis()->SetBinLabel(kMergedInto, "Merged into");
773 fSummed->SetDirectory(0);
776 fHighCuts = new TH2D("highCuts", "High cuts used", 1,0,1, 1,0,1);
777 fHighCuts->SetXTitle("#eta");
778 fHighCuts->SetDirectory(0);
782 TIter next(&fRingHistos);
784 while ((o = static_cast<RingHistos*>(next()))) {
788 //____________________________________________________________________
790 AliFMDSharingFilter::Print(Option_t* /*option*/) const
798 char ind[gROOT->GetDirLevel()+1];
799 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
800 ind[gROOT->GetDirLevel()] = '\0';
801 std::cout << ind << ClassName() << ": " << GetName() << '\n'
803 << ind << " Debug: " << fDebug << "\n"
804 << ind << " Low cut: " << fLowCut << '\n'
805 << ind << " N xi factor: " << fNXi << '\n'
806 << ind << " Include sigma in cut: " << fIncludeSigma << '\n'
807 << ind << " Use corrected angles: " << fCorrectAngles
808 << std::noboolalpha << std::endl;
811 //====================================================================
812 AliFMDSharingFilter::RingHistos::RingHistos()
813 : AliForwardUtil::RingHistos(),
829 //____________________________________________________________________
830 AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
831 : AliForwardUtil::RingHistos(d,r),
848 fBefore = new TH1D("esdEloss", "Energy loss (reconstruction)",
850 fBefore->SetXTitle("#Delta E/#Delta E_{mip}");
851 fBefore->SetYTitle("P(#Delta E/#Delta E_{mip})");
852 fBefore->SetFillColor(Color());
853 fBefore->SetFillStyle(3001);
854 fBefore->SetDirectory(0);
856 fAfter = static_cast<TH1D*>(fBefore->Clone("anaEloss"));
857 fAfter->SetTitle("Energy loss in %s (sharing corrected)");
858 fAfter->SetFillColor(Color()+2);
859 fAfter->SetDirectory(0);
863 Int_t n = int((max-min) / (max / 300));
864 fBeforeAfter = new TH2D("beforeAfter", "Before and after correlation",
865 n, min, max, n, min, max);
866 fBeforeAfter->SetXTitle("#Delta E/#Delta E_{mip} before");
867 fBeforeAfter->SetYTitle("#Delta E/#Delta E_{mip} after");
868 fBeforeAfter->SetZTitle("Correlation");
869 fBeforeAfter->SetDirectory(0);
871 fNeighborsBefore = static_cast<TH2D*>(fBeforeAfter->Clone("neighborsBefore"));
872 fNeighborsBefore->SetTitle("Correlation of neighbors befire");
873 fNeighborsBefore->SetXTitle("#Delta E_{i}/#Delta E_{mip}");
874 fNeighborsBefore->SetYTitle("#Delta E_{i+1}/#Delta E_{mip}");
875 fNeighborsBefore->SetDirectory(0);
878 static_cast<TH2D*>(fNeighborsBefore->Clone("neighborsAfter"));
879 fNeighborsAfter->SetTitle("Correlation of neighbors after");
880 fNeighborsAfter->SetDirectory(0);
882 fSum = new TH2D("summed", "Summed signal", 200, -4, 6,
883 (fRing == 'I' || fRing == 'i' ? 20 : 40), 0, 2*TMath::Pi());
884 fSum->SetDirectory(0);
886 fSum->SetMarkerColor(Color());
887 // fSum->SetFillColor(Color());
888 fSum->SetXTitle("#eta");
889 fSum->SetYTitle("#varphi [radians]");
890 fSum->SetZTitle("#sum #Delta/#Delta_{mip}(#eta,#varphi) ");
892 fHits = new TH1D("hits", "Number of hits", 200, 0, 200000);
893 fHits->SetDirectory(0);
894 fHits->SetXTitle("# of hits");
895 fHits->SetFillColor(kGreen+1);
897 //____________________________________________________________________
898 AliFMDSharingFilter::RingHistos::RingHistos(const RingHistos& o)
899 : AliForwardUtil::RingHistos(o),
902 fBeforeAfter(o.fBeforeAfter),
903 fNeighborsBefore(o.fNeighborsBefore),
904 fNeighborsAfter(o.fNeighborsAfter),
913 // o Object to copy from
917 //____________________________________________________________________
918 AliFMDSharingFilter::RingHistos&
919 AliFMDSharingFilter::RingHistos::operator=(const RingHistos& o)
922 // Assignment operator
925 // o Object to assign from
930 AliForwardUtil::RingHistos::operator=(o);
934 if (fBefore) delete fBefore;
935 if (fAfter) delete fAfter;
936 if (fHits) delete fHits;
938 fBefore = static_cast<TH1D*>(o.fBefore->Clone());
939 fAfter = static_cast<TH1D*>(o.fAfter->Clone());
940 fBeforeAfter = static_cast<TH2D*>(o.fBeforeAfter->Clone());
941 fNeighborsBefore = static_cast<TH2D*>(o.fNeighborsBefore->Clone());
942 fNeighborsAfter = static_cast<TH2D*>(o.fNeighborsAfter->Clone());
943 fHits = static_cast<TH1D*>(o.fHits->Clone());
944 fSum = static_cast<TH2D*>(o.fSum->Clone());
948 //____________________________________________________________________
949 AliFMDSharingFilter::RingHistos::~RingHistos()
955 //____________________________________________________________________
957 AliFMDSharingFilter::RingHistos::Finish()
966 //____________________________________________________________________
968 AliFMDSharingFilter::RingHistos::ScaleHistograms(const TList* dir,
972 // Scale the histograms to the total number of events
975 // nEvents Number of events
976 // dir Where the output is
978 TList* l = GetOutputList(dir);
981 TH1D* before = static_cast<TH1D*>(l->FindObject("esdELoss"));
982 TH1D* after = static_cast<TH1D*>(l->FindObject("anaELoss"));
983 TH2D* summed = static_cast<TH2D*>(l->FindObject("summed"));
984 if (before) before->Scale(1./nEvents);
985 if (after) after->Scale(1./nEvents);
986 if (summed) summed->Scale(1./nEvents);
990 //____________________________________________________________________
992 AliFMDSharingFilter::RingHistos::Output(TList* dir)
998 // dir where to store
1000 TList* d = DefineOutputList(dir);
1004 d->Add(fBeforeAfter);
1005 d->Add(fNeighborsBefore);
1006 d->Add(fNeighborsAfter);
1013 //____________________________________________________________________