]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/AliForwardUtil.h
Various fixes to not free output memory
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / AliForwardUtil.h
1 // 
2 // Utilities used in the forward multiplcity analysis 
3 // 
4 //
5 #ifndef ALIFORWARDUTIL_H
6 #define ALIFORWARDUTIL_H
7 /**
8  * @file   AliForwardUtil.h
9  * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk>
10  * @date   Wed Mar 23 14:06:54 2011
11  * 
12  * @brief  
13  * 
14  * 
15  * @ingroup pwglf_forward 
16  */
17 #include <TObject.h>
18 #include <TString.h>
19 #include <TObjArray.h>
20 class TH2D;
21 class TH1I;
22 class TH1;
23 class TF1;
24 class TAxis;
25 class AliESDEvent;
26 class AliAODEvent;
27 class AliAnalysisTaskSE;
28
29 /** 
30  * Utilities used in the forward multiplcity analysis 
31  * 
32  * @ingroup pwglf_forward 
33  */
34 class AliForwardUtil : public TObject
35 {
36 public:
37   /** 
38    * Get the standard color for a ring  
39    *
40    * @param d Detector
41    * @param r Ring 
42    * 
43    * @return 
44    */
45   static Color_t RingColor(UShort_t d, Char_t r)
46   { 
47     return ((d == 1 ? kRed : (d == 2 ? kGreen : kBlue))
48             + ((r == 'I' || r == 'i') ? 2 : -3));
49   }
50   //==================================================================
51   /** 
52    * @{ 
53    * @name Collision/run parameters 
54    */
55   /**                                           
56    * Defined collision types 
57    */
58   enum ECollisionSystem {
59     kUnknown, 
60     kPP, 
61     kPbPb,
62     kPPb
63   };
64   //__________________________________________________________________
65   /** 
66    * Parse a collision system spec given in a string.   Known values are 
67    * 
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 
72    * 
73    * @param sys Collision system spec 
74    * 
75    * @return Collision system id 
76    */
77   static UShort_t ParseCollisionSystem(const char* sys);
78   /** 
79    * Get a string representation of the collision system 
80    * 
81    * @param sys  Collision system 
82    * - kPP -> "pp"
83    * - kPbPb -> "PbPb" 
84    * - kPPb -> "pPb"
85    * - anything else gives "unknown"
86    * 
87    * @return String representation of the collision system 
88    */
89   static const char* CollisionSystemString(UShort_t sys);
90   //__________________________________________________________________
91   /** 
92    * Parse the center of mass energy given as a float and return known 
93    * values as a unsigned integer
94    * 
95    * @param sys  Collision system (needed for AA)
96    * @param cms  Center of mass energy * total charge 
97    * 
98    * @return Center of mass energy per nucleon
99    */
100   static UShort_t ParseCenterOfMassEnergy(UShort_t sys, Float_t cms);
101   /** 
102    * Get a string representation of the center of mass energy per nuclean
103    * 
104    * @param cms  Center of mass energy per nucleon
105    * 
106    * @return String representation of the center of mass energy per nuclean
107    */
108   static const char* CenterOfMassEnergyString(UShort_t cms);
109   //__________________________________________________________________
110   /** 
111    * Parse the magnetic field (in kG) as given by a floating point number
112    * 
113    * @param field  Magnetic field in kG 
114    * 
115    * @return Short integer value of magnetic field in kG 
116    */
117   static Short_t ParseMagneticField(Float_t field);
118   /** 
119    * Get eta from strip
120    * 
121    * @param det, ring, sec, strip, zvtx
122    * 
123    * @return eta
124    */
125   static Double_t GetEtaFromStrip(UShort_t det, Char_t ring, UShort_t sec, UShort_t strip, Double_t zvtx) ;
126   /** 
127    * Get a string representation of the magnetic field
128    * 
129    * @param field Magnetic field in kG
130    * 
131    * @return String representation of the magnetic field
132    */
133    static const char* MagneticFieldString(Short_t field);
134   /* @} */
135
136   //__________________________________________________________________
137   /** 
138    * Get the AOD event - either from the input (AOD analysis) or the
139    * output (ESD analysis)
140    * 
141    * @param task Task to do the investigation for
142    * 
143    * @return Found AOD event or null
144    */
145   static AliAODEvent* GetAODEvent(AliAnalysisTaskSE* task);
146   /** 
147    * Check if we have something that will provide and AOD event 
148    * 
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)
152    */
153   static UShort_t CheckForAOD();
154   /** 
155    * Check if we have a particular (kind) of task in our train
156    * 
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
160    * 
161    * @return true if the needed task was found 
162    */
163   static Bool_t CheckForTask(const char* clsOrName, Bool_t cls=true);
164
165   //__________________________________________________________________
166   /** 
167    * @{ 
168    * @name Member functions to store and retrieve analysis parameters 
169    */
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);
178   /* @} */
179
180   /** 
181    * @{ 
182    * @name Energy stragling functions 
183    */
184   //__________________________________________________________________
185   /**
186    * Number of steps to do in the Landau, Gaussiam convolution 
187    */
188   static Int_t fgConvolutionSteps; // Number of convolution steps
189   //------------------------------------------------------------------
190   /** 
191    * How many sigma's of the Gaussian in the Landau, Gaussian
192    * convolution to integrate over
193    */
194   static Double_t fgConvolutionNSigma; // Number of convolution sigmas 
195   //------------------------------------------------------------------
196   /** 
197    * Calculate the shifted Landau
198    * @f[
199    *    f'_{L}(x;\Delta,\xi) = f_L(x;\Delta+0.22278298\xi)
200    * @f]
201    *
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$. 
205    *
206    * @param x      Where to evaluate @f$ f'_{L}@f$ 
207    * @param delta  Most probable value 
208    * @param xi     The 'width' of the distribution 
209    *
210    * @return @f$ f'_{L}(x;\Delta,\xi) @f$
211    */
212   static Double_t Landau(Double_t x, Double_t delta, Double_t xi);
213   
214   //------------------------------------------------------------------
215   /** 
216    * Calculate the value of a Landau convolved with a Gaussian 
217    * 
218    * @f[ 
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}}
222    * @f]
223    * 
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.  
229    *
230    * Note that this function uses the constants fgConvolutionSteps and
231    * fgConvolutionNSigma
232    * 
233    * References: 
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>
237    * 
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$
243    * 
244    * @return @f$ f@f$ evaluated at @f$ x@f$.  
245    */
246   static Double_t LandauGaus(Double_t x, Double_t delta, Double_t xi, 
247                              Double_t sigma, Double_t sigma_n);
248
249   //------------------------------------------------------------------
250   /** 
251    * Evaluate 
252    * @f[ 
253    *    f_i(x;\Delta,\xi,\sigma') = f(x;\Delta_i,\xi_i,\sigma_i')
254    * @f] 
255    * corresponding to @f$ i@f$ particles i.e., with the substitutions 
256    * @f{eqnarray*}{ 
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
261    * @f} 
262    * 
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$
268    * @param i        @f$ i @f$
269    * 
270    * @return @f$ f_i @f$ evaluated
271    */  
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);
274
275   //------------------------------------------------------------------
276   /** 
277    * Numerically evaluate 
278    * @f[ 
279    *    \left.\frac{\partial f_i}{\partial p_i}\right|_{x}
280    * @f] 
281    * where @f$ p_i@f$ is the @f$ i^{\mbox{th}}@f$ parameter.  The mapping 
282    * of the parameters is given by 
283    *
284    * - 0: @f$\Delta@f$ 
285    * - 1: @f$\xi@f$ 
286    * - 2: @f$\sigma@f$ 
287    * - 3: @f$\sigma_n@f$ 
288    *
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
292    * @f[ 
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
297    * @f] 
298    * 
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$
306    * @param i        @f$ i@f$
307    * 
308    * @return @f$ f_i@f$ evaluated
309    */  
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);
313
314   //------------------------------------------------------------------
315   /** 
316    * Evaluate 
317    * @f[ 
318    *   f_N(x;\Delta,\xi,\sigma') = \sum_{i=1}^N a_i f_i(x;\Delta,\xi,\sigma'a)
319    * @f] 
320    * 
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$. 
325    *  
326    * References: 
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>
330    * 
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 
338    *                 @f$ i > 1@f$ 
339    * 
340    * @return @f$ f_N(x;\Delta,\xi,\sigma')@f$ 
341    */
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, 
344                               const Double_t* a);
345   /** 
346    * Generate a TF1 object of @f$ f_I@f$ 
347    * 
348    * @param c        Constant
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
356    * 
357    * @return Newly allocated TF1 object
358    */
359   static TF1* MakeILandauGaus(Double_t c, 
360                               Double_t delta, Double_t xi, 
361                               Double_t sigma, Double_t sigma_n,
362                               Int_t    i, 
363                               Double_t xmin,  Double_t  xmax);
364   /** 
365    * Generate a TF1 object of @f$ f_N@f$ 
366    * 
367    * @param c         Constant                         
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 
374    *                  @f$ i > 1@f$ 
375    * @param xmin      Least value of range  
376    * @param xmax      Largest value of range
377    * 
378    * @return Newly allocated TF1 object
379    */
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);
385                                                     
386   //__________________________________________________________________
387   /** 
388    * Structure to do fits to the energy loss spectrum 
389    * 
390    * @ingroup pwglf_forward 
391    */
392   struct ELossFitter 
393   {
394     enum { 
395       kC     = 0,
396       kDelta, 
397       kXi, 
398       kSigma, 
399       kSigmaN, 
400       kN, 
401       kA
402     };
403     /** 
404      * Constructor 
405      * 
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 
409      */
410     ELossFitter(Double_t lowCut, Double_t maxRange, UShort_t minusBins); 
411     /** 
412      * Destructor
413      * 
414      */
415     virtual ~ELossFitter();
416     /** 
417      * Clear internal arrays 
418      * 
419      */
420     void Clear();
421     /** 
422      * Fit a 1-particle signal to the passed energy loss distribution 
423      * 
424      * Note that this function clears the internal arrays first 
425      *
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)
430      * 
431      * @return The function fitted to the data 
432      */
433     TF1* Fit1Particle(TH1* dist, Double_t sigman=-1);
434     /** 
435      * Fit a N-particle signal to the passed energy loss distribution 
436      *
437      * If there's no 1-particle fit present, it does that first 
438      *
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)
444      * 
445      * @return The function fitted to the data 
446      */
447     TF1* FitNParticle(TH1* dist, UShort_t n, Double_t sigman=-1);
448     /**
449      * Get Lower cut on data 
450      *
451      * @return Lower cut on data 
452      */
453     Double_t GetLowCut() const { return fLowCut; }
454     /**
455      * Get Maximum range to fit 
456      *
457      * @return Maximum range to fit 
458      */
459     Double_t GetMaxRange() const { return fMaxRange; }
460     /**
461      * Get Number of bins from maximum to fit 1st peak
462      *
463      * @return Number of bins from maximum to fit 1st peak
464      */
465     UShort_t GetMinusBins() const { return fMinusBins; }
466     /**
467      * Get Array of fit results 
468      *
469      * @return Array of fit results 
470      */
471     const TObjArray& GetFitResults() const { return fFitResults; }
472     /** 
473      * Get Array of fit results  
474      *
475      * @return Array of fit results 
476      */
477     TObjArray& GetFitResults() { return fFitResults; }
478     /**
479      * Get Array of functions 
480      *
481      * @return Array of functions 
482      */
483     const TObjArray& GetFunctions() const { return fFunctions; }
484     /** 
485      * Get Array of functions  
486      *
487      * @return Array of functions 
488      */
489     TObjArray& GetFunctions() { return fFunctions; }
490   private:
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 
496   };
497   /* @} */
498       
499
500   //==================================================================
501   /** 
502    * @{
503    * @name Convenience containers 
504    */
505   /** 
506    * Structure to hold histograms 
507    *
508    * @ingroup pwglf_forward 
509    */
510   struct Histos : public TObject
511   {     
512     /** 
513      * Constructor 
514      * 
515      * 
516      */
517     Histos() : fFMD1i(0), fFMD2i(0), fFMD2o(0), fFMD3i(0), fFMD3o(0) {}
518     /** 
519      * Copy constructor 
520      * 
521      * @param o Object to copy from 
522      */
523     Histos(const Histos& o) 
524       : TObject(o), 
525         fFMD1i(o.fFMD1i), 
526         fFMD2i(o.fFMD2i), 
527         fFMD2o(o.fFMD2o), 
528         fFMD3i(o.fFMD3i), 
529         fFMD3o(o.fFMD3o)
530     {}
531     /** 
532      * Assignement operator 
533      * 
534      * @return Reference to this 
535      */
536     Histos& operator=(const Histos&) { return *this;}
537     /** 
538      * Destructor.  This does not delete the interally allocated
539      * memory.  Use the member function Delete for that.
540      */
541     ~Histos();
542     /** 
543      * Clear internal memory.  Note, if the internal histograms are
544      * added to an output container, then we must not free this
545      * memory.
546      */
547     void Delete(Option_t* opt="");
548     /** 
549      * Initialize the object 
550      * 
551      * @param etaAxis Eta axis to use 
552      */
553     void Init(const TAxis& etaAxis);
554     /** 
555      * Make a histogram 
556      * 
557      * @param d        Detector
558      * @param r        Ring 
559      * @param etaAxis  Eta axis to use
560      * 
561      * @return Newly allocated histogram 
562      */
563     TH2D* Make(UShort_t d, Char_t r, const TAxis& etaAxis) const;
564     /** 
565      * Clear data 
566      * 
567      * @param option Not used 
568      */
569     void  Clear(Option_t* option="");
570     // const TH2D* Get(UShort_t d, Char_t r) const;
571     /** 
572      * Get the histogram for a particular detector,ring
573      * 
574      * @param d Detector 
575      * @param r Ring 
576      * 
577      * @return Histogram for detector,ring or nul 
578      */
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
585
586     ClassDef(Histos,1) 
587   };
588
589   //__________________________________________________________________
590   /**
591    * Base class for structure holding ring specific histograms
592    * 
593    * @ingroup pwglf_forward 
594    */
595   struct RingHistos : public TObject
596   {
597     /** 
598      * Constructor
599      * 
600      */
601     RingHistos() : fDet(0), fRing('\0'), fName("") {}
602     /** 
603      * 
604      * 
605      * @param d Detector
606      * @param r Ring 
607      */
608     RingHistos(UShort_t d, Char_t r) 
609       : fDet(d), fRing(r), fName(TString::Format("FMD%d%c", d, r)) 
610     {}
611     /** 
612      * Copy constructor
613      * 
614      * @param o Object to copy from 
615      */
616     RingHistos(const RingHistos& o) 
617       : TObject(o), fDet(o.fDet), fRing(o.fRing), fName(o.fName)
618     {}
619     /** 
620      * 
621      */
622     virtual ~RingHistos() {}
623     /** 
624      * Assignement operator
625      * 
626      * @param o Object to assign from
627      * 
628      * @return Reference to this
629      */
630     RingHistos& operator=(const RingHistos& o) 
631     {
632       if (&o == this) return *this;
633       TObject::operator=(o);
634       fDet  = o.fDet;
635       fRing = o.fRing;
636       fName = o.fName;
637       return *this;
638     }
639     /** 
640      * Define the outout list in @a d
641      * 
642      * @param d Where to put the output list
643      * 
644      * @return Newly allocated TList object or null
645      */
646     TList* DefineOutputList(TList* d) const;
647     /** 
648      * Get our output list from the container @a d
649      * 
650      * @param d where to get the output list from 
651      * 
652      * @return The found TList or null
653      */
654     TList* GetOutputList(const TList* d) const;
655     /** 
656      * Find a specific histogram in the source list @a d
657      * 
658      * @param d     (top)-container 
659      * @param name  Name of histogram
660      * 
661      * @return Found histogram or null
662      */
663     TH1* GetOutputHist(const TList* d, const char* name) const;
664     /** 
665      * 
666      * 
667      * 
668      * @return 
669      */
670     Color_t Color() const 
671     { 
672       return AliForwardUtil::RingColor(fDet, fRing);
673     }
674     /** 
675      * The name of this ring 
676      * 
677      * @return Name of this ring 
678      */
679     const char* GetName() const { return fName.Data(); } 
680     UShort_t fDet;   // Detector
681     Char_t   fRing;  // Ring
682     TString  fName;  // Name
683
684     ClassDef(RingHistos,1) 
685   };
686   /* @} */
687
688   //__________________________________________________________________
689   /**
690    * A guard idom for producing debug output 
691    * 
692    */
693   struct DebugGuard 
694   {
695     /** 
696      * Constructor 
697      * 
698      * @param lvl       Current level
699      * @param msgLvl    Target level 
700      * @param format    @c printf -like format
701      * 
702      * @return 
703      */
704     DebugGuard(Int_t lvl, Int_t msgLvl, const char* format, ...);
705     /** 
706      * Destructor
707      */
708     ~DebugGuard();
709     /** 
710      * Make a message 
711      * 
712      * @param lvl    Current level
713      * @param msgLvl Target level 
714      * @param format @c printf -like format
715      */
716     static void Message(Int_t lvl, Int_t msgLvl, const char* format, ...);
717   private:
718     /** 
719      * Output the message 
720      * 
721      * @param in    Direction
722      * @param msg   Message 
723      */
724     static void Output(int in, TString& msg);
725     /** 
726      * Format a message 
727      * 
728      * @param out     Output is stored here
729      * @param format  @c printf -like format
730      * @param ap      List of arguments
731      */
732     static void Format(TString& out, const char* format, va_list ap);
733     TString fMsg;
734   };
735 private:
736   /** 
737    * Constructor 
738    */
739   AliForwardUtil() {}
740   /** 
741    * Copy constructor 
742    * 
743    * @param o Object to copy from 
744    */
745   AliForwardUtil(const AliForwardUtil& o) : TObject(o) {}
746   /** 
747    * Assingment operator 
748    * 
749    * 
750    * @return Reference to this object 
751    */
752   AliForwardUtil& operator=(const AliForwardUtil&) { return *this; }
753   /** 
754    * Destructor
755    */
756   ~AliForwardUtil() {}
757   
758
759   ClassDef(AliForwardUtil,1) // Utilities - do not make object
760 };
761
762 // #ifdef LOG_NO_DEBUG
763 // # define DGUARD(L,N,F,...) do {} while(false) 
764 // #else
765 /** 
766  * Macro to declare a DebugGuard
767  * 
768  * @param L Current debug level
769  * @param N Target debug level
770  * @param F @c printf -like Format 
771  */
772 # define DGUARD(L,N,F,...)                                      \
773   AliForwardUtil::DebugGuard _GUARD(L,N,F, ## __VA_ARGS__)
774 /** 
775  * Macro to make a debug message, using DebugGuard::Message
776  * 
777  * @param L Current debug level
778  * @param N Target debug level
779  * @param F @c printf -like Format 
780  */
781 # define DMSG(L,N,F,...)                                        \
782   AliForwardUtil::DebugGuard::Message(L,N,F, ## __VA_ARGS__)
783 // #endif
784 #endif
785 // Local Variables:
786 //  mode: C++
787 // End:
788