485987a21fcc79230fd0a4029a02278976216595
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnEvent.cxx
1 //
2 // *** Class AliRsnEvent ***
3 //
4 // A container for a collection of AliRsnDaughter objects from an event.
5 // Contains also the primary vertex, useful for some cuts.
6 // In order to retrieve easily the tracks which have been identified
7 // as a specific type and charge, there is an array of indexes which
8 // allows to avoid to loop on all tracks and have only the neede ones.
9 //
10 // authors: A. Pulvirenti (email: alberto.pulvirenti@ct.infn.it)
11 //          M. Vala (email: martin.vala@cern.ch)
12 //
13
14 #include <TArrayF.h>
15
16 #include "AliLog.h"
17 #include "AliVEvent.h"
18 #include "AliMCEvent.h"
19 #include "AliStack.h"
20 #include "AliGenEventHeader.h"
21 #include "AliRsnCutPID.h"
22
23 #include "AliRsnEvent.h"
24
25 ClassImp(AliRsnEvent)
26
27 //_____________________________________________________________________________
28 AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliMCEvent *refMC) :
29   fRef(ref),
30   fRefMC(refMC),
31   fLeading(-1)
32 {
33 //
34 // Default constructor.
35 //
36 }
37
38 //_____________________________________________________________________________
39 AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
40   TObject(event),
41   fRef(event.fRef),
42   fRefMC(event.fRefMC),
43   fLeading(event.fLeading)
44 {
45 //
46 // Copy constructor.
47 //
48 }
49
50 //_____________________________________________________________________________
51 AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent & event)
52 {
53 //
54 // Works in the same way as the copy constructor.
55 //
56
57   (TObject)(*this) = (TObject)event;
58   fRef             = event.fRef;
59   fRefMC           = event.fRefMC;
60   fLeading         = event.fLeading;
61
62   return (*this);
63 }
64
65 //_____________________________________________________________________________
66 AliRsnEvent::~AliRsnEvent()
67 {
68 //
69 // Destructor.
70 //
71 }
72
73 //_____________________________________________________________________________
74 Bool_t AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i, AliRsnDaughter::ERefType type)
75 {
76 //
77 // Using the second and third arguments, retrieves the i-th object in the
78 // appropriate sample (tracks or V0s) and sets the firs reference object
79 // in order to point to that.
80 // If a MonteCarlo information is provided, sets the useful informations from there,
81 // and in case of a V0, sets the 'label' data member only when the two daughters
82 // of the V0 point to the same mother.
83 // Returns kFALSE whenever the operation fails (out of range, NULL references).
84 //
85
86   Int_t label;
87
88   // retrieve reference particle from reference event
89   // if it is found, by defaul track can be used (good)
90   if (type == AliRsnDaughter::kTrack)
91   {
92     if (i >= fRef->GetNumberOfTracks())
93     {
94       out.SetBad();
95       return kFALSE;
96     }
97     AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
98     label = TMath::Abs(track->GetLabel());
99     if (!track)
100     {
101       out.SetBad();
102       return kFALSE;
103     }
104     else
105     {
106       out.SetRef(track);
107       out.SetLabel(label);
108       if (fRefMC)
109       {
110         if (label < fRefMC->GetNumberOfTracks()) 
111         {
112           AliMCParticle *part = (AliMCParticle*)fRefMC->GetTrack(label);
113           out.SetRefMC(part);
114         }
115       }
116       out.SetGood();
117     }
118   }
119   else if (type == AliRsnDaughter::kV0)
120   {
121     if (i > fRef->GetNumberOfV0s())
122     {
123       out.SetBad();
124       return kFALSE;
125     }
126     AliESDv0     *esdV = 0x0;
127     AliAODv0     *aodV = 0x0;
128     Int_t         lp, ln;
129     AliVTrack    *tp = 0x0, *tn = 0x0;
130     if (IsESD()) esdV = GetRefESD()->GetV0(i);
131     if (IsAOD()) aodV = GetRefAOD()->GetV0(i);
132     if (!esdV && !aodV)
133     {
134       out.SetBad();
135       return kFALSE;
136     }
137     else
138     {
139       if (esdV) out.SetRef(esdV); else out.SetRef(aodV);
140       // retrieve the V0 daughters, which must be done differently with ESD and AOD v0s
141       if (esdV)
142       {
143         // get the 2 daughters of the V0
144         AliESDEvent *ev = dynamic_cast<AliESDEvent*>(fRef);
145         tp = ev->GetTrack(esdV->GetPindex());
146         tn = ev->GetTrack(esdV->GetNindex());
147       }
148       else if (aodV)
149       {
150         // get the 2 daughters of the V0
151         AliAODEvent *ev = dynamic_cast<AliAODEvent*>(fRef);
152         tp = ev->GetTrack(aodV->GetPosID());
153         tn = ev->GetTrack(aodV->GetNegID());
154       }
155
156       // now, if we have a MC, use the two track objects
157       // to retrieve the true particle which generated the V0
158       // using their labels; by default they are a false V0 with label -1
159       label = -1;
160       if (tp && tn && fRefMC)
161       {
162         lp = TMath::Abs(tp->GetLabel());
163         ln = TMath::Abs(tn->GetLabel());
164         // if labels are meaningful, retrieve corresponding particles
165         TParticle *pp = fRefMC->Stack()->Particle(lp);
166         TParticle *pn = fRefMC->Stack()->Particle(ln);
167         // if their first mothers are the same, the V0 is true
168         // otherwise no label can be assigned
169         if (pp->GetFirstMother() == pn->GetFirstMother()) label = pp->GetFirstMother();
170       }
171       out.SetLabel(label);
172       out.SetGood();
173     }
174   }
175   
176   // finally, in case we have a MC, searches for the mother, in order to store
177   // its PDG code into the output AliRsnDaughter
178   if (fRefMC)
179   {
180     label = out.GetLabel();
181     AliStack *stack = fRefMC->Stack();
182     if (label >= 0 && label < stack->GetNtrack())
183     {
184       TParticle *part = stack->Particle(label);
185       if (part)
186       {
187         Int_t imum = part->GetFirstMother();
188         if (imum >= 0 && imum <= stack->GetNtrack())
189         {
190           TParticle *mum = stack->Particle(imum);
191           if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
192         }
193       }
194     }
195   }
196   
197   return kTRUE;
198 }
199
200 //_____________________________________________________________________________
201 Bool_t AliRsnEvent::SetDaughterMC(AliRsnDaughter &out, Int_t i)
202 {
203 //
204 // Using the second argument, retrieves the i-th object in the
205 // appropriate sample and sets the firs reference object
206 // in order to point to that.
207 // If a MonteCarlo information is provided, sets the useful informations from there,
208 // and in case of a V0, sets the 'label' data member only when the two daughters
209 // of the V0 point to the same mother.
210 // Returns kFALSE whenever the operation fails (out of range, NULL references).
211 //
212
213   if (!fRefMC)
214   {
215     out.SetBad();
216     return kFALSE;
217   }
218
219   if (i >= fRefMC->GetNumberOfTracks())
220   {
221     out.SetBad();
222     return kFALSE;
223   }
224   
225   AliMCParticle *track = (AliMCParticle*)fRef->GetTrack(i);
226   if (!track)
227   {
228     out.SetBad();
229     return kFALSE;
230   }
231   else
232   {
233     out.SetRef(track);
234     out.SetRefMC(track);
235     out.SetLabel(i);
236     out.SetGood();
237   }
238   
239   AliStack  *stack = fRefMC->Stack();
240   TParticle *part  = track->Particle();
241   if (part)
242   {
243     Int_t imum = part->GetFirstMother();
244     if (imum >= 0 && imum <= stack->GetNtrack())
245     {
246       TParticle *mum = stack->Particle(imum);
247       if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
248     }
249   }
250   
251   return kTRUE;
252 }
253
254 //_____________________________________________________________________________
255 AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, AliRsnDaughter::ERefType type)
256 {
257 //
258 // Return an AliRsnDaughter taken from this event,
259 // with all additional data members well set.
260 //
261
262   AliRsnDaughter out;
263   SetDaughter(out, i, type);
264
265   return out;
266 }
267
268 //_____________________________________________________________________________
269 AliRsnDaughter AliRsnEvent::GetDaughterMC(Int_t i)
270 {
271 //
272 // Return an AliRsnDaughter taken from this event,
273 // with all additional data members well set.
274 //
275
276   AliRsnDaughter out;
277   SetDaughterMC(out, i);
278
279   return out;
280 }
281
282 //_____________________________________________________________________________
283 Int_t AliRsnEvent::GetMultiplicity()
284 {
285 //
286 // Returns event multiplicity
287 //
288   AliDebug(AliLog::kDebug+2,"<-");
289   if (!fRef) return 0;
290   AliDebug(AliLog::kDebug+2,"->");
291   return fRef->GetNumberOfTracks();
292 }
293
294 //_____________________________________________________________________________
295 Double_t AliRsnEvent::GetVz()
296 {
297 //
298 // Return Z coord of primary vertex
299 //
300
301   AliDebug(AliLog::kDebug+2,"<-");
302   return fRef->GetPrimaryVertex()->GetZ();
303   AliDebug(AliLog::kDebug+2,"->");
304 }
305
306 //_____________________________________________________________________________
307 Int_t AliRsnEvent::SelectLeadingParticle
308 (Double_t ptMin, AliRsnCutPID *cutPID)
309 {
310 //
311 // Searches the collection of all particles with given PID type and charge,
312 // and returns the one with largest momentum, provided that it is greater than 1st argument.
313 // If one specifies AliRsnPID::kUnknown as type or AliRsnDaughter::kNoPID as method,
314 // the check is done over all particles irrespectively of their PID.
315 // If the sign argument is '+' or '-', the check is done over the particles of that charge,
316 // otherwise it is done irrespectively of the charge.
317 //
318
319   Int_t i, nTracks = fRef->GetNumberOfTracks();
320   fLeading = -1;
321   AliRsnDaughter leading;
322   leading.SetBad();
323
324   for (i = 0; i < nTracks; i++) {
325     AliRsnDaughter track = GetDaughter(i);
326     if (cutPID) if (!cutPID->IsSelected(&track)) continue;
327     if (track.P().Perp() < ptMin) continue;
328     if (!leading.IsOK() || track.P().Perp() > leading.P().Perp())
329     {
330       fLeading = i;
331       leading = track;
332     }
333   }
334
335   return fLeading;
336 }
337
338 //_________________________________________________________________________________________________
339 Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID)
340 {
341 //
342 // Loops on the list of tracks and computes average total momentum.
343 //
344
345   Int_t i, nTracks = fRef->GetNumberOfTracks();
346   Double_t pmean = 0.0;
347
348   for (i = 0, count = 0; i < nTracks; i++) {
349     AliRsnDaughter track = GetDaughter(i);
350     if (cutPID) if (!cutPID->IsSelected(&track)) continue;
351     pmean += track.P().Mag();
352     count++;
353   }
354
355   if (count > 0) pmean /= (Double_t)count;
356   else pmean = 0.0;
357
358   return pmean;
359 }
360
361 //_____________________________________________________________________________
362 Bool_t AliRsnEvent::GetAngleDistr
363 (Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter leading)
364 {
365 //
366 // Takes the leading particle and computes the mean and RMS
367 // of the distribution of directions of all other tracks
368 // with respect to the direction of leading particle.
369 //
370
371   if (!leading.IsOK()) return kFALSE;
372
373   Int_t i, count, nTracks = fRef->GetNumberOfTracks();
374   Double_t angle, angle2Mean = 0.0;
375
376   angleMean = angle2Mean = 0.0;
377
378   for (i = 0, count = 0; i < nTracks; i++) {
379     AliRsnDaughter trk = GetDaughter(i);
380     if (trk.GetID() == leading.GetID()) continue;
381
382     angle = leading.P().Angle(trk.P().Vect());
383
384     angleMean += angle;
385     angle2Mean += angle * angle;
386     count++;
387   }
388
389   if (!count) return kFALSE;
390
391   angleMean /= (Double_t)count;
392   angle2Mean /= (Double_t)count;
393   angleRMS = TMath::Sqrt(angle2Mean - angleMean * angleMean);
394
395   return kTRUE;
396 }