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