]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/AliFMDSharingFilter.cxx
Make clones of cut histos, and flag as scaled
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / AliFMDSharingFilter.cxx
CommitLineData
7e4038b5 1//
7984e5f7 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.
6//
7// Input:
8// - AliESDFMD object - from reconstruction
9//
10// Output:
11// - AliESDFMD object - copy of input, but with signals merged
12//
13// Corrections used:
14// - AliFMDCorrELossFit
15//
16// Histograms:
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)
21//
22//
7e4038b5 23//
24#include "AliFMDSharingFilter.h"
5ca83fee 25#include "AliFMDStripIndex.h"
7e4038b5 26#include <AliESDFMD.h>
27#include <TAxis.h>
28#include <TList.h>
29#include <TH1.h>
30#include <TMath.h>
0bd4b00f 31#include "AliForwardCorrectionManager.h"
fb3430ac 32#include "AliFMDCorrELossFit.h"
7e4038b5 33#include <AliLog.h>
0bd4b00f 34#include <TROOT.h>
5bb5d1f6 35#include <THStack.h>
f7cfc454 36#include <TParameter.h>
0bd4b00f 37#include <iostream>
38#include <iomanip>
7e4038b5 39
40ClassImp(AliFMDSharingFilter)
41#if 0
42; // This is for Emacs
43#endif
44
1f7aa5c7 45#define DBG(L,M) \
5bb5d1f6 46 do { if (L>fDebug)break; std::cout << (M) << std::flush;} while(false)
1f7aa5c7 47#define DBGL(L,M) \
5bb5d1f6 48 do { if (L>fDebug)break; std::cout << (M) << std::endl;} while(false)
49
50
7e4038b5 51
52//____________________________________________________________________
53AliFMDSharingFilter::AliFMDSharingFilter()
54 : TNamed(),
55 fRingHistos(),
ea3e5d95 56 fCorrectAngles(kFALSE),
8449e3e0 57 // fSummed(0),
5bb5d1f6 58 fHighCuts(0),
d2638bb7 59 fLowCuts(0),
8449e3e0 60 // fOper(0),
40196108 61 fDebug(0),
d2638bb7 62 fZeroSharedHitsBelowThreshold(false),
63 fLCuts(),
7b212e49 64 fHCuts(),
d1013ccf 65 fUseSimpleMerging(false),
6f4a5c0d 66 fThreeStripSharing(true),
bdd49110 67 fMergingDisabled(false),
68 fIgnoreESDForAngleCorrection(false)
7984e5f7 69{
70 //
71 // Default Constructor - do not use
72 //
241cca4d 73 DGUARD(fDebug,1, "Default CTOR for AliFMDSharingFilter");
7984e5f7 74}
7e4038b5 75
76//____________________________________________________________________
77AliFMDSharingFilter::AliFMDSharingFilter(const char* title)
78 : TNamed("fmdSharingFilter", title),
79 fRingHistos(),
ea3e5d95 80 fCorrectAngles(kFALSE),
8449e3e0 81 // fSummed(0),
5bb5d1f6 82 fHighCuts(0),
d2638bb7 83 fLowCuts(0),
8449e3e0 84 // fOper(0),
40196108 85 fDebug(0),
d2638bb7 86 fZeroSharedHitsBelowThreshold(false),
87 fLCuts(),
7b212e49 88 fHCuts(),
d1013ccf 89 fUseSimpleMerging(false),
6f4a5c0d 90 fThreeStripSharing(true),
bdd49110 91 fMergingDisabled(false),
92 fIgnoreESDForAngleCorrection(false)
7e4038b5 93{
7984e5f7 94 //
95 // Constructor
96 //
97 // Parameters:
98 // title Title of object - not significant
99 //
241cca4d 100 DGUARD(fDebug,1, "Named CTOR for AliFMDSharingFilter: %s", title);
1c8feb73 101 fRingHistos.SetName(GetName());
102 fRingHistos.SetOwner();
103
7e4038b5 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'));
d2638bb7 109
7d596e9b 110 fHCuts.Set(AliFMDMultCuts::kLandauSigmaWidth, 1);
111 fLCuts.Set(AliFMDMultCuts::kFixed, .15);
5ca83fee 112
1f7aa5c7 113 // fExtraDead.Reset(-1);
7e4038b5 114}
115
7e4038b5 116//____________________________________________________________________
117AliFMDSharingFilter::~AliFMDSharingFilter()
118{
7984e5f7 119 //
120 // Destructor
121 //
6ab100ec 122 DGUARD(fDebug,3, "DTOR for AliFMDSharingFilter");
36ffcf83 123 // fRingHistos.Delete();
7e4038b5 124}
125
7e4038b5 126//____________________________________________________________________
127AliFMDSharingFilter::RingHistos*
128AliFMDSharingFilter::GetRingHistos(UShort_t d, Char_t r) const
129{
7984e5f7 130 //
131 // Get the ring histogram container
132 //
133 // Parameters:
134 // d Detector
135 // r Ring
136 //
137 // Return:
138 // Ring histogram container
139 //
7e4038b5 140 Int_t idx = -1;
141 switch (d) {
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;
145 }
146 if (idx < 0 || idx >= fRingHistos.GetEntries()) return 0;
147
148 return static_cast<RingHistos*>(fRingHistos.At(idx));
149}
150
5bb5d1f6 151//____________________________________________________________________
152void
5934a3e3 153AliFMDSharingFilter::SetupForData(const TAxis& axis)
5bb5d1f6 154{
5934a3e3 155 // Initialise - called on first event
6ab100ec 156 DGUARD(fDebug,1, "Initialize for AliFMDSharingFilter");
5c1012c1 157 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
8449e3e0 158 const AliFMDCorrELossFit* fits = fcm.GetELossFit();
1f7aa5c7 159
5bb5d1f6 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.
4077f3e8 163
a76fb27d 164 TAxis eAxis(axis.GetNbins(),
165 axis.GetXmin(),
166 axis.GetXmax());
5c1012c1 167 if(fits)
168 eAxis.Set(fits->GetEtaAxis().GetNbins(),
169 fits->GetEtaAxis().GetXmin(),
170 fits->GetEtaAxis().GetXmax());
5bb5d1f6 171
5c1012c1 172 UShort_t nEta = eAxis.GetNbins();
4077f3e8 173
5bb5d1f6 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");
180
d2638bb7 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");
187
7095962e
CHC
188 // Cache our cuts in histograms
189 fLCuts.FillHistogram(fLowCuts);
190 fHCuts.FillHistogram(fHighCuts);
5bb5d1f6 191}
192
7e4038b5 193//____________________________________________________________________
1f7aa5c7 194#define ETA2COS(ETA) \
241cca4d 195 TMath::Cos(2*TMath::ATan(TMath::Exp(-TMath::Abs(ETA))))
196
7e4038b5 197Bool_t
198AliFMDSharingFilter::Filter(const AliESDFMD& input,
8449e3e0 199 Bool_t /*lowFlux*/,
6f4a5c0d 200 AliESDFMD& output,
0ccdab7b 201 Double_t /*zvtx*/)
7e4038b5 202{
7984e5f7 203 //
204 // Filter the input AliESDFMD object
205 //
206 // Parameters:
207 // input Input
208 // lowFlux If this is a low-flux event
209 // output Output AliESDFMD object
210 //
211 // Return:
212 // True on success, false otherwise
213 //
6ab100ec 214 DGUARD(fDebug,1, "Filter event in AliFMDSharingFilter");
7e4038b5 215 output.Clear();
216 TIter next(&fRingHistos);
0bd4b00f 217 RingHistos* o = 0;
8449e3e0 218 while ((o = static_cast<RingHistos*>(next()))) o->Clear();
219
241cca4d 220 Int_t nSingle = 0;
221 Int_t nDouble = 0;
222 Int_t nTriple = 0;
7e4038b5 223
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++) {
5bb5d1f6 227 Char_t r = (q == 0 ? 'I' : 'O');
228 UShort_t nsec = (q == 0 ? 20 : 40);
229 UShort_t nstr = (q == 0 ? 512 : 256);
7e4038b5 230 RingHistos* histos = GetRingHistos(d, r);
231
8449e3e0 232 for(UShort_t s = 0; s < nsec; s++) {
233 // `used' flags if the _current_ strip was used by _previous_
234 // iteration.
241cca4d 235 Bool_t used = kFALSE;
8449e3e0 236 // `eTotal' contains the current sum of merged signals so far
241cca4d 237 Double_t eTotal = -1;
8449e3e0 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;
f71c22f5
CHC
243 Int_t nStripsAboveCut = 0;
244
7e4038b5 245 for(UShort_t t = 0; t < nstr; t++) {
8449e3e0 246 // nDistanceBefore++;
247 // nDistanceAfter++;
f71c22f5 248
7e4038b5 249 output.SetMultiplicity(d,r,s,t,0.);
241cca4d 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;
9223d782 255 if(!fThreeStripSharing) multNextNext = 0;
241cca4d 256
5bb5d1f6 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);
7e4038b5 261
8449e3e0 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.
0ccdab7b 265 if (mult == AliESDFMD::kInvalidMult) {
7e4038b5 266 output.SetMultiplicity(d,r,s,t,AliESDFMD::kInvalidMult);
8449e3e0 267 histos->fBefore->Fill(-1);
762754c0 268 mult = AliESDFMD::kInvalidMult;
269 }
7b212e49 270
8aa0b3db 271 Double_t lowCut = GetLowCut(d, r, eta);
272 Double_t highCut = GetHighCut(d, r, eta, false);
273 if (mult != AliESDFMD::kInvalidMult && mult > lowCut) {
77f97e3f
CHC
274 // Always fill the ESD sum histogram
275 histos->fSumESD->Fill(eta, phi, mult);
0ccdab7b 276 }
77f97e3f 277
7e4038b5 278 // If no signal or dead strip, go on.
5bb5d1f6 279 if (mult == AliESDFMD::kInvalidMult || mult == 0) {
280 if (mult == 0) histos->fSum->Fill(eta,phi,mult);
8449e3e0 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.
285 eTotal = -1;
286 used = false;
287 twoLow = false;
f71c22f5
CHC
288 if (t > 0)
289 histos->fNConsecutive->Fill(nStripsAboveCut);
290 if (mult == AliESDFMD::kInvalidMult)
291 // Why not fill immidiately here?
292 nStripsAboveCut = -1;
293 else
294 // Why not fill immidiately here?
295 nStripsAboveCut = 0;
5bb5d1f6 296 continue;
297 }
7e4038b5 298
7e4038b5 299 // Fill the diagnostics histogram
300 histos->fBefore->Fill(mult);
428cd802 301
302 Double_t mergedEnergy = mult;
f71c22f5 303 // it seems to me that this logic could be condensed a bit
8aa0b3db 304 if(mult > lowCut) {
f71c22f5
CHC
305 if(nStripsAboveCut < 1) {
306 if(t > 0)
307 histos->fNConsecutive->Fill(nStripsAboveCut);
308 nStripsAboveCut=0;
309 }
310 nStripsAboveCut++;
311 }
312 else {
313 if (t > 0)
314 histos->fNConsecutive->Fill(nStripsAboveCut);
315 nStripsAboveCut=0;
316 }
317
428cd802 318 if (!fMergingDisabled) {
319 mergedEnergy = 0;
320
321 // The current sum
322 Float_t etot = 0;
8449e3e0 323
428cd802 324 // Fill in neighbor information
325 if (t < nstr-1) histos->fNeighborsBefore->Fill(mult,multNext);
8449e3e0 326
8aa0b3db 327 Bool_t thisValid = mult > lowCut;
328 Bool_t nextValid = multNext > lowCut;
329 Bool_t thisSmall = mult < highCut;
330 Bool_t nextSmall = multNext < highCut;
8449e3e0 331
428cd802 332 // If this strips signal is above the high cut, reset distance
333 // if (!thisSmall) {
334 // histos->fDistanceBefore->Fill(nDistanceBefore);
335 // nDistanceBefore = -1;
336 // }
8449e3e0 337
428cd802 338 // If the total signal in the past 1 or 2 strips are non-zero
339 // we need to check
340 if (eTotal > 0) {
341 // Here, we have already flagged one strip as a candidate
7b212e49 342
428cd802 343 // If 3-strip merging is enabled, then check the next
344 // strip to see that it falls within cut, or if we have
345 // two low signals
346 if (fThreeStripSharing && nextValid && (nextSmall || twoLow)) {
347 eTotal = eTotal + multNext;
348 used = kTRUE;
349 histos->fTriple->Fill(eTotal);
350 nTriple++;
351 twoLow = kFALSE;
352 }
353 // Otherwise, we got a double hit before, and that
354 // should be stored.
355 else {
356 used = kFALSE;
357 histos->fDouble->Fill(eTotal);
358 nDouble++;
359 }
360 // Store energy loss and reset sum
361 etot = eTotal;
362 eTotal = -1;
363 } // if (eTotal>0)
b0036461 364 else {
428cd802 365 // If we have no current sum
8449e3e0 366
428cd802 367 // Check if this is marked as used, and if so, continue
368 if (used) {used = kFALSE; continue; }
8449e3e0 369
428cd802 370 // If the signal is abvoe the cut, set current
371 if (thisValid) etot = mult;
8449e3e0 372
428cd802 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)) {
8449e3e0 376
428cd802 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;
b0036461 380
428cd802 381 // If this signal is bigger than the next, and the
382 // one after that is below the low-cut, then update
383 // the sum
8aa0b3db 384 if (mult>multNext && multNextNext < lowCut) {
428cd802 385 etot = mult + multNext;
386 used = kTRUE;
387 histos->fDouble->Fill(etot);
388 nDouble++;
389 }
390 // Otherwise, we may need to merge with a third strip
391 else {
392 etot = 0;
393 eTotal = mult + multNext;
394 }
b0036461 395 }
428cd802 396 // This is a signle hit
397 else if(etot > 0) {
398 histos->fSingle->Fill(etot);
399 histos->fSinglePerStrip->Fill(etot,t);
400 nSingle++;
f26a8959 401 }
428cd802 402 } // else if (etotal >= 0)
8449e3e0 403
428cd802 404 mergedEnergy = etot;
405 // if (mergedEnergy > GetHighCut(d, r, eta ,false)) {
406 // histos->fDistanceAfter->Fill(nDistanceAfter);
407 // nDistanceAfter = -1;
408 // }
409 //if(mult>0 && multNext >0)
410 // std::cout<<mult<<" "<<multNext<<" "<<mergedEnergy<<std::endl;
411 } // if (!fMergingDisabled)
412
5bb5d1f6 413 if (!fCorrectAngles)
414 mergedEnergy = AngleCorrect(mergedEnergy, eta);
8449e3e0 415 // if (mergedEnergy > 0) histos->Incr();
7b212e49 416
5bb5d1f6 417 if (t != 0)
418 histos->fNeighborsAfter->Fill(output.Multiplicity(d,r,s,t-1),
419 mergedEnergy);
420 histos->fBeforeAfter->Fill(mult, mergedEnergy);
f26a8959 421 if(mergedEnergy > 0)
422 histos->fAfter->Fill(mergedEnergy);
5bb5d1f6 423 histos->fSum->Fill(eta,phi,mergedEnergy);
7b212e49 424
7e4038b5 425 output.SetMultiplicity(d,r,s,t,mergedEnergy);
7e4038b5 426 } // for strip
f71c22f5 427 histos->fNConsecutive->Fill(nStripsAboveCut); // fill the last sector
7e4038b5 428 } // for sector
429 } // for ring
430 } // for detector
241cca4d 431 DMSG(fDebug, 3,"single=%9d, double=%9d, triple=%9d",
432 nSingle, nDouble, nTriple);
7e4038b5 433 next.Reset();
8449e3e0 434 // while ((o = static_cast<RingHistos*>(next()))) o->Finish();
7e4038b5 435
436 return kTRUE;
437}
438
439//_____________________________________________________________________
440Double_t
441AliFMDSharingFilter::SignalInStrip(const AliESDFMD& input,
442 UShort_t d,
443 Char_t r,
444 UShort_t s,
445 UShort_t t) const
446{
7984e5f7 447 //
448 // Get the signal in a strip
449 //
450 // Parameters:
451 // fmd ESD object
452 // d Detector
453 // r Ring
454 // s Sector
455 // t Strip
456 //
457 // Return:
458 // The energy signal
459 //
7e4038b5 460 Double_t mult = input.Multiplicity(d,r,s,t);
5bb5d1f6 461 // In case of
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 ||
467 mult == 0 ||
bdd49110 468 (fCorrectAngles && (fIgnoreESDForAngleCorrection || input.IsAngleCorrected())) ||
469 (!fCorrectAngles && !fIgnoreESDForAngleCorrection && !input.IsAngleCorrected()))
5bb5d1f6 470 return mult;
471
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));
7e4038b5 476 return mult;
477}
7095962e
CHC
478
479namespace {
480 Double_t Rng2Cut(UShort_t d, Char_t r, Double_t eta, TH2* h) {
481 Double_t ret = 1024;
482 Int_t ybin = 0;
483 switch(d) {
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;
487 default: return ret;
488 }
489 Int_t xbin = h->GetXaxis()->FindBin(eta);
490 if (xbin < 1 && xbin > h->GetXaxis()->GetNbins()) return ret;
491 ret = h->GetBinContent(xbin,ybin);
492 return ret;
493 }
494}
495
496 //_____________________________________________________________________
0bd4b00f 497Double_t
d2638bb7 498AliFMDSharingFilter::GetLowCut(UShort_t d, Char_t r, Double_t eta) const
0bd4b00f 499{
7984e5f7 500 //
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.
505 //
7095962e
CHC
506 return Rng2Cut(d, r, eta, fLowCuts);
507 // return fLCuts.GetMultCut(d,r,eta,false);
0bd4b00f 508}
7e4038b5 509
510//_____________________________________________________________________
511Double_t
5bb5d1f6 512AliFMDSharingFilter::GetHighCut(UShort_t d, Char_t r,
7095962e 513 Double_t eta, Bool_t /*errors*/) const
7e4038b5 514{
7984e5f7 515 //
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.
519 //
7095962e
CHC
520 return Rng2Cut(d, r, eta, fHighCuts);
521 // return fHCuts.GetMultCut(d,r,eta,errors);
5bb5d1f6 522}
523
7e4038b5 524//____________________________________________________________________
525Double_t
526AliFMDSharingFilter::AngleCorrect(Double_t mult, Double_t eta) const
527{
7984e5f7 528 //
529 // Angle correct the signal
530 //
531 // Parameters:
532 // mult Angle Un-corrected Signal
533 // eta Pseudo-rapidity
534 //
535 // Return:
536 // Angle corrected signal
537 //
7e4038b5 538 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
539 if (eta < 0) theta -= TMath::Pi();
540 return mult * TMath::Cos(theta);
541}
542//____________________________________________________________________
543Double_t
544AliFMDSharingFilter::DeAngleCorrect(Double_t mult, Double_t eta) const
545{
7984e5f7 546 //
547 // Angle de-correct the signal
548 //
549 // Parameters:
550 // mult Angle corrected Signal
551 // eta Pseudo-rapidity
552 //
553 // Return:
554 // Angle un-corrected signal
555 //
7e4038b5 556 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
557 if (eta < 0) theta -= TMath::Pi();
558 return mult / TMath::Cos(theta);
559}
560
561//____________________________________________________________________
562void
5934a3e3 563AliFMDSharingFilter::Terminate(const TList* dir, TList* output, Int_t nEvents)
7e4038b5 564{
7984e5f7 565 //
566 // Scale the histograms to the total number of events
567 //
568 // Parameters:
569 // dir Where the output is
570 // nEvents Number of events
571 //
6ab100ec 572 DGUARD(fDebug,1, "Scale histograms in AliFMDSharingFilter");
7e4038b5 573 if (nEvents <= 0) return;
9d99b0dd 574 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
575 if (!d) return;
7e4038b5 576
5934a3e3 577 TList* out = new TList;
578 out->SetName(d->GetName());
579 out->SetOwner();
bfab35d9 580
581 TParameter<int>* nFiles =
bc31b177 582 static_cast<TParameter<int>*>(d->FindObject("nFiles"));
bfab35d9 583
bc31b177 584 TH2* lowCuts = static_cast<TH2*>(d->FindObject("lowCuts"));
585 TH2* highCuts = static_cast<TH2*>(d->FindObject("highCuts"));
bfab35d9 586 if (lowCuts && nFiles) {
9ae052ad 587 TH1* oh = static_cast<TH1*>(lowCuts->Clone());
588 oh->Scale(1. / nFiles->GetVal());
589 oh->SetBit(BIT(20));
590 out->Add(oh);
bfab35d9 591 }
592 else
593 AliWarning("low cuts histogram not found in input list");
594 if (highCuts && nFiles) {
9ae052ad 595 TH1* oh = static_cast<TH1*>(highCuts->Clone());
596 oh->Scale(1. / nFiles->GetVal());
597 oh->SetBit(BIT(20));
598 out->Add(oh);
bfab35d9 599 }
600 else
601 AliWarning("high cuts histogram not found in input list");
5934a3e3 602
7e4038b5 603 TIter next(&fRingHistos);
604 RingHistos* o = 0;
5bb5d1f6 605 THStack* sums = new THStack("sums", "Sum of ring signals");
77f97e3f 606 THStack* sumsESD = new THStack("sumsESD", "Sum of ring ESD signals");
5bb5d1f6 607 while ((o = static_cast<RingHistos*>(next()))) {
5934a3e3 608 o->Terminate(d, nEvents);
609 if (!o->fSum) {
610 Warning("Terminate", "No sum histogram found for ring %s", o->GetName());
611 continue;
612 }
5bb5d1f6 613 TH1D* sum = o->fSum->ProjectionX(o->GetName(), 1, o->fSum->GetNbinsY(),"e");
614 sum->Scale(1., "width");
615 sum->SetTitle(o->GetName());
616 sum->SetDirectory(0);
77f97e3f 617 sum->SetYTitle("#sum_{c} #Delta/#Delta_{mip}");
5bb5d1f6 618 sums->Add(sum);
77f97e3f
CHC
619
620 sum = o->fSumESD->ProjectionX(o->GetName(), 1, o->fSumESD->GetNbinsY(),"e");
621 sum->Scale(1., "width");
622 sum->SetTitle(o->GetName());
623 sum->SetDirectory(0);
624 sum->SetYTitle("#sum_{s} #Delta/#Delta_{mip}");
625 sumsESD->Add(sum);
5bb5d1f6 626 }
5934a3e3 627 out->Add(sums);
77f97e3f 628 out->Add(sumsESD);
5934a3e3 629 output->Add(out);
7e4038b5 630}
631
632//____________________________________________________________________
633void
5934a3e3 634AliFMDSharingFilter::CreateOutputObjects(TList* dir)
7e4038b5 635{
7984e5f7 636 //
637 // Define the output histograms. These are put in a sub list of the
638 // passed list. The histograms are merged before the parent task calls
639 // AliAnalysisTaskSE::Terminate
640 //
641 // Parameters:
642 // dir Directory to add to
643 //
6ab100ec 644 DGUARD(fDebug,1, "Define output in AliFMDSharingFilter");
7e4038b5 645 TList* d = new TList;
646 d->SetName(GetName());
647 dir->Add(d);
5bb5d1f6 648
8449e3e0 649#if 0
5bb5d1f6 650 fSummed = new TH2I("operations", "Strip operations",
651 kMergedInto, kNone-.5, kMergedInto+.5,
652 51201, -.5, 51200.5);
653 fSummed->SetXTitle("Operation");
654 fSummed->SetYTitle("# of strips");
655 fSummed->SetZTitle("Events");
656 fSummed->GetXaxis()->SetBinLabel(kNone, "None");
657 fSummed->GetXaxis()->SetBinLabel(kCandidate, "Candidate");
658 fSummed->GetXaxis()->SetBinLabel(kMergedWithOther, "Merged w/other");
659 fSummed->GetXaxis()->SetBinLabel(kMergedInto, "Merged into");
660 fSummed->SetDirectory(0);
661 d->Add(fSummed);
8449e3e0 662#endif
5bb5d1f6 663
664 fHighCuts = new TH2D("highCuts", "High cuts used", 1,0,1, 1,0,1);
665 fHighCuts->SetXTitle("#eta");
666 fHighCuts->SetDirectory(0);
667 d->Add(fHighCuts);
668
d2638bb7 669 fLowCuts = new TH2D("lowCuts", "Low cuts used", 1,0,1, 1,0,1);
670 fLowCuts->SetXTitle("#eta");
671 fLowCuts->SetDirectory(0);
672 d->Add(fLowCuts);
673
d2638bb7 674 // d->Add(lowCut);
675 // d->Add(nXi);
676 // d->Add(sigma);
241cca4d 677 d->Add(AliForwardUtil::MakeParameter("angle", fCorrectAngles));
678 d->Add(AliForwardUtil::MakeParameter("lowSignal",
679 fZeroSharedHitsBelowThreshold));
680 d->Add(AliForwardUtil::MakeParameter("simple", fUseSimpleMerging));
bfab35d9 681 d->Add(AliForwardUtil::MakeParameter("sumThree", fThreeStripSharing));
428cd802 682 d->Add(AliForwardUtil::MakeParameter("disabled", fMergingDisabled));
bfab35d9 683 TParameter<int>* nFiles = new TParameter<int>("nFiles", 1);
684 nFiles->SetMergeMode('+');
685 d->Add(nFiles);
0ccdab7b 686
d2638bb7 687 fLCuts.Output(d,"lCuts");
688 fHCuts.Output(d,"hCuts");
5bb5d1f6 689
7e4038b5 690 TIter next(&fRingHistos);
691 RingHistos* o = 0;
692 while ((o = static_cast<RingHistos*>(next()))) {
5934a3e3 693 o->CreateOutputObjects(d);
7e4038b5 694 }
695}
c8b1a7db 696#define PF(N,V,...) \
697 AliForwardUtil::PrintField(N,V, ## __VA_ARGS__)
698#define PFB(N,FLAG) \
699 do { \
700 AliForwardUtil::PrintName(N); \
701 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
702 } while(false)
703#define PFV(N,VALUE) \
704 do { \
705 AliForwardUtil::PrintName(N); \
706 std::cout << (VALUE) << std::endl; } while(false)
707
0bd4b00f 708//____________________________________________________________________
709void
710AliFMDSharingFilter::Print(Option_t* /*option*/) const
711{
7984e5f7 712 //
713 // Print information
714 //
715 // Parameters:
716 // option Not used
717 //
c8b1a7db 718 AliForwardUtil::PrintTask(*this);
719 gROOT->IncreaseDirLevel();
720
721 PFB("Use corrected angles", fCorrectAngles);
722 PFB("Zero below threshold", fZeroSharedHitsBelowThreshold);
723 PFB("Use simple sharing", fUseSimpleMerging);
c8b1a7db 724 PFB("Allow 3 strip merging", fThreeStripSharing);
725 PF("Low cuts", "");
d2638bb7 726 fLCuts.Print();
c8b1a7db 727 PF("High cuts", "");
d2638bb7 728 fHCuts.Print();
c8b1a7db 729 gROOT->DecreaseDirLevel();
0bd4b00f 730}
7e4038b5 731
732//====================================================================
733AliFMDSharingFilter::RingHistos::RingHistos()
9d99b0dd 734 : AliForwardUtil::RingHistos(),
7e4038b5 735 fBefore(0),
736 fAfter(0),
f26a8959 737 fSingle(0),
738 fDouble(0),
739 fTriple(0),
740 fSinglePerStrip(0),
8449e3e0 741 // fDistanceBefore(0),
742 // fDistanceAfter(0),
5bb5d1f6 743 fBeforeAfter(0),
744 fNeighborsBefore(0),
745 fNeighborsAfter(0),
77f97e3f 746 fSumESD(0),
f71c22f5
CHC
747 fSum(0),
748 fNConsecutive(0)
749 // ,
8449e3e0 750 // fHits(0),
751 // fNHits(0)
7984e5f7 752{
753 //
754 // Default CTOR
755 //
756
757}
7e4038b5 758
759//____________________________________________________________________
760AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
9d99b0dd 761 : AliForwardUtil::RingHistos(d,r),
7e4038b5 762 fBefore(0),
763 fAfter(0),
f26a8959 764 fSingle(0),
765 fDouble(0),
766 fTriple(0),
767 fSinglePerStrip(0),
8449e3e0 768 // fDistanceBefore(0),
769 // fDistanceAfter(0),
5bb5d1f6 770 fBeforeAfter(0),
771 fNeighborsBefore(0),
772 fNeighborsAfter(0),
77f97e3f 773 fSumESD(0),
f71c22f5
CHC
774 fSum(0),
775 fNConsecutive(0)
776 //,
8449e3e0 777 // fHits(0),
778 // fNHits(0)
7e4038b5 779{
7984e5f7 780 //
781 // Constructor
782 //
783 // Parameters:
784 // d detector
785 // r ring
786 //
9b2f2e39 787 fBefore = new TH1D("esdEloss", Form("Energy loss in %s (reconstruction)",
8449e3e0 788 GetName()), 640, -1, 15);
7e4038b5 789 fBefore->SetXTitle("#Delta E/#Delta E_{mip}");
790 fBefore->SetYTitle("P(#Delta E/#Delta E_{mip})");
5bb5d1f6 791 fBefore->SetFillColor(Color());
7e4038b5 792 fBefore->SetFillStyle(3001);
f7cfc454 793 fBefore->SetLineColor(kBlack);
794 fBefore->SetLineStyle(2);
7e4038b5 795 fBefore->SetDirectory(0);
5bb5d1f6 796
797 fAfter = static_cast<TH1D*>(fBefore->Clone("anaEloss"));
9b2f2e39 798 fAfter->SetTitle(Form("Energy loss in %s (sharing corrected)", GetName()));
5bb5d1f6 799 fAfter->SetFillColor(Color()+2);
f7cfc454 800 fAfter->SetLineStyle(1);
7e4038b5 801 fAfter->SetDirectory(0);
f26a8959 802
803 fSingle = new TH1D("singleEloss", "Energy loss (single strips)",
804 600, 0, 15);
9b2f2e39 805 fSingle->SetXTitle("#Delta/#Delta_{mip}");
806 fSingle->SetYTitle("P(#Delta/#Delta_{mip})");
807 fSingle->SetFillColor(Color());
f26a8959 808 fSingle->SetFillStyle(3001);
809 fSingle->SetLineColor(kBlack);
810 fSingle->SetLineStyle(2);
811 fSingle->SetDirectory(0);
812
9b2f2e39 813 fDouble = static_cast<TH1D*>(fSingle->Clone("doubleEloss"));
814 fDouble->SetTitle("Energy loss (two strips)");
815 fDouble->SetFillColor(Color()+1);
f26a8959 816 fDouble->SetDirectory(0);
9b2f2e39 817
818 fTriple = static_cast<TH1D*>(fSingle->Clone("tripleEloss"));
819 fTriple->SetTitle("Energy loss (three strips)");
820 fTriple->SetFillColor(Color()+2);
f26a8959 821 fTriple->SetDirectory(0);
822
823 //Int_t nBinsForInner = (r == 'I' ? 32 : 16);
824 Int_t nBinsForInner = (r == 'I' ? 512 : 256);
825 Int_t nStrips = (r == 'I' ? 512 : 256);
826
827 fSinglePerStrip = new TH2D("singlePerStrip", "SinglePerStrip",
828 600,0,15, nBinsForInner,0,nStrips);
9b2f2e39 829 fSinglePerStrip->SetXTitle("#Delta/#Delta_{mip}");
830 fSinglePerStrip->SetYTitle("Strip #");
f26a8959 831 fSinglePerStrip->SetZTitle("Counts");
832 fSinglePerStrip->SetDirectory(0);
7e4038b5 833
8449e3e0 834#if 0
7f1cfdfd 835 fDistanceBefore = new TH1D("distanceBefore", "Distance before sharing",
9b2f2e39 836 nStrips , 0,nStrips );
7f1cfdfd 837 fDistanceBefore->SetXTitle("Distance");
838 fDistanceBefore->SetYTitle("Counts");
839 fDistanceBefore->SetFillColor(kGreen+2);
840 fDistanceBefore->SetFillStyle(3001);
841 fDistanceBefore->SetLineColor(kBlack);
842 fDistanceBefore->SetLineStyle(2);
843 fDistanceBefore->SetDirectory(0);
844
9b2f2e39 845 fDistanceAfter = static_cast<TH1D*>(fDistanceBefore->Clone("distanceAfter"));
846 fDistanceAfter->SetTitle("Distance after sharing");
7f1cfdfd 847 fDistanceAfter->SetFillColor(kGreen+1);
7f1cfdfd 848 fDistanceAfter->SetDirectory(0);
8449e3e0 849#endif
f26a8959 850
5bb5d1f6 851 Double_t max = 15;
852 Double_t min = -1;
853 Int_t n = int((max-min) / (max / 300));
854 fBeforeAfter = new TH2D("beforeAfter", "Before and after correlation",
855 n, min, max, n, min, max);
856 fBeforeAfter->SetXTitle("#Delta E/#Delta E_{mip} before");
857 fBeforeAfter->SetYTitle("#Delta E/#Delta E_{mip} after");
858 fBeforeAfter->SetZTitle("Correlation");
859 fBeforeAfter->SetDirectory(0);
860
861 fNeighborsBefore = static_cast<TH2D*>(fBeforeAfter->Clone("neighborsBefore"));
f7cfc454 862 fNeighborsBefore->SetTitle("Correlation of neighbors before");
5bb5d1f6 863 fNeighborsBefore->SetXTitle("#Delta E_{i}/#Delta E_{mip}");
864 fNeighborsBefore->SetYTitle("#Delta E_{i+1}/#Delta E_{mip}");
865 fNeighborsBefore->SetDirectory(0);
866
867 fNeighborsAfter =
868 static_cast<TH2D*>(fNeighborsBefore->Clone("neighborsAfter"));
869 fNeighborsAfter->SetTitle("Correlation of neighbors after");
870 fNeighborsAfter->SetDirectory(0);
871
77f97e3f
CHC
872 fSumESD = new TH2D("summedESD", "Summed ESD signal", 200, -4, 6,
873 NSector(), 0, 2*TMath::Pi());
874 fSumESD->SetDirectory(0);
875 fSumESD->Sumw2();
876 fSumESD->SetMarkerColor(Color());
5bb5d1f6 877 // fSum->SetFillColor(Color());
77f97e3f
CHC
878 fSumESD->SetXTitle("#eta");
879 fSumESD->SetYTitle("#varphi [radians]");
880 fSumESD->SetZTitle("#sum_{strip} #Delta/#Delta_{mip}(#eta,#varphi) ");
8449e3e0 881
77f97e3f
CHC
882 fSum = static_cast<TH2D*>(fSumESD->Clone("summed"));
883 fSum->SetTitle("Summed cluster signal");
884 fSum->SetZTitle("#sum_{cluster} #Delta/#Delta_{mip}(#eta,#varphi) ");
885 fSum->SetDirectory(0);
f71c22f5
CHC
886
887 // Perhaps we need to ensure that this histogram has enough range to
888 // accommondate all possible ranges - that is, from -1 to the number
889 // of strips in this ring(-type) - i.e., NStrips(). Perhaps the
890 // axis should be defined with increasin bin size - e.g.,
891 //
892 // -1.5,-.5,.5,1.5,...,100.5,128.5,192.5,...,NStrips()
893 //
894 fNConsecutive = new TH1D("nConsecutive","# consecutive strips above low cut",
895 201,-1.5,199.5);
896 fNConsecutive->SetXTitle("N_{strips}");
897 fNConsecutive->SetYTitle("N_{entries}");
898 fNConsecutive->SetFillColor(kYellow+2);
899 fNConsecutive->SetFillStyle(3001);
900 fNConsecutive->SetDirectory(0);
77f97e3f 901
f71c22f5 902
8449e3e0 903#if 0
5bb5d1f6 904 fHits = new TH1D("hits", "Number of hits", 200, 0, 200000);
7e4038b5 905 fHits->SetDirectory(0);
906 fHits->SetXTitle("# of hits");
907 fHits->SetFillColor(kGreen+1);
8449e3e0 908#endif
7e4038b5 909}
910//____________________________________________________________________
911AliFMDSharingFilter::RingHistos::RingHistos(const RingHistos& o)
9d99b0dd 912 : AliForwardUtil::RingHistos(o),
7e4038b5 913 fBefore(o.fBefore),
914 fAfter(o.fAfter),
f26a8959 915 fSingle(o.fSingle),
916 fDouble(o.fDouble),
917 fTriple(o.fTriple),
918 fSinglePerStrip(o.fSinglePerStrip),
8449e3e0 919 // fDistanceBefore(o.fDistanceBefore),
920 // fDistanceAfter(o.fDistanceAfter),
5bb5d1f6 921 fBeforeAfter(o.fBeforeAfter),
922 fNeighborsBefore(o.fNeighborsBefore),
923 fNeighborsAfter(o.fNeighborsAfter),
77f97e3f 924 fSumESD(o.fSumESD), //,
f71c22f5
CHC
925 fSum(o.fSum),
926 fNConsecutive(o.fNConsecutive)
927 //,
8449e3e0 928 // fHits(o.fHits),
929 // fNHits(o.fNHits)
7984e5f7 930{
931 //
932 // Copy constructor
933 //
934 // Parameters:
935 // o Object to copy from
936 //
937}
7e4038b5 938
939//____________________________________________________________________
940AliFMDSharingFilter::RingHistos&
941AliFMDSharingFilter::RingHistos::operator=(const RingHistos& o)
942{
7984e5f7 943 //
944 // Assignment operator
945 //
946 // Parameters:
947 // o Object to assign from
948 //
949 // Return:
950 // Reference to this
951 //
d015ecfe 952 if (&o == this) return *this;
9d99b0dd 953 AliForwardUtil::RingHistos::operator=(o);
7e4038b5 954 fDet = o.fDet;
955 fRing = o.fRing;
956
36ffcf83 957 if (fBefore) delete fBefore;
958 if (fAfter) delete fAfter;
959 if (fSingle) delete fSingle;
960 if (fDouble) delete fDouble;
961 if (fTriple) delete fTriple;
f71c22f5
CHC
962 if (fSinglePerStrip) delete fSinglePerStrip;
963 if (fNConsecutive) delete fNConsecutive;
8449e3e0 964 // if (fDistanceBefore) delete fDistanceBefore;
965 // if (fDistanceAfter) delete fDistanceAfter;
966 // if (fHits) delete fHits;
7e4038b5 967
f26a8959 968
5bb5d1f6 969 fBefore = static_cast<TH1D*>(o.fBefore->Clone());
970 fAfter = static_cast<TH1D*>(o.fAfter->Clone());
f26a8959 971 fSingle = static_cast<TH1D*>(o.fSingle->Clone());
972 fDouble = static_cast<TH1D*>(o.fDouble->Clone());
973 fTriple = static_cast<TH1D*>(o.fTriple->Clone());
974 fSinglePerStrip = static_cast<TH2D*>(o.fSinglePerStrip->Clone());
8449e3e0 975 // fDistanceBefore = static_cast<TH1D*>(o.fDistanceBefore->Clone());
976 // fDistanceAfter = static_cast<TH1D*>(o.fDistanceAfter->Clone());
5bb5d1f6 977 fBeforeAfter = static_cast<TH2D*>(o.fBeforeAfter->Clone());
978 fNeighborsBefore = static_cast<TH2D*>(o.fNeighborsBefore->Clone());
979 fNeighborsAfter = static_cast<TH2D*>(o.fNeighborsAfter->Clone());
8449e3e0 980 // fHits = static_cast<TH1D*>(o.fHits->Clone());
77f97e3f 981 fSumESD = static_cast<TH2D*>(o.fSumESD->Clone());
5bb5d1f6 982 fSum = static_cast<TH2D*>(o.fSum->Clone());
f71c22f5 983 fNConsecutive = static_cast<TH1D*>(o.fNConsecutive->Clone());
5bb5d1f6 984
7e4038b5 985 return *this;
986}
987//____________________________________________________________________
988AliFMDSharingFilter::RingHistos::~RingHistos()
989{
7984e5f7 990 //
991 // Destructor
992 //
7e4038b5 993}
8449e3e0 994#if 0
7e4038b5 995//____________________________________________________________________
996void
997AliFMDSharingFilter::RingHistos::Finish()
998{
7984e5f7 999 //
1000 // Finish off
1001 //
1002 //
8449e3e0 1003 // fHits->Fill(fNHits);
7e4038b5 1004}
8449e3e0 1005#endif
9d99b0dd 1006//____________________________________________________________________
1007void
5934a3e3 1008AliFMDSharingFilter::RingHistos::Terminate(const TList* dir, Int_t nEvents)
9d99b0dd 1009{
7984e5f7 1010 //
1011 // Scale the histograms to the total number of events
1012 //
1013 // Parameters:
1014 // nEvents Number of events
1015 // dir Where the output is
1016 //
9d99b0dd 1017 TList* l = GetOutputList(dir);
1018 if (!l) return;
1019
f7cfc454 1020#if 0
1021 TH1D* before = static_cast<TH1D*>(l->FindObject("esdEloss"));
1022 TH1D* after = static_cast<TH1D*>(l->FindObject("anaEloss"));
9d99b0dd 1023 if (before) before->Scale(1./nEvents);
1024 if (after) after->Scale(1./nEvents);
f7cfc454 1025#endif
1026
1027 TH2D* summed = static_cast<TH2D*>(l->FindObject("summed"));
5bb5d1f6 1028 if (summed) summed->Scale(1./nEvents);
5934a3e3 1029 fSum = summed;
77f97e3f
CHC
1030
1031 TH2D* summedESD = static_cast<TH2D*>(l->FindObject("summedESD"));
1032 if (summedESD) summedESD->Scale(1./nEvents);
1033 fSumESD = summedESD;
f71c22f5
CHC
1034
1035 TH1D* consecutive = static_cast<TH1D*>(l->FindObject("nConsecutive"));
1036 if (consecutive) consecutive->Scale(1./nEvents);
1037 fNConsecutive= consecutive;
9d99b0dd 1038}
1039
7e4038b5 1040//____________________________________________________________________
1041void
5934a3e3 1042AliFMDSharingFilter::RingHistos::CreateOutputObjects(TList* dir)
7e4038b5 1043{
7984e5f7 1044 //
1045 // Make output
1046 //
1047 // Parameters:
1048 // dir where to store
1049 //
9d99b0dd 1050 TList* d = DefineOutputList(dir);
5bb5d1f6 1051
7e4038b5 1052 d->Add(fBefore);
1053 d->Add(fAfter);
f26a8959 1054 d->Add(fSingle);
1055 d->Add(fDouble);
1056 d->Add(fTriple);
1057 d->Add(fSinglePerStrip);
8449e3e0 1058 // d->Add(fDistanceBefore);
1059 // d->Add(fDistanceAfter);
5bb5d1f6 1060 d->Add(fBeforeAfter);
1061 d->Add(fNeighborsBefore);
1062 d->Add(fNeighborsAfter);
8449e3e0 1063 // d->Add(fHits);
77f97e3f 1064 d->Add(fSumESD);
5bb5d1f6 1065 d->Add(fSum);
f71c22f5 1066 d->Add(fNConsecutive);
bfab35d9 1067
1c8feb73 1068 // Removed to avoid doubly adding the list which destroys
1069 // the merging
1070 //dir->Add(d);
7e4038b5 1071}
1072
1073//____________________________________________________________________
1074//
1075// EOF
1076//