2 // *** Class AliRsnEvent ***
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.
10 // authors: A. Pulvirenti (email: alberto.pulvirenti@ct.infn.it)
11 // M. Vala (email: martin.vala@cern.ch)
17 #include "AliVEvent.h"
18 #include "AliMCEvent.h"
20 #include "AliGenEventHeader.h"
21 #include "AliAODEvent.h"
22 #include "AliRsnCutPID.h"
23 #include "AliESDtrackCuts.h"
25 #include "AliRsnEvent.h"
29 //_____________________________________________________________________________
30 AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliVEvent *refMC) :
36 // Default constructor.
40 //_____________________________________________________________________________
41 AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
45 fLeading(event.fLeading)
52 //_____________________________________________________________________________
53 AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent & event)
56 // Works in the same way as the copy constructor.
59 (TObject)(*this) = (TObject)event;
61 fRefMC = event.fRefMC;
62 fLeading = event.fLeading;
67 //_____________________________________________________________________________
68 Bool_t AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i, AliRsnDaughter::ERefType type)
71 // Using the second and third arguments, retrieves the i-th object in the
72 // appropriate sample (tracks or V0s) and sets the first reference object
73 // in order to point to that.
74 // If a MonteCarlo information is provided, sets the useful informations from there,
75 // and in case of a V0, sets the 'label' data member only when the two daughters
76 // of the V0 point to the same mother.
77 // Returns kFALSE whenever the operation fails (out of range, NULL references).
80 if (IsESD() && type == AliRsnDaughter::kTrack ) return SetDaughterESDtrack (out, i);
81 if (IsAOD() && type == AliRsnDaughter::kTrack ) return SetDaughterAODtrack (out, i);
82 if (IsESD() && type == AliRsnDaughter::kV0 ) return SetDaughterESDv0 (out, i);
83 if (IsAOD() && type == AliRsnDaughter::kV0 ) return SetDaughterAODv0 (out, i);
84 if (IsESD() && type == AliRsnDaughter::kCascade) return SetDaughterESDcascade(out, i);
85 if (IsAOD() && type == AliRsnDaughter::kCascade) return SetDaughterAODcascade(out, i);
90 //_____________________________________________________________________________
91 Bool_t AliRsnEvent::SetDaughterMC(AliRsnDaughter &out, Int_t label)
94 // Using the second argument, retrieves the i-th object in the
95 // MC sample (if present) and assigns the track using only that,
96 // so that it is considered both as main reference and MC reference.
97 // (used for MC-only analysis).
106 // try to convert into both types
108 AliMCEvent *esd = GetRefMCESD();
109 AliAODEvent *aod = GetRefMCAOD();
114 // if the MC track exists, assign it
115 AliMCParticle *track = (AliMCParticle*)fRef->GetTrack(label);
126 // search for its mother in stack
127 imum = track->GetMother();
128 if (imum >= 0 && imum < esd->Stack()->GetNtrack())
130 TParticle *mum = esd->Stack()->Particle(imum);
131 if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
138 // checks that array of MC particles exists
139 TClonesArray *mcArray = (TClonesArray*)aod->GetList()->FindObject(AliAODMCParticle::StdBranchName());
146 // in this case one has to loop over the sample to find the good one
147 TObjArrayIter next(mcArray);
148 AliAODMCParticle *part = 0x0;
149 while ( (part = (AliAODMCParticle*)next()) )
151 if (TMath::Abs(part->GetLabel()) == label)
153 // if the MC track exists, assign it
159 // search for the mother
160 imum = part->GetMother();
161 if (imum >= 0 && imum < mcArray->GetEntriesFast())
163 AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
164 if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
175 //_____________________________________________________________________________
176 AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, AliRsnDaughter::ERefType type)
179 // Returns a daughter set using same criteria as SetDaughter
183 SetDaughter(d, i, type);
187 //_____________________________________________________________________________
188 AliRsnDaughter AliRsnEvent::GetDaughterMC(Int_t i)
191 // Returns a daughter set using same criteria as SetDaughterMC
199 //_____________________________________________________________________________
200 Int_t AliRsnEvent::GetAbsoluteSum()
203 // Utility method that returns the sum of all daughter-like objects:
204 // tracks, V0s and cascades
209 total += fRef->GetNumberOfTracks();
210 total += fRef->GetNumberOfV0s();
211 total += fRef->GetNumberOfCascades();
216 //_____________________________________________________________________________
217 Bool_t AliRsnEvent::ConvertAbsoluteIndex(Int_t index, Int_t &realIndex, AliRsnDaughter::ERefType &type)
220 // Using the phylosophy of the absolute index, which loops over
221 // all tracks, V0s and cascades, returns the result of a check
222 // on it (first argument) based on this criterion:
223 // 1) if the absolute ID is smaller than number of tracks,
224 // return itself and the type 'track'
225 // 2) if the absolute ID is larger than number of tracks, subtract it
226 // and if the result is smaller than number of V0s,
227 // return the corresponding V0 index and type
228 // 3) if the absolute ID is larger than number of tracks + V0s, subtract them
229 // and if the result is smaller than number of cascades,
230 // return the corresponding cascade index and type
231 // The results of this check are stored in the reference arguments, while the outcome of
232 // the function is kTRUE if one of these checks was successful, otherwise it is kFALSE,
233 // meaning that the absolute index reached the end.
236 Int_t nTracks = fRef->GetNumberOfTracks();
237 Int_t nV0s = fRef->GetNumberOfV0s();
238 Int_t nCascades = fRef->GetNumberOfCascades();
243 type = AliRsnDaughter::kTrack;
246 else if (index >= nTracks && index < nTracks + nV0s)
248 realIndex = index - nTracks;
249 type = AliRsnDaughter::kV0;
252 else if (index >= nTracks + nV0s && index < nTracks + nV0s + nCascades)
254 realIndex = index - nTracks - nV0s;
255 type = AliRsnDaughter::kCascade;
260 type = AliRsnDaughter::kNoType;
264 //_____________________________________________________________________________
265 Int_t AliRsnEvent::GetMultiplicity(AliESDtrackCuts *cuts)
268 // Returns event multiplicity as the number of tracks.
269 // If the argument is not NULL, returns instead the
270 // number of tracks passing the cuts hereby defined.
275 AliESDEvent *esd = GetRefESD();
276 if (cuts && esd) return cuts->CountAcceptedTracks(esd);
277 else return fRef->GetNumberOfTracks();
280 //_____________________________________________________________________________
281 Double_t AliRsnEvent::GetVz()
284 // Return Z coord of primary vertex
287 return fRef->GetPrimaryVertex()->GetZ();
290 //_____________________________________________________________________________
291 Int_t AliRsnEvent::SelectLeadingParticle
292 (Double_t ptMin, AliRsnCutPID *cutPID)
295 // Searches the collection of all particles with given PID type and charge,
296 // and returns the one with largest momentum, provided that it is greater than 1st argument.
297 // If one specifies AliRsnPID::kUnknown as type or AliRsnDaughter::kNoPID as method,
298 // the check is done over all particles irrespectively of their PID.
299 // If the sign argument is '+' or '-', the check is done over the particles of that charge,
300 // otherwise it is done irrespectively of the charge.
303 Int_t i, nTracks = fRef->GetNumberOfTracks();
305 AliRsnDaughter leading;
308 for (i = 0; i < nTracks; i++)
310 AliRsnDaughter track = GetDaughter(i);
311 if (cutPID) if (!cutPID->IsSelected(&track)) continue;
312 const AliVParticle *ref = track.GetRef();
313 if (ref->Pt() < ptMin) continue;
314 //double pt = track.P().Perp();
315 //Printf("track %d %g", i, pt);
316 if (!leading.IsOK() || ref->Pt() > ptMin)
326 //_________________________________________________________________________________________________
327 Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID)
330 // Loops on the list of tracks and computes average total momentum.
333 Int_t i, nTracks = fRef->GetNumberOfTracks();
334 Double_t pmean = 0.0;
336 for (i = 0, count = 0; i < nTracks; i++) {
337 AliRsnDaughter track = GetDaughter(i);
338 if (cutPID) if (!cutPID->IsSelected(&track)) continue;
339 pmean += track.P().Mag();
343 if (count > 0) pmean /= (Double_t)count;
349 //_____________________________________________________________________________
350 Bool_t AliRsnEvent::GetAngleDistr
351 (Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter leading)
354 // Takes the leading particle and computes the mean and RMS
355 // of the distribution of directions of all other tracks
356 // with respect to the direction of leading particle.
359 if (!leading.IsOK()) return kFALSE;
361 Int_t i, count, nTracks = fRef->GetNumberOfTracks();
362 Double_t angle, angle2Mean = 0.0;
364 angleMean = angle2Mean = 0.0;
366 for (i = 0, count = 0; i < nTracks; i++) {
367 AliRsnDaughter trk = GetDaughter(i);
368 if (trk.GetID() == leading.GetID()) continue;
370 angle = leading.P().Angle(trk.P().Vect());
373 angle2Mean += angle * angle;
377 if (!count) return kFALSE;
379 angleMean /= (Double_t)count;
380 angle2Mean /= (Double_t)count;
381 angleRMS = TMath::Sqrt(angle2Mean - angleMean * angleMean);
386 //_____________________________________________________________________________
387 Bool_t AliRsnEvent::SetDaughterESDtrack(AliRsnDaughter &out, Int_t i)
390 // Setup the first argument to the track identified by the index.
391 // When available, adds the MC information and references.
393 // Version #1: ESD tracks
396 // check 1: index in good range
397 if (i < 0 || i >= fRef->GetNumberOfTracks())
403 // check 2: not NULL object
404 AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
411 // assign references of reconstructed track
412 Int_t label = TMath::Abs(track->GetLabel());
417 // assign MC info, if available
418 return SetMCInfoESD(out);
421 //_____________________________________________________________________________
422 Bool_t AliRsnEvent::SetDaughterAODtrack(AliRsnDaughter &out, Int_t i)
425 // Setup the first argument to the track identified by the index.
426 // When available, adds the MC information and references.
428 // Version #2: AOD tracks
431 // check 1: index in good range
432 if (i < 0 || i >= fRef->GetNumberOfTracks())
438 // check 2: not NULL object
439 AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
446 // assign references of reconstructed track
447 Int_t label = TMath::Abs(track->GetLabel());
452 // assign MC info, if available
453 return SetMCInfoAOD(out);
456 //_____________________________________________________________________________
457 Bool_t AliRsnEvent::SetDaughterESDv0(AliRsnDaughter &out, Int_t i)
460 // Setup the first argument to the track identified by the index.
461 // When available, adds the MC information and references.
463 // Version #3: ESD v0
466 // check 1: index in good range
467 if (i > fRef->GetNumberOfV0s())
473 // check 2: not NULL object
474 AliESDEvent *ev = GetRefESD();
475 AliESDv0 *v0 = ev->GetV0(i);
482 // assign references of reconstructed track
486 // this time, assigning label is not trivial,
487 // it is done only if MC is present and both
488 // daughters come from a true particle
489 AliMCEvent *mc = GetRefMCESD();
490 AliESDtrack *tp = ev->GetTrack(v0->GetPindex());
491 AliESDtrack *tn = ev->GetTrack(v0->GetNindex());
494 Int_t lp = TMath::Abs(tp->GetLabel());
495 Int_t ln = TMath::Abs(tn->GetLabel());
496 TParticle *pp = mc->Stack()->Particle(lp);
497 TParticle *pn = mc->Stack()->Particle(ln);
498 // if their first mothers are the same, the V0 is true
499 // otherwise no label can be assigned
500 if (pp->GetFirstMother() == pn->GetFirstMother()) out.SetLabel(pp->GetFirstMother());
503 // assign MC info, if available
504 return SetMCInfoESD(out);
507 //_____________________________________________________________________________
508 Bool_t AliRsnEvent::SetDaughterAODv0(AliRsnDaughter &out, Int_t i)
511 // Setup the first argument to the track identified by the index.
512 // When available, adds the MC information and references.
514 // Version #4: AOD v0
517 // check 1: index in good range
518 if (i > fRef->GetNumberOfV0s())
524 // check 2: not NULL object
525 AliAODEvent *ev = GetRefAOD();
526 AliAODv0 *v0 = ev->GetV0(i);
533 // assign references of reconstructed track
538 // this time, assigning label is not trivial,
539 // it is done only if MC is present and both
540 // daughters come from a true particle
541 TClonesArray *mcArray = (TClonesArray*)ev->GetList()->FindObject(AliAODMCParticle::StdBranchName());
542 AliAODTrack *tp = ev->GetTrack(v0->GetPosID());
543 AliAODTrack *tn = ev->GetTrack(v0->GetNegID());
544 if (mcArray && tp && tn)
546 Int_t lp = TMath::Abs(tp->GetLabel());
547 Int_t ln = TMath::Abs(tn->GetLabel());
548 // loop on array to find MC daughters
549 AliAODMCParticle *pp = 0x0, *pn = 0x0;
550 TObjArrayIter next(mcArray);
551 AliAODMCParticle *part = 0x0;
552 while ( (part = (AliAODMCParticle*)next()) )
554 if (TMath::Abs(part->GetLabel()) == lp) pp = (AliAODMCParticle*)mcArray->IndexOf(part);
555 if (TMath::Abs(part->GetLabel()) == ln) pn = (AliAODMCParticle*)mcArray->IndexOf(part);
557 // assign a MC reference and a label only to true V0s
558 if (pp->GetMother() == pn->GetMother()) out.SetLabel(pp->GetMother());
561 // assign MC info, if available
562 return SetMCInfoAOD(out);
565 //_____________________________________________________________________________
566 Bool_t AliRsnEvent::SetDaughterESDcascade(AliRsnDaughter &out, Int_t i)
569 // Setup the first argument to the track identified by the index.
570 // When available, adds the MC information and references.
572 // Version #3: ESD cascade
578 //_____________________________________________________________________________
579 Bool_t AliRsnEvent::SetDaughterAODcascade(AliRsnDaughter &out, Int_t i)
582 // Setup the first argument to the track identified by the index.
583 // When available, adds the MC information and references.
585 // Version #4: AOD cascade
591 //_____________________________________________________________________________
592 Bool_t AliRsnEvent::SetMCInfoESD(AliRsnDaughter &out)
595 // Using the label assigned to the daughter, searches for the MC informations:
600 Int_t label = out.GetLabel();
601 if (label < 0) return kFALSE;
603 // if no MC reference is available, exit here (successfully)
604 AliMCEvent *mc = GetRefMCESD();
605 if (!mc) return kTRUE;
606 Int_t nMC = mc->GetNumberOfTracks();
608 // assign MC reference, being aware of eventual
609 // overflows in the array (sometimes happened)
610 if (label < 0 || label >= nMC)
612 AliWarning(Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
615 AliMCParticle *mcPart = (AliMCParticle*)mc->GetTrack(label);
618 AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
621 out.SetRefMC(mcPart);
623 // if this is a primary track, exit here (successfully)
624 Int_t imum = mcPart->Particle()->GetFirstMother();
625 if (imum < 0) return kTRUE;
627 // if didn't stop there, search for the mother
630 AliWarning(Form("Stack overflow: track mother label = %d -- stack maximum = %d", label, nMC));
633 AliMCParticle *mcMother = (AliMCParticle*)mc->GetTrack(imum);
636 AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", imum));
639 out.SetMotherPDG(TMath::Abs(mcMother->Particle()->GetPdgCode()));
644 //_____________________________________________________________________________
645 Bool_t AliRsnEvent::SetMCInfoAOD(AliRsnDaughter &out)
648 // Using the label assigned to the daughter, searches for the MC informations:
653 Int_t label = out.GetLabel();
654 if (label < 0) return kFALSE;
656 // if no MC reference is available, exit here (successfully)
657 AliAODEvent *mc = GetRefMCAOD();
658 if (!mc) return kTRUE;
660 // loop on particles using the track label as reference
661 // and then assign also the mother type, if found
662 TClonesArray *mcArray = (TClonesArray*)mc->GetList()->FindObject(AliAODMCParticle::StdBranchName());
663 if(!mcArray) return kFALSE;
664 TObjArrayIter next(mcArray);
665 AliAODMCParticle *part = 0x0;
666 while ( (part = (AliAODMCParticle*)next()) )
668 if (TMath::Abs(part->GetLabel()) == label)
671 Int_t imum = part->GetMother();
672 if (imum >= 0 && imum <= mcArray->GetEntriesFast())
674 AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
675 if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
679 AliWarning(Form("Array overflow: track mother label = %d -- stack maximum = %d", imum, mcArray->GetEntriesFast()));
683 // if a MC reference is found, there is no need to go on with the loop