2 // Class to do the sharing correction of FMD ESD data
4 #include "AliFMDSharingFilter.h"
10 #include "AliFMDAnaParameters.h"
13 ClassImp(AliFMDSharingFilter)
15 ; // This is for Emacs
19 //____________________________________________________________________
20 AliFMDSharingFilter::AliFMDSharingFilter()
24 fCorrectAngles(kFALSE),
28 //____________________________________________________________________
29 AliFMDSharingFilter::AliFMDSharingFilter(const char* title)
30 : TNamed("fmdSharingFilter", title),
33 fCorrectAngles(kFALSE),
36 fRingHistos.Add(new RingHistos(1, 'I'));
37 fRingHistos.Add(new RingHistos(2, 'I'));
38 fRingHistos.Add(new RingHistos(2, 'O'));
39 fRingHistos.Add(new RingHistos(3, 'I'));
40 fRingHistos.Add(new RingHistos(3, 'O'));
41 fEtaCorr = new TH2F("etaCorr", "Correction of #eta",
42 200, -4, 6, 200, -4, 6);
43 fEtaCorr->SetXTitle("#eta from ESD");
44 fEtaCorr->SetYTitle("#eta from AnaParameters");
47 //____________________________________________________________________
48 AliFMDSharingFilter::AliFMDSharingFilter(const AliFMDSharingFilter& o)
52 fCorrectAngles(o.fCorrectAngles),
55 TIter next(&o.fRingHistos);
57 while ((obj = next())) fRingHistos.Add(obj);
60 //____________________________________________________________________
61 AliFMDSharingFilter::~AliFMDSharingFilter()
66 //____________________________________________________________________
68 AliFMDSharingFilter::operator=(const AliFMDSharingFilter& o)
71 SetTitle(o.GetTitle());
74 fCorrectAngles = o.fCorrectAngles;
77 TIter next(&o.fRingHistos);
79 while ((obj = next())) fRingHistos.Add(obj);
84 //____________________________________________________________________
85 AliFMDSharingFilter::RingHistos*
86 AliFMDSharingFilter::GetRingHistos(UShort_t d, Char_t r) const
90 case 1: idx = 0; break;
91 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
92 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
94 if (idx < 0 || idx >= fRingHistos.GetEntries()) return 0;
96 return static_cast<RingHistos*>(fRingHistos.At(idx));
99 //____________________________________________________________________
101 AliFMDSharingFilter::Filter(const AliESDFMD& input,
107 TIter next(&fRingHistos);
109 while ((o = static_cast<RingHistos*>(next())))
112 AliFMDAnaParameters* pars = AliFMDAnaParameters::Instance();
114 for(UShort_t d = 1; d <= 3; d++) {
115 Int_t nRings = (d == 1 ? 1 : 2);
116 for (UShort_t q = 0; q < nRings; q++) {
117 Char_t r = (q == 0 ? 'I' : 'O');
118 UShort_t nsec = (q == 0 ? 20 : 40);
119 UShort_t nstr = (q == 0 ? 512 : 256);
121 RingHistos* histos = GetRingHistos(d, r);
123 for(UShort_t s = 0; s < nsec; s++) {
124 Bool_t usedThis = kFALSE;
125 Bool_t usedPrev = kFALSE;
127 for(UShort_t t = 0; t < nstr; t++) {
128 output.SetMultiplicity(d,r,s,t,0.);
129 Float_t mult = SignalInStrip(input,d,r,s,t);
131 // Keep dead-channel information.
132 if(mult == AliESDFMD::kInvalidMult)
133 output.SetMultiplicity(d,r,s,t,AliESDFMD::kInvalidMult);
135 // If no signal or dead strip, go on.
136 if (mult == AliESDFMD::kInvalidMult || mult == 0) continue;
138 // Get the pseudo-rapidity
139 Double_t eta1 = input.Eta(d,r,s,t);
140 Double_t eta2 = pars->GetEtaFromStrip(d,r,s,t,vz);
141 fEtaCorr->Fill(eta1, eta2);
144 // Fill the diagnostics histogram
145 histos->fBefore->Fill(mult);
147 // Get next and previous signal - if any
151 prevE = SignalInStrip(input,d,r,s,t-1);
152 if (prevE == AliESDFMD::kInvalidMult) prevE = 0;
155 nextE = SignalInStrip(input,d,r,s,t+1);
156 if (nextE == AliESDFMD::kInvalidMult) nextE = 0;
159 Double_t mergedEnergy = MultiplicityOfStrip(mult,eta,prevE,nextE,
162 if (mergedEnergy > fLowCut) histos->Incr();
163 histos->fAfter->Fill(mergedEnergy);
165 output.SetMultiplicity(d,r,s,t,mergedEnergy);
166 output.SetEta(d,r,s,t,eta);
173 while ((o = static_cast<RingHistos*>(next())))
179 //_____________________________________________________________________
181 AliFMDSharingFilter::SignalInStrip(const AliESDFMD& input,
187 Double_t mult = input.Multiplicity(d,r,s,t);
188 if (mult == AliESDFMD::kInvalidMult || mult == 0) return mult;
190 if (fCorrectAngles && !input.IsAngleCorrected())
191 mult = AngleCorrect(mult, input.Eta(d,r,s,t));
192 else if (!fCorrectAngles && input.IsAngleCorrected())
193 mult = DeAngleCorrect(mult, input.Eta(d,r,s,t));
197 //_____________________________________________________________________
199 AliFMDSharingFilter::GetHighCut(UShort_t d, Char_t r, Double_t eta) const
201 AliFMDAnaParameters* pars = AliFMDAnaParameters::Instance();
203 // Get the high cut. The high cut is defined as the
204 // most-probably-value peak found from the energy distributions, minus
205 // 2 times the width of the corresponding Landau.
206 Double_t mpv = pars->GetMPV(d,r,eta);
207 Double_t w = pars->GetSigma(d,r,eta);
209 AliWarning(Form("FMD%d%c, eta=%f, MPV=%f, W=%f", d, r, eta, mpv, w));
210 Double_t highCut = (mpv - 2 * w);
214 //_____________________________________________________________________
216 AliFMDSharingFilter::MultiplicityOfStrip(Double_t mult,
228 // IF the multiplicity is very large, or below the cut, reject it, and
229 // flag it as candidate for sharing
230 if(mult > 12 || mult < fLowCut) {
236 // If this was shared with the previous signal, return 0 and mark it as
237 // not a candiate for sharing
244 //analyse and perform sharing on one strip
246 // Calculate the total energy loss
247 Double_t highCut = GetHighCut(d, r, eta);
249 // If this signal is smaller than the next, and the next signal is smaller
250 // than then the high cut, and it's a low-flux event, then mark this and
251 // the next signal as candidates for sharing
253 // This is the test if the signal is the smaller of two possibly
263 Double_t totalE = mult;
265 // If the previous signal was larger than the low cut, and
266 // the previous was smaller than high cut, and the previous signal
267 // isn't marked as used, then add it's energy to this signal
268 if (prevE > fLowCut &&
273 // If the next signal is larger than the low cut, and
274 // the next signal is smaller than the low cut, then add the next signal
275 // to this, and marked the next signal as used
276 if(nextE > fLowCut && nextE < highCut ) {
281 // If we're processing on non-angle corrected data, we should do the
282 // angle correction here
284 totalE = AngleCorrect(totalE, eta);
286 // Fill post processing histogram
287 // if(totalE > fLowCut)
288 // GetRingHistos(d,r)->fAfter->Fill(totalE);
291 Double_t mergedEnergy = 0;
294 // If we have a signal, then this is used (sharedPrev=true) and
295 // the signal is set to the result
296 mergedEnergy = totalE;
300 // If we do not have a signal (too low), then this is not shared,
301 // and the next strip is not shared either
308 //____________________________________________________________________
310 AliFMDSharingFilter::AngleCorrect(Double_t mult, Double_t eta) const
312 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
313 if (eta < 0) theta -= TMath::Pi();
314 return mult * TMath::Cos(theta);
316 //____________________________________________________________________
318 AliFMDSharingFilter::DeAngleCorrect(Double_t mult, Double_t eta) const
320 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
321 if (eta < 0) theta -= TMath::Pi();
322 return mult / TMath::Cos(theta);
325 //____________________________________________________________________
327 AliFMDSharingFilter::ScaleHistograms(TList* dir, Int_t nEvents)
329 if (nEvents <= 0) return;
330 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
333 TIter next(&fRingHistos);
335 while ((o = static_cast<RingHistos*>(next())))
336 o->ScaleHistograms(d, nEvents);
339 //____________________________________________________________________
341 AliFMDSharingFilter::DefineOutput(TList* dir)
343 TList* d = new TList;
344 d->SetName(GetName());
347 TIter next(&fRingHistos);
349 while ((o = static_cast<RingHistos*>(next()))) {
354 //====================================================================
355 AliFMDSharingFilter::RingHistos::RingHistos()
356 : AliForwardUtil::RingHistos(),
363 //____________________________________________________________________
364 AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
365 : AliForwardUtil::RingHistos(d,r),
371 fBefore = new TH1D(Form("%s_ESD_Eloss", fName.Data()),
372 Form("Energy loss in %s (reconstruction)", fName.Data()),
374 fAfter = new TH1D(Form("%s_Ana_Eloss", fName.Data()),
375 Form("Energy loss in %s (sharing corrected)",
376 fName.Data()), 1000, 0, 25);
377 fBefore->SetXTitle("#Delta E/#Delta E_{mip}");
378 fBefore->SetYTitle("P(#Delta E/#Delta E_{mip})");
379 fBefore->SetFillColor(kRed+1);
380 fBefore->SetFillStyle(3001);
382 fBefore->SetDirectory(0);
383 fAfter->SetXTitle("#Delta E/#Delta E_{mip}");
384 fAfter->SetYTitle("P(#Delta E/#Delta E_{mip})");
385 fAfter->SetFillColor(kBlue+1);
386 fAfter->SetFillStyle(3001);
388 fAfter->SetDirectory(0);
390 fHits = new TH1D(Form("%s_Hits", fName.Data()),
391 Form("Number of hits in %s", fName.Data()),
393 fHits->SetDirectory(0);
394 fHits->SetXTitle("# of hits");
395 fHits->SetFillColor(kGreen+1);
397 //____________________________________________________________________
398 AliFMDSharingFilter::RingHistos::RingHistos(const RingHistos& o)
399 : AliForwardUtil::RingHistos(o),
406 //____________________________________________________________________
407 AliFMDSharingFilter::RingHistos&
408 AliFMDSharingFilter::RingHistos::operator=(const RingHistos& o)
410 AliForwardUtil::RingHistos::operator=(o);
414 if (fBefore) delete fBefore;
415 if (fAfter) delete fAfter;
416 if (fHits) delete fHits;
418 fBefore = static_cast<TH1D*>(o.fBefore->Clone());
419 fAfter = static_cast<TH1D*>(o.fAfter->Clone());
420 fHits = static_cast<TH1D*>(o.fHits->Clone());
424 //____________________________________________________________________
425 AliFMDSharingFilter::RingHistos::~RingHistos()
427 if (fBefore) delete fBefore;
428 if (fAfter) delete fAfter;
429 if (fHits) delete fHits;
431 //____________________________________________________________________
433 AliFMDSharingFilter::RingHistos::Finish()
438 //____________________________________________________________________
440 AliFMDSharingFilter::RingHistos::ScaleHistograms(TList* dir, Int_t nEvents)
442 TList* l = GetOutputList(dir);
445 TH1D* before = static_cast<TH1D*>(l->FindObject(Form("%s_ESD_ELoss",
447 TH1D* after = static_cast<TH1D*>(l->FindObject(Form("%s_Ana_ELoss",
449 if (before) before->Scale(1./nEvents);
450 if (after) after->Scale(1./nEvents);
453 //____________________________________________________________________
455 AliFMDSharingFilter::RingHistos::Output(TList* dir)
457 TList* d = DefineOutputList(dir);
464 //____________________________________________________________________