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 AliRsnEvent* AliRsnEvent::fgRsnEvent1 = 0;
30 AliRsnEvent* AliRsnEvent::fgRsnEvent2 = 0;
32 //_____________________________________________________________________________
33 AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliVEvent *refMC) :
40 // Default constructor.
44 //_____________________________________________________________________________
45 AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
49 fLeading(event.fLeading),
50 fLocalID(event.fLocalID)
57 //_____________________________________________________________________________
58 AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent & event)
61 // Works in the same way as the copy constructor.
64 (TObject)(*this) = (TObject)event;
66 fRefMC = event.fRefMC;
67 fLeading = event.fLeading;
68 fLocalID = event.fLocalID;
73 //_____________________________________________________________________________
74 AliRsnEvent::~AliRsnEvent()
78 // Dereferences global pointer, if needed.
81 //if (gRsnCurrentEvent == this) gRsnCurrentEvent = 0;
82 //if (gRsnMixedEvent == this) gRsnMixedEvent = 0;
85 //_____________________________________________________________________________
86 Bool_t AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i, AliRsnDaughter::ERefType type)
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).
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);
108 //_____________________________________________________________________________
109 Bool_t AliRsnEvent::SetDaughterMC(AliRsnDaughter &out, Int_t label)
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).
124 // try to convert into both types
126 AliMCEvent *esd = GetRefMCESD();
127 AliAODEvent *aod = GetRefMCAOD();
132 // if the MC track exists, assign it
133 AliMCParticle *track = (AliMCParticle*)fRef->GetTrack(label);
144 // search for its mother in stack
145 imum = track->GetMother();
146 if (imum >= 0 && imum < esd->Stack()->GetNtrack())
148 TParticle *mum = esd->Stack()->Particle(imum);
149 if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
156 // checks that array of MC particles exists
157 TClonesArray *mcArray = (TClonesArray*)aod->GetList()->FindObject(AliAODMCParticle::StdBranchName());
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()) )
169 if (TMath::Abs(part->GetLabel()) == label)
171 // if the MC track exists, assign it
177 // search for the mother
178 imum = part->GetMother();
179 if (imum >= 0 && imum < mcArray->GetEntriesFast())
181 AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
182 if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
193 //_____________________________________________________________________________
194 AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, AliRsnDaughter::ERefType type)
197 // Returns a daughter set using same criteria as SetDaughter
201 SetDaughter(d, i, type);
205 //_____________________________________________________________________________
206 AliRsnDaughter AliRsnEvent::GetDaughterMC(Int_t i)
209 // Returns a daughter set using same criteria as SetDaughterMC
217 //_____________________________________________________________________________
218 Int_t AliRsnEvent::GetAbsoluteSum()
221 // Utility method that returns the sum of all daughter-like objects:
222 // tracks, V0s and cascades
227 total += fRef->GetNumberOfTracks();
228 total += fRef->GetNumberOfV0s();
229 total += fRef->GetNumberOfCascades();
234 //_____________________________________________________________________________
235 Bool_t AliRsnEvent::ConvertAbsoluteIndex(Int_t index, Int_t &realIndex, AliRsnDaughter::ERefType &type)
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.
254 Int_t nTracks = fRef->GetNumberOfTracks();
255 Int_t nV0s = fRef->GetNumberOfV0s();
256 Int_t nCascades = fRef->GetNumberOfCascades();
261 type = AliRsnDaughter::kTrack;
264 else if (index >= nTracks && index < nTracks + nV0s)
266 realIndex = index - nTracks;
267 type = AliRsnDaughter::kV0;
270 else if (index >= nTracks + nV0s && index < nTracks + nV0s + nCascades)
272 realIndex = index - nTracks - nV0s;
273 type = AliRsnDaughter::kCascade;
278 type = AliRsnDaughter::kNoType;
282 //_____________________________________________________________________________
283 Int_t AliRsnEvent::GetMultiplicity(AliESDtrackCuts *cuts)
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.
293 AliESDEvent *esd = GetRefESD();
294 if (cuts && esd) return cuts->CountAcceptedTracks(esd);
295 else return fRef->GetNumberOfTracks();
298 //_____________________________________________________________________________
299 Double_t AliRsnEvent::GetVz()
302 // Return Z coord of primary vertex
305 return fRef->GetPrimaryVertex()->GetZ();
308 //_____________________________________________________________________________
309 Int_t AliRsnEvent::SelectLeadingParticle
310 (Double_t ptMin, AliRsnCutPID *cutPID)
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.
321 Int_t i, nTracks = fRef->GetNumberOfTracks();
323 AliRsnDaughter leading;
326 for (i = 0; i < nTracks; i++)
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)
344 //_________________________________________________________________________________________________
345 Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID)
348 // Loops on the list of tracks and computes average total momentum.
351 Int_t i, nTracks = fRef->GetNumberOfTracks();
352 Double_t pmean = 0.0;
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();
361 if (count > 0) pmean /= (Double_t)count;
367 //_____________________________________________________________________________
368 Bool_t AliRsnEvent::GetAngleDistr
369 (Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter leading)
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.
377 if (!leading.IsOK()) return kFALSE;
379 Int_t i, count, nTracks = fRef->GetNumberOfTracks();
380 Double_t angle, angle2Mean = 0.0;
382 angleMean = angle2Mean = 0.0;
384 for (i = 0, count = 0; i < nTracks; i++) {
385 AliRsnDaughter trk = GetDaughter(i);
386 if (trk.GetID() == leading.GetID()) continue;
388 angle = leading.P().Angle(trk.P().Vect());
391 angle2Mean += angle * angle;
395 if (!count) return kFALSE;
397 angleMean /= (Double_t)count;
398 angle2Mean /= (Double_t)count;
399 angleRMS = TMath::Sqrt(angle2Mean - angleMean * angleMean);
404 //_____________________________________________________________________________
405 Bool_t AliRsnEvent::SetDaughterESDtrack(AliRsnDaughter &out, Int_t i)
408 // Setup the first argument to the track identified by the index.
409 // When available, adds the MC information and references.
411 // Version #1: ESD tracks
414 // check 1: index in good range
415 if (i < 0 || i >= fRef->GetNumberOfTracks())
421 // check 2: not NULL object
422 AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
429 // assign references of reconstructed track
430 Int_t label = TMath::Abs(track->GetLabel());
435 // assign MC info, if available
436 return SetMCInfoESD(out);
439 //_____________________________________________________________________________
440 Bool_t AliRsnEvent::SetDaughterAODtrack(AliRsnDaughter &out, Int_t i)
443 // Setup the first argument to the track identified by the index.
444 // When available, adds the MC information and references.
446 // Version #2: AOD tracks
449 // check 1: index in good range
450 if (i < 0 || i >= fRef->GetNumberOfTracks())
456 // check 2: not NULL object
457 AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
464 // assign references of reconstructed track
465 Int_t label = TMath::Abs(track->GetLabel());
470 // assign MC info, if available
471 return SetMCInfoAOD(out);
474 //_____________________________________________________________________________
475 Bool_t AliRsnEvent::SetDaughterESDv0(AliRsnDaughter &out, Int_t i)
478 // Setup the first argument to the track identified by the index.
479 // When available, adds the MC information and references.
481 // Version #3: ESD v0
484 // check 1: index in good range
485 if (i > fRef->GetNumberOfV0s())
491 // check 2: not NULL object
492 AliESDEvent *ev = GetRefESD();
493 AliESDv0 *v0 = ev->GetV0(i);
500 // assign references of reconstructed track
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());
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());
521 // assign MC info, if available
522 return SetMCInfoESD(out);
525 //_____________________________________________________________________________
526 Bool_t AliRsnEvent::SetDaughterAODv0(AliRsnDaughter &out, Int_t i)
529 // Setup the first argument to the track identified by the index.
530 // When available, adds the MC information and references.
532 // Version #4: AOD v0
535 // check 1: index in good range
536 if (i > fRef->GetNumberOfV0s())
542 // check 2: not NULL object
543 AliAODEvent *ev = GetRefAOD();
544 AliAODv0 *v0 = ev->GetV0(i);
551 // assign references of reconstructed track
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)
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()) )
572 if (TMath::Abs(part->GetLabel()) == lp) pp = (AliAODMCParticle*)mcArray->IndexOf(part);
573 if (TMath::Abs(part->GetLabel()) == ln) pn = (AliAODMCParticle*)mcArray->IndexOf(part);
575 // assign a MC reference and a label only to true V0s
576 if (pp->GetMother() == pn->GetMother()) out.SetLabel(pp->GetMother());
579 // assign MC info, if available
580 return SetMCInfoAOD(out);
583 //_____________________________________________________________________________
584 Bool_t AliRsnEvent::SetDaughterESDcascade(AliRsnDaughter &, Int_t)
587 // Setup the first argument to the track identified by the index.
588 // When available, adds the MC information and references.
590 // Version #3: ESD cascade
596 //_____________________________________________________________________________
597 Bool_t AliRsnEvent::SetDaughterAODcascade(AliRsnDaughter &, Int_t)
600 // Setup the first argument to the track identified by the index.
601 // When available, adds the MC information and references.
603 // Version #4: AOD cascade
609 //_____________________________________________________________________________
610 Bool_t AliRsnEvent::SetMCInfoESD(AliRsnDaughter &out)
613 // Using the label assigned to the daughter, searches for the MC informations:
618 Int_t label = out.GetLabel();
619 if (label < 0) return kFALSE;
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();
626 // assign MC reference, being aware of eventual
627 // overflows in the array (sometimes happened)
628 if (label < 0 || label >= nMC)
630 AliWarning(Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
633 AliMCParticle *mcPart = (AliMCParticle*)mc->GetTrack(label);
636 AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
639 out.SetRefMC(mcPart);
641 // if this is a primary track, exit here (successfully)
642 Int_t imum = mcPart->Particle()->GetFirstMother();
643 if (imum < 0) return kTRUE;
645 // if didn't stop there, search for the mother
648 AliWarning(Form("Stack overflow: track mother label = %d -- stack maximum = %d", label, nMC));
651 AliMCParticle *mcMother = (AliMCParticle*)mc->GetTrack(imum);
654 AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", imum));
657 out.SetMotherPDG(TMath::Abs(mcMother->Particle()->GetPdgCode()));
662 //_____________________________________________________________________________
663 Bool_t AliRsnEvent::SetMCInfoAOD(AliRsnDaughter &out)
666 // Using the label assigned to the daughter, searches for the MC informations:
671 Int_t label = out.GetLabel();
672 if (label < 0) return kFALSE;
674 // if no MC reference is available, exit here (successfully)
675 AliAODEvent *mc = GetRefMCAOD();
676 if (!mc) return kTRUE;
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()) )
686 if (TMath::Abs(part->GetLabel()) == label)
689 Int_t imum = part->GetMother();
690 if (imum >= 0 && imum <= mcArray->GetEntriesFast())
692 AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
693 if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
697 AliWarning(Form("Array overflow: track mother label = %d -- stack maximum = %d", imum, mcArray->GetEntriesFast()));
701 // if a MC reference is found, there is no need to go on with the loop