3 // Class to do the sharing correction. That is, a filter that merges
4 // adjacent strip signals presumably originating from a single particle
5 // that impinges on the detector in such a way that it deposite energy
6 // into two or more strips.
9 // - AliESDFMD object - from reconstruction
12 // - AliESDFMD object - copy of input, but with signals merged
15 // - AliFMDCorrELossFit
18 // - For each ring (FMD1i, FMD2i, FMD2o, FMD3i, FMD3o) the distribution of
19 // signals before and after the filter.
20 // - For each ring (see above), an array of distributions of number of
21 // hit strips for each vertex bin (if enabled - see Init method)
25 #include "AliFMDSharingFilter.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),
64 fZeroSharedHitsBelowThreshold(false),
67 fUseSimpleMerging(false)
70 // Default Constructor - do not use
74 //____________________________________________________________________
75 AliFMDSharingFilter::AliFMDSharingFilter(const char* title)
76 : TNamed("fmdSharingFilter", title),
78 fCorrectAngles(kFALSE),
86 fZeroSharedHitsBelowThreshold(false),
89 fUseSimpleMerging(false)
95 // title Title of object - not significant
97 fRingHistos.Add(new RingHistos(1, 'I'));
98 fRingHistos.Add(new RingHistos(2, 'I'));
99 fRingHistos.Add(new RingHistos(2, 'O'));
100 fRingHistos.Add(new RingHistos(3, 'I'));
101 fRingHistos.Add(new RingHistos(3, 'O'));
104 fHCuts.SetIncludeSigma(1);
105 fLCuts.SetMultCuts(.15);
108 //____________________________________________________________________
109 AliFMDSharingFilter::AliFMDSharingFilter(const AliFMDSharingFilter& o)
112 fCorrectAngles(o.fCorrectAngles),
114 fIncludeSigma(o.fIncludeSigma),
116 fHighCuts(o.fHighCuts),
117 fLowCuts(o.fLowCuts),
120 fZeroSharedHitsBelowThreshold(o.fZeroSharedHitsBelowThreshold),
123 fUseSimpleMerging(o.fUseSimpleMerging)
129 // o Object to copy from
131 TIter next(&o.fRingHistos);
133 while ((obj = next())) fRingHistos.Add(obj);
136 //____________________________________________________________________
137 AliFMDSharingFilter::~AliFMDSharingFilter()
142 fRingHistos.Delete();
145 //____________________________________________________________________
147 AliFMDSharingFilter::operator=(const AliFMDSharingFilter& o)
150 // Assignment operator
153 // o Object to assign from
158 TNamed::operator=(o);
160 fCorrectAngles = o.fCorrectAngles;
165 fHighCuts = o.fHighCuts;
166 fLowCuts = o.fLowCuts;
167 fIncludeSigma = o.fIncludeSigma;
168 fZeroSharedHitsBelowThreshold = o.fZeroSharedHitsBelowThreshold;
171 fUseSimpleMerging = o.fUseSimpleMerging;
173 fRingHistos.Delete();
174 TIter next(&o.fRingHistos);
176 while ((obj = next())) fRingHistos.Add(obj);
181 //____________________________________________________________________
182 AliFMDSharingFilter::RingHistos*
183 AliFMDSharingFilter::GetRingHistos(UShort_t d, Char_t r) const
186 // Get the ring histogram container
193 // Ring histogram container
197 case 1: idx = 0; break;
198 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
199 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
201 if (idx < 0 || idx >= fRingHistos.GetEntries()) return 0;
203 return static_cast<RingHistos*>(fRingHistos.At(idx));
206 //____________________________________________________________________
208 AliFMDSharingFilter::Init()
211 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
213 // Get the high cut. The high cut is defined as the
214 // most-probably-value peak found from the energy distributions, minus
215 // 2 times the width of the corresponding Landau.
216 AliFMDCorrELossFit* fits = fcm.GetELossFit();
217 const TAxis& eAxis = fits->GetEtaAxis();
219 UShort_t nEta = eAxis.GetNbins();
220 fHighCuts->SetBins(nEta, eAxis.GetXmin(), eAxis.GetXmax(), 5, .5, 5.5);
221 fHighCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
222 fHighCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
223 fHighCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
224 fHighCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
225 fHighCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
227 fLowCuts->SetBins(nEta, eAxis.GetXmin(), eAxis.GetXmax(), 5, .5, 5.5);
228 fLowCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
229 fLowCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
230 fLowCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
231 fLowCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
232 fLowCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
235 for (UShort_t d = 1; d <= 3; d++) {
236 UShort_t nr = (d == 1 ? 1 : 2);
237 for (UShort_t q = 0; q < nr; q++) {
238 Char_t r = (q == 0 ? 'I' : 'O');
240 for (UShort_t e = 1; e <= nEta; e++) {
241 Double_t eta = eAxis.GetBinCenter(e);
242 Double_t hcut = GetHighCut(d, r, eta, false);
243 Double_t lcut = GetLowCut(d, r, eta);
244 if (hcut > 0) fHighCuts->SetBinContent(e, ybin, hcut);
245 if (lcut > 0) fLowCuts ->SetBinContent(e, ybin, lcut);
251 //____________________________________________________________________
253 AliFMDSharingFilter::Filter(const AliESDFMD& input,
258 // Filter the input AliESDFMD object
262 // lowFlux If this is a low-flux event
263 // output Output AliESDFMD object
266 // True on success, false otherwise
269 TIter next(&fRingHistos);
271 while ((o = static_cast<RingHistos*>(next())))
274 if (fOper) fOper->Reset(0);
276 Int_t nCandidate = 0;
282 for(UShort_t d = 1; d <= 3; d++) {
283 Int_t nRings = (d == 1 ? 1 : 2);
284 for (UShort_t q = 0; q < nRings; q++) {
285 Char_t r = (q == 0 ? 'I' : 'O');
286 UShort_t nsec = (q == 0 ? 20 : 40);
287 UShort_t nstr = (q == 0 ? 512 : 256);
288 RingHistos* histos = GetRingHistos(d, r);
290 for(UShort_t s = 0; s < nsec; s++) {
292 for (UShort_t t = 0; t < nstr; t++) status[t] = kCandidate;
294 #ifdef USE_OLDER_MERGING
295 Bool_t usedThis = kFALSE;
296 Bool_t usedPrev = kFALSE;
299 Bool_t used = kFALSE;
300 for(UShort_t t = 0; t < nstr; t++) {
301 output.SetMultiplicity(d,r,s,t,0.);
302 Float_t mult = SignalInStrip(input,d,r,s,t);
304 Float_t multNext = 0;
305 if(t<nstr-1) multNext = SignalInStrip(input,d,r,s,t+1);
306 if(multNext == AliESDFMD::kInvalidMult) multNext = 0;
308 // Get the pseudo-rapidity
309 Double_t eta = input.Eta(d,r,s,t);
310 Double_t phi = input.Phi(d,r,s,t) * TMath::Pi() / 180.;
311 if (s == 0) output.SetEta(d,r,s,t,eta);
313 // Keep dead-channel information.
314 if(mult == AliESDFMD::kInvalidMult)
315 output.SetMultiplicity(d,r,s,t,AliESDFMD::kInvalidMult);
317 // If no signal or dead strip, go on.
318 if (mult == AliESDFMD::kInvalidMult || mult == 0) {
319 if (mult == 0) histos->fSum->Fill(eta,phi,mult);
324 // Fill the diagnostics histogram
325 histos->fBefore->Fill(mult);
327 Double_t mergedEnergy = 0;
329 if(fUseSimpleMerging) {
331 if(mult > GetLowCut(d, r, eta)) etot = mult;
332 if(used) {used = kFALSE; continue; }
334 if(mult > GetLowCut(d, r, eta) &&
335 multNext > GetLowCut(d, r, eta) &&
336 (mult < GetHighCut(d, r, eta ,false) ||
337 multNext < GetHighCut(d, r, eta ,false))) {
338 etot = mult + multNext;
345 // Get next and previous signal - if any
348 Status prevStatus = (t == 0 ? kNone : status[t-1]);
349 Status thisStatus = status[t];
350 Status nextStatus = (t == nstr-1 ? kNone : status[t+1]);
352 prevE = SignalInStrip(input,d,r,s,t-1);
353 if (prevE == AliESDFMD::kInvalidMult) prevE = 0;
356 nextE = SignalInStrip(input,d,r,s,t+1);
357 if (nextE == AliESDFMD::kInvalidMult) nextE = 0;
359 if (t != 0) histos->fNeighborsBefore->Fill(prevE, mult);
361 #ifdef USE_OLDER_MERGING
362 /*Double_t*/ mergedEnergy = MultiplicityOfStrip(mult,eta,prevE,nextE,
365 status[t] = (usedPrev ? kMergedWithOther : kNone);
366 if (t != nstr - 1) status[t] = (usedThis ? kMergedWithOther : kNone);
368 /*Double_t*/ mergedEnergy = MultiplicityOfStrip(mult, prevE, nextE,
374 if (t != 0) status[t-1] = prevStatus;
375 if (t != nstr-1) status[t+1] = nextStatus;
376 status[t] = thisStatus;
379 // If we're processing on non-angle corrected data, we
380 // should do the angle correction here
383 mergedEnergy = AngleCorrect(mergedEnergy, eta);
384 if (mergedEnergy > 0) histos->Incr();
387 histos->fNeighborsAfter->Fill(output.Multiplicity(d,r,s,t-1),
389 histos->fBeforeAfter->Fill(mult, mergedEnergy);
390 histos->fAfter->Fill(mergedEnergy);
391 histos->fSum->Fill(eta,phi,mergedEnergy);
393 output.SetMultiplicity(d,r,s,t,mergedEnergy);
395 for (UShort_t t = 0; t < nstr; t++) {
396 if (fOper) fOper->operator()(d, r, s, t) = status[t];
398 case kNone: nNone++; break;
399 case kCandidate: nCandidate++; break;
400 case kMergedWithOther: nMerged++; break;
401 case kMergedInto: nSummed++; break;
407 fSummed->Fill(kNone, nNone);
408 fSummed->Fill(kCandidate, nCandidate);
409 fSummed->Fill(kMergedWithOther, nMerged);
410 fSummed->Fill(kMergedInto, nSummed);
412 DBGL(1, Form("none=%9d, candidate=%9d, merged=%9d, summed=%9d",
413 nNone, nCandidate, nMerged, nSummed));
415 while ((o = static_cast<RingHistos*>(next())))
421 //_____________________________________________________________________
423 AliFMDSharingFilter::SignalInStrip(const AliESDFMD& input,
430 // Get the signal in a strip
442 Double_t mult = input.Multiplicity(d,r,s,t);
444 // - bad value (invalid or 0)
445 // - we want angle corrected and data is
446 // - we don't want angle corrected and data isn't
447 // just return read value
448 if (mult == AliESDFMD::kInvalidMult ||
450 (fCorrectAngles && input.IsAngleCorrected()) ||
451 (!fCorrectAngles && !input.IsAngleCorrected()))
454 // If we want angle corrected data, correct it,
455 // otherwise de-correct it
456 if (fCorrectAngles) mult = AngleCorrect(mult, input.Eta(d,r,s,t));
457 else mult = DeAngleCorrect(mult, input.Eta(d,r,s,t));
460 //_____________________________________________________________________
462 AliFMDSharingFilter::GetLowCut(UShort_t d, Char_t r, Double_t eta) const
465 // Get the low cut. Normally, the low cut is taken to be the lower
466 // value of the fit range used when generating the energy loss fits.
467 // However, if fLowCut is set (using SetLowCit) to a value greater
468 // than 0, then that value is used.
470 return fLCuts.GetMultCut(d,r,eta,false);
472 if (!fCutAtFractionOfMPV && fLowCut > 0) return fLowCut;
474 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
475 AliFMDCorrELossFit* fits = fcm.GetELossFit();
477 if (fCutAtFractionOfMPV) {
478 AliFMDCorrELossFit::ELossFit* func = fits->GetFit(d,r,eta);
479 return fFractionOfMPV*func->GetDelta() ;
481 return fits->GetLowCut();
485 //_____________________________________________________________________
487 AliFMDSharingFilter::GetHighCut(UShort_t d, Char_t r,
488 Double_t eta, Bool_t errors) const
491 // Get the high cut. The high cut is defined as the
492 // most-probably-value peak found from the energy distributions, minus
493 // 2 times the width of the corresponding Landau.
495 return fHCuts.GetMultCut(d,r,eta,errors);
497 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
500 // Get the high cut. The high cut is defined as the
501 // most-probably-value peak found from the energy distributions, minus
502 // 2 times the width of the corresponding Landau.
503 AliFMDCorrELossFit* fits = fcm.GetELossFit();
505 return fits->GetLowerBound(d, r, eta, fNXi, errors, fIncludeSigma);
509 //_____________________________________________________________________
511 const char* status2String(AliFMDSharingFilter::Status s)
514 case AliFMDSharingFilter::kNone: return "none ";
515 case AliFMDSharingFilter::kCandidate: return "candidate";
516 case AliFMDSharingFilter::kMergedWithOther: return "merged ";
517 case AliFMDSharingFilter::kMergedInto: return "summed ";
523 //_____________________________________________________________________
525 AliFMDSharingFilter::MultiplicityOfStrip(Double_t thisE,
536 Status& nextStatus) const
538 Double_t lowCut = GetLowCut(d, r, eta);
540 DBG(3,Form("FMD%d%c[%2d,%3d]: this=%9f(%s), prev=%9f(%s), next=%9f(%s)",
542 thisE, status2String(thisStatus),
543 prevE, status2String(prevStatus),
544 nextE, status2String(nextStatus)));
546 // If below cut, then modify zero signal and make sure the next
547 // strip is considered a candidate.
548 if (thisE < lowCut || thisE > 20) {
550 DBGL(3,Form(" %9f<%9f || %9f>20, 0'ed", thisE, lowCut, thisE));
551 if (prevStatus == kCandidate) prevStatus = kNone;
554 // It this strip was merged with the previous strip, then
555 // make the next strip a candidate and zero the value in this strip.
556 if (thisStatus == kMergedWithOther) {
557 DBGL(3,Form(" Merged with other, 0'ed"));
561 // Get the upper cut on the sharing
562 Double_t highCut = GetHighCut(d, r, eta ,false);
568 // Only for low-flux events
570 // If this is smaller than the next, and the next is larger
571 // then the cut, mark both as candidates for sharing.
572 // They should be be merged on the next iteration
573 if (thisE < nextE && nextE > highCut) {
574 thisStatus = kCandidate;
575 nextStatus = kCandidate;
580 // Variable to sum signal in
581 Double_t totalE = thisE;
583 // If the previous signal was between the two cuts, and is still
584 // marked as a candidate , then merge it in here.
585 if (prevStatus == kCandidate && prevE > lowCut && prevE < highCut) {
587 prevStatus = kMergedWithOther;
588 DBG(3, Form(" Prev candidate %9f<%9f<%9f->%9f",
589 lowCut, prevE, highCut, totalE));
592 // If the next signal is between the two cuts, then merge it here
593 if (nextE > lowCut && nextE < highCut) {
595 nextStatus = kMergedWithOther;
596 DBG(3, Form(" Next %9f<%9f<%9f->%9f", lowCut, nextE, highCut,totalE));
599 // If the signal is bigger than the high-cut, then return the value
600 if (totalE > highCut) {
602 thisStatus = kMergedInto;
605 DBGL(3, Form(" %9f>%f9 (was %9f) -> %9f %s",
606 totalE, highCut, thisE, totalE,status2String(thisStatus)));
610 // This is below cut, so flag next as a candidate
611 DBG(3, Form(" %9f<=%9f, next candidate", totalE, highCut));
612 nextStatus = kCandidate;
615 // If the total signal is smaller than low cut then zero this and kill this
616 if (totalE < lowCut) {
617 DBGL(3, Form(" %9f<%9f (was %9f), zeroed", totalE, lowCut, thisE));
622 // If total signal not above high cut or lower than low cut,
623 // mark this as a candidate for merging into the next, and zero signal
624 DBGL(3, Form(" %9f<%9f<%9f (was %9f), zeroed, candidate",
625 lowCut, totalE, highCut, thisE));
626 thisStatus = kCandidate;
627 return (fZeroSharedHitsBelowThreshold ? 0 : totalE);
630 //_____________________________________________________________________
632 AliFMDSharingFilter::MultiplicityOfStrip(Double_t mult,
642 Bool_t& usedThis) const
645 // The actual algorithm
648 // mult The unfiltered signal in the strip
649 // eta Psuedo rapidity
650 // prevE Previous strip signal (or 0)
651 // nextE Next strip signal (or 0)
652 // lowFlux Whether this is a low flux event
657 // usedPrev Whether the previous strip was used in sharing or not
658 // usedThis Wether this strip was used in sharing or not.
661 // The filtered signal in the strip
664 // IF the multiplicity is very large, or below the cut, reject it, and
665 // flag it as candidate for sharing
666 Double_t lowCut = GetLowCut(d,r,eta);
667 if(mult > 12 || mult < lowCut) {
673 // If this was shared with the previous signal, return 0 and mark it as
674 // not a candiate for sharing
681 //analyse and perform sharing on one strip
684 Double_t highCut = GetHighCut(d, r, eta, false);
691 // If this signal is smaller than the next, and the next signal is smaller
692 // than then the high cut, and it's a low-flux event, then mark this and
693 // the next signal as candidates for sharing
695 // This is the test if the signal is the smaller of two possibly
705 Double_t totalE = mult;
707 // If the previous signal was larger than the low cut, and
708 // the previous was smaller than high cut, and the previous signal
709 // isn't marked as used, then add it's energy to this signal
710 if (prevE > lowCut &&
715 // If the next signal is larger than the low cut, and
716 // the next signal is smaller than the high cut, then add the next signal
717 // to this, and marked the next signal as used
718 if(nextE > lowCut && nextE < highCut ) {
723 // If we're processing on non-angle corrected data, we should do the
724 // angle correction here
725 // if (!fCorrectAngles)
726 // totalE = AngleCorrect(totalE, eta);
728 // Fill post processing histogram
729 // if(totalE > fLowCut)
730 // GetRingHistos(d,r)->fAfter->Fill(totalE);
733 Double_t mergedEnergy = 0;
736 // If we have a signal, then this is used (sharedPrev=true) and
737 // the signal is set to the result
738 mergedEnergy = totalE;
742 // If we do not have a signal (too low), then this is not shared,
743 // and the next strip is not shared either
750 //____________________________________________________________________
752 AliFMDSharingFilter::AngleCorrect(Double_t mult, Double_t eta) const
755 // Angle correct the signal
758 // mult Angle Un-corrected Signal
759 // eta Pseudo-rapidity
762 // Angle corrected signal
764 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
765 if (eta < 0) theta -= TMath::Pi();
766 return mult * TMath::Cos(theta);
768 //____________________________________________________________________
770 AliFMDSharingFilter::DeAngleCorrect(Double_t mult, Double_t eta) const
773 // Angle de-correct the signal
776 // mult Angle corrected Signal
777 // eta Pseudo-rapidity
780 // Angle un-corrected signal
782 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
783 if (eta < 0) theta -= TMath::Pi();
784 return mult / TMath::Cos(theta);
787 //____________________________________________________________________
789 AliFMDSharingFilter::ScaleHistograms(const TList* dir, Int_t nEvents)
792 // Scale the histograms to the total number of events
795 // dir Where the output is
796 // nEvents Number of events
798 if (nEvents <= 0) return;
799 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
802 TIter next(&fRingHistos);
804 THStack* sums = new THStack("sums", "Sum of ring signals");
805 while ((o = static_cast<RingHistos*>(next()))) {
806 o->ScaleHistograms(d, nEvents);
807 TH1D* sum = o->fSum->ProjectionX(o->GetName(), 1, o->fSum->GetNbinsY(),"e");
808 sum->Scale(1., "width");
809 sum->SetTitle(o->GetName());
810 sum->SetDirectory(0);
811 sum->SetYTitle("#sum #Delta/#Delta_{mip}");
817 //____________________________________________________________________
819 AliFMDSharingFilter::DefineOutput(TList* dir)
822 // Define the output histograms. These are put in a sub list of the
823 // passed list. The histograms are merged before the parent task calls
824 // AliAnalysisTaskSE::Terminate
827 // dir Directory to add to
829 TList* d = new TList;
830 d->SetName(GetName());
833 fSummed = new TH2I("operations", "Strip operations",
834 kMergedInto, kNone-.5, kMergedInto+.5,
835 51201, -.5, 51200.5);
836 fSummed->SetXTitle("Operation");
837 fSummed->SetYTitle("# of strips");
838 fSummed->SetZTitle("Events");
839 fSummed->GetXaxis()->SetBinLabel(kNone, "None");
840 fSummed->GetXaxis()->SetBinLabel(kCandidate, "Candidate");
841 fSummed->GetXaxis()->SetBinLabel(kMergedWithOther, "Merged w/other");
842 fSummed->GetXaxis()->SetBinLabel(kMergedInto, "Merged into");
843 fSummed->SetDirectory(0);
846 fHighCuts = new TH2D("highCuts", "High cuts used", 1,0,1, 1,0,1);
847 fHighCuts->SetXTitle("#eta");
848 fHighCuts->SetDirectory(0);
851 fLowCuts = new TH2D("lowCuts", "Low cuts used", 1,0,1, 1,0,1);
852 fLowCuts->SetXTitle("#eta");
853 fLowCuts->SetDirectory(0);
856 // TParameter<double>* lowCut = new TParameter<double>("lowCut", fLowCut);
857 // TParameter<double>* nXi = new TParameter<double>("nXi", fNXi);
858 // TNamed* sigma = new TNamed("sigma", fIncludeSigma ?
859 // "included" : "excluded");
860 // sigma->SetUniqueID(fIncludeSigma);
861 TNamed* angle = new TNamed("angle", fCorrectAngles ?
862 "corrected" : "uncorrected");
863 angle->SetUniqueID(fCorrectAngles);
864 TNamed* low = new TNamed("lowSignal", fZeroSharedHitsBelowThreshold ?
866 low->SetUniqueID(fZeroSharedHitsBelowThreshold);
867 TNamed* simple = new TNamed("simple", fUseSimpleMerging ? "yes" : "no");
868 simple->SetUniqueID(fUseSimpleMerging);
876 fLCuts.Output(d,"lCuts");
877 fHCuts.Output(d,"hCuts");
879 TIter next(&fRingHistos);
881 while ((o = static_cast<RingHistos*>(next()))) {
885 //____________________________________________________________________
887 AliFMDSharingFilter::Print(Option_t* /*option*/) const
895 char ind[gROOT->GetDirLevel()+1];
896 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
897 ind[gROOT->GetDirLevel()] = '\0';
898 std::cout << ind << ClassName() << ": " << GetName() << '\n'
900 << ind << " Debug: " << fDebug << "\n"
901 << ind << " Use corrected angles: " << fCorrectAngles << '\n'
902 << ind << " Zero below threshold: "
903 << fZeroSharedHitsBelowThreshold << '\n'
904 << ind << " Use simple sharing: " << fUseSimpleMerging << '\n'
905 << std::noboolalpha << std::endl;
906 std::cout << ind << " Low cuts: " << std::endl;
908 std::cout << ind << " High cuts: " << std::endl;
912 //====================================================================
913 AliFMDSharingFilter::RingHistos::RingHistos()
914 : AliForwardUtil::RingHistos(),
930 //____________________________________________________________________
931 AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
932 : AliForwardUtil::RingHistos(d,r),
949 fBefore = new TH1D("esdEloss", "Energy loss (reconstruction)",
951 fBefore->SetXTitle("#Delta E/#Delta E_{mip}");
952 fBefore->SetYTitle("P(#Delta E/#Delta E_{mip})");
953 fBefore->SetFillColor(Color());
954 fBefore->SetFillStyle(3001);
955 fBefore->SetLineColor(kBlack);
956 fBefore->SetLineStyle(2);
957 fBefore->SetDirectory(0);
959 fAfter = static_cast<TH1D*>(fBefore->Clone("anaEloss"));
960 fAfter->SetTitle("Energy loss in %s (sharing corrected)");
961 fAfter->SetFillColor(Color()+2);
962 fAfter->SetLineStyle(1);
963 fAfter->SetDirectory(0);
967 Int_t n = int((max-min) / (max / 300));
968 fBeforeAfter = new TH2D("beforeAfter", "Before and after correlation",
969 n, min, max, n, min, max);
970 fBeforeAfter->SetXTitle("#Delta E/#Delta E_{mip} before");
971 fBeforeAfter->SetYTitle("#Delta E/#Delta E_{mip} after");
972 fBeforeAfter->SetZTitle("Correlation");
973 fBeforeAfter->SetDirectory(0);
975 fNeighborsBefore = static_cast<TH2D*>(fBeforeAfter->Clone("neighborsBefore"));
976 fNeighborsBefore->SetTitle("Correlation of neighbors before");
977 fNeighborsBefore->SetXTitle("#Delta E_{i}/#Delta E_{mip}");
978 fNeighborsBefore->SetYTitle("#Delta E_{i+1}/#Delta E_{mip}");
979 fNeighborsBefore->SetDirectory(0);
982 static_cast<TH2D*>(fNeighborsBefore->Clone("neighborsAfter"));
983 fNeighborsAfter->SetTitle("Correlation of neighbors after");
984 fNeighborsAfter->SetDirectory(0);
986 fSum = new TH2D("summed", "Summed signal", 200, -4, 6,
987 (fRing == 'I' || fRing == 'i' ? 20 : 40), 0, 2*TMath::Pi());
988 fSum->SetDirectory(0);
990 fSum->SetMarkerColor(Color());
991 // fSum->SetFillColor(Color());
992 fSum->SetXTitle("#eta");
993 fSum->SetYTitle("#varphi [radians]");
994 fSum->SetZTitle("#sum #Delta/#Delta_{mip}(#eta,#varphi) ");
996 fHits = new TH1D("hits", "Number of hits", 200, 0, 200000);
997 fHits->SetDirectory(0);
998 fHits->SetXTitle("# of hits");
999 fHits->SetFillColor(kGreen+1);
1001 //____________________________________________________________________
1002 AliFMDSharingFilter::RingHistos::RingHistos(const RingHistos& o)
1003 : AliForwardUtil::RingHistos(o),
1006 fBeforeAfter(o.fBeforeAfter),
1007 fNeighborsBefore(o.fNeighborsBefore),
1008 fNeighborsAfter(o.fNeighborsAfter),
1017 // o Object to copy from
1021 //____________________________________________________________________
1022 AliFMDSharingFilter::RingHistos&
1023 AliFMDSharingFilter::RingHistos::operator=(const RingHistos& o)
1026 // Assignment operator
1029 // o Object to assign from
1032 // Reference to this
1034 AliForwardUtil::RingHistos::operator=(o);
1038 if (fBefore) delete fBefore;
1039 if (fAfter) delete fAfter;
1040 if (fHits) delete fHits;
1042 fBefore = static_cast<TH1D*>(o.fBefore->Clone());
1043 fAfter = static_cast<TH1D*>(o.fAfter->Clone());
1044 fBeforeAfter = static_cast<TH2D*>(o.fBeforeAfter->Clone());
1045 fNeighborsBefore = static_cast<TH2D*>(o.fNeighborsBefore->Clone());
1046 fNeighborsAfter = static_cast<TH2D*>(o.fNeighborsAfter->Clone());
1047 fHits = static_cast<TH1D*>(o.fHits->Clone());
1048 fSum = static_cast<TH2D*>(o.fSum->Clone());
1052 //____________________________________________________________________
1053 AliFMDSharingFilter::RingHistos::~RingHistos()
1059 //____________________________________________________________________
1061 AliFMDSharingFilter::RingHistos::Finish()
1067 fHits->Fill(fNHits);
1070 //____________________________________________________________________
1072 AliFMDSharingFilter::RingHistos::ScaleHistograms(const TList* dir,
1076 // Scale the histograms to the total number of events
1079 // nEvents Number of events
1080 // dir Where the output is
1082 TList* l = GetOutputList(dir);
1086 TH1D* before = static_cast<TH1D*>(l->FindObject("esdEloss"));
1087 TH1D* after = static_cast<TH1D*>(l->FindObject("anaEloss"));
1088 if (before) before->Scale(1./nEvents);
1089 if (after) after->Scale(1./nEvents);
1092 TH2D* summed = static_cast<TH2D*>(l->FindObject("summed"));
1093 if (summed) summed->Scale(1./nEvents);
1097 //____________________________________________________________________
1099 AliFMDSharingFilter::RingHistos::Output(TList* dir)
1105 // dir where to store
1107 TList* d = DefineOutputList(dir);
1111 d->Add(fBeforeAfter);
1112 d->Add(fNeighborsBefore);
1113 d->Add(fNeighborsAfter);
1120 //____________________________________________________________________