]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG2/RESONANCES/AliRsnEvent.cxx
8a86555b886a1bb67830ce8c4ac6bf9e49479979
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnEvent.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 ////////////////////////////////////////////////////////////////////////////////
17 //
18 //  This class works as generic interface to an event.
19 //  Its main purpose is to provide a unique reference which includes all the
20 //  facilities available in the AliVEvent generic base class, plus all info
21 //  which could be needed during analysis, which are not in AliVEvent but
22 //  need to be accessed from ESD or AOD objects, usually in different ways.
23 //  When MC is available, it is properly taken into account.
24 //  
25 //  authors: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
26 //           M. Vala (martin.vala@cern.ch)
27 //
28 ////////////////////////////////////////////////////////////////////////////////
29
30 #include <Riostream.h>
31 #include <TArrayF.h>
32
33 #include "AliLog.h"
34 #include "AliVEvent.h"
35 #include "AliMCEvent.h"
36 #include "AliStack.h"
37 #include "AliGenEventHeader.h"
38 #include "AliESDtrackCuts.h"
39 #include "AliESDUtils.h"
40 #include "AliAODVertex.h"
41 #include "AliMultiplicity.h"
42 #include "AliRsnCutPID.h"
43 #include "AliRsnEvent.h"
44
45 ClassImp(AliRsnEvent)
46
47 //_____________________________________________________________________________
48 AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliVEvent *refMC) :
49    fRef(ref),
50    fRefMC(refMC),
51    fLeading(-1),
52    fLocalID(-1),
53    fPID(0x0)
54 {
55 //
56 // Default constructor.
57 //
58 }
59
60 //_____________________________________________________________________________
61 AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
62    TObject(event),
63    fRef(event.fRef),
64    fRefMC(event.fRefMC),
65    fLeading(event.fLeading),
66    fLocalID(event.fLocalID),
67    fPID(event.fPID)
68 {
69 //
70 // Copy constructor.
71 //
72 }
73
74 //_____________________________________________________________________________
75 AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent & event)
76 {
77 //
78 // Works in the same way as the copy constructor.
79 //
80
81    (TObject)(*this) = (TObject)event;
82    fRef             = event.fRef;
83    fRefMC           = event.fRefMC;
84    fLeading         = event.fLeading;
85    fLocalID         = event.fLocalID;
86    fPID             = event.fPID;
87
88    return (*this);
89 }
90
91 //_____________________________________________________________________________
92 AliRsnEvent::~AliRsnEvent()
93 {
94 //
95 // Destructor.
96 // Dereferences global pointer, if needed.
97 //
98
99    //if (gRsnCurrentEvent == this) gRsnCurrentEvent = 0;
100    //if (gRsnMixedEvent   == this) gRsnMixedEvent = 0;
101 }
102
103 //_____________________________________________________________________________
104 Bool_t AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i, AliRsnDaughter::ERefType type)
105 {
106 //
107 // Using the second and third arguments, retrieves the i-th object in the
108 // appropriate sample (tracks or V0s) and sets the first reference object
109 // in order to point to that.
110 // If a MonteCarlo information is provided, sets the useful informations from there,
111 // and in case of a V0, sets the 'label' data member only when the two daughters
112 // of the V0 point to the same mother.
113 // Returns kFALSE whenever the operation fails (out of range, NULL references).
114 //
115
116    Bool_t ok = kFALSE;
117    
118    out.Reset();
119    out.SetOwnerEvent(this);
120
121    if (IsESD() && type == AliRsnDaughter::kTrack)   ok = SetDaughterESDtrack  (out, i);
122    if (IsAOD() && type == AliRsnDaughter::kTrack)   ok = SetDaughterAODtrack  (out, i);
123    if (IsESD() && type == AliRsnDaughter::kV0)      ok = SetDaughterESDv0     (out, i);
124    if (IsAOD() && type == AliRsnDaughter::kV0)      ok = SetDaughterAODv0     (out, i);
125    if (IsESD() && type == AliRsnDaughter::kCascade) ok = SetDaughterESDcascade(out, i);
126    if (IsAOD() && type == AliRsnDaughter::kCascade) ok = SetDaughterAODcascade(out, i);
127    
128    return ok;
129 }
130
131 //_____________________________________________________________________________
132 Bool_t AliRsnEvent::SetDaughterAbs(AliRsnDaughter &out, Int_t absIndex)
133 {
134 //
135 // Sets the first argument daughter using the absolute index, which
136 // runs continuously from tracks, to V0s, to cascades.
137 // In case the conversion to real index fails, the track is flagged as bad.
138 // Additionally, sets the daughter internal 'fRsnID' member to this index.
139 //
140
141    Int_t index;
142    AliRsnDaughter::ERefType type;
143    
144    out.SetRsnID(absIndex);
145
146    if (ConvertAbsoluteIndex(absIndex, index, type)) {
147       return SetDaughter(out, index, type);
148    }
149    else {
150       out.Reset();
151       return kFALSE;
152    }
153 }
154
155 //_____________________________________________________________________________
156 Bool_t AliRsnEvent::SetDaughterMC(AliRsnDaughter &out, Int_t label)
157 {
158 //
159 // Using the second argument, retrieves the i-th object in the
160 // MC sample (if present) and assigns the track using only that,
161 // so that it is considered both as main reference and MC reference.
162 // (used for MC-only analysis).
163 //
164
165    if (!fRefMC) {
166       out.SetBad();
167       return kFALSE;
168    }
169
170    // try to convert into both types
171    Int_t        imum;
172    AliMCEvent  *esd = GetRefMCESD();
173    AliAODEvent *aod = GetRefMCAOD();
174
175    // ESD
176    if (esd) {
177       // if the MC track exists, assign it
178       AliMCParticle *track = (AliMCParticle*)fRef->GetTrack(label);
179       if (!track) {
180          out.SetBad();
181          return kFALSE;
182       }
183       out.SetRef(track);
184       out.SetRefMC(track);
185       out.SetLabel(label);
186       out.SetGood();
187
188       // search for its mother in stack
189       imum = track->GetMother();
190       if (imum >= 0 && imum < esd->Stack()->GetNtrack()) {
191          TParticle *mum = esd->Stack()->Particle(imum);
192          if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
193       }
194    }
195
196    // AOD
197    if (aod) {
198       // checks that array of MC particles exists
199       TClonesArray *mcArray = (TClonesArray*)aod->GetList()->FindObject(AliAODMCParticle::StdBranchName());
200       if (!mcArray) {
201          out.SetBad();
202          return kFALSE;
203       }
204
205       // in this case one has to loop over the sample to find the good one
206       TObjArrayIter next(mcArray);
207       AliAODMCParticle *part = 0x0;
208       while ((part = (AliAODMCParticle*)next())) {
209          if (TMath::Abs(part->GetLabel()) == label) {
210             // if the MC track exists, assign it
211             out.SetRef(part);
212             out.SetRefMC(part);
213             out.SetLabel(label);
214             out.SetGood();
215
216             // search for the mother
217             imum = part->GetMother();
218             if (imum >= 0 && imum < mcArray->GetEntriesFast()) {
219                AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
220                if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
221             }
222             break;
223          }
224       }
225       return kTRUE;
226    }
227    
228    out.SetOwnerEvent(this);
229
230    return kFALSE;
231 }
232
233 //_____________________________________________________________________________
234 AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, AliRsnDaughter::ERefType type)
235 {
236 //
237 // Returns a daughter set using same criteria as SetDaughter
238 //
239
240    AliRsnDaughter d;
241    SetDaughter(d, i, type);
242    return d;
243 }
244
245 //_____________________________________________________________________________
246 AliRsnDaughter AliRsnEvent::GetDaughterAbs(Int_t absIndex)
247 {
248 //
249 // Returns a daughter set using same criteria as SetDaughter
250 //
251
252    AliRsnDaughter d;
253    SetDaughterAbs(d, absIndex);
254    return d;
255 }
256
257 //_____________________________________________________________________________
258 AliRsnDaughter AliRsnEvent::GetDaughterMC(Int_t i)
259 {
260 //
261 // Returns a daughter set using same criteria as SetDaughterMC
262 //
263
264    AliRsnDaughter d;
265    SetDaughterMC(d, i);
266    return d;
267 }
268
269 //_____________________________________________________________________________
270 Bool_t AliRsnEvent::ConvertAbsoluteIndex(Int_t index, Int_t &realIndex, AliRsnDaughter::ERefType &type)
271 {
272 //
273 // Using the phylosophy of the absolute index, which loops over
274 // all tracks, V0s and cascades, returns the result of a check
275 // on it (first argument) based on this criterion:
276 // 1) if the absolute ID is smaller than number of tracks,
277 //    return itself and the type 'track'
278 // 2) if the absolute ID is larger than number of tracks, subtract it
279 //    and if the result is smaller than number of V0s,
280 //    return the corresponding V0 index and type
281 // 3) if the absolute ID is larger than number of tracks + V0s, subtract them
282 //    and if the result is smaller than number of cascades,
283 //    return the corresponding cascade index and type
284 // The results of this check are stored in the reference arguments, while the outcome of
285 // the function is kTRUE if one of these checks was successful, otherwise it is kFALSE,
286 // meaning that the absolute index reached the end.
287 //
288
289    Int_t nTracks   = fRef->GetNumberOfTracks();
290    Int_t nV0s      = fRef->GetNumberOfV0s();
291    Int_t nCascades = fRef->GetNumberOfCascades();
292
293    if (index < nTracks) {
294       realIndex = index;
295       type = AliRsnDaughter::kTrack;
296       return kTRUE;
297    } else if (index >= nTracks && index < nTracks + nV0s) {
298       realIndex = index - nTracks;
299       type = AliRsnDaughter::kV0;
300       return kTRUE;
301    } else if (index >= nTracks + nV0s && index < nTracks + nV0s + nCascades) {
302       realIndex = index - nTracks - nV0s;
303       type = AliRsnDaughter::kCascade;
304       return kTRUE;
305    }
306
307    realIndex = -1;
308    type = AliRsnDaughter::kNoType;
309    return kFALSE;
310 }
311
312 //_____________________________________________________________________________
313 Int_t AliRsnEvent::ConvertRealIndex(Int_t index, AliRsnDaughter::ERefType type)
314 {
315 //
316 // Translates a pair made by index + object type into the corresponding
317 // absolute index, which is set to -1 in case the real index overflows.
318 //
319
320    Int_t nTracks   = fRef->GetNumberOfTracks();
321    Int_t nV0s      = fRef->GetNumberOfV0s();
322    Int_t nCascades = fRef->GetNumberOfCascades();
323
324    switch (type) {
325       case AliRsnDaughter::kTrack:
326          if (index >= 0 && index < nTracks)
327             return index;
328          else
329             return -1;
330       case AliRsnDaughter::kV0:
331          if (index >= 0 && index < nV0s)
332             return nTracks + index;
333          else
334             return -1;
335       case AliRsnDaughter::kCascade:
336          if (index >= 0 && index < nCascades)
337             return nTracks + nV0s + index;
338          else
339             return -1;
340       default:
341          return -1;
342    }
343 }
344
345 //_____________________________________________________________________________
346 Int_t AliRsnEvent::GetMultiplicityFromESDCuts()
347 {
348 //
349 // Returns event multiplicity as the number of
350 // tracks passing the standard quality cuts.
351 //
352
353    if (!fRef) return -1;
354
355    AliESDEvent *esd = GetRefESD();
356    if (esd) 
357       return AliESDtrackCuts::GetReferenceMultiplicity(esd, kTRUE);
358    else {
359       AliWarning("Invoked multicplicity estimation from AliESDtrackCuts with null ESD");
360       return -1;
361    }
362 }
363
364 //_____________________________________________________________________________
365 Float_t AliRsnEvent::GetMultiplicityFromSPD()
366 {
367 //
368 // Returns event multiplicity computed from SPD.
369 //
370
371    if (!fRef) return -1.0;
372
373    AliESDEvent *esd = GetRefESD();
374    if (esd) {
375       const AliMultiplicity *mult = esd->GetMultiplicity();
376       Float_t nClusters[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
377       for(Int_t ilay = 0; ilay < 6; ilay++) nClusters[ilay] = (Float_t)mult->GetNumberOfITSClusters(ilay);
378       return AliESDUtils::GetCorrSPD2(nClusters[1], GetVz());
379    }
380    else {
381       AliWarning("Cannot compute SPD multiplicity without a well initialized ESD event");
382       return -1.0;
383    }
384 }
385
386 //_____________________________________________________________________________
387 Int_t AliRsnEvent::SelectLeadingParticle
388 (Double_t ptMin, AliRsnCutPID *cutPID)
389 {
390 //
391 // Searches the collection of all particles with given PID type and charge,
392 // and returns the one with largest momentum, provided that it is greater than 1st argument.
393 // If one specifies AliRsnPID::kUnknown as type or AliRsnDaughter::kNoPID as method,
394 // the check is done over all particles irrespectively of their PID.
395 // If the sign argument is '+' or '-', the check is done over the particles of that charge,
396 // otherwise it is done irrespectively of the charge.
397 //
398
399    Int_t i, nTracks = fRef->GetNumberOfTracks();
400    fLeading = -1;
401    AliRsnDaughter leading;
402    leading.SetBad();
403
404    for (i = 0; i < nTracks; i++) {
405       AliRsnDaughter track = GetDaughter(i);
406       if (cutPID) if (!cutPID->IsSelected(&track)) continue;
407       const AliVParticle *ref = track.GetRef();
408       if (ref->Pt() < ptMin) continue;
409       //double pt = track.P().Perp();
410       //Printf("track %d %g", i, pt);
411       if (!leading.IsOK() || ref->Pt() > ptMin) {
412          fLeading = i;
413          //leading = track;
414          ptMin = ref->Pt();
415       }
416    }
417    return fLeading;
418 }
419
420 //_________________________________________________________________________________________________
421 Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID)
422 {
423 //
424 // Loops on the list of tracks and computes average total momentum.
425 //
426
427    Int_t i, nTracks = fRef->GetNumberOfTracks();
428    Double_t pmean = 0.0;
429
430    for (i = 0, count = 0; i < nTracks; i++) {
431       AliRsnDaughter track = GetDaughter(i);
432       if (cutPID) if (!cutPID->IsSelected(&track)) continue;
433       pmean += track.Prec().Mag();
434       count++;
435    }
436
437    if (count > 0) pmean /= (Double_t)count;
438    else pmean = 0.0;
439
440    return pmean;
441 }
442
443 //_____________________________________________________________________________
444 Bool_t AliRsnEvent::GetAngleDistr
445 (Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter *leading)
446 {
447 //
448 // Takes the leading particle and computes the mean and RMS
449 // of the distribution of directions of all other tracks
450 // with respect to the direction of leading particle.
451 //
452
453    if (!leading) return kFALSE;
454    if (!leading->IsOK()) return kFALSE;
455
456    Int_t i, count, nTracks = fRef->GetNumberOfTracks();
457    Double_t angle, angle2Mean = 0.0;
458
459    angleMean = angle2Mean = 0.0;
460
461    for (i = 0, count = 0; i < nTracks; i++) {
462       AliRsnDaughter trk = GetDaughter(i);
463       if (trk.GetID() == leading->GetID()) continue;
464
465       angle = leading->Prec().Angle(trk.Prec().Vect());
466
467       angleMean += angle;
468       angle2Mean += angle * angle;
469       count++;
470    }
471
472    if (!count) return kFALSE;
473
474    angleMean /= (Double_t)count;
475    angle2Mean /= (Double_t)count;
476    angleRMS = TMath::Sqrt(angle2Mean - angleMean * angleMean);
477
478    return kTRUE;
479 }
480
481 //_____________________________________________________________________________
482 Bool_t AliRsnEvent::SetDaughterESDtrack(AliRsnDaughter &out, Int_t i)
483 {
484 //
485 // Setup the first argument to the track identified by the index.
486 // When available, adds the MC information and references.
487 // ---
488 // Version #1: ESD tracks
489 //
490
491    // check 1: index in good range
492    if (i < 0 || i >= fRef->GetNumberOfTracks()) {
493       out.SetBad();
494       return kFALSE;
495    }
496
497    // check 2: not NULL object
498    AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
499    if (!track) {
500       out.SetBad();
501       return kFALSE;
502    }
503
504    // assign references of reconstructed track
505    Int_t label = TMath::Abs(track->GetLabel());
506    out.SetRef(track);
507    out.SetLabel(label);
508    out.SetGood();
509
510    // assign MC info, if available
511    return SetMCInfoESD(out);
512 }
513
514 //_____________________________________________________________________________
515 Bool_t AliRsnEvent::SetDaughterAODtrack(AliRsnDaughter &out, Int_t i)
516 {
517 //
518 // Setup the first argument to the track identified by the index.
519 // When available, adds the MC information and references.
520 // ---
521 // Version #2: AOD tracks
522 //
523
524    // check 1: index in good range
525    if (i < 0 || i >= fRef->GetNumberOfTracks()) {
526       out.SetBad();
527       return kFALSE;
528    }
529
530    // check 2: not NULL object
531    AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
532    if (!track) {
533       out.SetBad();
534       return kFALSE;
535    }
536
537    // assign references of reconstructed track
538    Int_t label = TMath::Abs(track->GetLabel());
539    out.SetRef(track);
540    out.SetLabel(label);
541    out.SetGood();
542
543    // assign MC info, if available
544    return SetMCInfoAOD(out);
545 }
546
547 //_____________________________________________________________________________
548 Bool_t AliRsnEvent::SetDaughterESDv0(AliRsnDaughter &out, Int_t i)
549 {
550 //
551 // Setup the first argument to the track identified by the index.
552 // When available, adds the MC information and references.
553 // ---
554 // Version #3: ESD v0
555 //
556
557    // check 1: index in good range
558    if (i > fRef->GetNumberOfV0s()) {
559       out.SetBad();
560       return 1;
561    }
562
563    // check 2: not NULL object
564    AliESDEvent *ev = GetRefESD();
565    AliESDv0    *v0 = ev->GetV0(i);
566    if (!v0) {
567       out.SetBad();
568       return 2;
569    }
570
571    // assign references of reconstructed track
572    out.SetRef(v0);
573    out.SetGood();
574    out.SetLabel(-1);
575
576    // this time, assigning label is not trivial,
577    // it is done only if MC is present and both
578    // daughters come from a true particle
579    AliMCEvent  *mc = GetRefMCESD();
580    AliESDtrack *tp = ev->GetTrack(v0->GetPindex());
581    AliESDtrack *tn = ev->GetTrack(v0->GetNindex());
582    if (mc && tp && tn) {
583       Int_t        lp = TMath::Abs(tp->GetLabel());
584       Int_t        ln = TMath::Abs(tn->GetLabel());
585       TParticle   *pp = mc->Stack()->Particle(lp);
586       TParticle   *pn = mc->Stack()->Particle(ln);
587       // if their first mothers are the same, the V0 is true
588       // otherwise no label can be assigned
589       if (pp->GetFirstMother() == pn->GetFirstMother() && pp->GetFirstMother() >= 0) out.SetLabel(pp->GetFirstMother());
590    }
591
592    // assign MC info, if available
593    return SetMCInfoESD(out);
594 }
595
596 //_____________________________________________________________________________
597 Bool_t AliRsnEvent::SetDaughterAODv0(AliRsnDaughter &out, Int_t i)
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 v0
604 //
605
606    // check 1: index in good range
607    if (i > fRef->GetNumberOfV0s()) {
608       out.SetBad();
609       return kFALSE;
610    }
611
612    // check 2: not NULL object
613    AliAODEvent *ev = GetRefAOD();
614    AliAODv0    *v0 = ev->GetV0(i);
615    if (!v0) {
616       out.SetBad();
617       return kFALSE;
618    }
619
620    TClonesArray *mcArray = (TClonesArray*)ev->GetList()->FindObject(AliAODMCParticle::StdBranchName());
621    if (!mcArray) {
622       out.SetBad();
623       return kFALSE;
624    }
625
626    // assign references of reconstructed track
627    out.SetRef(v0);
628    out.SetGood();
629    out.SetLabel(-1);
630    
631    // retrieve the owner vertex and its daughters
632    AliAODTrack  *tp  = (AliAODTrack*)v0->GetDaughter(0);
633    AliAODTrack  *tn  = (AliAODTrack*)v0->GetDaughter(1);
634    if (mcArray && tp && tn) {
635       Int_t lp = TMath::Abs(tp->GetLabel());
636       Int_t ln = TMath::Abs(tn->GetLabel());
637       // loop on array to find MC daughters
638       AliAODMCParticle *pp = 0x0, *pn = 0x0;
639       TObjArrayIter next(mcArray);
640       AliAODMCParticle *part = 0x0;
641       while ((part = (AliAODMCParticle*)next())) {
642          if (TMath::Abs(part->GetLabel()) == lp) pp = part;
643          if (TMath::Abs(part->GetLabel()) == ln) pn = part;
644       }
645       // assign a MC reference and a label only to true V0s
646       if (pp && pn)
647          if (pp->GetMother() == pn->GetMother() && pp->GetMother() >= 0) out.SetLabel(pp->GetMother());
648    }
649
650    // assign MC info, if available
651    return SetMCInfoAOD(out);
652 }
653
654 //_____________________________________________________________________________
655 Bool_t AliRsnEvent::SetDaughterESDcascade(AliRsnDaughter &out, Int_t i)
656 {
657 //
658 // Setup the first argument to the track identified by the index.
659 // When available, adds the MC information and references.
660 // ---
661 // Version #3: ESD cascade
662 //
663
664    // check 1: index in good range
665    if (i > fRef->GetNumberOfCascades()) {
666       out.SetBad();
667       return 1;
668    }
669
670    // check 2: not NULL object
671    AliESDEvent   *ev   = GetRefESD();
672    AliESDcascade *casc = ev->GetCascade(i);
673    if (!casc) {
674       out.SetBad();
675       return 2;
676    }
677
678    // assign references of reconstructed track
679    out.SetRef(casc);
680    out.SetGood();
681    out.SetLabel(-1);
682
683    return kTRUE;
684 }
685
686 //_____________________________________________________________________________
687 Bool_t AliRsnEvent::SetDaughterAODcascade(AliRsnDaughter &out, Int_t i)
688 {
689 //
690 // Setup the first argument to the track identified by the index.
691 // When available, adds the MC information and references.
692 // ---
693 // Version #4: AOD cascade
694 //
695
696    // check 1: index in good range
697    if (i > fRef->GetNumberOfCascades()) {
698       out.SetBad();
699       return kFALSE;
700    }
701
702    // check 2: not NULL object
703    AliAODEvent *ev = GetRefAOD();
704    AliAODv0    *casc = ev->GetCascade(i);
705    if (!casc) {
706       out.SetBad();
707       return kFALSE;
708    }
709
710    // assign references of reconstructed track
711    out.SetRef(casc);
712    out.SetGood();
713    out.SetLabel(-1);
714
715    return kTRUE;
716 }
717
718 //_____________________________________________________________________________
719 Bool_t AliRsnEvent::SetMCInfoESD(AliRsnDaughter &out)
720 {
721 //
722 // Using the label assigned to the daughter, searches for the MC informations:
723 // -- MC reference
724 // -- mother
725 //
726
727    Int_t label = out.GetLabel();
728
729    // if no MC reference is available, exit here (successfully)
730    AliMCEvent *mc = GetRefMCESD();
731    if (!mc) return kTRUE;
732    Int_t nMC = mc->GetNumberOfTracks();
733    
734    // debug message for fakes
735    if (label < 0) {
736       AliDebug(AliLog::kDebug + 1, "Fake object (fake track or false V0)");
737       return kFALSE;
738    }
739
740    // assign MC reference, being aware of eventual
741    // overflows in the array (sometimes happened)
742    if (label >= nMC) {
743       AliWarning(Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
744       return kFALSE;
745    }
746    AliMCParticle *mcPart = (AliMCParticle*)mc->GetTrack(label);
747    if (!mcPart) {
748       AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
749       return kFALSE;
750    }
751    out.SetRefMC(mcPart);
752
753    // if this is a primary track, exit here (successfully)
754    Int_t imum = mcPart->Particle()->GetFirstMother();
755    if (imum < 0) {
756       out.SetMotherPDG(0);
757       return kTRUE;
758    }
759
760    // if didn't stop there, search for the mother
761    if (imum >= nMC) {
762       AliWarning(Form("Stack overflow: track mother label = %d -- stack maximum = %d", label, nMC));
763       return kFALSE;
764    }
765    AliMCParticle *mcMother = (AliMCParticle*)mc->GetTrack(imum);
766    if (!mcMother) {
767       AliWarning(Form("Stack discontinuity: label mother %d refers to a NULL object", imum));
768       return kFALSE;
769    }
770    out.SetMotherPDG(TMath::Abs(mcMother->Particle()->GetPdgCode()));
771
772    return kTRUE;
773 }
774
775 //_____________________________________________________________________________
776 Bool_t AliRsnEvent::SetMCInfoAOD(AliRsnDaughter &out)
777 {
778 //
779 // Using the label assigned to the daughter, searches for the MC informations:
780 // -- MC reference
781 // -- mother
782 //
783
784    Int_t label = out.GetLabel();
785    
786    // debug message for fakes
787    if (label < 0) {
788       AliDebug(AliLog::kDebug + 1, "Fake object (fake track or false V0)");
789       return kFALSE;
790    }
791
792    // if no MC reference is available, exit here (successfully)
793    AliAODEvent *mc = GetRefMCAOD();
794    if (!mc) return kTRUE;
795
796    // loop on particles using the track label as reference
797    // and then assign also the mother type, if found
798    TClonesArray *mcArray = (TClonesArray*)mc->GetList()->FindObject(AliAODMCParticle::StdBranchName());
799    if (!mcArray) return kFALSE;
800    TObjArrayIter next(mcArray);
801    AliAODMCParticle *part = 0x0;
802    while ((part = (AliAODMCParticle*)next())) {
803       if (TMath::Abs(part->GetLabel()) == label) {
804          out.SetRefMC(part);
805          out.SetMotherPDG(0);
806          Int_t imum = part->GetMother();
807          if (imum >= 0 && imum <= mcArray->GetEntriesFast()) {
808             AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
809             if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
810             return kTRUE;
811          } else {
812             AliWarning(Form("Array overflow: track mother label = %d -- stack maximum = %d", imum, mcArray->GetEntriesFast()));
813             return kFALSE;
814          }
815
816          // if a MC reference is found, there is no need to go on with the loop
817          break;
818       }
819    }
820
821    return kTRUE;
822 }