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