]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG2/RESONANCES/AliRsnEvent.cxx
Update of package classes.
[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 "AliAODEvent.h"
22 #include "AliRsnCutPID.h"
23 #include "AliESDtrackCuts.h"
24
25 #include "AliRsnEvent.h"
26
27 ClassImp(AliRsnEvent)
28
29 //_____________________________________________________________________________
30 AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliVEvent *refMC) :
31   fRef(ref),
32   fRefMC(refMC),
33   fLeading(-1)
34 {
35 //
36 // Default constructor.
37 //
38 }
39
40 //_____________________________________________________________________________
41 AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
42   TObject(event),
43   fRef(event.fRef),
44   fRefMC(event.fRefMC),
45   fLeading(event.fLeading)
46 {
47 //
48 // Copy constructor.
49 //
50 }
51
52 //_____________________________________________________________________________
53 AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent & event)
54 {
55 //
56 // Works in the same way as the copy constructor.
57 //
58
59   (TObject)(*this) = (TObject)event;
60   fRef             = event.fRef;
61   fRefMC           = event.fRefMC;
62   fLeading         = event.fLeading;
63
64   return (*this);
65 }
66
67 //_____________________________________________________________________________
68 Bool_t AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i, AliRsnDaughter::ERefType type)
69 {
70 //
71 // Using the second and third arguments, retrieves the i-th object in the
72 // appropriate sample (tracks or V0s) and sets the first reference object
73 // in order to point to that.
74 // If a MonteCarlo information is provided, sets the useful informations from there,
75 // and in case of a V0, sets the 'label' data member only when the two daughters
76 // of the V0 point to the same mother.
77 // Returns kFALSE whenever the operation fails (out of range, NULL references).
78 //
79   
80   if (IsESD() && type == AliRsnDaughter::kTrack  ) return SetDaughterESDtrack  (out, i);
81   if (IsAOD() && type == AliRsnDaughter::kTrack  ) return SetDaughterAODtrack  (out, i);
82   if (IsESD() && type == AliRsnDaughter::kV0     ) return SetDaughterESDv0     (out, i);
83   if (IsAOD() && type == AliRsnDaughter::kV0     ) return SetDaughterAODv0     (out, i);
84   if (IsESD() && type == AliRsnDaughter::kCascade) return SetDaughterESDcascade(out, i);
85   if (IsAOD() && type == AliRsnDaughter::kCascade) return SetDaughterAODcascade(out, i);
86   
87   return kFALSE;
88 }
89
90 //_____________________________________________________________________________
91 Bool_t AliRsnEvent::SetDaughterMC(AliRsnDaughter &out, Int_t label)
92 {
93 //
94 // Using the second argument, retrieves the i-th object in the
95 // MC sample (if present) and assigns the track using only that,
96 // so that it is considered both as main reference and MC reference.
97 // (used for MC-only analysis).
98 //
99
100   if (!fRefMC)
101   {
102     out.SetBad();
103     return kFALSE;
104   }
105   
106   // try to convert into both types
107   Int_t        imum;
108   AliMCEvent  *esd = GetRefMCESD();
109   AliAODEvent *aod = GetRefMCAOD();
110   
111   // ESD
112   if (esd)
113   {
114     // if the MC track exists, assign it
115     AliMCParticle *track = (AliMCParticle*)fRef->GetTrack(label);
116     if (!track)
117     {
118       out.SetBad();
119       return kFALSE;
120     }
121     out.SetRef(track);
122     out.SetRefMC(track);
123     out.SetLabel(label);
124     out.SetGood();
125     
126     // search for its mother in stack
127     imum = track->GetMother();
128     if (imum >= 0 && imum < esd->Stack()->GetNtrack())
129     {
130       TParticle *mum = esd->Stack()->Particle(imum);
131       if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
132     }
133   }
134   
135   // AOD
136   if (aod)
137   {
138     // checks that array of MC particles exists
139     TClonesArray *mcArray = (TClonesArray*)aod->GetList()->FindObject(AliAODMCParticle::StdBranchName());
140     if(!mcArray)
141     {
142       out.SetBad();
143       return kFALSE;
144     }
145     
146     // in this case one has to loop over the sample to find the good one
147     TObjArrayIter next(mcArray);
148     AliAODMCParticle *part = 0x0;
149     while ( (part = (AliAODMCParticle*)next()) )
150     {
151       if (TMath::Abs(part->GetLabel()) == label)
152       {
153         // if the MC track exists, assign it
154         out.SetRef(part);
155         out.SetRefMC(part);
156         out.SetLabel(label);
157         out.SetGood();
158         
159         // search for the mother
160         imum = part->GetMother();
161         if (imum >= 0 && imum < mcArray->GetEntriesFast())
162         {
163           AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
164           if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
165         }
166         break;
167       }
168     }
169     return kTRUE;
170   }
171   
172   return kFALSE;
173 }
174
175 //_____________________________________________________________________________
176 AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, AliRsnDaughter::ERefType type)
177 {
178 //
179 // Returns a daughter set using same criteria as SetDaughter
180 //
181   
182   AliRsnDaughter d; 
183   SetDaughter(d, i, type); 
184   return d;
185 }
186
187 //_____________________________________________________________________________
188 AliRsnDaughter AliRsnEvent::GetDaughterMC(Int_t i)
189 {
190 //
191 // Returns a daughter set using same criteria as SetDaughterMC
192 //
193   
194   AliRsnDaughter d; 
195   SetDaughterMC(d, i); 
196   return d;
197 }
198
199 //_____________________________________________________________________________
200 Int_t AliRsnEvent::GetAbsoluteSum()
201 {
202 //
203 // Utility method that returns the sum of all daughter-like objects:
204 // tracks, V0s and cascades
205 //
206
207   Int_t total = 0;
208   
209   total += fRef->GetNumberOfTracks();
210   total += fRef->GetNumberOfV0s();
211   total += fRef->GetNumberOfCascades();
212   
213   return total;
214 }
215
216 //_____________________________________________________________________________
217 Bool_t AliRsnEvent::ConvertAbsoluteIndex(Int_t index, Int_t &realIndex, AliRsnDaughter::ERefType &type)
218 {
219 //
220 // Using the phylosophy of the absolute index, which loops over
221 // all tracks, V0s and cascades, returns the result of a check
222 // on it (first argument) based on this criterion:
223 // 1) if the absolute ID is smaller than number of tracks,
224 //    return itself and the type 'track'
225 // 2) if the absolute ID is larger than number of tracks, subtract it
226 //    and if the result is smaller than number of V0s,
227 //    return the corresponding V0 index and type
228 // 3) if the absolute ID is larger than number of tracks + V0s, subtract them
229 //    and if the result is smaller than number of cascades,
230 //    return the corresponding cascade index and type
231 // The results of this check are stored in the reference arguments, while the outcome of
232 // the function is kTRUE if one of these checks was successful, otherwise it is kFALSE,
233 // meaning that the absolute index reached the end.
234 //
235
236   Int_t nTracks   = fRef->GetNumberOfTracks();
237   Int_t nV0s      = fRef->GetNumberOfV0s();
238   Int_t nCascades = fRef->GetNumberOfCascades();
239   
240   if (index < nTracks)
241   {
242     realIndex = index;
243     type = AliRsnDaughter::kTrack;
244     return kTRUE;
245   }
246   else if (index >= nTracks && index < nTracks + nV0s)
247   {
248     realIndex = index - nTracks;
249     type = AliRsnDaughter::kV0;
250     return kTRUE;
251   }
252   else if (index >= nTracks + nV0s && index < nTracks + nV0s + nCascades)
253   {
254     realIndex = index - nTracks - nV0s;
255     type = AliRsnDaughter::kCascade;
256     return kTRUE;
257   }
258   
259   realIndex = -1;
260   type = AliRsnDaughter::kNoType;
261   return kFALSE;
262 }
263
264 //_____________________________________________________________________________
265 Int_t AliRsnEvent::GetMultiplicity(AliESDtrackCuts *cuts)
266 {
267 //
268 // Returns event multiplicity as the number of tracks.
269 // If the argument is not NULL, returns instead the 
270 // number of tracks passing the cuts hereby defined.
271 //
272
273   if (!fRef) return 0;
274   
275   AliESDEvent *esd = GetRefESD();
276   if (cuts && esd) return cuts->CountAcceptedTracks(esd); 
277   else return fRef->GetNumberOfTracks();
278 }
279
280 //_____________________________________________________________________________
281 Double_t AliRsnEvent::GetVz()
282 {
283 //
284 // Return Z coord of primary vertex
285 //
286
287   return fRef->GetPrimaryVertex()->GetZ();
288 }
289
290 //_____________________________________________________________________________
291 Int_t AliRsnEvent::SelectLeadingParticle
292 (Double_t ptMin, AliRsnCutPID *cutPID)
293 {
294 //
295 // Searches the collection of all particles with given PID type and charge,
296 // and returns the one with largest momentum, provided that it is greater than 1st argument.
297 // If one specifies AliRsnPID::kUnknown as type or AliRsnDaughter::kNoPID as method,
298 // the check is done over all particles irrespectively of their PID.
299 // If the sign argument is '+' or '-', the check is done over the particles of that charge,
300 // otherwise it is done irrespectively of the charge.
301 //
302
303   Int_t i, nTracks = fRef->GetNumberOfTracks();
304   fLeading = -1;
305   AliRsnDaughter leading;
306   leading.SetBad();
307
308   for (i = 0; i < nTracks; i++) 
309   {
310     AliRsnDaughter track = GetDaughter(i);
311     if (cutPID) if (!cutPID->IsSelected(&track)) continue;
312     const AliVParticle *ref = track.GetRef();
313     if (ref->Pt() < ptMin) continue;
314     //double pt = track.P().Perp();
315     //Printf("track %d %g", i, pt);
316     if (!leading.IsOK() || ref->Pt() > ptMin)
317     {
318       fLeading = i;
319       //leading = track;
320       ptMin = ref->Pt();
321     }
322   }
323   return fLeading;
324 }
325
326 //_________________________________________________________________________________________________
327 Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID)
328 {
329 //
330 // Loops on the list of tracks and computes average total momentum.
331 //
332
333   Int_t i, nTracks = fRef->GetNumberOfTracks();
334   Double_t pmean = 0.0;
335
336   for (i = 0, count = 0; i < nTracks; i++) {
337     AliRsnDaughter track = GetDaughter(i);
338     if (cutPID) if (!cutPID->IsSelected(&track)) continue;
339     pmean += track.P().Mag();
340     count++;
341   }
342
343   if (count > 0) pmean /= (Double_t)count;
344   else pmean = 0.0;
345
346   return pmean;
347 }
348
349 //_____________________________________________________________________________
350 Bool_t AliRsnEvent::GetAngleDistr
351 (Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter leading)
352 {
353 //
354 // Takes the leading particle and computes the mean and RMS
355 // of the distribution of directions of all other tracks
356 // with respect to the direction of leading particle.
357 //
358
359   if (!leading.IsOK()) return kFALSE;
360
361   Int_t i, count, nTracks = fRef->GetNumberOfTracks();
362   Double_t angle, angle2Mean = 0.0;
363
364   angleMean = angle2Mean = 0.0;
365
366   for (i = 0, count = 0; i < nTracks; i++) {
367     AliRsnDaughter trk = GetDaughter(i);
368     if (trk.GetID() == leading.GetID()) continue;
369
370     angle = leading.P().Angle(trk.P().Vect());
371
372     angleMean += angle;
373     angle2Mean += angle * angle;
374     count++;
375   }
376
377   if (!count) return kFALSE;
378
379   angleMean /= (Double_t)count;
380   angle2Mean /= (Double_t)count;
381   angleRMS = TMath::Sqrt(angle2Mean - angleMean * angleMean);
382
383   return kTRUE;
384 }
385
386 //_____________________________________________________________________________
387 Bool_t AliRsnEvent::SetDaughterESDtrack(AliRsnDaughter &out, Int_t i)
388 {
389 //
390 // Setup the first argument to the track identified by the index.
391 // When available, adds the MC information and references.
392 // ---
393 // Version #1: ESD tracks
394 //
395   
396   // check 1: index in good range
397   if (i < 0 || i >= fRef->GetNumberOfTracks())
398   {
399     out.SetBad();
400     return kFALSE;
401   }
402   
403   // check 2: not NULL object
404   AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
405   if (!track)
406   {
407     out.SetBad();
408     return kFALSE;
409   }
410   
411   // assign references of reconstructed track
412   Int_t label = TMath::Abs(track->GetLabel());
413   out.SetRef(track);
414   out.SetLabel(label);
415   out.SetGood();
416   
417   // assign MC info, if available
418   return SetMCInfoESD(out);
419 }
420
421 //_____________________________________________________________________________
422 Bool_t AliRsnEvent::SetDaughterAODtrack(AliRsnDaughter &out, Int_t i)
423 {
424 //
425 // Setup the first argument to the track identified by the index.
426 // When available, adds the MC information and references.
427 // ---
428 // Version #2: AOD tracks
429 //
430   
431   // check 1: index in good range
432   if (i < 0 || i >= fRef->GetNumberOfTracks())
433   {
434     out.SetBad();
435     return kFALSE;
436   }
437   
438   // check 2: not NULL object
439   AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
440   if (!track)
441   {
442     out.SetBad();
443     return kFALSE;
444   }
445   
446   // assign references of reconstructed track
447   Int_t label = TMath::Abs(track->GetLabel());
448   out.SetRef(track);
449   out.SetLabel(label);
450   out.SetGood();
451   
452   // assign MC info, if available
453   return SetMCInfoAOD(out);
454 }
455
456 //_____________________________________________________________________________
457 Bool_t AliRsnEvent::SetDaughterESDv0(AliRsnDaughter &out, Int_t i)
458 {
459 //
460 // Setup the first argument to the track identified by the index.
461 // When available, adds the MC information and references.
462 // ---
463 // Version #3: ESD v0
464 //
465
466   // check 1: index in good range
467   if (i > fRef->GetNumberOfV0s())
468   {
469     out.SetBad();
470     return 1;
471   }
472   
473   // check 2: not NULL object
474   AliESDEvent *ev = GetRefESD();
475   AliESDv0    *v0 = ev->GetV0(i);
476   if (!v0)
477   {
478     out.SetBad();
479     return 2;
480   }
481   
482   // assign references of reconstructed track
483   out.SetRef(v0);
484   out.SetGood();
485   
486   // this time, assigning label is not trivial,
487   // it is done only if MC is present and both
488   // daughters come from a true particle
489   AliMCEvent  *mc = GetRefMCESD();
490   AliESDtrack *tp = ev->GetTrack(v0->GetPindex());
491   AliESDtrack *tn = ev->GetTrack(v0->GetNindex());
492   if (mc && tp && tn)
493   {
494     Int_t        lp = TMath::Abs(tp->GetLabel());
495     Int_t        ln = TMath::Abs(tn->GetLabel());
496     TParticle   *pp = mc->Stack()->Particle(lp);
497     TParticle   *pn = mc->Stack()->Particle(ln);
498     // if their first mothers are the same, the V0 is true
499     // otherwise no label can be assigned
500     if (pp->GetFirstMother() == pn->GetFirstMother()) out.SetLabel(pp->GetFirstMother());
501   }
502   
503   // assign MC info, if available
504   return SetMCInfoESD(out);
505 }
506
507 //_____________________________________________________________________________
508 Bool_t AliRsnEvent::SetDaughterAODv0(AliRsnDaughter &out, Int_t i)
509 {
510 //
511 // Setup the first argument to the track identified by the index.
512 // When available, adds the MC information and references.
513 // ---
514 // Version #4: AOD v0
515 //
516
517   // check 1: index in good range
518   if (i > fRef->GetNumberOfV0s())
519   {
520     out.SetBad();
521     return kFALSE;
522   }
523   
524   // check 2: not NULL object
525   AliAODEvent *ev = GetRefAOD();
526   AliAODv0    *v0 = ev->GetV0(i);
527   if (!v0)
528   {
529     out.SetBad();
530     return kFALSE;
531   }
532   
533   // assign references of reconstructed track
534   out.SetRef(v0);
535   out.SetGood();
536   out.SetLabel(-1);
537   
538   // this time, assigning label is not trivial,
539   // it is done only if MC is present and both
540   // daughters come from a true particle
541   TClonesArray *mcArray = (TClonesArray*)ev->GetList()->FindObject(AliAODMCParticle::StdBranchName());
542   AliAODTrack  *tp = ev->GetTrack(v0->GetPosID());
543   AliAODTrack  *tn = ev->GetTrack(v0->GetNegID());
544   if (mcArray && tp && tn)
545   {
546     Int_t        lp = TMath::Abs(tp->GetLabel());
547     Int_t        ln = TMath::Abs(tn->GetLabel());
548     // loop on array to find MC daughters
549     AliAODMCParticle *pp = 0x0, *pn = 0x0;
550     TObjArrayIter next(mcArray);
551     AliAODMCParticle *part = 0x0;
552     while ( (part = (AliAODMCParticle*)next()) )
553     {
554       if (TMath::Abs(part->GetLabel()) == lp) pp = (AliAODMCParticle*)mcArray->IndexOf(part);
555       if (TMath::Abs(part->GetLabel()) == ln) pn = (AliAODMCParticle*)mcArray->IndexOf(part);
556     }
557     // assign a MC reference and a label only to true V0s
558     if (pp->GetMother() == pn->GetMother()) out.SetLabel(pp->GetMother());
559   }
560   
561   // assign MC info, if available
562   return SetMCInfoAOD(out);
563 }
564
565 //_____________________________________________________________________________
566 Bool_t AliRsnEvent::SetDaughterESDcascade(AliRsnDaughter &out, Int_t i)
567 {
568 //
569 // Setup the first argument to the track identified by the index.
570 // When available, adds the MC information and references.
571 // ---
572 // Version #3: ESD cascade
573 //
574
575   return kTRUE;
576 }
577
578 //_____________________________________________________________________________
579 Bool_t AliRsnEvent::SetDaughterAODcascade(AliRsnDaughter &out, Int_t i)
580 {
581 //
582 // Setup the first argument to the track identified by the index.
583 // When available, adds the MC information and references.
584 // ---
585 // Version #4: AOD cascade
586 //
587
588   return kTRUE;
589 }
590
591 //_____________________________________________________________________________
592 Bool_t AliRsnEvent::SetMCInfoESD(AliRsnDaughter &out)
593 {
594 //
595 // Using the label assigned to the daughter, searches for the MC informations:
596 // -- MC reference
597 // -- mother
598 //
599
600   Int_t label = out.GetLabel();
601   if (label < 0) return kFALSE;
602   
603   // if no MC reference is available, exit here (successfully)
604   AliMCEvent *mc = GetRefMCESD();
605   if (!mc) return kTRUE;
606   Int_t nMC = mc->GetNumberOfTracks();
607   
608   // assign MC reference, being aware of eventual
609   // overflows in the array (sometimes happened)
610   if (label < 0 || label >= nMC)
611   {
612     AliWarning(Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
613     return kFALSE;
614   }
615   AliMCParticle *mcPart = (AliMCParticle*)mc->GetTrack(label);
616   if (!mcPart)
617   {
618     AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
619     return kFALSE;
620   }
621   out.SetRefMC(mcPart);
622   
623   // if this is a primary track, exit here (successfully)
624   Int_t imum = mcPart->Particle()->GetFirstMother();
625   if (imum < 0) return kTRUE;
626   
627   // if didn't stop there, search for the mother
628   if (imum >= nMC)
629   {
630     AliWarning(Form("Stack overflow: track mother label = %d -- stack maximum = %d", label, nMC));
631     return kFALSE;
632   }
633   AliMCParticle *mcMother = (AliMCParticle*)mc->GetTrack(imum);
634   if (!mcMother)
635   {
636     AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", imum));
637     return kFALSE;
638   }
639   out.SetMotherPDG(TMath::Abs(mcMother->Particle()->GetPdgCode()));
640   
641   return kTRUE;
642 }
643
644 //_____________________________________________________________________________
645 Bool_t AliRsnEvent::SetMCInfoAOD(AliRsnDaughter &out)
646 {
647 //
648 // Using the label assigned to the daughter, searches for the MC informations:
649 // -- MC reference
650 // -- mother
651 //
652
653   Int_t label = out.GetLabel();
654   if (label < 0) return kFALSE;
655   
656   // if no MC reference is available, exit here (successfully)
657   AliAODEvent *mc = GetRefMCAOD();
658   if (!mc) return kTRUE;
659   
660   // loop on particles using the track label as reference
661   // and then assign also the mother type, if found
662   TClonesArray *mcArray = (TClonesArray*)mc->GetList()->FindObject(AliAODMCParticle::StdBranchName());
663   if(!mcArray) return kFALSE;
664   TObjArrayIter next(mcArray);
665   AliAODMCParticle *part = 0x0;
666   while ( (part = (AliAODMCParticle*)next()) )
667   {
668     if (TMath::Abs(part->GetLabel()) == label)
669     {
670       out.SetRefMC(part);
671       Int_t imum = part->GetMother();
672       if (imum >= 0 && imum <= mcArray->GetEntriesFast())
673       {
674         AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
675         if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
676       }
677       else
678       {
679         AliWarning(Form("Array overflow: track mother label = %d -- stack maximum = %d", imum, mcArray->GetEntriesFast()));
680         return kFALSE;
681       }
682       
683       // if a MC reference is found, there is no need to go on with the loop
684       break;
685     }
686   }
687   
688   return kTRUE;
689 }