2 // Utilities used in the forward multiplcity analysis
5 #ifndef ALIFORWARDUTIL_H
6 #define ALIFORWARDUTIL_H
8 * @file AliForwardUtil.h
9 * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
10 * @date Wed Mar 23 14:06:54 2011
15 * @ingroup pwglf_forward
19 #include <TObjArray.h>
27 class AliAnalysisTaskSE;
30 * Utilities used in the forward multiplcity analysis
32 * @ingroup pwglf_forward
34 class AliForwardUtil : public TObject
38 * Get the standard color for a ring
45 static Color_t RingColor(UShort_t d, Char_t r)
47 return ((d == 1 ? kRed : (d == 2 ? kGreen : kBlue))
48 + ((r == 'I' || r == 'i') ? 2 : -3));
50 //==================================================================
53 * @name Collision/run parameters
56 * Defined collision types
58 enum ECollisionSystem {
64 //__________________________________________________________________
66 * Parse a collision system spec given in a string. Known values are
68 * - "pp", "p-p" which returns kPP
69 * - "PbPb", "Pb-Pb", "A-A", which returns kPbPb
70 * - "pPb", "p-Pb", "pA", p-A" which returns kPPb
71 * - Everything else gives kUnknown
73 * @param sys Collision system spec
75 * @return Collision system id
77 static UShort_t ParseCollisionSystem(const char* sys);
79 * Get a string representation of the collision system
81 * @param sys Collision system
85 * - anything else gives "unknown"
87 * @return String representation of the collision system
89 static const char* CollisionSystemString(UShort_t sys);
90 //__________________________________________________________________
92 * Parse the center of mass energy given as a float and return known
93 * values as a unsigned integer
95 * @param sys Collision system (needed for AA)
96 * @param cms Center of mass energy * total charge
98 * @return Center of mass energy per nucleon
100 static UShort_t ParseCenterOfMassEnergy(UShort_t sys, Float_t cms);
102 * Get a string representation of the center of mass energy per nuclean
104 * @param cms Center of mass energy per nucleon
106 * @return String representation of the center of mass energy per nuclean
108 static const char* CenterOfMassEnergyString(UShort_t cms);
109 //__________________________________________________________________
111 * Parse the magnetic field (in kG) as given by a floating point number
113 * @param field Magnetic field in kG
115 * @return Short integer value of magnetic field in kG
117 static Short_t ParseMagneticField(Float_t field);
121 * @param det, ring, sec, strip, zvtx
125 static Double_t GetEtaFromStrip(UShort_t det, Char_t ring, UShort_t sec, UShort_t strip, Double_t zvtx) ;
127 * Get a string representation of the magnetic field
129 * @param field Magnetic field in kG
131 * @return String representation of the magnetic field
133 static const char* MagneticFieldString(Short_t field);
136 //__________________________________________________________________
138 * Get the AOD event - either from the input (AOD analysis) or the
139 * output (ESD analysis)
141 * @param task Task to do the investigation for
143 * @return Found AOD event or null
145 static AliAODEvent* GetAODEvent(AliAnalysisTaskSE* task);
147 * Check if we have something that will provide and AOD event
149 * @return 0 if there's nothing that provide an AOD event, 1 if it
150 * is provided on the input (AOD analysis) or 2 if it is provided on
151 * the output (ESD analysis)
153 static UShort_t CheckForAOD();
155 * Check if we have a particular (kind) of task in our train
157 * @param clsOrName Class name or name of task
158 * @param cls If true, look for a task of a particular class -
159 * otherwise search for a speficially name task
161 * @return true if the needed task was found
163 static Bool_t CheckForTask(const char* clsOrName, Bool_t cls=true);
165 //__________________________________________________________________
168 * @name Member functions to store and retrieve analysis parameters
170 static TObject* MakeParameter(const char* name, UShort_t value);
171 static TObject* MakeParameter(const char* name, Int_t value);
172 static TObject* MakeParameter(const char* name, Double_t value);
173 static TObject* MakeParameter(const char* name, Bool_t value);
174 static void GetParameter(TObject* o, UShort_t& value);
175 static void GetParameter(TObject* o, Int_t& value);
176 static void GetParameter(TObject* o, Double_t& value);
177 static void GetParameter(TObject* o, Bool_t& value);
182 * @name Energy stragling functions
184 //__________________________________________________________________
186 * Number of steps to do in the Landau, Gaussiam convolution
188 static Int_t fgConvolutionSteps; // Number of convolution steps
189 //------------------------------------------------------------------
191 * How many sigma's of the Gaussian in the Landau, Gaussian
192 * convolution to integrate over
194 static Double_t fgConvolutionNSigma; // Number of convolution sigmas
195 //------------------------------------------------------------------
197 * Calculate the shifted Landau
199 * f'_{L}(x;\Delta,\xi) = f_L(x;\Delta+0.22278298\xi)
202 * where @f$ f_{L}@f$ is the ROOT implementation of the Landau
203 * distribution (known to have @f$ \Delta_{p}=-0.22278298@f$ for
204 * @f$\Delta=0,\xi=1@f$.
206 * @param x Where to evaluate @f$ f'_{L}@f$
207 * @param delta Most probable value
208 * @param xi The 'width' of the distribution
210 * @return @f$ f'_{L}(x;\Delta,\xi) @f$
212 static Double_t Landau(Double_t x, Double_t delta, Double_t xi);
214 //------------------------------------------------------------------
216 * Calculate the value of a Landau convolved with a Gaussian
219 * f(x;\Delta,\xi,\sigma') = \frac{1}{\sigma' \sqrt{2 \pi}}
220 * \int_{-\infty}^{+\infty} d\Delta' f'_{L}(x;\Delta',\xi)
221 * \exp{-\frac{(\Delta-\Delta')^2}{2\sigma'^2}}
224 * where @f$ f'_{L}@f$ is the Landau distribution, @f$ \Delta@f$ the
225 * energy loss, @f$ \xi@f$ the width of the Landau, and
226 * @f$ \sigma'^2=\sigma^2-\sigma_n^2 @f$. Here, @f$\sigma@f$ is the
227 * variance of the Gaussian, and @f$\sigma_n@f$ is a parameter modelling
228 * noise in the detector.
230 * Note that this function uses the constants fgConvolutionSteps and
231 * fgConvolutionNSigma
234 * - <a href="http://dx.doi.org/10.1016/0168-583X(84)90472-5">Nucl.Instrum.Meth.B1:16</a>
235 * - <a href="http://dx.doi.org/10.1103/PhysRevA.28.615">Phys.Rev.A28:615</a>
236 * - <a href="http://root.cern.ch/root/htmldoc/tutorials/fit/langaus.C.html">ROOT implementation</a>
238 * @param x where to evaluate @f$ f@f$
239 * @param delta @f$ \Delta@f$ of @f$ f(x;\Delta,\xi,\sigma')@f$
240 * @param xi @f$ \xi@f$ of @f$ f(x;\Delta,\xi,\sigma')@f$
241 * @param sigma @f$ \sigma@f$ of @f$\sigma'^2=\sigma^2-\sigma_n^2 @f$
242 * @param sigma_n @f$ \sigma_n@f$ of @f$\sigma'^2=\sigma^2-\sigma_n^2 @f$
244 * @return @f$ f@f$ evaluated at @f$ x@f$.
246 static Double_t LandauGaus(Double_t x, Double_t delta, Double_t xi,
247 Double_t sigma, Double_t sigma_n);
249 //------------------------------------------------------------------
253 * f_i(x;\Delta,\xi,\sigma') = f(x;\Delta_i,\xi_i,\sigma_i')
255 * corresponding to @f$ i@f$ particles i.e., with the substitutions
257 * \Delta \rightarrow \Delta_i &=& i(\Delta + \xi\log(i))\\
258 * \xi \rightarrow \xi_i &=& i \xi\\
259 * \sigma \rightarrow \sigma_i &=& \sqrt{i}\sigma\\
260 * \sigma'^2 \rightarrow \sigma_i'^2 &=& \sigma_n^2 + \sigma_i^2
263 * @param x Where to evaluate
264 * @param delta @f$ \Delta@f$
265 * @param xi @f$ \xi@f$
266 * @param sigma @f$ \sigma@f$
267 * @param sigma_n @f$ \sigma_n@f$
270 * @return @f$ f_i @f$ evaluated
272 static Double_t ILandauGaus(Double_t x, Double_t delta, Double_t xi,
273 Double_t sigma, Double_t sigma_n, Int_t i);
275 //------------------------------------------------------------------
277 * Numerically evaluate
279 * \left.\frac{\partial f_i}{\partial p_i}\right|_{x}
281 * where @f$ p_i@f$ is the @f$ i^{\mbox{th}}@f$ parameter. The mapping
282 * of the parameters is given by
287 * - 3: @f$\sigma_n@f$
289 * This is the partial derivative with respect to the parameter of
290 * the response function corresponding to @f$ i@f$ particles i.e.,
291 * with the substitutions
293 * \Delta \rightarrow \Delta_i = i(\Delta + \xi\log(i))\\
294 * \xi \rightarrow \xi_i = i \xi\\
295 * \sigma \rightarrow \sigma_i = \sqrt{i}\sigma\\
296 * \sigma'^2 \rightarrow \sigma_i'^2 = \sigma_n^2 + \sigma_i^2
299 * @param x Where to evaluate
300 * @param ipar Parameter number
301 * @param dp @f$ \epsilon\delta p_i@f$ for some value of @f$\epsilon@f$
302 * @param delta @f$ \Delta@f$
303 * @param xi @f$ \xi@f$
304 * @param sigma @f$ \sigma@f$
305 * @param sigma_n @f$ \sigma_n@f$
308 * @return @f$ f_i@f$ evaluated
310 static Double_t IdLandauGausdPar(Double_t x, UShort_t ipar, Double_t dp,
311 Double_t delta, Double_t xi,
312 Double_t sigma, Double_t sigma_n, Int_t i);
314 //------------------------------------------------------------------
318 * f_N(x;\Delta,\xi,\sigma') = \sum_{i=1}^N a_i f_i(x;\Delta,\xi,\sigma'a)
321 * where @f$ f(x;\Delta,\xi,\sigma')@f$ is the convolution of a
322 * Landau with a Gaussian (see LandauGaus). Note that
323 * @f$ a_1 = 1@f$, @f$\Delta_i = i(\Delta_1 + \xi\log(i))@f$,
324 * @f$\xi_i=i\xi_1@f$, and @f$\sigma_i'^2 = \sigma_n^2 + i\sigma_1^2@f$.
327 * - <a href="http://dx.doi.org/10.1016/0168-583X(84)90472-5">Nucl.Instrum.Meth.B1:16</a>
328 * - <a href="http://dx.doi.org/10.1103/PhysRevA.28.615">Phys.Rev.A28:615</a>
329 * - <a href="http://root.cern.ch/root/htmldoc/tutorials/fit/langaus.C.html">ROOT implementation</a>
331 * @param x Where to evaluate @f$ f_N@f$
332 * @param delta @f$ \Delta_1@f$
333 * @param xi @f$ \xi_1@f$
334 * @param sigma @f$ \sigma_1@f$
335 * @param sigma_n @f$ \sigma_n@f$
336 * @param n @f$ N@f$ in the sum above.
337 * @param a Array of size @f$ N-1@f$ of the weights @f$ a_i@f$ for
340 * @return @f$ f_N(x;\Delta,\xi,\sigma')@f$
342 static Double_t NLandauGaus(Double_t x, Double_t delta, Double_t xi,
343 Double_t sigma, Double_t sigma_n, Int_t n,
346 * Generate a TF1 object of @f$ f_I@f$
349 * @param delta @f$ \Delta@f$
350 * @param xi @f$ \xi_1@f$
351 * @param sigma @f$ \sigma_1@f$
352 * @param sigma_n @f$ \sigma_n@f$
353 * @param i @f$ i@f$ - the number of particles
354 * @param xmin Least value of range
355 * @param xmax Largest value of range
357 * @return Newly allocated TF1 object
359 static TF1* MakeILandauGaus(Double_t c,
360 Double_t delta, Double_t xi,
361 Double_t sigma, Double_t sigma_n,
363 Double_t xmin, Double_t xmax);
365 * Generate a TF1 object of @f$ f_N@f$
368 * @param delta @f$ \Delta@f$
369 * @param xi @f$ \xi_1@f$
370 * @param sigma @f$ \sigma_1@f$
371 * @param sigma_n @f$ \sigma_n@f$
372 * @param n @f$ N@f$ - how many particles to sum to
373 * @param a Array of size @f$ N-1@f$ of the weights @f$ a_i@f$ for
375 * @param xmin Least value of range
376 * @param xmax Largest value of range
378 * @return Newly allocated TF1 object
380 static TF1* MakeNLandauGaus(Double_t c,
381 Double_t delta, Double_t xi,
382 Double_t sigma, Double_t sigma_n,
383 Int_t n, const Double_t* a,
384 Double_t xmin, Double_t xmax);
386 //__________________________________________________________________
388 * Structure to do fits to the energy loss spectrum
390 * @ingroup pwglf_forward
406 * @param lowCut Lower cut of spectrum - data below this cuts is ignored
407 * @param maxRange Maximum range to fit to
408 * @param minusBins The number of bins below maximum to use
410 ELossFitter(Double_t lowCut, Double_t maxRange, UShort_t minusBins);
415 virtual ~ELossFitter();
417 * Clear internal arrays
422 * Fit a 1-particle signal to the passed energy loss distribution
424 * Note that this function clears the internal arrays first
426 * @param dist Data to fit the function to
427 * @param sigman If larger than zero, the initial guess of the
428 * detector induced noise. If zero or less, then this
429 * parameter is ignored in the fit (fixed at 0)
431 * @return The function fitted to the data
433 TF1* Fit1Particle(TH1* dist, Double_t sigman=-1);
435 * Fit a N-particle signal to the passed energy loss distribution
437 * If there's no 1-particle fit present, it does that first
439 * @param dist Data to fit the function to
440 * @param n Number of particle signals to fit
441 * @param sigman If larger than zero, the initial guess of the
442 * detector induced noise. If zero or less, then this
443 * parameter is ignored in the fit (fixed at 0)
445 * @return The function fitted to the data
447 TF1* FitNParticle(TH1* dist, UShort_t n, Double_t sigman=-1);
449 * Get Lower cut on data
451 * @return Lower cut on data
453 Double_t GetLowCut() const { return fLowCut; }
455 * Get Maximum range to fit
457 * @return Maximum range to fit
459 Double_t GetMaxRange() const { return fMaxRange; }
461 * Get Number of bins from maximum to fit 1st peak
463 * @return Number of bins from maximum to fit 1st peak
465 UShort_t GetMinusBins() const { return fMinusBins; }
467 * Get Array of fit results
469 * @return Array of fit results
471 const TObjArray& GetFitResults() const { return fFitResults; }
473 * Get Array of fit results
475 * @return Array of fit results
477 TObjArray& GetFitResults() { return fFitResults; }
479 * Get Array of functions
481 * @return Array of functions
483 const TObjArray& GetFunctions() const { return fFunctions; }
485 * Get Array of functions
487 * @return Array of functions
489 TObjArray& GetFunctions() { return fFunctions; }
491 const Double_t fLowCut; // Lower cut on data
492 const Double_t fMaxRange; // Maximum range to fit
493 const UShort_t fMinusBins; // Number of bins from maximum to fit 1st peak
494 TObjArray fFitResults; // Array of fit results
495 TObjArray fFunctions; // Array of functions
500 //==================================================================
503 * @name Convenience containers
506 * Structure to hold histograms
508 * @ingroup pwglf_forward
510 struct Histos : public TObject
517 Histos() : fFMD1i(0), fFMD2i(0), fFMD2o(0), fFMD3i(0), fFMD3o(0) {}
521 * @param o Object to copy from
523 Histos(const Histos& o)
532 * Assignement operator
534 * @return Reference to this
536 Histos& operator=(const Histos&) { return *this;}
538 * Destructor. This does not delete the interally allocated
539 * memory. Use the member function Delete for that.
543 * Clear internal memory. Note, if the internal histograms are
544 * added to an output container, then we must not free this
547 void Delete(Option_t* opt="");
549 * Initialize the object
551 * @param etaAxis Eta axis to use
553 void Init(const TAxis& etaAxis);
559 * @param etaAxis Eta axis to use
561 * @return Newly allocated histogram
563 TH2D* Make(UShort_t d, Char_t r, const TAxis& etaAxis) const;
567 * @param option Not used
569 void Clear(Option_t* option="");
570 // const TH2D* Get(UShort_t d, Char_t r) const;
572 * Get the histogram for a particular detector,ring
577 * @return Histogram for detector,ring or nul
579 TH2D* Get(UShort_t d, Char_t r) const;
580 TH2D* fFMD1i; // Histogram for FMD1i
581 TH2D* fFMD2i; // Histogram for FMD2i
582 TH2D* fFMD2o; // Histogram for FMD2o
583 TH2D* fFMD3i; // Histogram for FMD3i
584 TH2D* fFMD3o; // Histogram for FMD3o
589 //__________________________________________________________________
591 * Base class for structure holding ring specific histograms
593 * @ingroup pwglf_forward
595 struct RingHistos : public TObject
601 RingHistos() : fDet(0), fRing('\0'), fName("") {}
608 RingHistos(UShort_t d, Char_t r)
609 : fDet(d), fRing(r), fName(TString::Format("FMD%d%c", d, r))
614 * @param o Object to copy from
616 RingHistos(const RingHistos& o)
617 : TObject(o), fDet(o.fDet), fRing(o.fRing), fName(o.fName)
622 virtual ~RingHistos() {}
624 * Assignement operator
626 * @param o Object to assign from
628 * @return Reference to this
630 RingHistos& operator=(const RingHistos& o)
632 if (&o == this) return *this;
633 TObject::operator=(o);
640 * Define the outout list in @a d
642 * @param d Where to put the output list
644 * @return Newly allocated TList object or null
646 TList* DefineOutputList(TList* d) const;
648 * Get our output list from the container @a d
650 * @param d where to get the output list from
652 * @return The found TList or null
654 TList* GetOutputList(const TList* d) const;
656 * Find a specific histogram in the source list @a d
658 * @param d (top)-container
659 * @param name Name of histogram
661 * @return Found histogram or null
663 TH1* GetOutputHist(const TList* d, const char* name) const;
670 Color_t Color() const
672 return AliForwardUtil::RingColor(fDet, fRing);
675 * The name of this ring
677 * @return Name of this ring
679 const char* GetName() const { return fName.Data(); }
680 UShort_t fDet; // Detector
681 Char_t fRing; // Ring
682 TString fName; // Name
684 ClassDef(RingHistos,1)
688 //__________________________________________________________________
690 * A guard idom for producing debug output
698 * @param lvl Current level
699 * @param msgLvl Target level
700 * @param format @c printf -like format
704 DebugGuard(Int_t lvl, Int_t msgLvl, const char* format, ...);
712 * @param lvl Current level
713 * @param msgLvl Target level
714 * @param format @c printf -like format
716 static void Message(Int_t lvl, Int_t msgLvl, const char* format, ...);
721 * @param in Direction
724 static void Output(int in, TString& msg);
728 * @param out Output is stored here
729 * @param format @c printf -like format
730 * @param ap List of arguments
732 static void Format(TString& out, const char* format, va_list ap);
743 * @param o Object to copy from
745 AliForwardUtil(const AliForwardUtil& o) : TObject(o) {}
747 * Assingment operator
750 * @return Reference to this object
752 AliForwardUtil& operator=(const AliForwardUtil&) { return *this; }
759 ClassDef(AliForwardUtil,1) // Utilities - do not make object
762 // #ifdef LOG_NO_DEBUG
763 // # define DGUARD(L,N,F,...) do {} while(false)
766 * Macro to declare a DebugGuard
768 * @param L Current debug level
769 * @param N Target debug level
770 * @param F @c printf -like Format
772 # define DGUARD(L,N,F,...) \
773 AliForwardUtil::DebugGuard _GUARD(L,N,F, ## __VA_ARGS__)
775 * Macro to make a debug message, using DebugGuard::Message
777 * @param L Current debug level
778 * @param N Target debug level
779 * @param F @c printf -like Format
781 # define DMSG(L,N,F,...) \
782 AliForwardUtil::DebugGuard::Message(L,N,F, ## __VA_ARGS__)