Splitted the PID cuts into three classes for ITS, TPC and TOF, and added the possibil...
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnEvent.cxx
CommitLineData
06351446 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//
0dffcc8a 13
4fbb2459 14#include <TArrayF.h>
0dffcc8a 15
7c2974c8 16#include "AliLog.h"
5eb970a4 17#include "AliVEvent.h"
5eb970a4 18#include "AliMCEvent.h"
19#include "AliStack.h"
4fbb2459 20#include "AliGenEventHeader.h"
a378358c 21#include "AliAODEvent.h"
2dab9030 22#include "AliRsnCutPID.h"
a378358c 23#include "AliESDtrackCuts.h"
7c2974c8 24
0dffcc8a 25#include "AliRsnEvent.h"
26
aec0ec32 27ClassImp(AliRsnEvent)
0dffcc8a 28
5faf5a07 29AliRsnEvent* AliRsnEvent::fgRsnEvent1 = 0;
30AliRsnEvent* AliRsnEvent::fgRsnEvent2 = 0;
31
7c2974c8 32//_____________________________________________________________________________
a378358c 33AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliVEvent *refMC) :
2dab9030 34 fRef(ref),
35 fRefMC(refMC),
5faf5a07 36 fLeading(-1),
37 fLocalID(-1)
2f769150 38{
06351446 39//
4fbb2459 40// Default constructor.
06351446 41//
0dffcc8a 42}
7c2974c8 43
44//_____________________________________________________________________________
aec0ec32 45AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
2dab9030 46 TObject(event),
47 fRef(event.fRef),
48 fRefMC(event.fRefMC),
5faf5a07 49 fLeading(event.fLeading),
50 fLocalID(event.fLocalID)
2f769150 51{
06351446 52//
0dffcc8a 53// Copy constructor.
06351446 54//
2f769150 55}
7c2974c8 56
57//_____________________________________________________________________________
9477aa42 58AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent & event)
0dffcc8a 59{
06351446 60//
61// Works in the same way as the copy constructor.
62//
aec0ec32 63
5eb970a4 64 (TObject)(*this) = (TObject)event;
2dab9030 65 fRef = event.fRef;
66 fRefMC = event.fRefMC;
67 fLeading = event.fLeading;
5faf5a07 68 fLocalID = event.fLocalID;
5eb970a4 69
aec0ec32 70 return (*this);
0dffcc8a 71}
7c2974c8 72
73//_____________________________________________________________________________
5faf5a07 74AliRsnEvent::~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//_____________________________________________________________________________
2dab9030 86Bool_t AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i, AliRsnDaughter::ERefType type)
06351446 87{
88//
2dab9030 89// Using the second and third arguments, retrieves the i-th object in the
a378358c 90// appropriate sample (tracks or V0s) and sets the first reference object
2dab9030 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).
06351446 96//
2dab9030 97
32992791 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);
2dab9030 104
32992791 105 return kFALSE;
e0baff8c 106}
107
108//_____________________________________________________________________________
a378358c 109Bool_t AliRsnEvent::SetDaughterMC(AliRsnDaughter &out, Int_t label)
2e521c29 110{
111//
112// Using the second argument, retrieves the i-th object in the
a378358c 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).
2e521c29 116//
117
118 if (!fRefMC)
119 {
120 out.SetBad();
121 return kFALSE;
122 }
2e521c29 123
a378358c 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)
2e521c29 131 {
a378358c 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 }
2e521c29 139 out.SetRef(track);
140 out.SetRefMC(track);
a378358c 141 out.SetLabel(label);
2e521c29 142 out.SetGood();
a378358c 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 }
2e521c29 151 }
152
a378358c 153 // AOD
154 if (aod)
2e521c29 155 {
a378358c 156 // checks that array of MC particles exists
157 TClonesArray *mcArray = (TClonesArray*)aod->GetList()->FindObject(AliAODMCParticle::StdBranchName());
158 if(!mcArray)
2e521c29 159 {
a378358c 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 }
2e521c29 186 }
a378358c 187 return kTRUE;
2e521c29 188 }
189
a378358c 190 return kFALSE;
2e521c29 191}
192
193//_____________________________________________________________________________
2dab9030 194AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, AliRsnDaughter::ERefType type)
15d5fd02 195{
196//
a378358c 197// Returns a daughter set using same criteria as SetDaughter
15d5fd02 198//
a378358c 199
200 AliRsnDaughter d;
201 SetDaughter(d, i, type);
202 return d;
15d5fd02 203}
204
205//_____________________________________________________________________________
2e521c29 206AliRsnDaughter AliRsnEvent::GetDaughterMC(Int_t i)
207{
208//
a378358c 209// Returns a daughter set using same criteria as SetDaughterMC
2e521c29 210//
a378358c 211
212 AliRsnDaughter d;
213 SetDaughterMC(d, i);
214 return d;
2e521c29 215}
216
217//_____________________________________________________________________________
32992791 218Int_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//_____________________________________________________________________________
235Bool_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//_____________________________________________________________________________
a378358c 283Int_t AliRsnEvent::GetMultiplicity(AliESDtrackCuts *cuts)
7c2974c8 284{
06351446 285//
a378358c 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.
06351446 289//
a378358c 290
5eb970a4 291 if (!fRef) return 0;
a378358c 292
293 AliESDEvent *esd = GetRefESD();
294 if (cuts && esd) return cuts->CountAcceptedTracks(esd);
295 else return fRef->GetNumberOfTracks();
7c2974c8 296}
297
298//_____________________________________________________________________________
5eb970a4 299Double_t AliRsnEvent::GetVz()
78b94cbd 300{
301//
5eb970a4 302// Return Z coord of primary vertex
78b94cbd 303//
2dab9030 304
5eb970a4 305 return fRef->GetPrimaryVertex()->GetZ();
78b94cbd 306}
307
308//_____________________________________________________________________________
2dab9030 309Int_t AliRsnEvent::SelectLeadingParticle
310(Double_t ptMin, AliRsnCutPID *cutPID)
78b94cbd 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
5eb970a4 321 Int_t i, nTracks = fRef->GetNumberOfTracks();
2dab9030 322 fLeading = -1;
323 AliRsnDaughter leading;
324 leading.SetBad();
5eb970a4 325
a378358c 326 for (i = 0; i < nTracks; i++)
327 {
5eb970a4 328 AliRsnDaughter track = GetDaughter(i);
2dab9030 329 if (cutPID) if (!cutPID->IsSelected(&track)) continue;
a378358c 330 const AliVParticle *ref = track.GetRef();
11ba7ebc 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)
2dab9030 335 {
336 fLeading = i;
11ba7ebc 337 //leading = track;
338 ptMin = ref->Pt();
78b94cbd 339 }
78b94cbd 340 }
2dab9030 341 return fLeading;
78b94cbd 342}
343
5eb970a4 344//_________________________________________________________________________________________________
2dab9030 345Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID)
78b94cbd 346{
347//
348// Loops on the list of tracks and computes average total momentum.
349//
350
5eb970a4 351 Int_t i, nTracks = fRef->GetNumberOfTracks();
78b94cbd 352 Double_t pmean = 0.0;
5eb970a4 353
354 for (i = 0, count = 0; i < nTracks; i++) {
355 AliRsnDaughter track = GetDaughter(i);
2dab9030 356 if (cutPID) if (!cutPID->IsSelected(&track)) continue;
357 pmean += track.P().Mag();
5eb970a4 358 count++;
78b94cbd 359 }
15d5fd02 360
5eb970a4 361 if (count > 0) pmean /= (Double_t)count;
362 else pmean = 0.0;
363
78b94cbd 364 return pmean;
365}
366
367//_____________________________________________________________________________
5eb970a4 368Bool_t AliRsnEvent::GetAngleDistr
369(Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter leading)
78b94cbd 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
5eb970a4 377 if (!leading.IsOK()) return kFALSE;
15d5fd02 378
5eb970a4 379 Int_t i, count, nTracks = fRef->GetNumberOfTracks();
380 Double_t angle, angle2Mean = 0.0;
15d5fd02 381
78b94cbd 382 angleMean = angle2Mean = 0.0;
15d5fd02 383
5eb970a4 384 for (i = 0, count = 0; i < nTracks; i++) {
385 AliRsnDaughter trk = GetDaughter(i);
386 if (trk.GetID() == leading.GetID()) continue;
15d5fd02 387
2dab9030 388 angle = leading.P().Angle(trk.P().Vect());
15d5fd02 389
78b94cbd 390 angleMean += angle;
391 angle2Mean += angle * angle;
392 count++;
393 }
15d5fd02 394
78b94cbd 395 if (!count) return kFALSE;
15d5fd02 396
78b94cbd 397 angleMean /= (Double_t)count;
398 angle2Mean /= (Double_t)count;
9477aa42 399 angleRMS = TMath::Sqrt(angle2Mean - angleMean * angleMean);
15d5fd02 400
78b94cbd 401 return kTRUE;
96e9d35d 402}
a378358c 403
404//_____________________________________________________________________________
32992791 405Bool_t AliRsnEvent::SetDaughterESDtrack(AliRsnDaughter &out, Int_t i)
a378358c 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();
32992791 418 return kFALSE;
a378358c 419 }
420
421 // check 2: not NULL object
422 AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
423 if (!track)
424 {
425 out.SetBad();
32992791 426 return kFALSE;
a378358c 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
32992791 435 // assign MC info, if available
436 return SetMCInfoESD(out);
a378358c 437}
438
439//_____________________________________________________________________________
32992791 440Bool_t AliRsnEvent::SetDaughterAODtrack(AliRsnDaughter &out, Int_t i)
a378358c 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();
32992791 453 return kFALSE;
a378358c 454 }
455
456 // check 2: not NULL object
457 AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
458 if (!track)
459 {
460 out.SetBad();
32992791 461 return kFALSE;
a378358c 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
32992791 470 // assign MC info, if available
471 return SetMCInfoAOD(out);
a378358c 472}
473
474//_____________________________________________________________________________
32992791 475Bool_t AliRsnEvent::SetDaughterESDv0(AliRsnDaughter &out, Int_t i)
a378358c 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
32992791 521 // assign MC info, if available
522 return SetMCInfoESD(out);
a378358c 523}
524
525//_____________________________________________________________________________
32992791 526Bool_t AliRsnEvent::SetDaughterAODv0(AliRsnDaughter &out, Int_t i)
a378358c 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();
32992791 539 return kFALSE;
a378358c 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();
32992791 548 return kFALSE;
a378358c 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
32992791 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//_____________________________________________________________________________
5faf5a07 584Bool_t AliRsnEvent::SetDaughterESDcascade(AliRsnDaughter &, Int_t)
32992791 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//_____________________________________________________________________________
5faf5a07 597Bool_t AliRsnEvent::SetDaughterAODcascade(AliRsnDaughter &, Int_t)
32992791 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//_____________________________________________________________________________
610Bool_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//_____________________________________________________________________________
663Bool_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)
a378358c 687 {
32992791 688 out.SetRefMC(part);
689 Int_t imum = part->GetMother();
a378358c 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 }
32992791 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;
a378358c 703 }
704 }
705
32992791 706 return kTRUE;
a378358c 707}