]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/AliFMDSharingFilter.cxx
Added scripts for Casper/Valentina style P(N_{ch}) analysis
[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),
5ca83fee 67 fRecalculateEta(false),
1f7aa5c7 68 // fExtraDead(0),
69 fXtraDead(0),
8449e3e0 70 fInvalidIsEmpty(false)
7984e5f7 71{
72 //
73 // Default Constructor - do not use
74 //
241cca4d 75 DGUARD(fDebug,1, "Default CTOR for AliFMDSharingFilter");
7984e5f7 76}
7e4038b5 77
78//____________________________________________________________________
79AliFMDSharingFilter::AliFMDSharingFilter(const char* title)
80 : TNamed("fmdSharingFilter", title),
81 fRingHistos(),
ea3e5d95 82 fCorrectAngles(kFALSE),
8449e3e0 83 // fSummed(0),
5bb5d1f6 84 fHighCuts(0),
d2638bb7 85 fLowCuts(0),
8449e3e0 86 // fOper(0),
40196108 87 fDebug(0),
d2638bb7 88 fZeroSharedHitsBelowThreshold(false),
89 fLCuts(),
7b212e49 90 fHCuts(),
d1013ccf 91 fUseSimpleMerging(false),
6f4a5c0d 92 fThreeStripSharing(true),
5ca83fee 93 fRecalculateEta(false),
1f7aa5c7 94 // fExtraDead(51200),
95 fXtraDead(AliFMDStripIndex::Pack(3,'O',19,511)+1),
8449e3e0 96 fInvalidIsEmpty(false)
7e4038b5 97{
7984e5f7 98 //
99 // Constructor
100 //
101 // Parameters:
102 // title Title of object - not significant
103 //
241cca4d 104 DGUARD(fDebug,1, "Named CTOR for AliFMDSharingFilter: %s", title);
1c8feb73 105 fRingHistos.SetName(GetName());
106 fRingHistos.SetOwner();
107
7e4038b5 108 fRingHistos.Add(new RingHistos(1, 'I'));
109 fRingHistos.Add(new RingHistos(2, 'I'));
110 fRingHistos.Add(new RingHistos(2, 'O'));
111 fRingHistos.Add(new RingHistos(3, 'I'));
112 fRingHistos.Add(new RingHistos(3, 'O'));
d2638bb7 113
114 fHCuts.SetNXi(1);
115 fHCuts.SetIncludeSigma(1);
116 fLCuts.SetMultCuts(.15);
5ca83fee 117
1f7aa5c7 118 // fExtraDead.Reset(-1);
7e4038b5 119}
120
121//____________________________________________________________________
122AliFMDSharingFilter::AliFMDSharingFilter(const AliFMDSharingFilter& o)
123 : TNamed(o),
124 fRingHistos(),
ea3e5d95 125 fCorrectAngles(o.fCorrectAngles),
8449e3e0 126 // fSummed(o.fSummed),
5bb5d1f6 127 fHighCuts(o.fHighCuts),
d2638bb7 128 fLowCuts(o.fLowCuts),
8449e3e0 129 // fOper(o.fOper),
40196108 130 fDebug(o.fDebug),
d2638bb7 131 fZeroSharedHitsBelowThreshold(o.fZeroSharedHitsBelowThreshold),
132 fLCuts(o.fLCuts),
7b212e49 133 fHCuts(o.fHCuts),
d1013ccf 134 fUseSimpleMerging(o.fUseSimpleMerging),
6f4a5c0d 135 fThreeStripSharing(o.fThreeStripSharing),
5ca83fee 136 fRecalculateEta(o.fRecalculateEta),
1f7aa5c7 137 //fExtraDead(o.fExtraDead),
138 fXtraDead(o.fXtraDead),
8449e3e0 139 fInvalidIsEmpty(o.fInvalidIsEmpty)
7e4038b5 140{
7984e5f7 141 //
142 // Copy constructor
143 //
144 // Parameters:
145 // o Object to copy from
146 //
241cca4d 147 DGUARD(fDebug,1, "Copy CTOR for AliFMDSharingFilter");
7e4038b5 148 TIter next(&o.fRingHistos);
149 TObject* obj = 0;
150 while ((obj = next())) fRingHistos.Add(obj);
151}
152
153//____________________________________________________________________
154AliFMDSharingFilter::~AliFMDSharingFilter()
155{
7984e5f7 156 //
157 // Destructor
158 //
6ab100ec 159 DGUARD(fDebug,3, "DTOR for AliFMDSharingFilter");
36ffcf83 160 // fRingHistos.Delete();
7e4038b5 161}
162
163//____________________________________________________________________
164AliFMDSharingFilter&
165AliFMDSharingFilter::operator=(const AliFMDSharingFilter& o)
166{
7984e5f7 167 //
168 // Assignment operator
169 //
170 // Parameters:
171 // o Object to assign from
172 //
173 // Return:
174 // Reference to this
175 //
6ab100ec 176 DGUARD(fDebug,3, "Assigment for AliFMDSharingFilter");
d015ecfe 177 if (&o == this) return *this;
ea3e5d95 178 TNamed::operator=(o);
7e4038b5 179
40196108 180 fCorrectAngles = o.fCorrectAngles;
40196108 181 fDebug = o.fDebug;
8449e3e0 182 // fOper = o.fOper;
183 // fSummed = o.fSummed;
40196108 184 fHighCuts = o.fHighCuts;
d2638bb7 185 fLowCuts = o.fLowCuts;
40196108 186 fZeroSharedHitsBelowThreshold = o.fZeroSharedHitsBelowThreshold;
d2638bb7 187 fLCuts = o.fLCuts;
188 fHCuts = o.fHCuts;
7b212e49 189 fUseSimpleMerging = o.fUseSimpleMerging;
d1013ccf 190 fThreeStripSharing = o.fThreeStripSharing;
6f4a5c0d 191 fRecalculateEta = o.fRecalculateEta;
8449e3e0 192 fInvalidIsEmpty = o.fInvalidIsEmpty;
7b212e49 193
7e4038b5 194 fRingHistos.Delete();
195 TIter next(&o.fRingHistos);
196 TObject* obj = 0;
197 while ((obj = next())) fRingHistos.Add(obj);
198
199 return *this;
200}
201
202//____________________________________________________________________
203AliFMDSharingFilter::RingHistos*
204AliFMDSharingFilter::GetRingHistos(UShort_t d, Char_t r) const
205{
7984e5f7 206 //
207 // Get the ring histogram container
208 //
209 // Parameters:
210 // d Detector
211 // r Ring
212 //
213 // Return:
214 // Ring histogram container
215 //
7e4038b5 216 Int_t idx = -1;
217 switch (d) {
218 case 1: idx = 0; break;
219 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
220 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
221 }
222 if (idx < 0 || idx >= fRingHistos.GetEntries()) return 0;
223
224 return static_cast<RingHistos*>(fRingHistos.At(idx));
225}
226
5ca83fee 227//____________________________________________________________________
228void
229AliFMDSharingFilter::AddDead(UShort_t d, Char_t r, UShort_t s, UShort_t t)
230{
231 if (d < 1 || d > 3) {
232 Warning("AddDead", "Invalid detector FMD%d", d);
233 return;
234 }
235 Bool_t inner = (r == 'I' || r == 'i');
236 if (d == 1 && !inner) {
237 Warning("AddDead", "Invalid ring FMD%d%c", d, r);
238 return;
239 }
240 if ((inner && s >= 20) || (!inner && s >= 40)) {
241 Warning("AddDead", "Invalid sector FMD%d%c[%02d]", d, r, s);
242 return;
243 }
244 if ((inner && t >= 512) || (!inner && t >= 256)) {
245 Warning("AddDead", "Invalid strip FMD%d%c[%02d,%03d]", d, r, s, t);
246 return;
247 }
248
249 Int_t id = AliFMDStripIndex::Pack(d, r, s, t);
1f7aa5c7 250 // Int_t i = 0;
251 fXtraDead.SetBitNumber(id, true);
252#if 0
5ca83fee 253 for (i = 0; i < fExtraDead.GetSize(); i++) {
254 Int_t j = fExtraDead.At(i);
255 if (j == id) return; // Already there
256 if (j < 0) break; // Free slot
257 }
258 if (i >= fExtraDead.GetSize()) {
259 Warning("AddDead", "No free slot to add FMD%d%c[%02d,%03d] at",
260 d, r, s, t);
261 return;
262 }
263 fExtraDead[i] = id;
1f7aa5c7 264#endif
5ca83fee 265}
266//____________________________________________________________________
267void
268AliFMDSharingFilter::AddDeadRegion(UShort_t d, Char_t r,
269 UShort_t s1, UShort_t s2,
270 UShort_t t1, UShort_t t2)
271{
272 // Add a dead region spanning from FMD<d><r>[<s1>,<t1>] to
273 // FMD<d><r>[<s2>,<t2>] (both inclusive)
274 for (Int_t s = s1; s <= s2; s++)
275 for (Int_t t = t1; t <= t2; t++)
276 AddDead(d, r, s, t);
277}
bfab35d9 278//____________________________________________________________________
279void
280AliFMDSharingFilter::AddDead(const Char_t* script)
281{
282 if (!script || script[0] == '\0') return;
283
284 gROOT->Macro(Form("%s((AliFMDSharingFilter*)%p);", script, this));
285}
286
5ca83fee 287//____________________________________________________________________
288Bool_t
289AliFMDSharingFilter::IsDead(UShort_t d, Char_t r, UShort_t s, UShort_t t) const
290{
291 Int_t id = AliFMDStripIndex::Pack(d, r, s, t);
1f7aa5c7 292 return fXtraDead.TestBitNumber(id);
293#if 0
5ca83fee 294 for (Int_t i = 0; i < fExtraDead.GetSize(); i++) {
295 Int_t j = fExtraDead.At(i);
296 if (j == id) {
297 //Info("IsDead", "FMD%d%c[%02d,%03d] marked as dead here", d, r, s, t);
298 return true;
299 }
300 if (j < 0) break; // High water mark
301 }
302 return false;
1f7aa5c7 303#endif
5ca83fee 304}
5bb5d1f6 305//____________________________________________________________________
306void
5934a3e3 307AliFMDSharingFilter::SetupForData(const TAxis& axis)
5bb5d1f6 308{
5934a3e3 309 // Initialise - called on first event
6ab100ec 310 DGUARD(fDebug,1, "Initialize for AliFMDSharingFilter");
5c1012c1 311 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
8449e3e0 312 const AliFMDCorrELossFit* fits = fcm.GetELossFit();
1f7aa5c7 313
314 // Compactify the xtra dead bits
315 fXtraDead.Compact();
316
5bb5d1f6 317 // Get the high cut. The high cut is defined as the
318 // most-probably-value peak found from the energy distributions, minus
319 // 2 times the width of the corresponding Landau.
4077f3e8 320
a76fb27d 321 TAxis eAxis(axis.GetNbins(),
322 axis.GetXmin(),
323 axis.GetXmax());
5c1012c1 324 if(fits)
325 eAxis.Set(fits->GetEtaAxis().GetNbins(),
326 fits->GetEtaAxis().GetXmin(),
327 fits->GetEtaAxis().GetXmax());
5bb5d1f6 328
5c1012c1 329 UShort_t nEta = eAxis.GetNbins();
4077f3e8 330
5bb5d1f6 331 fHighCuts->SetBins(nEta, eAxis.GetXmin(), eAxis.GetXmax(), 5, .5, 5.5);
332 fHighCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
333 fHighCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
334 fHighCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
335 fHighCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
336 fHighCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
337
d2638bb7 338 fLowCuts->SetBins(nEta, eAxis.GetXmin(), eAxis.GetXmax(), 5, .5, 5.5);
339 fLowCuts->GetYaxis()->SetBinLabel(1, "FMD1i");
340 fLowCuts->GetYaxis()->SetBinLabel(2, "FMD2i");
341 fLowCuts->GetYaxis()->SetBinLabel(3, "FMD2o");
342 fLowCuts->GetYaxis()->SetBinLabel(4, "FMD3i");
343 fLowCuts->GetYaxis()->SetBinLabel(5, "FMD3o");
344
5bb5d1f6 345 UShort_t ybin = 0;
346 for (UShort_t d = 1; d <= 3; d++) {
347 UShort_t nr = (d == 1 ? 1 : 2);
348 for (UShort_t q = 0; q < nr; q++) {
349 Char_t r = (q == 0 ? 'I' : 'O');
350 ybin++;
351 for (UShort_t e = 1; e <= nEta; e++) {
352 Double_t eta = eAxis.GetBinCenter(e);
4077f3e8 353
58ebb4bf 354 if (fDebug > 3) fHCuts.Print();
355
d2638bb7 356 Double_t hcut = GetHighCut(d, r, eta, false);
357 Double_t lcut = GetLowCut(d, r, eta);
4077f3e8 358
d2638bb7 359 if (hcut > 0) fHighCuts->SetBinContent(e, ybin, hcut);
360 if (lcut > 0) fLowCuts ->SetBinContent(e, ybin, lcut);
5bb5d1f6 361 }
362 }
363 }
364}
365
7e4038b5 366//____________________________________________________________________
1f7aa5c7 367#define ETA2COS(ETA) \
241cca4d 368 TMath::Cos(2*TMath::ATan(TMath::Exp(-TMath::Abs(ETA))))
369
7e4038b5 370Bool_t
371AliFMDSharingFilter::Filter(const AliESDFMD& input,
8449e3e0 372 Bool_t /*lowFlux*/,
6f4a5c0d 373 AliESDFMD& output,
374 Double_t zvtx)
7e4038b5 375{
7984e5f7 376 //
377 // Filter the input AliESDFMD object
378 //
379 // Parameters:
380 // input Input
381 // lowFlux If this is a low-flux event
382 // output Output AliESDFMD object
383 //
384 // Return:
385 // True on success, false otherwise
386 //
6ab100ec 387 DGUARD(fDebug,1, "Filter event in AliFMDSharingFilter");
7e4038b5 388 output.Clear();
389 TIter next(&fRingHistos);
0bd4b00f 390 RingHistos* o = 0;
8449e3e0 391 while ((o = static_cast<RingHistos*>(next()))) o->Clear();
392
241cca4d 393 Int_t nSingle = 0;
394 Int_t nDouble = 0;
395 Int_t nTriple = 0;
7e4038b5 396
397 for(UShort_t d = 1; d <= 3; d++) {
398 Int_t nRings = (d == 1 ? 1 : 2);
399 for (UShort_t q = 0; q < nRings; q++) {
5bb5d1f6 400 Char_t r = (q == 0 ? 'I' : 'O');
401 UShort_t nsec = (q == 0 ? 20 : 40);
402 UShort_t nstr = (q == 0 ? 512 : 256);
7e4038b5 403 RingHistos* histos = GetRingHistos(d, r);
404
8449e3e0 405 for(UShort_t s = 0; s < nsec; s++) {
406 // `used' flags if the _current_ strip was used by _previous_
407 // iteration.
241cca4d 408 Bool_t used = kFALSE;
8449e3e0 409 // `eTotal' contains the current sum of merged signals so far
241cca4d 410 Double_t eTotal = -1;
8449e3e0 411 // Int_t nDistanceBefore = -1;
412 // Int_t nDistanceAfter = -1;
413 // `twoLow' flags if we saw two consequtive strips with a
414 // signal between the two cuts.
415 Bool_t twoLow = kFALSE;
7e4038b5 416 for(UShort_t t = 0; t < nstr; t++) {
8449e3e0 417 // nDistanceBefore++;
418 // nDistanceAfter++;
7f1cfdfd 419
7e4038b5 420 output.SetMultiplicity(d,r,s,t,0.);
241cca4d 421 Float_t mult = SignalInStrip(input,d,r,s,t);
422 Float_t multNext = (t<nstr-1) ? SignalInStrip(input,d,r,s,t+1) :0;
423 Float_t multNextNext = (t<nstr-2) ? SignalInStrip(input,d,r,s,t+2) :0;
424 if (multNext == AliESDFMD::kInvalidMult) multNext = 0;
425 if (multNextNext == AliESDFMD::kInvalidMult) multNextNext = 0;
9223d782 426 if(!fThreeStripSharing) multNextNext = 0;
241cca4d 427
5bb5d1f6 428 // Get the pseudo-rapidity
429 Double_t eta = input.Eta(d,r,s,t);
430 Double_t phi = input.Phi(d,r,s,t) * TMath::Pi() / 180.;
431 if (s == 0) output.SetEta(d,r,s,t,eta);
7e4038b5 432
6f4a5c0d 433 if(fRecalculateEta) {
241cca4d 434 Double_t etaOld = eta;
435 Double_t etaCalc = AliForwardUtil::GetEtaFromStrip(d,r,s,t,zvtx);
436 eta = etaCalc;
6f4a5c0d 437
241cca4d 438 if (mult > 0 && mult != AliESDFMD::kInvalidMult ) {
439 Double_t cosOld = ETA2COS(etaOld);
440 Double_t cosNew = ETA2COS(etaCalc);
441 Double_t corr = cosNew / cosOld;
442 mult *= corr;
443 multNext *= corr;
444 multNextNext *= corr;
445 }
6f4a5c0d 446 }
8449e3e0 447
448 // Special case for pre revision 43611 AliFMDReconstructor.
449 // If fInvalidIsEmpty and we get an invalid signal from the
450 // ESD, then we need to set this signal to zero. Note, dead
451 // strips added in the ForwardAODConfig.C file are not
452 // effected by this, and we can use that to set the proper
453 // dead strips.
454 if (mult == AliESDFMD::kInvalidMult && fInvalidIsEmpty)
455 mult = 0;
456
457 // Keep dead-channel information - either from the ESD (but
458 // see above for older data) or from the settings in the
459 // ForwardAODConfig.C file.
460 if (mult == AliESDFMD::kInvalidMult || IsDead(d,r,s,t)) {
7e4038b5 461 output.SetMultiplicity(d,r,s,t,AliESDFMD::kInvalidMult);
8449e3e0 462 histos->fBefore->Fill(-1);
762754c0 463 mult = AliESDFMD::kInvalidMult;
464 }
7b212e49 465
7e4038b5 466 // If no signal or dead strip, go on.
5bb5d1f6 467 if (mult == AliESDFMD::kInvalidMult || mult == 0) {
468 if (mult == 0) histos->fSum->Fill(eta,phi,mult);
8449e3e0 469 // Flush a possible signal
470 if (eTotal > 0 && t > 0)
471 output.SetMultiplicity(d,r,s,t-1,eTotal);
472 // Reset states so we do not try to merge over a dead strip.
473 eTotal = -1;
474 used = false;
475 twoLow = false;
5bb5d1f6 476 continue;
477 }
7e4038b5 478
7e4038b5 479 // Fill the diagnostics histogram
480 histos->fBefore->Fill(mult);
7e4038b5 481
7b212e49 482 Double_t mergedEnergy = 0;
483
8449e3e0 484 // The current sum
485 Float_t etot = 0;
486
487 // Fill in neighbor information
488 if (t < nstr-1) histos->fNeighborsBefore->Fill(mult,multNext);
489
490 Bool_t thisValid = mult > GetLowCut(d, r, eta);
491 Bool_t nextValid = multNext > GetLowCut(d, r, eta);
492 Bool_t thisSmall = mult < GetHighCut(d, r, eta ,false);
493 Bool_t nextSmall = multNext < GetHighCut(d, r, eta ,false);
494
495 // If this strips signal is above the high cut, reset distance
496 // if (!thisSmall) {
497 // histos->fDistanceBefore->Fill(nDistanceBefore);
498 // nDistanceBefore = -1;
499 // }
500
501 // If the total signal in the past 1 or 2 strips are non-zero
502 // we need to check
503 if (eTotal > 0) {
504 // Here, we have already flagged one strip as a candidate
7b212e49 505
8449e3e0 506 // If 3-strip merging is enabled, then check the next
507 // strip to see that it falls within cut, or if we have
508 // two low signals
509 if (fThreeStripSharing && nextValid && (nextSmall || twoLow)) {
510 eTotal = eTotal + multNext;
511 used = kTRUE;
512 histos->fTriple->Fill(eTotal);
513 nTriple++;
514 twoLow = kFALSE;
7b212e49 515 }
8449e3e0 516 // Otherwise, we got a double hit before, and that
517 // should be stored.
b0036461 518 else {
8449e3e0 519 used = kFALSE;
520 histos->fDouble->Fill(eTotal);
521 nDouble++;
522 }
523 // Store energy loss and reset sum
524 etot = eTotal;
525 eTotal = -1;
526 } // if (eTotal>0)
527 else {
528 // If we have no current sum
529
530 // Check if this is marked as used, and if so, continue
531 if (used) {used = kFALSE; continue; }
532
533 // If the signal is abvoe the cut, set current
534 if (thisValid) etot = mult;
535
536 // If the signal is abiove the cut, and so is the next
537 // signal and either of them are below the high cut,
538 if (thisValid && nextValid && (thisSmall || nextSmall)) {
539
540 // If this is below the high cut, and the next is too, then
541 // we have two low signals
542 if (thisSmall && nextSmall) twoLow = kTRUE;
b0036461 543
8449e3e0 544 // If this signal is bigger than the next, and the
545 // one after that is below the low-cut, then update
546 // the sum
547 if (mult>multNext && multNextNext < GetLowCut(d, r, eta)) {
548 etot = mult + multNext;
549 used = kTRUE;
550 histos->fDouble->Fill(etot);
551 nDouble++;
b0036461 552 }
8449e3e0 553 // Otherwise, we may need to merge with a third strip
f26a8959 554 else {
8449e3e0 555 etot = 0;
556 eTotal = mult + multNext;
f26a8959 557 }
b0036461 558 }
8449e3e0 559 // This is a signle hit
560 else if(etot > 0) {
561 histos->fSingle->Fill(etot);
562 histos->fSinglePerStrip->Fill(etot,t);
563 nSingle++;
7b212e49 564 }
8449e3e0 565 } // else if (etotal >= 0)
566
567 mergedEnergy = etot;
568 // if (mergedEnergy > GetHighCut(d, r, eta ,false)) {
569 // histos->fDistanceAfter->Fill(nDistanceAfter);
570 // nDistanceAfter = -1;
571 // }
572 //if(mult>0 && multNext >0)
573 // std::cout<<mult<<" "<<multNext<<" "<<mergedEnergy<<std::endl;
574
5bb5d1f6 575 if (!fCorrectAngles)
576 mergedEnergy = AngleCorrect(mergedEnergy, eta);
8449e3e0 577 // if (mergedEnergy > 0) histos->Incr();
7b212e49 578
5bb5d1f6 579 if (t != 0)
580 histos->fNeighborsAfter->Fill(output.Multiplicity(d,r,s,t-1),
581 mergedEnergy);
582 histos->fBeforeAfter->Fill(mult, mergedEnergy);
f26a8959 583 if(mergedEnergy > 0)
584 histos->fAfter->Fill(mergedEnergy);
5bb5d1f6 585 histos->fSum->Fill(eta,phi,mergedEnergy);
7b212e49 586
7e4038b5 587 output.SetMultiplicity(d,r,s,t,mergedEnergy);
7e4038b5 588 } // for strip
589 } // for sector
590 } // for ring
591 } // for detector
241cca4d 592 DMSG(fDebug, 3,"single=%9d, double=%9d, triple=%9d",
593 nSingle, nDouble, nTriple);
7e4038b5 594 next.Reset();
8449e3e0 595 // while ((o = static_cast<RingHistos*>(next()))) o->Finish();
7e4038b5 596
597 return kTRUE;
598}
599
600//_____________________________________________________________________
601Double_t
602AliFMDSharingFilter::SignalInStrip(const AliESDFMD& input,
603 UShort_t d,
604 Char_t r,
605 UShort_t s,
606 UShort_t t) const
607{
7984e5f7 608 //
609 // Get the signal in a strip
610 //
611 // Parameters:
612 // fmd ESD object
613 // d Detector
614 // r Ring
615 // s Sector
616 // t Strip
617 //
618 // Return:
619 // The energy signal
620 //
7e4038b5 621 Double_t mult = input.Multiplicity(d,r,s,t);
5bb5d1f6 622 // In case of
623 // - bad value (invalid or 0)
624 // - we want angle corrected and data is
625 // - we don't want angle corrected and data isn't
626 // just return read value
627 if (mult == AliESDFMD::kInvalidMult ||
628 mult == 0 ||
629 (fCorrectAngles && input.IsAngleCorrected()) ||
630 (!fCorrectAngles && !input.IsAngleCorrected()))
631 return mult;
632
633 // If we want angle corrected data, correct it,
634 // otherwise de-correct it
635 if (fCorrectAngles) mult = AngleCorrect(mult, input.Eta(d,r,s,t));
636 else mult = DeAngleCorrect(mult, input.Eta(d,r,s,t));
7e4038b5 637 return mult;
638}
0bd4b00f 639//_____________________________________________________________________
640Double_t
d2638bb7 641AliFMDSharingFilter::GetLowCut(UShort_t d, Char_t r, Double_t eta) const
0bd4b00f 642{
7984e5f7 643 //
644 // Get the low cut. Normally, the low cut is taken to be the lower
645 // value of the fit range used when generating the energy loss fits.
646 // However, if fLowCut is set (using SetLowCit) to a value greater
647 // than 0, then that value is used.
648 //
d2638bb7 649 return fLCuts.GetMultCut(d,r,eta,false);
0bd4b00f 650}
7e4038b5 651
652//_____________________________________________________________________
653Double_t
5bb5d1f6 654AliFMDSharingFilter::GetHighCut(UShort_t d, Char_t r,
655 Double_t eta, Bool_t errors) const
7e4038b5 656{
7984e5f7 657 //
658 // Get the high cut. The high cut is defined as the
659 // most-probably-value peak found from the energy distributions, minus
660 // 2 times the width of the corresponding Landau.
661 //
d2638bb7 662 return fHCuts.GetMultCut(d,r,eta,errors);
5bb5d1f6 663}
664
7e4038b5 665//____________________________________________________________________
666Double_t
667AliFMDSharingFilter::AngleCorrect(Double_t mult, Double_t eta) const
668{
7984e5f7 669 //
670 // Angle correct the signal
671 //
672 // Parameters:
673 // mult Angle Un-corrected Signal
674 // eta Pseudo-rapidity
675 //
676 // Return:
677 // Angle corrected signal
678 //
7e4038b5 679 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
680 if (eta < 0) theta -= TMath::Pi();
681 return mult * TMath::Cos(theta);
682}
683//____________________________________________________________________
684Double_t
685AliFMDSharingFilter::DeAngleCorrect(Double_t mult, Double_t eta) const
686{
7984e5f7 687 //
688 // Angle de-correct the signal
689 //
690 // Parameters:
691 // mult Angle corrected Signal
692 // eta Pseudo-rapidity
693 //
694 // Return:
695 // Angle un-corrected signal
696 //
7e4038b5 697 Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
698 if (eta < 0) theta -= TMath::Pi();
699 return mult / TMath::Cos(theta);
700}
701
702//____________________________________________________________________
703void
5934a3e3 704AliFMDSharingFilter::Terminate(const TList* dir, TList* output, Int_t nEvents)
7e4038b5 705{
7984e5f7 706 //
707 // Scale the histograms to the total number of events
708 //
709 // Parameters:
710 // dir Where the output is
711 // nEvents Number of events
712 //
6ab100ec 713 DGUARD(fDebug,1, "Scale histograms in AliFMDSharingFilter");
7e4038b5 714 if (nEvents <= 0) return;
9d99b0dd 715 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
716 if (!d) return;
7e4038b5 717
5934a3e3 718 TList* out = new TList;
719 out->SetName(d->GetName());
720 out->SetOwner();
bfab35d9 721
722 TParameter<int>* nFiles =
bc31b177 723 static_cast<TParameter<int>*>(d->FindObject("nFiles"));
bfab35d9 724
bc31b177 725 TH2* lowCuts = static_cast<TH2*>(d->FindObject("lowCuts"));
726 TH2* highCuts = static_cast<TH2*>(d->FindObject("highCuts"));
bfab35d9 727 if (lowCuts && nFiles) {
728 lowCuts->Scale(1. / nFiles->GetVal());
729 out->Add(lowCuts->Clone());
730 }
731 else
732 AliWarning("low cuts histogram not found in input list");
733 if (highCuts && nFiles) {
734 highCuts->Scale(1. / nFiles->GetVal());
735 out->Add(highCuts->Clone());
736 }
737 else
738 AliWarning("high cuts histogram not found in input list");
5934a3e3 739
7e4038b5 740 TIter next(&fRingHistos);
741 RingHistos* o = 0;
5bb5d1f6 742 THStack* sums = new THStack("sums", "Sum of ring signals");
743 while ((o = static_cast<RingHistos*>(next()))) {
5934a3e3 744 o->Terminate(d, nEvents);
745 if (!o->fSum) {
746 Warning("Terminate", "No sum histogram found for ring %s", o->GetName());
747 continue;
748 }
5bb5d1f6 749 TH1D* sum = o->fSum->ProjectionX(o->GetName(), 1, o->fSum->GetNbinsY(),"e");
750 sum->Scale(1., "width");
751 sum->SetTitle(o->GetName());
752 sum->SetDirectory(0);
753 sum->SetYTitle("#sum #Delta/#Delta_{mip}");
754 sums->Add(sum);
755 }
5934a3e3 756 out->Add(sums);
757 output->Add(out);
7e4038b5 758}
759
760//____________________________________________________________________
761void
5934a3e3 762AliFMDSharingFilter::CreateOutputObjects(TList* dir)
7e4038b5 763{
7984e5f7 764 //
765 // Define the output histograms. These are put in a sub list of the
766 // passed list. The histograms are merged before the parent task calls
767 // AliAnalysisTaskSE::Terminate
768 //
769 // Parameters:
770 // dir Directory to add to
771 //
6ab100ec 772 DGUARD(fDebug,1, "Define output in AliFMDSharingFilter");
7e4038b5 773 TList* d = new TList;
774 d->SetName(GetName());
775 dir->Add(d);
5bb5d1f6 776
8449e3e0 777#if 0
5bb5d1f6 778 fSummed = new TH2I("operations", "Strip operations",
779 kMergedInto, kNone-.5, kMergedInto+.5,
780 51201, -.5, 51200.5);
781 fSummed->SetXTitle("Operation");
782 fSummed->SetYTitle("# of strips");
783 fSummed->SetZTitle("Events");
784 fSummed->GetXaxis()->SetBinLabel(kNone, "None");
785 fSummed->GetXaxis()->SetBinLabel(kCandidate, "Candidate");
786 fSummed->GetXaxis()->SetBinLabel(kMergedWithOther, "Merged w/other");
787 fSummed->GetXaxis()->SetBinLabel(kMergedInto, "Merged into");
788 fSummed->SetDirectory(0);
789 d->Add(fSummed);
8449e3e0 790#endif
5bb5d1f6 791
792 fHighCuts = new TH2D("highCuts", "High cuts used", 1,0,1, 1,0,1);
793 fHighCuts->SetXTitle("#eta");
794 fHighCuts->SetDirectory(0);
795 d->Add(fHighCuts);
796
d2638bb7 797 fLowCuts = new TH2D("lowCuts", "Low cuts used", 1,0,1, 1,0,1);
798 fLowCuts->SetXTitle("#eta");
799 fLowCuts->SetDirectory(0);
800 d->Add(fLowCuts);
801
d2638bb7 802 // d->Add(lowCut);
803 // d->Add(nXi);
804 // d->Add(sigma);
241cca4d 805 d->Add(AliForwardUtil::MakeParameter("angle", fCorrectAngles));
806 d->Add(AliForwardUtil::MakeParameter("lowSignal",
807 fZeroSharedHitsBelowThreshold));
808 d->Add(AliForwardUtil::MakeParameter("simple", fUseSimpleMerging));
bfab35d9 809 d->Add(AliForwardUtil::MakeParameter("sumThree", fThreeStripSharing));
810 TParameter<int>* nFiles = new TParameter<int>("nFiles", 1);
811 nFiles->SetMergeMode('+');
812 d->Add(nFiles);
5ca83fee 813
814 TObjArray* extraDead = new TObjArray;
815 extraDead->SetOwner();
816 extraDead->SetName("extraDead");
1f7aa5c7 817#if 0
5ca83fee 818 for (Int_t i = 0; i < fExtraDead.GetSize(); i++) {
819 if (fExtraDead.At(i) < 0) break;
820 UShort_t dd, s, t;
821 Char_t r;
822 Int_t id = fExtraDead.At(i);
823 AliFMDStripIndex::Unpack(id, dd, r, s, t);
824 extraDead->Add(AliForwardUtil::MakeParameter(Form("FMD%d%c[%02d,%03d]",
825 dd, r, s, t), id));
826 }
1f7aa5c7 827#endif
828 fXtraDead.Compact();
829 UInt_t firstBit = fXtraDead.FirstSetBit();
830 UInt_t nBits = fXtraDead.GetNbits();
831 for (UInt_t i = firstBit; i < nBits; i++) {
832 if (!fXtraDead.TestBitNumber(i)) continue;
833 UShort_t dd, s, t;
834 Char_t r;
835 AliFMDStripIndex::Unpack(i, dd, r, s, t);
836 extraDead->Add(AliForwardUtil::MakeParameter(Form("FMD%d%c[%02d,%03d]",
837 dd, r, s, t),
838 UShort_t(i)));
839 }
840 // d->Add(&fXtraDead);
5ca83fee 841 d->Add(extraDead);
d2638bb7 842 fLCuts.Output(d,"lCuts");
843 fHCuts.Output(d,"hCuts");
5bb5d1f6 844
7e4038b5 845 TIter next(&fRingHistos);
846 RingHistos* o = 0;
847 while ((o = static_cast<RingHistos*>(next()))) {
5934a3e3 848 o->CreateOutputObjects(d);
7e4038b5 849 }
850}
0bd4b00f 851//____________________________________________________________________
852void
853AliFMDSharingFilter::Print(Option_t* /*option*/) const
854{
7984e5f7 855 //
856 // Print information
857 //
858 // Parameters:
859 // option Not used
860 //
0bd4b00f 861 char ind[gROOT->GetDirLevel()+1];
862 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
863 ind[gROOT->GetDirLevel()] = '\0';
1f480471 864 std::cout << ind << ClassName() << ": " << GetName() << '\n'
5bb5d1f6 865 << std::boolalpha
866 << ind << " Debug: " << fDebug << "\n"
f7cfc454 867 << ind << " Use corrected angles: " << fCorrectAngles << '\n'
868 << ind << " Zero below threshold: "
7b212e49 869 << fZeroSharedHitsBelowThreshold << '\n'
1f7aa5c7 870 << ind << " Use simple sharing: " << fUseSimpleMerging << '\n'
8449e3e0 871 << ind << " Consider invalid null: " << fInvalidIsEmpty << '\n'
bfab35d9 872 << ind << " Allow 3 strip merging: " << fThreeStripSharing
5bb5d1f6 873 << std::noboolalpha << std::endl;
d2638bb7 874 std::cout << ind << " Low cuts: " << std::endl;
875 fLCuts.Print();
876 std::cout << ind << " High cuts: " << std::endl;
877 fHCuts.Print();
0bd4b00f 878}
7e4038b5 879
880//====================================================================
881AliFMDSharingFilter::RingHistos::RingHistos()
9d99b0dd 882 : AliForwardUtil::RingHistos(),
7e4038b5 883 fBefore(0),
884 fAfter(0),
f26a8959 885 fSingle(0),
886 fDouble(0),
887 fTriple(0),
888 fSinglePerStrip(0),
8449e3e0 889 // fDistanceBefore(0),
890 // fDistanceAfter(0),
5bb5d1f6 891 fBeforeAfter(0),
892 fNeighborsBefore(0),
893 fNeighborsAfter(0),
8449e3e0 894 fSum(0) // ,
895 // fHits(0),
896 // fNHits(0)
7984e5f7 897{
898 //
899 // Default CTOR
900 //
901
902}
7e4038b5 903
904//____________________________________________________________________
905AliFMDSharingFilter::RingHistos::RingHistos(UShort_t d, Char_t r)
9d99b0dd 906 : AliForwardUtil::RingHistos(d,r),
7e4038b5 907 fBefore(0),
908 fAfter(0),
f26a8959 909 fSingle(0),
910 fDouble(0),
911 fTriple(0),
912 fSinglePerStrip(0),
8449e3e0 913 // fDistanceBefore(0),
914 // fDistanceAfter(0),
5bb5d1f6 915 fBeforeAfter(0),
916 fNeighborsBefore(0),
917 fNeighborsAfter(0),
8449e3e0 918 fSum(0) //,
919 // fHits(0),
920 // fNHits(0)
7e4038b5 921{
7984e5f7 922 //
923 // Constructor
924 //
925 // Parameters:
926 // d detector
927 // r ring
928 //
9b2f2e39 929 fBefore = new TH1D("esdEloss", Form("Energy loss in %s (reconstruction)",
8449e3e0 930 GetName()), 640, -1, 15);
7e4038b5 931 fBefore->SetXTitle("#Delta E/#Delta E_{mip}");
932 fBefore->SetYTitle("P(#Delta E/#Delta E_{mip})");
5bb5d1f6 933 fBefore->SetFillColor(Color());
7e4038b5 934 fBefore->SetFillStyle(3001);
f7cfc454 935 fBefore->SetLineColor(kBlack);
936 fBefore->SetLineStyle(2);
7e4038b5 937 fBefore->SetDirectory(0);
5bb5d1f6 938
939 fAfter = static_cast<TH1D*>(fBefore->Clone("anaEloss"));
9b2f2e39 940 fAfter->SetTitle(Form("Energy loss in %s (sharing corrected)", GetName()));
5bb5d1f6 941 fAfter->SetFillColor(Color()+2);
f7cfc454 942 fAfter->SetLineStyle(1);
7e4038b5 943 fAfter->SetDirectory(0);
f26a8959 944
945 fSingle = new TH1D("singleEloss", "Energy loss (single strips)",
946 600, 0, 15);
9b2f2e39 947 fSingle->SetXTitle("#Delta/#Delta_{mip}");
948 fSingle->SetYTitle("P(#Delta/#Delta_{mip})");
949 fSingle->SetFillColor(Color());
f26a8959 950 fSingle->SetFillStyle(3001);
951 fSingle->SetLineColor(kBlack);
952 fSingle->SetLineStyle(2);
953 fSingle->SetDirectory(0);
954
9b2f2e39 955 fDouble = static_cast<TH1D*>(fSingle->Clone("doubleEloss"));
956 fDouble->SetTitle("Energy loss (two strips)");
957 fDouble->SetFillColor(Color()+1);
f26a8959 958 fDouble->SetDirectory(0);
9b2f2e39 959
960 fTriple = static_cast<TH1D*>(fSingle->Clone("tripleEloss"));
961 fTriple->SetTitle("Energy loss (three strips)");
962 fTriple->SetFillColor(Color()+2);
f26a8959 963 fTriple->SetDirectory(0);
964
965 //Int_t nBinsForInner = (r == 'I' ? 32 : 16);
966 Int_t nBinsForInner = (r == 'I' ? 512 : 256);
967 Int_t nStrips = (r == 'I' ? 512 : 256);
968
969 fSinglePerStrip = new TH2D("singlePerStrip", "SinglePerStrip",
970 600,0,15, nBinsForInner,0,nStrips);
9b2f2e39 971 fSinglePerStrip->SetXTitle("#Delta/#Delta_{mip}");
972 fSinglePerStrip->SetYTitle("Strip #");
f26a8959 973 fSinglePerStrip->SetZTitle("Counts");
974 fSinglePerStrip->SetDirectory(0);
7e4038b5 975
8449e3e0 976#if 0
7f1cfdfd 977 fDistanceBefore = new TH1D("distanceBefore", "Distance before sharing",
9b2f2e39 978 nStrips , 0,nStrips );
7f1cfdfd 979 fDistanceBefore->SetXTitle("Distance");
980 fDistanceBefore->SetYTitle("Counts");
981 fDistanceBefore->SetFillColor(kGreen+2);
982 fDistanceBefore->SetFillStyle(3001);
983 fDistanceBefore->SetLineColor(kBlack);
984 fDistanceBefore->SetLineStyle(2);
985 fDistanceBefore->SetDirectory(0);
986
9b2f2e39 987 fDistanceAfter = static_cast<TH1D*>(fDistanceBefore->Clone("distanceAfter"));
988 fDistanceAfter->SetTitle("Distance after sharing");
7f1cfdfd 989 fDistanceAfter->SetFillColor(kGreen+1);
7f1cfdfd 990 fDistanceAfter->SetDirectory(0);
8449e3e0 991#endif
992
7f1cfdfd 993
f26a8959 994
5bb5d1f6 995 Double_t max = 15;
996 Double_t min = -1;
997 Int_t n = int((max-min) / (max / 300));
998 fBeforeAfter = new TH2D("beforeAfter", "Before and after correlation",
999 n, min, max, n, min, max);
1000 fBeforeAfter->SetXTitle("#Delta E/#Delta E_{mip} before");
1001 fBeforeAfter->SetYTitle("#Delta E/#Delta E_{mip} after");
1002 fBeforeAfter->SetZTitle("Correlation");
1003 fBeforeAfter->SetDirectory(0);
1004
1005 fNeighborsBefore = static_cast<TH2D*>(fBeforeAfter->Clone("neighborsBefore"));
f7cfc454 1006 fNeighborsBefore->SetTitle("Correlation of neighbors before");
5bb5d1f6 1007 fNeighborsBefore->SetXTitle("#Delta E_{i}/#Delta E_{mip}");
1008 fNeighborsBefore->SetYTitle("#Delta E_{i+1}/#Delta E_{mip}");
1009 fNeighborsBefore->SetDirectory(0);
1010
1011 fNeighborsAfter =
1012 static_cast<TH2D*>(fNeighborsBefore->Clone("neighborsAfter"));
1013 fNeighborsAfter->SetTitle("Correlation of neighbors after");
1014 fNeighborsAfter->SetDirectory(0);
1015
1016 fSum = new TH2D("summed", "Summed signal", 200, -4, 6,
1017 (fRing == 'I' || fRing == 'i' ? 20 : 40), 0, 2*TMath::Pi());
1018 fSum->SetDirectory(0);
1019 fSum->Sumw2();
1020 fSum->SetMarkerColor(Color());
1021 // fSum->SetFillColor(Color());
1022 fSum->SetXTitle("#eta");
1023 fSum->SetYTitle("#varphi [radians]");
1024 fSum->SetZTitle("#sum #Delta/#Delta_{mip}(#eta,#varphi) ");
8449e3e0 1025
1026#if 0
5bb5d1f6 1027 fHits = new TH1D("hits", "Number of hits", 200, 0, 200000);
7e4038b5 1028 fHits->SetDirectory(0);
1029 fHits->SetXTitle("# of hits");
1030 fHits->SetFillColor(kGreen+1);
8449e3e0 1031#endif
7e4038b5 1032}
1033//____________________________________________________________________
1034AliFMDSharingFilter::RingHistos::RingHistos(const RingHistos& o)
9d99b0dd 1035 : AliForwardUtil::RingHistos(o),
7e4038b5 1036 fBefore(o.fBefore),
1037 fAfter(o.fAfter),
f26a8959 1038 fSingle(o.fSingle),
1039 fDouble(o.fDouble),
1040 fTriple(o.fTriple),
1041 fSinglePerStrip(o.fSinglePerStrip),
8449e3e0 1042 // fDistanceBefore(o.fDistanceBefore),
1043 // fDistanceAfter(o.fDistanceAfter),
5bb5d1f6 1044 fBeforeAfter(o.fBeforeAfter),
1045 fNeighborsBefore(o.fNeighborsBefore),
1046 fNeighborsAfter(o.fNeighborsAfter),
8449e3e0 1047 fSum(o.fSum) //,
1048 // fHits(o.fHits),
1049 // fNHits(o.fNHits)
7984e5f7 1050{
1051 //
1052 // Copy constructor
1053 //
1054 // Parameters:
1055 // o Object to copy from
1056 //
1057}
7e4038b5 1058
1059//____________________________________________________________________
1060AliFMDSharingFilter::RingHistos&
1061AliFMDSharingFilter::RingHistos::operator=(const RingHistos& o)
1062{
7984e5f7 1063 //
1064 // Assignment operator
1065 //
1066 // Parameters:
1067 // o Object to assign from
1068 //
1069 // Return:
1070 // Reference to this
1071 //
d015ecfe 1072 if (&o == this) return *this;
9d99b0dd 1073 AliForwardUtil::RingHistos::operator=(o);
7e4038b5 1074 fDet = o.fDet;
1075 fRing = o.fRing;
1076
36ffcf83 1077 if (fBefore) delete fBefore;
1078 if (fAfter) delete fAfter;
1079 if (fSingle) delete fSingle;
1080 if (fDouble) delete fDouble;
1081 if (fTriple) delete fTriple;
f26a8959 1082 if (fSinglePerStrip) delete fSinglePerStrip;
8449e3e0 1083 // if (fDistanceBefore) delete fDistanceBefore;
1084 // if (fDistanceAfter) delete fDistanceAfter;
1085 // if (fHits) delete fHits;
7e4038b5 1086
f26a8959 1087
5bb5d1f6 1088 fBefore = static_cast<TH1D*>(o.fBefore->Clone());
1089 fAfter = static_cast<TH1D*>(o.fAfter->Clone());
f26a8959 1090 fSingle = static_cast<TH1D*>(o.fSingle->Clone());
1091 fDouble = static_cast<TH1D*>(o.fDouble->Clone());
1092 fTriple = static_cast<TH1D*>(o.fTriple->Clone());
1093 fSinglePerStrip = static_cast<TH2D*>(o.fSinglePerStrip->Clone());
8449e3e0 1094 // fDistanceBefore = static_cast<TH1D*>(o.fDistanceBefore->Clone());
1095 // fDistanceAfter = static_cast<TH1D*>(o.fDistanceAfter->Clone());
5bb5d1f6 1096 fBeforeAfter = static_cast<TH2D*>(o.fBeforeAfter->Clone());
1097 fNeighborsBefore = static_cast<TH2D*>(o.fNeighborsBefore->Clone());
1098 fNeighborsAfter = static_cast<TH2D*>(o.fNeighborsAfter->Clone());
8449e3e0 1099 // fHits = static_cast<TH1D*>(o.fHits->Clone());
5bb5d1f6 1100 fSum = static_cast<TH2D*>(o.fSum->Clone());
1101
7e4038b5 1102 return *this;
1103}
1104//____________________________________________________________________
1105AliFMDSharingFilter::RingHistos::~RingHistos()
1106{
7984e5f7 1107 //
1108 // Destructor
1109 //
7e4038b5 1110}
8449e3e0 1111#if 0
7e4038b5 1112//____________________________________________________________________
1113void
1114AliFMDSharingFilter::RingHistos::Finish()
1115{
7984e5f7 1116 //
1117 // Finish off
1118 //
1119 //
8449e3e0 1120 // fHits->Fill(fNHits);
7e4038b5 1121}
8449e3e0 1122#endif
9d99b0dd 1123//____________________________________________________________________
1124void
5934a3e3 1125AliFMDSharingFilter::RingHistos::Terminate(const TList* dir, Int_t nEvents)
9d99b0dd 1126{
7984e5f7 1127 //
1128 // Scale the histograms to the total number of events
1129 //
1130 // Parameters:
1131 // nEvents Number of events
1132 // dir Where the output is
1133 //
9d99b0dd 1134 TList* l = GetOutputList(dir);
1135 if (!l) return;
1136
f7cfc454 1137#if 0
1138 TH1D* before = static_cast<TH1D*>(l->FindObject("esdEloss"));
1139 TH1D* after = static_cast<TH1D*>(l->FindObject("anaEloss"));
9d99b0dd 1140 if (before) before->Scale(1./nEvents);
1141 if (after) after->Scale(1./nEvents);
f7cfc454 1142#endif
1143
1144 TH2D* summed = static_cast<TH2D*>(l->FindObject("summed"));
5bb5d1f6 1145 if (summed) summed->Scale(1./nEvents);
5934a3e3 1146 fSum = summed;
9d99b0dd 1147}
1148
7e4038b5 1149//____________________________________________________________________
1150void
5934a3e3 1151AliFMDSharingFilter::RingHistos::CreateOutputObjects(TList* dir)
7e4038b5 1152{
7984e5f7 1153 //
1154 // Make output
1155 //
1156 // Parameters:
1157 // dir where to store
1158 //
9d99b0dd 1159 TList* d = DefineOutputList(dir);
5bb5d1f6 1160
7e4038b5 1161 d->Add(fBefore);
1162 d->Add(fAfter);
f26a8959 1163 d->Add(fSingle);
1164 d->Add(fDouble);
1165 d->Add(fTriple);
1166 d->Add(fSinglePerStrip);
8449e3e0 1167 // d->Add(fDistanceBefore);
1168 // d->Add(fDistanceAfter);
5bb5d1f6 1169 d->Add(fBeforeAfter);
1170 d->Add(fNeighborsBefore);
1171 d->Add(fNeighborsAfter);
8449e3e0 1172 // d->Add(fHits);
5bb5d1f6 1173 d->Add(fSum);
bfab35d9 1174
1c8feb73 1175 // Removed to avoid doubly adding the list which destroys
1176 // the merging
1177 //dir->Add(d);
7e4038b5 1178}
1179
1180//____________________________________________________________________
1181//
1182// EOF
1183//