]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/RESONANCES/doc/rsndoc.tex
Migration of PWG2/RESONANCES -> PWGLF/RESONANCES
[u/mrichter/AliRoot.git] / PWGLF / RESONANCES / doc / rsndoc.tex
1 \documentclass[12pt,a4paper]{article}
2
3 \usepackage{vmargin}
4 \usepackage{listings}
5
6 \renewcommand{\rmdefault}{cmss}
7 \newcommand{\inlinecode}[2]{\mbox{{\bf #1(}#2{\bf)}}}
8
9 \setpapersize{A4}
10 \setmarginsrb{10mm}{10mm}{10mm}{10mm}{0mm}{10mm}{0mm}{10mm}
11
12 \title{ALICE resonance analysis package documentation}
13 \author{A. Pulvirenti}
14 \date{\tt alberto.pulvirenti@ct.infn.it}
15
16 \begin{document}
17 \lstset{language=C++}
18 \lstset{basicstyle=\tiny}
19
20 \maketitle
21
22 \section{Introduction}
23
24 This small guide will drive the user through the resonance analysis package (we'll call it RSN), in order to learn how to configure an analysis with it and how to personalize some of its aspects.
25 A slightly more advanced reference guide will also be provided at the end; it is of interest especially to all people interested in contributing to the package development, in order to go in a major detail through the code.
26
27 The purpose of the package is to set up an AnalysisTask object for resonance analysis.
28 Then, all of its objects aim at configuring it properly for a specific resonance study.
29 Keeping in mind this main purpose, we will explain how to configure a typical analysis, and this will give the possibility to introduce the user to all package classes he will have to manage directly.
30 This will be done just going through a typical configuration macro, and discussing its lines.
31
32 This guide assumes that the reader roughly knows how a typical aliroot AnalysisTask object should be initialized, so we will not spend much time on its general aspects (how to configure input handlers and output containers, how to setup the AnalysisManager etc.\,).
33 Anyway, in  the{\tt PWG2/RESONANCES/macros/test} path (inside the aliroot soruce code tree), it is available a set of macroes which can be used to steer an analysis from an aliroot session.
34
35 We will then give the initial description following a building scheme where we go through all aspects of analysis initialization.
36 The package is based on four independent pieces which all contribute to the final analysis:
37 the interface classes which are used to uniformize the way it accesses the informations taken from whatever kind of input source (namely, ESD, AOD or MC);
38 the work-flow classes which just execute the loops on the events and build up the output objects returned by the analysis task;
39 the cut classes which are the fundamental step for track/pair selection and can determine the difference between one analysis and another
40 the  output classes which implement the computation of all output values of interest
41 It must be specified that, in its current version, the package is built essentially in order to make computations on pairs of particles, when they are accepted as a candidate resonance decay.
42 This document will give a panoramic of all the classes which are currently available in the package, specifying what they are implemented for. Anyway, not all of the package classes need to be perfectly known by the user, since most of them implement just the necessary internal steps to loop on the event and produce the output. Whenever a class enters the necessary configuration and needs to be managed by the user, more details will be given to it.
43 Finally, we must mention that the package is currently built in such a way that it allows an advanced user to customize some aspects of the analysis.
44 \begin{lstlisting}[frame=single]
45 //
46 // This function configures the entire task for all resonances the user is interested in.
47 // This is done by creating all configuration objects which are defined in the package.
48 //
49 // Generally speaking, one has to define the following objects for each resonance:
50 //
51 //  1 - an AliRsnPairDef to define the resonance decay channel to be studied
52 //  2 - an AliRsnPair{Ntuple|Functions} where the output is stored
53 //  3 - one or more AliRsnCut objects to define track selections
54 //      which will have then to be organized into AliRsnCutSet objects
55 //  4 - an AliRsnCutManager to include all cuts to be applied (see point 3)
56 //  5 - definitions to build the TNtuple or histograms which are returned
57 //
58 // The return value is used to know if the configuration was successful
59 //
60 Bool_t RsnConfigTask(AliRsnAnalysisSE* &task, const char *dataLabel)
61 {
62   // for safety, return if no task is passed
63   if (!task)
64   {
65     Error("ConfigTaskRsn", "Task not found");
66     return kFALSE;
67   }
68   
69   // interpret the useful information from second argument
70   TString strDataLabel(dataLabel);
71   Bool_t isESD   = strDataLabel.Contains("ESD");
72   Bool_t isAOD   = strDataLabel.Contains("AOD");
73   Bool_t isSim   = strDataLabel.Contains("sim");
74   Bool_t isData  = strDataLabel.Contains("data");
75   Bool_t isPass1 = strDataLabel.Contains("pass1");
76   Bool_t isPass2 = strDataLabel.Contains("pass2");
77
78   //
79   // -- Set cuts for events (applied to all analyses) -----------------------------------------------
80   //
81   
82   // primary vertex range
83   AliRsnCutPrimaryVertex *cutVertex   = new AliRsnCutPrimaryVertex("cutVertex", 10.0, 0, kFALSE);
84   AliRsnCutSet           *cutSetEvent = new AliRsnCutSet("eventCuts", AliRsnCut::kEvent);
85   //cutSetEvent->AddCut(cutVertex);
86   //cutSetEvent->SetCutScheme("cutVertex");
87   //task->SetEventCuts(cutSetEvent);
88
89   //
90   // -- Setup pairs ---------------------------------------------------------------------------------
91   //
92
93   // decay channels
94   AliRsnPairDef         *pairDefpm = new AliRsnPairDef(AliPID::kKaon, '+', AliPID::kKaon, '-', 333, 1.019455);
95
96   // computation objects
97   AliRsnPairFunctions   *pairPMhist = new AliRsnPairFunctions("pairPMHist", pairDefpm);
98   AliRsnPairNtuple      *pairPMntp  = new AliRsnPairNtuple   ("pairPMNtp" , pairDefpm);
99
100   //
101   // -- Setup cuts ----------------------------------------------------------------------------------
102   //
103   
104   // -- track cut --
105   // --> global cuts for 2010 analysis
106   AliRsnCutESD2010 *cuts2010 = new AliRsnCutESD2010("cuts2010");
107   // ----> set the flag for sim/data management
108   cuts2010->SetMC(isSim);
109   // ----> require to check PID
110   cuts2010->SetCheckITS(kFALSE);
111   cuts2010->SetCheckTPC(kFALSE);
112   cuts2010->SetCheckTOF(kFALSE);
113   // ----> set TPC ranges and calibration
114   cuts2010->SetTPCrange(5.0, 3.0);
115   cuts2010->SetTPCpLimit(0.35);
116   cuts2010->SetITSband(4.0);
117   if (isSim) cuts2010->SetTPCpar(2.15898 / 50.0, 1.75295E1, 3.40030E-9, 1.96178, 3.91720);
118   else       cuts2010->SetTPCpar(1.41543 / 50.0, 2.63394E1, 5.0411E-11, 2.12543, 4.88663);
119   // ----> set standard quality cuts for TPC global tracks
120   //cuts2010->GetCutsTPC()->SetRequireTPCStandAlone(kTRUE); // require to have the projection at inner TPC wall
121   cuts2010->GetCutsTPC()->SetMinNClustersTPC(70);
122   cuts2010->GetCutsTPC()->SetMaxChi2PerClusterTPC(4);
123   cuts2010->GetCutsTPC()->SetAcceptKinkDaughters(kFALSE);
124   cuts2010->GetCutsTPC()->SetRequireTPCRefit(kTRUE);
125   cuts2010->GetCutsTPC()->SetRequireITSRefit(kTRUE);
126   cuts2010->GetCutsTPC()->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
127   cuts2010->GetCutsTPC()->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9"); // DCA pt dependent: 7*(0.0050+0.0060/pt0.9)
128   cuts2010->GetCutsTPC()->SetMaxDCAToVertexZ(1e6); // disabled
129   cuts2010->GetCutsTPC()->SetDCAToVertex2D(kFALSE); // each DCA is checked separately
130   cuts2010->GetCutsTPC()->SetRequireSigmaToVertex(kFALSE);
131   // ----> set standard quality cuts for ITS standalone tracks
132   cuts2010->GetCutsITS()->SetRequireITSStandAlone(kTRUE, kTRUE);
133   cuts2010->GetCutsITS()->SetRequireITSRefit(kTRUE);
134   cuts2010->GetCutsITS()->SetMinNClustersITS(4);
135   cuts2010->GetCutsITS()->SetClusterRequirementITS(AliESDtrackCuts::kSPD, AliESDtrackCuts::kAny);
136   cuts2010->GetCutsITS()->SetMaxChi2PerClusterITS(1.);
137   cuts2010->GetCutsITS()->SetMaxDCAToVertexXYPtDep("0.0595+0.0182/pt^1.55"); // DCA pt dependent
138   cuts2010->GetCutsITS()->SetMaxDCAToVertexZ(1e6); // disabled
139   cuts2010->GetCutsITS()->SetDCAToVertex2D(kFALSE); // each DCA is checked separately
140   // ----> set the configuration for TOF PID checks
141   if (isData && (isPass1 || isPass2))
142   {
143     cuts2010->SetTOFcalibrateESD(kTRUE);
144     //if (isPass2) cuts2010->SetTOFcalibrateESD(kFALSE); // potrebbe anche essere kFALSE
145     cuts2010->SetTOFcorrectTExp(kTRUE);
146     cuts2010->SetTOFuseT0(kTRUE);
147     cuts2010->SetTOFtuneMC(kFALSE);
148     cuts2010->SetTOFresolution(100.0);
149   }
150   else if (isSim)
151   {
152     cuts2010->SetTOFcalibrateESD(kFALSE);
153     cuts2010->SetTOFcorrectTExp(kTRUE);
154     cuts2010->SetTOFuseT0(kTRUE);
155     cuts2010->SetTOFtuneMC(kTRUE);
156     cuts2010->SetTOFresolution(100.0);
157   }
158   
159   // -- tracks --> PID
160   AliRsnCutPID *cutPID = new AliRsnCutPID("cutPID", AliPID::kKaon, 0.0, kTRUE);
161   
162   // cut sets
163   AliRsnCutSet *cutSetDaughterCommon = new AliRsnCutSet("commonDaughterCuts", AliRsnCut::kDaughter);
164
165   // --> add related cuts
166   //cutSetDaughterCommon->AddCut(cuts2010);
167   cutSetDaughterCommon->AddCut(cutPID);
168
169   // --> define schemes
170   cutSetDaughterCommon->SetCutScheme("cutPID");
171    
172   // cut managers
173   // define a proper name for each mult bin, to avoid omonyme output histos
174   pairPMhist->GetCutManager()->SetCommonDaughterCuts(cutSetDaughterCommon);
175   pairPMntp ->GetCutManager()->SetCommonDaughterCuts(cutSetDaughterCommon);
176
177   // function axes
178   Double_t ybins[] = {-0.8, -0.7, -0.6, -0.5, 0.5, 0.6, 0.7, 0.8};
179   AliRsnValue *axisIM   = new AliRsnValue("IM"  , AliRsnValue::kPairInvMass, 50,  0.9,  1.4);
180   AliRsnValue *axisPt   = new AliRsnValue("PT"  , AliRsnValue::kPairPt,      0.0, 20.0, 0.1);
181   AliRsnValue *axisY    = new AliRsnValue("Y"   , AliRsnValue::kPairY,       sizeof(ybins)/sizeof(ybins[0]), ybins);
182   AliRsnValue *axisQinv = new AliRsnValue("QInv", AliRsnValue::kQInv,       100,  0.0, 10.0);
183
184   // functions for TH1-like output
185   AliRsnFunction *fcnPt    = new AliRsnFunction;
186   // --> add axes
187   fcnPt   ->AddAxis(axisIM);
188   fcnPt   ->AddAxis(axisPt);
189   fcnPt   ->AddAxis(axisY);
190   fcnPt   ->AddAxis(axisQinv);
191   
192   // add functions to TH1-like output
193   pairPMhist->AddFunction(fcnPt);
194   //pairPMhist->SetOnlyTrue();
195   
196   // add values to TNtuple-like output
197   pairPMntp->AddValue(axisIM);
198   pairPMntp->AddValue(axisPt);
199   pairPMntp->AddValue(axisY);
200   pairPMntp->AddValue(axisQinv);
201   
202   // add everything to analysis manager
203   task->GetAnalysisManager()->Add(pairPMhist);
204   task->GetAnalysisManager()->Add(pairPMntp);
205
206   return kTRUE;
207 }
208 \end{lstlisting}
209
210 \section{Cuts}
211
212 Cuts are implemented in the package through the {\bf AliRsnCut} base class, which is the basic scheme from which all specific cut implementations must inherit.
213 Its general structure is given here:
214 %
215 \begin{lstlisting}[frame=single]
216 class AliRsnCut : public TNamed
217 {
218   public:
219
220     ...
221
222     virtual Bool_t   IsSelected(TObject *obj1, TObject *obj2 = 0x0);
223
224     ...
225
226   protected:
227
228     Bool_t  OkValue();
229     Bool_t  OkRange();
230     Bool_t  OkValueI();
231     Bool_t  OkRangeI();
232     Bool_t  OkValueD();
233     Bool_t  OkRangeD();
234     
235     ...
236
237     Int_t     fMinI;       // lower edge of INT range or ref. value for INT CUT
238     Int_t     fMaxI;       // upper edge of INT range (not used for value cuts)
239     Double_t  fMinD;       // lower edge of DOUBLE range or ref. value for INT CUT
240     Double_t  fMaxD;       // upper edge of DOUBLE range (not used for value cuts)
241
242     Int_t     fCutValueI;  // cut value INT
243     Double_t  fCutValueD;  // cut value DOUBLE
244     
245     ...
246 };
247 \end{lstlisting}
248 %
249 The heart of the class definition is the \inlinecode{IsSelected}{} function, which is called when the cut needs to be checked along the work-flow of the analysis and {\em must} be overloaded by each specific cut implementations inheriting from this base class.
250 Due to this structure, a user can implement his personalized version of the cuts by creating a class inheriting from {\bf AliRsnCut} and compiling it on the fly, and using it in the standard analysis.
251
252 Most cuts usually consist in checking that a value equals a given reference or stays inside a given range.
253 Then, we provide directly in the base class the instruments to make these checks with integer or floating-point variables.
254 One thing that needs to be considered here is that, for monitoring purposes, these value or range check functions (\inlinecode{OkValueD}{}, \inlinecode{OkValueI}{}, \inlinecode{OkRangeD}{} and \inlinecode{OkRangeI}{}) do not accept arguments, since the value to be checked is expected to be stored in an apposite data member of the class itself ({\bf fCutValueI} and {\bf fCutValueD}).
255 Then, all cuts which exploit this facility must first store the value to be checked in these data members and then call the corresponding range or value check function.
256 The advantage of this structure is that the cut value can be kept in memory and, for example, monitored using debug messages.
257
258 Since usually a user does many checks and sometimes the way to link cuts together is not exactly their simple ``and'', then we introduced a strategy which allows to implement each single check separately, with the advantage of having simpler code, easier to debug.
259 This strategy is based on the {\bf AliRsnCutSet} class, which acts as a collector of cuts.
260 All points where a cut check is done throughout the analysis work-flow uses object of this type, instead of accessing direcly to the single cuts.
261 With this object a user has to do two things: first, add all cuts he wants to check; second, defining a logic by means of a string containing an expression where the names of the single cuts are combined using the C++ logic operators (and, or not). 
262 Both these steps are necessary, since if one just adds the cuts but does not define a logic, then no cut check is taken into account.
263 On the other side, for ease of use, one can add cuts and not use them, since it is not mandatory to include all cut names inside the logic. 
264 Anywaym the user must keep in mind that all cuts added to a set are checked always, so, adding  a lot of unused cuts could unnecessarily slow down the analysis execution.
265
266 The uppermost step of the cut structure is the {\bf AliRsnCutManager}, which combines a set for each possible object to check.
267
268
269
270 \end{document}