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),
62 fZeroSharedHitsBelowThreshold(false),
65 fUseSimpleMerging(false),
66 fThreeStripSharing(true)
69 // Default Constructor - do not use
73 //____________________________________________________________________
74 AliFMDSharingFilter::AliFMDSharingFilter(const char* title)
75 : TNamed("fmdSharingFilter", title),
77 fCorrectAngles(kFALSE),
83 fZeroSharedHitsBelowThreshold(false),
86 fUseSimpleMerging(false),
87 fThreeStripSharing(true)
93 // title Title of object - not significant
95 fRingHistos.SetName(GetName());
96 fRingHistos.SetOwner();
98 fRingHistos.Add(new RingHistos(1, 'I'));
99 fRingHistos.Add(new RingHistos(2, 'I'));
100 fRingHistos.Add(new RingHistos(2, 'O'));
101 fRingHistos.Add(new RingHistos(3, 'I'));
102 fRingHistos.Add(new RingHistos(3, 'O'));
105 fHCuts.SetIncludeSigma(1);
106 fLCuts.SetMultCuts(.15);
109 //____________________________________________________________________
110 AliFMDSharingFilter::AliFMDSharingFilter(const AliFMDSharingFilter& o)
113 fCorrectAngles(o.fCorrectAngles),
115 fHighCuts(o.fHighCuts),
116 fLowCuts(o.fLowCuts),
119 fZeroSharedHitsBelowThreshold(o.fZeroSharedHitsBelowThreshold),
122 fUseSimpleMerging(o.fUseSimpleMerging),
123 fThreeStripSharing(o.fThreeStripSharing)
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 if (&o == this) return *this;
159 TNamed::operator=(o);
161 fCorrectAngles = o.fCorrectAngles;
165 fHighCuts = o.fHighCuts;
166 fLowCuts = o.fLowCuts;
167 fZeroSharedHitsBelowThreshold = o.fZeroSharedHitsBelowThreshold;
170 fUseSimpleMerging = o.fUseSimpleMerging;
171 fThreeStripSharing = o.fThreeStripSharing;
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 Double_t eTotal = -1;
301 Int_t nDistanceBefore = -1;
302 Int_t nDistanceAfter = -1;
303 Bool_t twoLow = kFALSE;
304 for(UShort_t t = 0; t < nstr; t++) {
308 output.SetMultiplicity(d,r,s,t,0.);
309 Float_t mult = SignalInStrip(input,d,r,s,t);
311 Float_t multNext = 0;
312 Float_t multNextNext = 0;
314 if(t<nstr-1) multNext = SignalInStrip(input,d,r,s,t+1);
315 if(t<nstr-2) multNextNext = SignalInStrip(input,d,r,s,t+2);
316 if(multNext == AliESDFMD::kInvalidMult) multNext = 0;
317 if(multNextNext == AliESDFMD::kInvalidMult) multNextNext = 0;
318 if(!fThreeStripSharing) multNextNext = 0;
319 // Get the pseudo-rapidity
320 Double_t eta = input.Eta(d,r,s,t);
321 Double_t phi = input.Phi(d,r,s,t) * TMath::Pi() / 180.;
322 if (s == 0) output.SetEta(d,r,s,t,eta);
324 // Keep dead-channel information.
325 if(mult == AliESDFMD::kInvalidMult)
326 output.SetMultiplicity(d,r,s,t,AliESDFMD::kInvalidMult);
328 // If no signal or dead strip, go on.
329 if (mult == AliESDFMD::kInvalidMult || mult == 0) {
330 if (mult == 0) histos->fSum->Fill(eta,phi,mult);
335 // Fill the diagnostics histogram
336 histos->fBefore->Fill(mult);
338 Double_t mergedEnergy = 0;
340 if(fUseSimpleMerging) {
342 if (t < nstr-1) histos->fNeighborsBefore->Fill(mult,multNext);
343 if(mult > GetHighCut(d, r, eta ,false)) {
344 histos->fDistanceBefore->Fill(nDistanceBefore);
345 nDistanceBefore = -1;
349 if(fThreeStripSharing && multNext > GetLowCut(d, r, eta) &&
350 (multNext < GetHighCut(d, r, eta ,false) || twoLow)) {
351 eTotal = eTotal + multNext;
353 histos->fTriple->Fill(eTotal);
358 histos->fDouble->Fill(eTotal);
364 if(used) {used = kFALSE; continue; }
365 if(mult > GetLowCut(d, r, eta)) etot = mult;
367 if(mult > GetLowCut(d, r, eta) &&
368 multNext > GetLowCut(d, r, eta) &&
369 (mult < GetHighCut(d, r, eta ,false) ||
370 multNext < GetHighCut(d, r, eta ,false))) {
372 if(mult < GetHighCut(d, r, eta ,false) &&
373 multNext < GetHighCut(d, r, eta ,false) )
376 if(mult>multNext && multNextNext < GetLowCut(d, r, eta))
378 etot = mult + multNext;
380 histos->fDouble->Fill(etot);
384 eTotal = mult + multNext;
389 histos->fSingle->Fill(etot);
390 histos->fSinglePerStrip->Fill(etot,t);
396 if(mergedEnergy > GetHighCut(d, r, eta ,false) ) {
397 histos->fDistanceAfter->Fill(nDistanceAfter);
400 //if(mult>0 && multNext >0)
401 // std::cout<<mult<<" "<<multNext<<" "<<mergedEnergy<<std::endl;
404 // Get next and previous signal - if any
407 Status prevStatus = (t == 0 ? kNone : status[t-1]);
408 Status thisStatus = status[t];
409 Status nextStatus = (t == nstr-1 ? kNone : status[t+1]);
411 prevE = SignalInStrip(input,d,r,s,t-1);
412 if (prevE == AliESDFMD::kInvalidMult) prevE = 0;
415 nextE = SignalInStrip(input,d,r,s,t+1);
416 if (nextE == AliESDFMD::kInvalidMult) nextE = 0;
418 if (t != 0) histos->fNeighborsBefore->Fill(prevE, mult);
420 #ifdef USE_OLDER_MERGING
421 /*Double_t*/ mergedEnergy = MultiplicityOfStrip(mult,eta,prevE,nextE,
424 status[t] = (usedPrev ? kMergedWithOther : kNone);
425 if (t != nstr - 1) status[t] = (usedThis ? kMergedWithOther : kNone);
427 /*Double_t*/ mergedEnergy = MultiplicityOfStrip(mult, prevE, nextE,
433 if (t != 0) status[t-1] = prevStatus;
434 if (t != nstr-1) status[t+1] = nextStatus;
435 status[t] = thisStatus;
438 // If we're processing on non-angle corrected data, we
439 // should do the angle correction here
442 mergedEnergy = AngleCorrect(mergedEnergy, eta);
443 if (mergedEnergy > 0) histos->Incr();
446 histos->fNeighborsAfter->Fill(output.Multiplicity(d,r,s,t-1),
448 histos->fBeforeAfter->Fill(mult, mergedEnergy);
450 histos->fAfter->Fill(mergedEnergy);
451 histos->fSum->Fill(eta,phi,mergedEnergy);
453 output.SetMultiplicity(d,r,s,t,mergedEnergy);
455 for (UShort_t t = 0; t < nstr; t++) {
456 if (fOper) fOper->operator()(d, r, s, t) = status[t];
458 case kNone: nNone++; break;
459 case kCandidate: nCandidate++; break;
460 case kMergedWithOther: nMerged++; break;
461 case kMergedInto: nSummed++; break;
467 fSummed->Fill(kNone, nNone);
468 fSummed->Fill(kCandidate, nCandidate);
469 fSummed->Fill(kMergedWithOther, nMerged);
470 fSummed->Fill(kMergedInto, nSummed);
472 DBGL(1, Form("none=%9d, candidate=%9d, merged=%9d, summed=%9d",
473 nNone, nCandidate, nMerged, nSummed));
475 while ((o = static_cast<RingHistos*>(next())))
481 //_____________________________________________________________________
483 AliFMDSharingFilter::SignalInStrip(const AliESDFMD& input,
490 // Get the signal in a strip
502 Double_t mult = input.Multiplicity(d,r,s,t);
504 // - bad value (invalid or 0)
505 // - we want angle corrected and data is
506 // - we don't want angle corrected and data isn't
507 // just return read value
508 if (mult == AliESDFMD::kInvalidMult ||
510 (fCorrectAngles && input.IsAngleCorrected()) ||
511 (!fCorrectAngles && !input.IsAngleCorrected()))
514 // If we want angle corrected data, correct it,
515 // otherwise de-correct it
516 if (fCorrectAngles) mult = AngleCorrect(mult, input.Eta(d,r,s,t));
517 else mult = DeAngleCorrect(mult, input.Eta(d,r,s,t));
520 //_____________________________________________________________________
522 AliFMDSharingFilter::GetLowCut(UShort_t d, Char_t r, Double_t eta) const
525 // Get the low cut. Normally, the low cut is taken to be the lower
526 // value of the fit range used when generating the energy loss fits.
527 // However, if fLowCut is set (using SetLowCit) to a value greater
528 // than 0, then that value is used.
530 return fLCuts.GetMultCut(d,r,eta,false);
532 if (!fCutAtFractionOfMPV && fLowCut > 0) return fLowCut;
534 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
535 AliFMDCorrELossFit* fits = fcm.GetELossFit();
537 if (fCutAtFractionOfMPV) {
538 AliFMDCorrELossFit::ELossFit* func = fits->GetFit(d,r,eta);
539 return fFractionOfMPV*func->GetDelta() ;
541 return fits->GetLowCut();
545 //_____________________________________________________________________
547 AliFMDSharingFilter::GetHighCut(UShort_t d, Char_t r,
548 Double_t eta, Bool_t errors) const
551 // Get the high cut. The high cut is defined as the
552 // most-probably-value peak found from the energy distributions, minus
553 // 2 times the width of the corresponding Landau.
555 return fHCuts.GetMultCut(d,r,eta,errors);
558 //_____________________________________________________________________
560 const char* status2String(AliFMDSharingFilter::Status s)
563 case AliFMDSharingFilter::kNone: return "none ";
564 case AliFMDSharingFilter::kCandidate: return "candidate";
565 case AliFMDSharingFilter::kMergedWithOther: return "merged ";
566 case AliFMDSharingFilter::kMergedInto: return "summed ";
572 //_____________________________________________________________________
574 AliFMDSharingFilter::MultiplicityOfStrip(Double_t thisE,
585 Status& nextStatus) const
587 Double_t lowCut = GetLowCut(d, r, eta);
589 DBG(3,Form("FMD%d%c[%2d,%3d]: this=%9f(%s), prev=%9f(%s), next=%9f(%s)",
591 thisE, status2String(thisStatus),
592 prevE, status2String(prevStatus),
593 nextE, status2String(nextStatus)));
595 // If below cut, then modify zero signal and make sure the next
596 // strip is considered a candidate.
597 if (thisE < lowCut || thisE > 20) {
599 DBGL(3,Form(" %9f<%9f || %9f>20, 0'ed", thisE, lowCut, thisE));
600 if (prevStatus == kCandidate) prevStatus = kNone;
603 // It this strip was merged with the previous strip, then
604 // make the next strip a candidate and zero the value in this strip.
605 if (thisStatus == kMergedWithOther) {
606 DBGL(3,Form(" Merged with other, 0'ed"));
610 // Get the upper cut on the sharing
611 Double_t highCut = GetHighCut(d, r, eta ,false);
617 // Only for low-flux events
619 // If this is smaller than the next, and the next is larger
620 // then the cut, mark both as candidates for sharing.
621 // They should be be merged on the next iteration
622 if (thisE < nextE && nextE > highCut) {
623 thisStatus = kCandidate;
624 nextStatus = kCandidate;
629 // Variable to sum signal in
630 Double_t totalE = thisE;
632 // If the previous signal was between the two cuts, and is still
633 // marked as a candidate , then merge it in here.
634 if (prevStatus == kCandidate && prevE > lowCut && prevE < highCut) {
636 prevStatus = kMergedWithOther;
637 DBG(3, Form(" Prev candidate %9f<%9f<%9f->%9f",
638 lowCut, prevE, highCut, totalE));
641 // If the next signal is between the two cuts, then merge it here
642 if (nextE > lowCut && nextE < highCut) {
644 nextStatus = kMergedWithOther;
645 DBG(3, Form(" Next %9f<%9f<%9f->%9f", lowCut, nextE, highCut,totalE));
648 // If the signal is bigger than the high-cut, then return the value
649 if (totalE > highCut) {
651 thisStatus = kMergedInto;
654 DBGL(3, Form(" %9f>%f9 (was %9f) -> %9f %s",
655 totalE, highCut, thisE, totalE,status2String(thisStatus)));
659 // This is below cut, so flag next as a candidate
660 DBG(3, Form(" %9f<=%9f, next candidate", totalE, highCut));
661 nextStatus = kCandidate;
664 // If the total signal is smaller than low cut then zero this and kill this
665 if (totalE < lowCut) {
666 DBGL(3, Form(" %9f<%9f (was %9f), zeroed", totalE, lowCut, thisE));
671 // If total signal not above high cut or lower than low cut,
672 // mark this as a candidate for merging into the next, and zero signal
673 DBGL(3, Form(" %9f<%9f<%9f (was %9f), zeroed, candidate",
674 lowCut, totalE, highCut, thisE));
675 thisStatus = kCandidate;
676 return (fZeroSharedHitsBelowThreshold ? 0 : totalE);
679 //_____________________________________________________________________
681 AliFMDSharingFilter::MultiplicityOfStrip(Double_t mult,
691 Bool_t& usedThis) const
694 // The actual algorithm
697 // mult The unfiltered signal in the strip
698 // eta Psuedo rapidity
699 // prevE Previous strip signal (or 0)
700 // nextE Next strip signal (or 0)
701 // lowFlux Whether this is a low flux event
706 // usedPrev Whether the previous strip was used in sharing or not
707 // usedThis Wether this strip was used in sharing or not.
710 // The filtered signal in the strip
713 // IF the multiplicity is very large, or below the cut, reject it, and
714 // flag it as candidate for sharing
715 Double_t lowCut = GetLowCut(d,r,eta);
716 if(mult > 12 || mult < lowCut) {
722 // If this was shared with the previous signal, return 0 and mark it as
723 // not a candiate for sharing
730 //analyse and perform sharing on one strip
733 Double_t highCut = GetHighCut(d, r, eta, false);
740 // If this signal is smaller than the next, and the next signal is smaller
741 // than then the high cut, and it's a low-flux event, then mark this and
742 // the next signal as candidates for sharing
744 // This is the test if the signal is the smaller of two possibly
754 Double_t totalE = mult;
756 // If the previous signal was larger than the low cut, and
757 // the previous was smaller than high cut, and the previous signal
758 // isn't marked as used, then add it's energy to this signal
759 if (prevE > lowCut &&
764 // If the next signal is larger than the low cut, and
765 // the next signal is smaller than the high cut, then add the next signal
766 // to this, and marked the next signal as used
767 if(nextE > lowCut && nextE < highCut ) {
772 // If we're processing on non-angle corrected data, we should do the
773 // angle correction here
774 // if (!fCorrectAngles)
775 // totalE = AngleCorrect(totalE, eta);
777 // Fill post processing histogram
778 // if(totalE > fLowCut)
779 // GetRingHistos(d,r)->fAfter->Fill(totalE);
782 Double_t mergedEnergy = 0;
785 // If we have a signal, then this is used (sharedPrev=true) and
786 // the signal is set to the result
787 mergedEnergy = totalE;
791 // If we do not have a signal (too low), then this is not shared,
792 // and the next strip is not shared either
799 //____________________________________________________________________
801 AliFMDSharingFilter::AngleCorrect(Double_t mult, Double_t eta) const
804 // Angle correct the signal
807 // mult Angle Un-corrected Signal
808 // eta Pseudo-rapidity
811 // Angle corrected signal
813 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
814 if (eta < 0) theta -= TMath::Pi();
815 return mult * TMath::Cos(theta);
817 //____________________________________________________________________
819 AliFMDSharingFilter::DeAngleCorrect(Double_t mult, Double_t eta) const
822 // Angle de-correct the signal
825 // mult Angle corrected Signal
826 // eta Pseudo-rapidity
829 // Angle un-corrected signal
831 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
832 if (eta < 0) theta -= TMath::Pi();
833 return mult / TMath::Cos(theta);
836 //____________________________________________________________________
838 AliFMDSharingFilter::ScaleHistograms(const TList* dir, Int_t nEvents)
841 // Scale the histograms to the total number of events
844 // dir Where the output is
845 // nEvents Number of events
847 if (nEvents <= 0) return;
848 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
851 TIter next(&fRingHistos);
853 THStack* sums = new THStack("sums", "Sum of ring signals");
854 while ((o = static_cast<RingHistos*>(next()))) {
855 o->ScaleHistograms(d, nEvents);
856 TH1D* sum = o->fSum->ProjectionX(o->GetName(), 1, o->fSum->GetNbinsY(),"e");
857 sum->Scale(1., "width");
858 sum->SetTitle(o->GetName());
859 sum->SetDirectory(0);
860 sum->SetYTitle("#sum #Delta/#Delta_{mip}");
866 //____________________________________________________________________
868 AliFMDSharingFilter::DefineOutput(TList* dir)
871 // Define the output histograms. These are put in a sub list of the
872 // passed list. The histograms are merged before the parent task calls
873 // AliAnalysisTaskSE::Terminate
876 // dir Directory to add to
878 TList* d = new TList;
879 d->SetName(GetName());
882 fSummed = new TH2I("operations", "Strip operations",
883 kMergedInto, kNone-.5, kMergedInto+.5,
884 51201, -.5, 51200.5);
885 fSummed->SetXTitle("Operation");
886 fSummed->SetYTitle("# of strips");
887 fSummed->SetZTitle("Events");
888 fSummed->GetXaxis()->SetBinLabel(kNone, "None");
889 fSummed->GetXaxis()->SetBinLabel(kCandidate, "Candidate");
890 fSummed->GetXaxis()->SetBinLabel(kMergedWithOther, "Merged w/other");
891 fSummed->GetXaxis()->SetBinLabel(kMergedInto, "Merged into");
892 fSummed->SetDirectory(0);
895 fHighCuts = new TH2D("highCuts", "High cuts used", 1,0,1, 1,0,1);
896 fHighCuts->SetXTitle("#eta");
897 fHighCuts->SetDirectory(0);
900 fLowCuts = new TH2D("lowCuts", "Low cuts used", 1,0,1, 1,0,1);
901 fLowCuts->SetXTitle("#eta");
902 fLowCuts->SetDirectory(0);
905 TNamed* angle = new TNamed("angle", fCorrectAngles ?
906 "corrected" : "uncorrected");
907 angle->SetUniqueID(fCorrectAngles);
908 TNamed* low = new TNamed("lowSignal", fZeroSharedHitsBelowThreshold ?
910 low->SetUniqueID(fZeroSharedHitsBelowThreshold);
911 TNamed* simple = new TNamed("simple", fUseSimpleMerging ? "yes" : "no");
912 simple->SetUniqueID(fUseSimpleMerging);
920 fLCuts.Output(d,"lCuts");
921 fHCuts.Output(d,"hCuts");
923 TIter next(&fRingHistos);
925 while ((o = static_cast<RingHistos*>(next()))) {
929 //____________________________________________________________________
931 AliFMDSharingFilter::Print(Option_t* /*option*/) const
939 char ind[gROOT->GetDirLevel()+1];
940 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
941 ind[gROOT->GetDirLevel()] = '\0';
942 std::cout << ind << ClassName() << ": " << GetName() << '\n'
944 << ind << " Debug: " << fDebug << "\n"
945 << ind << " Use corrected angles: " << fCorrectAngles << '\n'
946 << ind << " Zero below threshold: "
947 << fZeroSharedHitsBelowThreshold << '\n'
948 << ind << " Use simple sharing: " << fUseSimpleMerging << '\n'
949 << std::noboolalpha << std::endl;
950 std::cout << ind << " Low cuts: " << std::endl;
952 std::cout << ind << " High cuts: " << std::endl;
956 //====================================================================
957 AliFMDSharingFilter::RingHistos::RingHistos()
958 : AliForwardUtil::RingHistos(),
980 //____________________________________________________________________
981 AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
982 : AliForwardUtil::RingHistos(d,r),
1005 fBefore = new TH1D("esdEloss", Form("Energy loss in %s (reconstruction)",
1006 GetName()), 600, 0, 15);
1007 fBefore->SetXTitle("#Delta E/#Delta E_{mip}");
1008 fBefore->SetYTitle("P(#Delta E/#Delta E_{mip})");
1009 fBefore->SetFillColor(Color());
1010 fBefore->SetFillStyle(3001);
1011 fBefore->SetLineColor(kBlack);
1012 fBefore->SetLineStyle(2);
1013 fBefore->SetDirectory(0);
1015 fAfter = static_cast<TH1D*>(fBefore->Clone("anaEloss"));
1016 fAfter->SetTitle(Form("Energy loss in %s (sharing corrected)", GetName()));
1017 fAfter->SetFillColor(Color()+2);
1018 fAfter->SetLineStyle(1);
1019 fAfter->SetDirectory(0);
1021 fSingle = new TH1D("singleEloss", "Energy loss (single strips)",
1023 fSingle->SetXTitle("#Delta/#Delta_{mip}");
1024 fSingle->SetYTitle("P(#Delta/#Delta_{mip})");
1025 fSingle->SetFillColor(Color());
1026 fSingle->SetFillStyle(3001);
1027 fSingle->SetLineColor(kBlack);
1028 fSingle->SetLineStyle(2);
1029 fSingle->SetDirectory(0);
1031 fDouble = static_cast<TH1D*>(fSingle->Clone("doubleEloss"));
1032 fDouble->SetTitle("Energy loss (two strips)");
1033 fDouble->SetFillColor(Color()+1);
1034 fDouble->SetDirectory(0);
1036 fTriple = static_cast<TH1D*>(fSingle->Clone("tripleEloss"));
1037 fTriple->SetTitle("Energy loss (three strips)");
1038 fTriple->SetFillColor(Color()+2);
1039 fTriple->SetDirectory(0);
1041 //Int_t nBinsForInner = (r == 'I' ? 32 : 16);
1042 Int_t nBinsForInner = (r == 'I' ? 512 : 256);
1043 Int_t nStrips = (r == 'I' ? 512 : 256);
1045 fSinglePerStrip = new TH2D("singlePerStrip", "SinglePerStrip",
1046 600,0,15, nBinsForInner,0,nStrips);
1047 fSinglePerStrip->SetXTitle("#Delta/#Delta_{mip}");
1048 fSinglePerStrip->SetYTitle("Strip #");
1049 fSinglePerStrip->SetZTitle("Counts");
1050 fSinglePerStrip->SetDirectory(0);
1052 fDistanceBefore = new TH1D("distanceBefore", "Distance before sharing",
1053 nStrips , 0,nStrips );
1054 fDistanceBefore->SetXTitle("Distance");
1055 fDistanceBefore->SetYTitle("Counts");
1056 fDistanceBefore->SetFillColor(kGreen+2);
1057 fDistanceBefore->SetFillStyle(3001);
1058 fDistanceBefore->SetLineColor(kBlack);
1059 fDistanceBefore->SetLineStyle(2);
1060 fDistanceBefore->SetDirectory(0);
1062 fDistanceAfter = static_cast<TH1D*>(fDistanceBefore->Clone("distanceAfter"));
1063 fDistanceAfter->SetTitle("Distance after sharing");
1064 fDistanceAfter->SetFillColor(kGreen+1);
1065 fDistanceAfter->SetDirectory(0);
1070 Int_t n = int((max-min) / (max / 300));
1071 fBeforeAfter = new TH2D("beforeAfter", "Before and after correlation",
1072 n, min, max, n, min, max);
1073 fBeforeAfter->SetXTitle("#Delta E/#Delta E_{mip} before");
1074 fBeforeAfter->SetYTitle("#Delta E/#Delta E_{mip} after");
1075 fBeforeAfter->SetZTitle("Correlation");
1076 fBeforeAfter->SetDirectory(0);
1078 fNeighborsBefore = static_cast<TH2D*>(fBeforeAfter->Clone("neighborsBefore"));
1079 fNeighborsBefore->SetTitle("Correlation of neighbors before");
1080 fNeighborsBefore->SetXTitle("#Delta E_{i}/#Delta E_{mip}");
1081 fNeighborsBefore->SetYTitle("#Delta E_{i+1}/#Delta E_{mip}");
1082 fNeighborsBefore->SetDirectory(0);
1085 static_cast<TH2D*>(fNeighborsBefore->Clone("neighborsAfter"));
1086 fNeighborsAfter->SetTitle("Correlation of neighbors after");
1087 fNeighborsAfter->SetDirectory(0);
1089 fSum = new TH2D("summed", "Summed signal", 200, -4, 6,
1090 (fRing == 'I' || fRing == 'i' ? 20 : 40), 0, 2*TMath::Pi());
1091 fSum->SetDirectory(0);
1093 fSum->SetMarkerColor(Color());
1094 // fSum->SetFillColor(Color());
1095 fSum->SetXTitle("#eta");
1096 fSum->SetYTitle("#varphi [radians]");
1097 fSum->SetZTitle("#sum #Delta/#Delta_{mip}(#eta,#varphi) ");
1099 fHits = new TH1D("hits", "Number of hits", 200, 0, 200000);
1100 fHits->SetDirectory(0);
1101 fHits->SetXTitle("# of hits");
1102 fHits->SetFillColor(kGreen+1);
1104 //____________________________________________________________________
1105 AliFMDSharingFilter::RingHistos::RingHistos(const RingHistos& o)
1106 : AliForwardUtil::RingHistos(o),
1112 fSinglePerStrip(o.fSinglePerStrip),
1113 fDistanceBefore(o.fDistanceBefore),
1114 fDistanceAfter(o.fDistanceAfter),
1115 fBeforeAfter(o.fBeforeAfter),
1116 fNeighborsBefore(o.fNeighborsBefore),
1117 fNeighborsAfter(o.fNeighborsAfter),
1126 // o Object to copy from
1130 //____________________________________________________________________
1131 AliFMDSharingFilter::RingHistos&
1132 AliFMDSharingFilter::RingHistos::operator=(const RingHistos& o)
1135 // Assignment operator
1138 // o Object to assign from
1141 // Reference to this
1143 if (&o == this) return *this;
1144 AliForwardUtil::RingHistos::operator=(o);
1148 if (fBefore) delete fBefore;
1149 if (fAfter) delete fAfter;
1150 if (fSingle) delete fSingle;
1151 if (fDouble) delete fDouble;
1152 if (fTriple) delete fTriple;
1153 if (fSinglePerStrip) delete fSinglePerStrip;
1154 if (fDistanceBefore) delete fDistanceBefore;
1155 if (fDistanceAfter) delete fDistanceAfter;
1156 if (fHits) delete fHits;
1159 fBefore = static_cast<TH1D*>(o.fBefore->Clone());
1160 fAfter = static_cast<TH1D*>(o.fAfter->Clone());
1161 fSingle = static_cast<TH1D*>(o.fSingle->Clone());
1162 fDouble = static_cast<TH1D*>(o.fDouble->Clone());
1163 fTriple = static_cast<TH1D*>(o.fTriple->Clone());
1164 fSinglePerStrip = static_cast<TH2D*>(o.fSinglePerStrip->Clone());
1165 fDistanceBefore = static_cast<TH1D*>(o.fDistanceBefore->Clone());
1166 fDistanceAfter = static_cast<TH1D*>(o.fDistanceAfter->Clone());
1167 fBeforeAfter = static_cast<TH2D*>(o.fBeforeAfter->Clone());
1168 fNeighborsBefore = static_cast<TH2D*>(o.fNeighborsBefore->Clone());
1169 fNeighborsAfter = static_cast<TH2D*>(o.fNeighborsAfter->Clone());
1170 fHits = static_cast<TH1D*>(o.fHits->Clone());
1171 fSum = static_cast<TH2D*>(o.fSum->Clone());
1175 //____________________________________________________________________
1176 AliFMDSharingFilter::RingHistos::~RingHistos()
1182 //____________________________________________________________________
1184 AliFMDSharingFilter::RingHistos::Finish()
1190 fHits->Fill(fNHits);
1193 //____________________________________________________________________
1195 AliFMDSharingFilter::RingHistos::ScaleHistograms(const TList* dir,
1199 // Scale the histograms to the total number of events
1202 // nEvents Number of events
1203 // dir Where the output is
1205 TList* l = GetOutputList(dir);
1209 TH1D* before = static_cast<TH1D*>(l->FindObject("esdEloss"));
1210 TH1D* after = static_cast<TH1D*>(l->FindObject("anaEloss"));
1211 if (before) before->Scale(1./nEvents);
1212 if (after) after->Scale(1./nEvents);
1215 TH2D* summed = static_cast<TH2D*>(l->FindObject("summed"));
1216 if (summed) summed->Scale(1./nEvents);
1220 //____________________________________________________________________
1222 AliFMDSharingFilter::RingHistos::Output(TList* dir)
1228 // dir where to store
1230 TList* d = DefineOutputList(dir);
1237 d->Add(fSinglePerStrip);
1238 d->Add(fDistanceBefore);
1239 d->Add(fDistanceAfter);
1240 d->Add(fBeforeAfter);
1241 d->Add(fNeighborsBefore);
1242 d->Add(fNeighborsAfter);
1246 // Removed to avoid doubly adding the list which destroys
1251 //____________________________________________________________________