1 // This class calculates the inclusive charged particle density
2 // in each for the 5 FMD rings.
4 #ifndef ALIFMDDENSITYCALCULATOR_H
5 #define ALIFMDDENSITYCALCULATOR_H
7 * @file AliFMDDensityCalculator.h
8 * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
9 * @date Wed Mar 23 14:02:09 2011
14 * @ingroup pwglf_forward_aod
20 #include "AliForwardUtil.h"
21 #include "AliFMDMultCuts.h"
22 #include "AliPoissonCalculator.h"
27 class AliFMDCorrELossFit;
30 * This class calculates the inclusive charged particle density
31 * in each for the 5 FMD rings.
34 * - AliESDFMD object possibly corrected for sharing
37 * - 5 RingHistos objects - each with a number of vertex dependent
38 * 2D histograms of the inclusive charge particle density
40 * @par Corrections used:
41 * - AliFMDAnaCalibEnergyDistribution
42 * - AliFMDDoubleHitCorrection
43 * - AliFMDDeadCorrection
45 * @ingroup pwglf_forward_algo
46 * @ingroup pwglf_forward_aod
48 class AliFMDDensityCalculator : public TNamed
52 * How to correct for the missing phi coverage at the corners of the
59 /** Correct the calculated number charged particles */
61 /** Correct the energy loss */
67 static const char* fgkFolderName;
71 AliFMDDensityCalculator();
75 * @param name Name of object
77 AliFMDDensityCalculator(const char* name);
81 * @param o Object to copy from
83 AliFMDDensityCalculator(const AliFMDDensityCalculator& o);
87 virtual ~AliFMDDensityCalculator();
89 * Assignement operator
91 * @param o Object to assign from
93 * @return Reference to this object
95 AliFMDDensityCalculator& operator=(const AliFMDDensityCalculator& o);
97 * Initialize this sub-algorithm
99 * @param etaAxis Not used
101 virtual void SetupForData(const TAxis& etaAxis);
103 * Do the calculations
105 * @param fmd AliESDFMD object (possibly) corrected for sharing
106 * @param hists Histogram cache
107 * @param lowFlux Low flux flag.
108 * @param cent Centrality
109 * @param ip Coordinates of interaction point
111 * @return true on successs
113 virtual Bool_t Calculate(const AliESDFMD& fmd,
114 AliForwardUtil::Histos& hists,
117 const TVector3& ip=TVector3(1024,1024,0));
119 * Scale the histograms to the total number of events
121 * @param dir where to put the output
122 * @param output Output list
123 * @param nEvents Number of events
125 virtual void Terminate(const TList* dir, TList* output, Int_t nEvents);
127 * Output diagnostic histograms to directory
129 * @param dir List to write in
131 virtual void CreateOutputObjects(TList* dir);
133 * Set the debug level. The higher the value the more output
135 * @param dbg Debug level
137 void SetDebug(Int_t dbg=1) { fDebug = dbg; }
138 void SetDoTiming(Bool_t enable=true) { fDoTiming = enable; }
140 * Maximum particle weight to use
144 void SetMaxParticles(UShort_t m) { fMaxParticles = m; }
146 * Set whether to use poisson statistics to estimate the
147 * number of particles that has hit within a region. If this is true,
148 * then the average charge particle density is given by
150 * \lambda = -\log\left(\frac{N_e}{N_t}\right)
152 * where $N_e$ is the number of strips within the region that has no
153 * hits over threshold, and $N_t$ is the total number of strips in the
156 * @param u Whether to use poisson statistics to estimate the
157 * number of particles that has hit within a region.
159 void SetUsePoisson(Bool_t u) { fUsePoisson = u; }
161 * In case of a displaced vertices recalculate eta and angle correction
163 * @param use recalculate or not
166 void SetRecalculatePhi(Bool_t use) { fRecalculatePhi = use; }
168 * Set whether to use the phi acceptance correction.
170 * How the phi acceptance is used depends on the value passed.
171 * - 0: No phi acceptance
172 * - 1: Phi acceptance correction done to estimate of particles
173 * - 2: Phi acceptance correction done to energy deposited
175 * @param u If >0, use the phi acceptance (default is false)
178 void SetUsePhiAcceptance(UShort_t u=kPhiCorrectNch) { fUsePhiAcceptance = u; }
180 * Set the luming factors used in the Poisson method
182 * @param eta Must be 1 or larger
183 * @param phi Must be 1 or larger
185 void SetLumping(Int_t eta, Int_t phi) {
186 fEtaLumping = (eta < 1 ? 1 : eta);
187 fPhiLumping = (phi < 1 ? 1 : phi);
190 * Set the minimum quality of the energy loss fits
192 * @param cut Cut value
194 void SetMinQuality(UShort_t cut=10) { fMinQuality = cut; }
196 * Set the maximum ratio of outlier bins to the total number of bins
199 * @param ratio Maximum ratio (number between 0 and 1)
201 void SetMaxOutliers(Double_t ratio=0.10) { fMaxOutliers = ratio; }
203 * Set the maximum relative diviation between @f$N_{ch}^{Poisson}@f$
204 * and @f$N_{ch}^{\Delta}@f$
206 * @param cut Relative cut (number between 0 and 1)
208 void SetOutlierCut(Double_t cut=0.50) { fOutlierCut = cut; }
210 * Get the multiplicity cut. If the user has set fMultCut (via
211 * SetMultCut) then that value is used. If not, then the lower
212 * value of the fit range for the enery loss fits is returned.
216 * @param eta Psuedo-rapidity
217 * @param errors Factor in errors
219 * @return Lower cut on multiplicity
221 Double_t GetMultCut(UShort_t d, Char_t r, Double_t eta,
222 Bool_t errors=true) const;
224 * Get the multiplicity cut. If the user has set fMultCut (via
225 * SetMultCut) then that value is used. If not, then the lower
226 * value of the fit range for the enery loss fits is returned.
230 * @param ieta Psuedo-rapidity bin
231 * @param errors Factor in errors
233 * @return Lower cut on multiplicity
235 Double_t GetMultCut(UShort_t d, Char_t r, Int_t ieta,
236 Bool_t errors=true) const;
238 * Set the minimum quality of the energy loss fits
242 UShort_t GetMinQuality() const { return fMinQuality; }
246 * @param option Print options
247 * - max Print max weights
249 void Print(Option_t* option="") const;
253 * @return Reference to cuts object
255 AliFMDMultCuts& GetCuts() { return fCuts; }
257 * Set the cuts to use
259 * @param c Cuts to use
261 void SetCuts(const AliFMDMultCuts& c) { fCuts = c; }
264 * Find the max weight to use for FMD<i>dr</i> in eta bin @a iEta
266 * @param cor Correction
269 * @param iEta Eta bin
271 * @return The maximum weight
273 Int_t FindMaxWeight(const AliFMDCorrELossFit* cor,
274 UShort_t d, Char_t r, Int_t iEta) const;
277 * Find the max weight to use for FMD<i>dr</i> in eta @a eta
279 * @param cor Correction
284 * @return The maximum weight
286 Int_t FindMaxWeight(const AliFMDCorrELossFit* cor,
287 UShort_t d, Char_t r, Double_t iEta) const;
290 * Find the max weights and cache them
292 * @param axis Default @f$\eta@f$ axis from parent task
294 void CacheMaxWeights(const TAxis& axis);
296 * Find the (cached) maximum weight for FMD<i>dr</i> in
297 * @f$\eta@f$ bin @a iEta
301 * @param iEta Eta bin
303 * @return max weight or <= 0 in case of problems
305 Int_t GetMaxWeight(UShort_t d, Char_t r, Int_t iEta) const;
307 * Find the (cached) maximum weight for FMD<i>dr</i> iat
314 * @return max weight or <= 0 in case of problems
316 Int_t GetMaxWeight(UShort_t d, Char_t r, Float_t eta) const;
319 * Get the number of particles corresponding to the signal mult
324 * @param eta Pseudo-rapidity
325 * @param lowFlux Low-flux flag
327 * @return The number of particles
329 virtual Float_t NParticles(Float_t mult,
333 Bool_t lowFlux) const;
335 * Get the inverse correction factor. This consist of
337 * - acceptance correction (corners of sensors)
338 * - double hit correction (for low-flux events)
339 * - dead strip correction
344 * @param eta Pseudo-rapidity
345 * @param lowFlux Low-flux flag
347 * @return the correction factor
349 virtual Float_t Correction(UShort_t d, Char_t r, UShort_t t,
350 Float_t eta, Bool_t lowFlux) const;
352 * Get the acceptance correction for strip @a t in an ring of type @a r
354 * @param r Ring type ('I' or 'O')
355 * @param t Strip number
357 * @return Inverse acceptance correction
359 virtual Float_t AcceptanceCorrection(Char_t r, UShort_t t) const;
361 * Generate the acceptance corrections
363 * @param r Ring to generate for
365 * @return Newly allocated histogram of acceptance corrections
367 virtual TH1D* GenerateAcceptanceCorrection(Char_t r) const;
369 * Check if, for a given region, whether this is an outlier
371 * The condition for an outlier event are
373 * |N_{ch}^{Poisson} - N_{ch}^{\Delta}| / N_{ch}^{\Delta} > c
376 * @param eloss @f$ N_{ch}^{\Delta}@f$ - number of charged particles
377 * @param poisson @f$ N_{ch}^{Poisson}@f$ - number of charged particles
378 * @param cut @f$ c@f$ - the cut
380 * @return true if the region reflects an outlier event
382 virtual Bool_t CheckOutlier(Double_t eloss,
384 Double_t cut=0.5) const;
386 * Internal data structure to keep track of the histograms
388 struct RingHistos : public AliForwardUtil::RingHistos
400 RingHistos(UShort_t d, Char_t r);
404 * @param o Object to copy from
406 RingHistos(const RingHistos& o);
408 * Assignment operator
410 * @param o Object to assign from
412 * @return Reference to this
414 RingHistos& operator=(const RingHistos& o);
420 * Initialize the object
424 void SetupForData(const TAxis& eAxis);
428 * @param dir Where to put it
430 void CreateOutputObjects(TList* dir);
432 * Scale the histograms to the total number of events
434 * @param dir Where the output is
435 * @param nEvents Number of events
437 void Terminate(TList* dir, Int_t nEvents);
439 // TH2D* fEvsN; // Correlation of Eloss vs uncorrected Nch
440 // TH2D* fEvsM; // Correlation of Eloss vs corrected Nch
441 // TProfile* fEtaVsN; // Average uncorrected Nch vs eta
442 // TProfile* fEtaVsM; // Average corrected Nch vs eta
443 TProfile* fCorr; // Average correction vs eta
444 TH2D* fDensity; // Distribution inclusive Nch
445 TH2D* fELossVsPoisson; // Correlation of energy loss vs Poisson N_ch
446 TH1D* fDiffELossPoisson;// Relative difference to Poisson
447 TH2D* fELossVsPoissonOut; // Correlation of energy loss vs Poisson N_ch
448 TH1D* fDiffELossPoissonOut;// Relative difference to Poisson
449 TH1D* fOutliers; // Fraction of outliers per event
450 AliPoissonCalculator fPoisson; // Calculate density using Poisson method
451 TH1D* fELoss; // Energy loss as seen by this
452 TH1D* fELossUsed; // Energy loss in strips with signal
453 Double_t fMultCut; // If set, use this
454 TH1D* fTotal; // Total number of strips per eta
455 TH1D* fGood; // Number of good strips per eta
456 TH2D* fPhiAcc; // Phi acceptance vs IpZ
457 TH1D* fPhiBefore; // Phi before re-calce
458 TH1D* fPhiAfter; // Phi after re-calc
459 ClassDef(RingHistos,10);
462 * Get the ring histogram container
467 * @return Ring histogram container
469 RingHistos* GetRingHistos(UShort_t d, Char_t r) const;
470 TList fRingHistos; // List of histogram containers
471 TH1D* fSumOfWeights; // Histogram
472 TH1D* fWeightedSum; // Histogram
473 TH1D* fCorrections; // Histogram
474 UShort_t fMaxParticles; // Maximum particle weight to use
475 Bool_t fUsePoisson; // If true, then use poisson statistics
476 UShort_t fUsePhiAcceptance; // Whether to correct for corners
477 TH1D* fAccI; // Acceptance correction for inner rings
478 TH1D* fAccO; // Acceptance correction for outer rings
479 TArrayI fFMD1iMax; // Array of max weights
480 TArrayI fFMD2iMax; // Array of max weights
481 TArrayI fFMD2oMax; // Array of max weights
482 TArrayI fFMD3iMax; // Array of max weights
483 TArrayI fFMD3oMax; // Array of max weights
484 TH2D* fMaxWeights; // Histogram of max weights
485 TH2D* fLowCuts; // Histogram of low cuts
486 Int_t fEtaLumping; // How to lump eta bins for Poisson
487 Int_t fPhiLumping; // How to lump phi bins for Poisson
488 Int_t fDebug; // Debug level
489 AliFMDMultCuts fCuts; // Cuts
490 Bool_t fRecalculatePhi; // Whether to correct for (X,Y) offset
491 UShort_t fMinQuality; // Least quality for fits
492 AliForwardUtil::Histos fCache;
495 Double_t fMaxOutliers; // Maximum ratio of outlier bins
496 Double_t fOutlierCut; // Maximum relative diviation
498 ClassDef(AliFMDDensityCalculator,14); // Calculate Nch density