]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG2/RESONANCES/AliRsnLoopPair.cxx
Coverity fixes
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnLoopPair.cxx
1 //
2 // *** Class AliRsnLoopPair ***
3 //
4 // "Core" method for defining the work on a pari of particles.
5 // For one analysis, one must setup one of this for each pair he wants to analyze,
6 // adding to it all analysis which he desires to do.
7 // Here he defines the cuts, and the particle types and charges, and can add
8 // functions which do different operations on the same pair, and some binning
9 // with respect to some kinematic variables (eta, momentum)
10 //
11 // authors: A. Pulvirenti (email: alberto.pulvirenti@ct.infn.it)
12 //          M. Vala (email: martin.vala@cern.ch)
13 //
14
15 #include <TList.h>
16 #include <TEntryList.h>
17
18 #include "AliLog.h"
19
20 #include "AliRsnMother.h"
21 #include "AliRsnCutSet.h"
22 #include "AliRsnDaughterSelector.h"
23
24 #include "AliRsnLoopPair.h"
25
26 ClassImp(AliRsnLoopPair)
27
28 //_____________________________________________________________________________
29 AliRsnLoopPair::AliRsnLoopPair(const char *name, AliRsnPairDef *def, Bool_t isMixed) :
30    AliRsnLoop(name, isMixed),
31    fOnlyTrue(kFALSE),
32    fCheckDecay(kFALSE),
33    fPairDef(def),
34    fPairCuts(0x0),
35    fMother()
36 {
37 //
38 // Default constructor
39 //
40
41    fListID[0] = -1;
42    fListID[1] = -1;
43 }
44
45 //_____________________________________________________________________________
46 AliRsnLoopPair::AliRsnLoopPair(const AliRsnLoopPair& copy) :
47    AliRsnLoop(copy),
48    fOnlyTrue(copy.fOnlyTrue),
49    fCheckDecay(copy.fCheckDecay),
50    fPairDef(copy.fPairDef),
51    fPairCuts(copy.fPairCuts),
52    fMother(copy.fMother)
53 {
54 //
55 // Copy constructor
56 //
57
58    fListID[0] = copy.fListID[0];
59    fListID[1] = copy.fListID[1];
60 }
61
62 //_____________________________________________________________________________
63 AliRsnLoopPair& AliRsnLoopPair::operator=(const AliRsnLoopPair& copy)
64 {
65    AliRsnLoop::operator=(copy);
66    
67    fOnlyTrue = copy.fOnlyTrue;
68    fCheckDecay = copy.fCheckDecay;
69    fPairDef = copy.fPairDef;
70    fPairCuts = copy.fPairCuts;
71    fMother = copy.fMother;
72    fListID[0] = copy.fListID[0];
73    fListID[1] = copy.fListID[1];
74
75    return (*this);
76 }
77
78 //_____________________________________________________________________________
79 AliRsnLoopPair::~AliRsnLoopPair()
80 {
81 //
82 // Destructor
83 //
84 }
85
86 //_____________________________________________________________________________
87 void AliRsnLoopPair::Print(Option_t* /*option*/) const
88 {
89 //
90 // Prints info about pair
91 //
92
93    AliRsnLoop::Print();
94 }
95
96 //_____________________________________________________________________________
97 Bool_t AliRsnLoopPair::Init(const char *prefix, TList *list)
98 {
99 //
100 // Initialization function.
101 // Loops on all functions and eventual the ntuple, to initialize output objects.
102 //
103
104    // assign data members relations
105    fMother.SetDaughter(0, &fDaughter[0]);
106    fMother.SetDaughter(1, &fDaughter[1]);
107    AliInfo(Form("[%s] Initialization", GetName()));
108    
109    TString name(prefix);
110    name += '_';
111    name += GetName();
112    if (IsMixed()) name.Prepend("mix_");
113    
114    return AliRsnLoop::Init(name.Data(), list);
115 }
116
117 //_____________________________________________________________________________
118 Int_t AliRsnLoopPair::DoLoop
119 (AliRsnEvent *evMain, AliRsnDaughterSelector *selMain, AliRsnEvent *evMix, AliRsnDaughterSelector *selMix)
120 {
121 //
122 // Loop function.
123 // Computes what is needed from passed events.
124 // Returns the number of pairs successfully processed.
125 //
126
127    if (fIsMixed) {
128       AliDebugClass(1, Form("[%s]: event-mixing loop", GetName()));
129       if (!evMix || !selMix) {
130          AliError(Form("[%s] NULL mixed event when mixing is required: cannot process", GetName()));
131          return 0;
132       }
133    } else {
134       AliDebugClass(1, Form("[%s]: single-event loop", GetName()));
135       evMix = evMain;
136       selMix = selMain;
137    }
138    fMother.SetRefEvent(evMain);
139    
140    // check cuts
141    if (!OkEvent(evMain)) {
142       AliDebugClass(1, Form("[%s]: main event not accepted", GetName()));
143       return 0;
144    }
145    if (!OkEvent(evMix)) {
146       AliDebugClass(1, Form("[%s]: mixed event not accepted", GetName()));
147       return 0;
148    }
149    
150    Int_t i0, i1, start, npairs = 0;
151    
152    TEntryList *list0 = selMain->GetSelected(fListID[0], fPairDef->GetDef1().GetChargeC());
153    TEntryList *list1 = selMix ->GetSelected(fListID[1], fPairDef->GetDef2().GetChargeC());
154    if (!list0 || !list1) {
155       AliError("Can't process NULL lists");
156       return 0;
157    }
158    AliDebugClass(2, Form("[%s]: list counts: %d, %d", GetName(), (Int_t)list0->GetN(), (Int_t)list1->GetN()));
159    if (!list0->GetN() || !list1->GetN()) {
160       AliDebugClass(2, Form("[%s]: at least one list is empty", GetName()));
161       return 0;
162    }
163    
164    TObjArrayIter next(&fOutputs);
165    AliRsnListOutput *out = 0x0;
166    
167    for (i0 = 0; i0 < list0->GetN(); i0++) {
168       evMain->SetDaughterAbs(fDaughter[0], (Int_t)list0->GetEntry(i0));
169       start = 0;
170       if (!fDaughter[0].GetRef()) {
171          AliDebugClass(3, Form("[%s]: daughte #1 has NULL ref", GetName()));
172          continue;
173       }
174       if (!fDaughter[0].IsOK()) {
175          AliDebugClass(3, Form("[%s]: daughte #1 is BAD", GetName()));
176          continue;
177       }
178       if (!fIsMixed && list0 == list1) start = i0 + 1;
179       for (i1 = start; i1 < list1->GetN(); i1++) {
180          evMix->SetDaughterAbs(fDaughter[1], (Int_t)list1->GetEntry(i1));
181          if (!fDaughter[1].GetRef()) {
182             AliDebugClass(3, Form("[%s]: daughte #2 has NULL ref", GetName()));
183             continue;
184          }
185          if (!fDaughter[1].IsOK()) {
186             AliDebugClass(3, Form("[%s]: daughte #2 is BAD", GetName()));
187             continue;
188          }
189          // check mother
190          if (!MotherOK()) {
191             AliDebugClass(2, Form("[%s]: candidate mother didn't pass the cuts", GetName()));
192             continue;
193          }
194          // fill outputs
195          next.Reset();
196          while ( (out = (AliRsnListOutput*)next()) ) {
197             if (out->Fill(&fMother)) npairs++;
198             else AliDebugClass(3, Form("[%s]: failed computation", GetName()));
199          }
200       }
201    }
202    
203    return npairs;
204 }
205
206 //_____________________________________________________________________________
207 Bool_t AliRsnLoopPair::MotherOK()
208 {
209 //
210 // Checks that first argument matches definitions for first daughter
211 // and the same for second argument, where the order is defined by
212 // the AliRsnPairDef data member.
213 // If the matching is successful, the AliRsnMother data member is 
214 // initialized using the mass hypotheses defined here and the momenta
215 // in the passed daughters.
216 // The third argument is necessary to choose which one of the possible two
217 // events owning the two daughter will be used as reference.
218 //
219    
220    // check matching and exit if one of them fails
221    // if true pair is required, this is taken into account:
222    // if both true pairs and correct decay tree is required,
223    // then we must be sure that also the true PID of daughters matches,
224    // instead if correct decay tree is not required this additional check is not done
225    fPairDef->GetDef1().SetOnlyTrue(fOnlyTrue && fCheckDecay);
226    fPairDef->GetDef2().SetOnlyTrue(fOnlyTrue && fCheckDecay);
227    if (!fPairDef->GetDef1().MatchesDaughter(&fDaughter[0])) return kFALSE;
228    if (!fPairDef->GetDef2().MatchesDaughter(&fDaughter[1])) return kFALSE;
229    
230    // if matching is successful
231    // compute 4-momenta of daughters and mother
232    fMother.ComputeSum(fPairDef->GetDef1().GetMass(), fPairDef->GetDef2().GetMass());
233    
234    // if required a true pair, check this here and eventually return a fail message
235    // this is done using the method AliRsnMother::CommonMother with 2 arguments
236    // passed by reference, where the real GEANT label of the particle is stored
237    // and one can check if these tracks are both really secondaries (ID >= 0)
238    if (fOnlyTrue) {
239       Int_t m0, m1, common;
240       common = fMother.CommonMother(m0, m1);
241       if (m0 < 0 || m1 < 0) return kFALSE;
242       if (common != fPairDef->GetMotherPDG()) return kFALSE;
243    }
244    
245    // point to first event as reference
246    // and checks the pair cuts,
247    // (done first because it is more likely 
248    // that it is not passed and execution is faster)
249    if (fPairCuts)
250       return fPairCuts->IsSelected(&fMother);
251    else
252       return kTRUE;
253 }