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 SetRecalculateEta(Bool_t use) { fRecalculateEta = use; }
168 * In case of a displaced vertices recalculate eta and angle correction
170 * @param use recalculate or not
173 void SetRecalculatePhi(Bool_t use) { fRecalculatePhi = use; }
175 * Set whether to use the phi acceptance correction.
177 * How the phi acceptance is used depends on the value passed.
178 * - 0: No phi acceptance
179 * - 1: Phi acceptance correction done to estimate of particles
180 * - 2: Phi acceptance correction done to energy deposited
182 * @param u If >0, use the phi acceptance (default is false)
185 void SetUsePhiAcceptance(UShort_t u=kPhiCorrectNch) { fUsePhiAcceptance = u; }
187 * Set the luming factors used in the Poisson method
189 * @param eta Must be 1 or larger
190 * @param phi Must be 1 or larger
192 void SetLumping(Int_t eta, Int_t phi) {
193 fEtaLumping = (eta < 1 ? 1 : eta);
194 fPhiLumping = (phi < 1 ? 1 : phi);
197 * Set the minimum quality of the energy loss fits
199 * @param cut Cut value
201 void SetMinQuality(UShort_t cut=10) { fMinQuality = cut; }
203 * Set the maximum ratio of outlier bins to the total number of bins
206 * @param ratio Maximum ratio (number between 0 and 1)
208 void SetMaxOutliers(Double_t ratio=0.10) { fMaxOutliers = ratio; }
210 * Set the maximum relative diviation between @f$N_{ch}^{Poisson}@f$
211 * and @f$N_{ch}^{\Delta}@f$
213 * @param cut Relative cut (number between 0 and 1)
215 void SetOutlierCut(Double_t cut=0.50) { fOutlierCut = cut; }
217 * Get the multiplicity cut. If the user has set fMultCut (via
218 * SetMultCut) then that value is used. If not, then the lower
219 * value of the fit range for the enery loss fits is returned.
223 * @param eta Psuedo-rapidity
224 * @param errors Factor in errors
226 * @return Lower cut on multiplicity
228 Double_t GetMultCut(UShort_t d, Char_t r, Double_t eta,
229 Bool_t errors=true) const;
231 * Get the multiplicity cut. If the user has set fMultCut (via
232 * SetMultCut) then that value is used. If not, then the lower
233 * value of the fit range for the enery loss fits is returned.
237 * @param ieta Psuedo-rapidity bin
238 * @param errors Factor in errors
240 * @return Lower cut on multiplicity
242 Double_t GetMultCut(UShort_t d, Char_t r, Int_t ieta,
243 Bool_t errors=true) const;
245 * Set the minimum quality of the energy loss fits
249 UShort_t GetMinQuality() const { return fMinQuality; }
253 * @param option Print options
254 * - max Print max weights
256 void Print(Option_t* option="") const;
260 * @return Reference to cuts object
262 AliFMDMultCuts& GetCuts() { return fCuts; }
264 * Set the cuts to use
266 * @param c Cuts to use
268 void SetCuts(const AliFMDMultCuts& c) { fCuts = c; }
271 * Find the max weight to use for FMD<i>dr</i> in eta bin @a iEta
273 * @param cor Correction
276 * @param iEta Eta bin
278 * @return The maximum weight
280 Int_t FindMaxWeight(const AliFMDCorrELossFit* cor,
281 UShort_t d, Char_t r, Int_t iEta) const;
284 * Find the max weights and cache them
286 * @param axis Default @f$\eta@f$ axis from parent task
288 void CacheMaxWeights(const TAxis& axis);
290 * Find the (cached) maximum weight for FMD<i>dr</i> in
291 * @f$\eta@f$ bin @a iEta
295 * @param iEta Eta bin
297 * @return max weight or <= 0 in case of problems
299 Int_t GetMaxWeight(UShort_t d, Char_t r, Int_t iEta) const;
301 * Find the (cached) maximum weight for FMD<i>dr</i> iat
308 * @return max weight or <= 0 in case of problems
310 Int_t GetMaxWeight(UShort_t d, Char_t r, Float_t eta) const;
313 * Get the number of particles corresponding to the signal mult
318 * @param eta Pseudo-rapidity
319 * @param lowFlux Low-flux flag
321 * @return The number of particles
323 virtual Float_t NParticles(Float_t mult,
327 Bool_t lowFlux) const;
329 * Get the inverse correction factor. This consist of
331 * - acceptance correction (corners of sensors)
332 * - double hit correction (for low-flux events)
333 * - dead strip correction
338 * @param eta Pseudo-rapidity
339 * @param lowFlux Low-flux flag
341 * @return the correction factor
343 virtual Float_t Correction(UShort_t d, Char_t r, UShort_t t,
344 Float_t eta, Bool_t lowFlux) const;
346 * Get the acceptance correction for strip @a t in an ring of type @a r
348 * @param r Ring type ('I' or 'O')
349 * @param t Strip number
351 * @return Inverse acceptance correction
353 virtual Float_t AcceptanceCorrection(Char_t r, UShort_t t) const;
355 * Generate the acceptance corrections
357 * @param r Ring to generate for
359 * @return Newly allocated histogram of acceptance corrections
361 virtual TH1D* GenerateAcceptanceCorrection(Char_t r) const;
363 * Check if, for a given region, whether this is an outlier
365 * The condition for an outlier event are
367 * |N_{ch}^{Poisson} - N_{ch}^{\Delta}| / N_{ch}^{\Delta} > c
370 * @param eloss @f$ N_{ch}^{\Delta}@f$ - number of charged particles
371 * @param poisson @f$ N_{ch}^{Poisson}@f$ - number of charged particles
372 * @param cut @f$ c@f$ - the cut
374 * @return true if the region reflects an outlier event
376 virtual Bool_t CheckOutlier(Double_t eloss,
378 Double_t cut=0.5) const;
380 * Internal data structure to keep track of the histograms
382 struct RingHistos : public AliForwardUtil::RingHistos
394 RingHistos(UShort_t d, Char_t r);
398 * @param o Object to copy from
400 RingHistos(const RingHistos& o);
402 * Assignment operator
404 * @param o Object to assign from
406 * @return Reference to this
408 RingHistos& operator=(const RingHistos& o);
414 * Initialize the object
418 void SetupForData(const TAxis& eAxis);
422 * @param dir Where to put it
424 void CreateOutputObjects(TList* dir);
426 * Scale the histograms to the total number of events
428 * @param dir Where the output is
429 * @param nEvents Number of events
431 void Terminate(TList* dir, Int_t nEvents);
433 // TH2D* fEvsN; // Correlation of Eloss vs uncorrected Nch
434 // TH2D* fEvsM; // Correlation of Eloss vs corrected Nch
435 // TProfile* fEtaVsN; // Average uncorrected Nch vs eta
436 // TProfile* fEtaVsM; // Average corrected Nch vs eta
437 TProfile* fCorr; // Average correction vs eta
438 TH2D* fDensity; // Distribution inclusive Nch
439 TH2D* fELossVsPoisson; // Correlation of energy loss vs Poisson N_ch
440 TH1D* fDiffELossPoisson;// Relative difference to Poisson
441 TH2D* fELossVsPoissonOut; // Correlation of energy loss vs Poisson N_ch
442 TH1D* fDiffELossPoissonOut;// Relative difference to Poisson
443 TH1D* fOutliers; // Fraction of outliers per event
444 AliPoissonCalculator fPoisson; // Calculate density using Poisson method
445 TH1D* fELoss; // Energy loss as seen by this
446 TH1D* fELossUsed; // Energy loss in strips with signal
447 Double_t fMultCut; // If set, use this
448 TH1D* fTotal; // Total number of strips per eta
449 TH1D* fGood; // Number of good strips per eta
450 TH2D* fPhiAcc; // Phi acceptance vs IpZ
451 TH1D* fPhiBefore; // Phi before re-calce
452 TH1D* fPhiAfter; // Phi after re-calc
453 ClassDef(RingHistos,10);
456 * Get the ring histogram container
461 * @return Ring histogram container
463 RingHistos* GetRingHistos(UShort_t d, Char_t r) const;
464 TList fRingHistos; // List of histogram containers
465 TH1D* fSumOfWeights; // Histogram
466 TH1D* fWeightedSum; // Histogram
467 TH1D* fCorrections; // Histogram
468 UShort_t fMaxParticles; // Maximum particle weight to use
469 Bool_t fUsePoisson; // If true, then use poisson statistics
470 UShort_t fUsePhiAcceptance; // Whether to correct for corners
471 TH1D* fAccI; // Acceptance correction for inner rings
472 TH1D* fAccO; // Acceptance correction for outer rings
473 TArrayI fFMD1iMax; // Array of max weights
474 TArrayI fFMD2iMax; // Array of max weights
475 TArrayI fFMD2oMax; // Array of max weights
476 TArrayI fFMD3iMax; // Array of max weights
477 TArrayI fFMD3oMax; // Array of max weights
478 TH2D* fMaxWeights; // Histogram of max weights
479 TH2D* fLowCuts; // Histogram of low cuts
480 Int_t fEtaLumping; // How to lump eta bins for Poisson
481 Int_t fPhiLumping; // How to lump phi bins for Poisson
482 Int_t fDebug; // Debug level
483 AliFMDMultCuts fCuts; // Cuts
484 Bool_t fRecalculateEta; // Whether to recalc eta and angle correction (disp vtx)
485 Bool_t fRecalculatePhi; // Whether to correct for (X,Y) offset
486 UShort_t fMinQuality; // Least quality for fits
487 AliForwardUtil::Histos fCache;
490 Double_t fMaxOutliers; // Maximum ratio of outlier bins
491 Double_t fOutlierCut; // Maximum relative diviation
493 ClassDef(AliFMDDensityCalculator,14); // Calculate Nch density