1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ////////////////////////////////////////////////////////////////////////////////
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.
25 // authors: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
26 // M. Vala (martin.vala@cern.ch)
28 ////////////////////////////////////////////////////////////////////////////////
30 #include <Riostream.h>
33 #include "AliGenEventHeader.h"
35 #include "AliRsnCutSet.h"
36 #include "AliRsnEvent.h"
40 //_____________________________________________________________________________
41 AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliVEvent *refMC) :
49 // Default constructor.
53 //_____________________________________________________________________________
54 AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
58 fLeading(event.fLeading),
60 fAODList(event.fAODList)
67 //_____________________________________________________________________________
68 AliRsnEvent &AliRsnEvent::operator= (const AliRsnEvent &event)
71 // Works in the same way as the copy constructor.
74 TObject::operator=(event);
78 fRefMC = event.fRefMC;
79 fLeading = event.fLeading;
81 fAODList = event.fAODList;
86 //_____________________________________________________________________________
87 AliRsnEvent::~AliRsnEvent()
90 // Destructor (does nothing since there are not owned pointers)
94 //_____________________________________________________________________________
95 void AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t index, Bool_t fromMC)
98 // Assigns to the first argument the reference to the i-th track in the ref event.
99 // What assignment method to be used will depend on the index and on the type of input.
100 // If the last argument is kTRUE and an MC is referenced, then both fRef and fRefMC will
101 // point to the MC particle (pure MC analysis)
104 // by default the daughter is reset
105 // and assigned the used index
108 out.SetOwnerEvent(this);
111 if (!InputOK()) return;
112 Bool_t inputESD = IsESD();
114 // if it is pure MC, the index tells what particle
115 // to be read in the stack of MC particles, otherwise
116 // it is converted into a real collection index
119 Bool_t ok = (inputESD ? SetMCInfoESD(out) : SetMCInfoAOD(out));
122 out.SetRef(out.GetRefMC());
126 AliRsnDaughter::ERefType type;
127 if (!ConvertAbsoluteIndex(index, trueIndex, type)) {
128 AliError(Form("Failed to convert absolute index %d", index));
132 case AliRsnDaughter::kTrack:
133 if (inputESD) SetDaughterESDtrack(out, trueIndex); else SetDaughterAODtrack(out, trueIndex);
135 case AliRsnDaughter::kV0:
136 if (inputESD) SetDaughterESDv0(out, trueIndex); else SetDaughterAODv0(out, trueIndex);
138 case AliRsnDaughter::kCascade:
139 if (inputESD) SetDaughterESDcascade(out, trueIndex); else SetDaughterAODcascade(out, trueIndex);
142 AliError("Unrecognized daughter type");
148 //_____________________________________________________________________________
149 AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, Bool_t fromMC)
152 // Returns a daughter set using same criteria as SetDaughter
156 SetDaughter(d, i, fromMC);
160 //_____________________________________________________________________________
161 void AliRsnEvent::SetDaughterESDtrack(AliRsnDaughter &out, Int_t i)
164 // Setup the first argument to the track identified by the index.
165 // When available, adds the MC information and references.
167 // Version #1: ESD tracks
170 AliESDEvent *esd = (AliESDEvent *)fRef;
172 if (i >= 0 && i < esd->GetNumberOfTracks()) {
173 AliESDtrack *track = esd->GetTrack(i);
177 // if MC is present, assign label and retrieve corresponding particle
179 out.SetLabel(TMath::Abs(track->GetLabel()));
180 if (!SetMCInfoESD(out)) {
181 AliWarning("Failed assignment of MC info");
185 AliWarning("Null track");
188 AliWarning(Form("Overflow: required index = %d, max = %d", i, esd->GetNumberOfTracks()));
192 //_____________________________________________________________________________
193 void AliRsnEvent::SetDaughterAODtrack(AliRsnDaughter &out, Int_t i)
196 // Setup the first argument to the track identified by the index.
197 // When available, adds the MC information and references.
199 // Version #2: AOD tracks
202 AliAODEvent *aod = (AliAODEvent *)fRef;
204 if (i >= 0 && i < aod->GetNumberOfTracks()) {
205 AliAODTrack *track = dynamic_cast<AliAODTrack*>(aod->GetTrack(i));
206 if(!track) AliFatal("Not a standard AOD");
210 // if MC is present, assign label and retrieve corresponding particle
212 out.SetLabel(TMath::Abs(track->GetLabel()));
213 if (!SetMCInfoAOD(out)) {
214 AliWarning("Failed assignment of MC info");
218 AliWarning("Null track");
221 AliWarning(Form("Overflow: required index = %d, max = %d", i, aod->GetNumberOfTracks()));
225 //_____________________________________________________________________________
226 void AliRsnEvent::SetDaughterESDv0(AliRsnDaughter &out, Int_t i)
229 // Setup the first argument to the track identified by the index.
230 // When available, adds the MC information and references.
232 // Version #3: ESD v0
235 if (i >= 0 && i < fRef->GetNumberOfV0s()) {
236 AliESDEvent *ev = GetRefESD();
237 AliESDv0 *v0 = ev->GetV0(i);
241 // if MC is present, retrieve the label of V0 from those of daughters
243 AliMCEvent *mc = (AliMCEvent *)fRefMC;
244 AliESDtrack *tp = ev->GetTrack(v0->GetPindex());
245 AliESDtrack *tn = ev->GetTrack(v0->GetNindex());
246 if (mc && tp && tn) {
247 Int_t lp = TMath::Abs(tp->GetLabel());
248 Int_t ln = TMath::Abs(tn->GetLabel());
249 TParticle *pp = mc->Stack()->Particle(lp);
250 TParticle *pn = mc->Stack()->Particle(ln);
252 // if their first mothers are the same, the V0 is true
253 // otherwise label remains '-1' --> fake V0
254 if (pp->GetFirstMother() == pn->GetFirstMother() && pp->GetFirstMother() >= 0) {
255 out.SetLabel(pp->GetFirstMother());
257 TParticle *mom = mc->Stack()->Particle(pn->GetFirstMother());
258 if(mom->GetPdgCode() == 310) {
259 //take the mother of the k0s which is a k0 (311)
260 out.SetLabel(mom->GetFirstMother());
271 //_____________________________________________________________________________
272 void AliRsnEvent::SetDaughterAODv0(AliRsnDaughter &out, Int_t i)
275 // Setup the first argument to the track identified by the index.
276 // When available, adds the MC information and references.
278 // Version #4: AOD v0
281 if (i >= 0 && i < fRef->GetNumberOfV0s()) {
282 AliAODEvent *ev = (AliAODEvent *)fRef;
283 AliAODv0 *v0 = ev->GetV0(i);
288 AliAODEvent *mc = (AliAODEvent *)fRefMC;
289 TClonesArray *mcArray = (TClonesArray *)mc->GetList()->FindObject(AliAODMCParticle::StdBranchName());
290 AliAODTrack *tp = (AliAODTrack *)v0->GetDaughter(0);
291 AliAODTrack *tn = (AliAODTrack *)v0->GetDaughter(1);
292 if (mcArray && tp && tn) {
293 Int_t lp = TMath::Abs(tp->GetLabel());
294 Int_t ln = TMath::Abs(tn->GetLabel());
295 AliAODMCParticle *pp = (AliAODMCParticle *)mcArray->At(lp);
296 AliAODMCParticle *pn = (AliAODMCParticle *)mcArray->At(ln);
298 // if their first mothers are the same, the V0 is true
299 // otherwise label remains '-1' --> fake V0
300 if (pp->GetMother() == pn->GetMother() && pp->GetMother() >= 0) {
301 out.SetLabel(pp->GetMother());
311 //_____________________________________________________________________________
312 void AliRsnEvent::SetDaughterESDcascade(AliRsnDaughter &out, Int_t i)
315 // Setup the first argument to the track identified by the index.
316 // When available, adds the MC information and references.
318 // Version #3: ESD cascade
321 if (i >= 0 && i < fRef->GetNumberOfCascades()) {
322 AliESDEvent *ev = GetRefESD();
323 AliESDcascade *casc = ev->GetCascade(i);
334 //_____________________________________________________________________________
335 void AliRsnEvent::SetDaughterAODcascade(AliRsnDaughter &out, Int_t i)
338 // Setup the first argument to the track identified by the index.
339 // When available, adds the MC information and references.
341 // Version #4: AOD cascade
344 if (i >= 0 && i < fRef->GetNumberOfCascades()) {
345 AliAODEvent *ev = GetRefAOD();
346 AliAODv0 *casc = ev->GetCascade(i);
357 //_____________________________________________________________________________
358 Bool_t AliRsnEvent::SetMCInfoESD(AliRsnDaughter &out)
361 // Using the label assigned to the daughter, searches for the MC informations:
366 // if label makes no sense --> failed
367 Int_t label = out.GetLabel();
368 if (label < 0 || !fRefMC) return kFALSE;
370 // get number of particles
371 Int_t nMC = fRefMC->GetNumberOfTracks();
373 // if label too large --> failed
375 AliDebug(4, Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
380 AliMCEvent *mc = (AliMCEvent *)fRefMC;
381 AliMCParticle *mcPart = (AliMCParticle *)mc->GetTrack(label);
383 // if particle = NULL --> failed
385 AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
388 // otherwise --> success
389 out.SetRefMC(mcPart);
391 // if the particle is not primary, find the mother and get its PDG
392 Int_t imum = mcPart->Particle()->GetFirstMother();
393 if (imum >= 0 && imum < nMC) {
394 AliMCParticle *mcMother = (AliMCParticle *)mc->GetTrack(imum);
396 out.SetMotherPDG(mcMother->Particle()->GetPdgCode());
398 AliWarning(Form("Stack discontinuity: label mother %d refers to a NULL object", imum));
401 AliDebug(4, Form("Stack overflow: mother label = %d -- stack maximum = %d", imum, nMC));
407 //_____________________________________________________________________________
408 Bool_t AliRsnEvent::SetMCInfoAOD(AliRsnDaughter &out)
411 // Using the label assigned to the daughter, searches for the MC informations:
416 // if label makes no sense --> failed
417 Int_t label = out.GetLabel();
418 if (label < 0 || !fRefMC) return kFALSE;
421 AliAODEvent *mc = (AliAODEvent *)fRefMC;
422 TClonesArray *mcArray = (TClonesArray *)mc->GetList()->FindObject(AliAODMCParticle::StdBranchName());
424 // get number of particles
425 Int_t nMC = mcArray->GetEntriesFast();
427 // if label too large --> failed
429 AliDebug(4, Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
433 // if particle = NULL --> failed
434 AliAODMCParticle *mcPart = (AliAODMCParticle *)mcArray->At(label);
436 AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
439 // otherwise --> success
440 out.SetRefMC(mcPart);
442 // if the particle is not primary, find the mother and get its PDG
443 Int_t imum = mcPart->GetMother();
444 if (imum >= 0 && imum < nMC) {
445 AliAODMCParticle *mcMother = (AliAODMCParticle *)mcArray->At(imum);
447 out.SetMotherPDG(mcMother->GetPdgCode());
449 AliWarning(Form("Stack discontinuity: label mother %d refers to a NULL object", imum));
451 } else if (imum >= nMC) {
452 AliDebug(4, Form("Stack overflow: mother label = %d -- stack maximum = %d", imum, nMC));
458 //_____________________________________________________________________________
459 Bool_t AliRsnEvent::ConvertAbsoluteIndex(Int_t index, Int_t &realIndex, AliRsnDaughter::ERefType &type)
462 // Using the phylosophy of the absolute index, which loops over
463 // all tracks, V0s and cascades, returns the result of a check
464 // on it (first argument) based on this criterion:
465 // 1) if the absolute ID is smaller than number of tracks,
466 // return itself and the type 'track'
467 // 2) if the absolute ID is larger than number of tracks, subtract it
468 // and if the result is smaller than number of V0s,
469 // return the corresponding V0 index and type
470 // 3) if the absolute ID is larger than number of tracks + V0s, subtract them
471 // and if the result is smaller than number of cascades,
472 // return the corresponding cascade index and type
473 // The results of this check are stored in the reference arguments, while the outcome of
474 // the function is kTRUE if one of these checks was successful, otherwise it is kFALSE,
475 // meaning that the absolute index reached the end.
478 Int_t nTracks = fRef->GetNumberOfTracks();
479 Int_t nV0s = fRef->GetNumberOfV0s();
480 Int_t nCascades = fRef->GetNumberOfCascades();
482 if (index < nTracks) {
484 type = AliRsnDaughter::kTrack;
486 } else if (index >= nTracks && index < nTracks + nV0s) {
487 realIndex = index - nTracks;
488 type = AliRsnDaughter::kV0;
490 } else if (index >= nTracks + nV0s && index < nTracks + nV0s + nCascades) {
491 realIndex = index - nTracks - nV0s;
492 type = AliRsnDaughter::kCascade;
497 type = AliRsnDaughter::kNoType;
501 //_____________________________________________________________________________
502 Int_t AliRsnEvent::ConvertRealIndex(Int_t index, AliRsnDaughter::ERefType type)
505 // Translates a pair made by index + object type into the corresponding
506 // absolute index, which is set to -1 in case the real index overflows.
509 Int_t nTracks = fRef->GetNumberOfTracks();
510 Int_t nV0s = fRef->GetNumberOfV0s();
511 Int_t nCascades = fRef->GetNumberOfCascades();
514 case AliRsnDaughter::kTrack:
515 if (index >= 0 && index < nTracks)
519 case AliRsnDaughter::kV0:
520 if (index >= 0 && index < nV0s)
521 return nTracks + index;
524 case AliRsnDaughter::kCascade:
525 if (index >= 0 && index < nCascades)
526 return nTracks + nV0s + index;
534 //_____________________________________________________________________________
535 Int_t AliRsnEvent::SelectLeadingParticle(AliRsnCutSet *cuts)
538 // Searches the collection of all particles with given PID type and charge,
539 // and returns the one with largest momentum, provided that it is greater than 1st argument.
540 // If one specifies AliRsnPID::kUnknown as type or AliRsnDaughter::kNoPID as method,
541 // the check is done over all particles irrespectively of their PID.
542 // If the sign argument is '+' or '-', the check is done over the particles of that charge,
543 // otherwise it is done irrespectively of the charge.
547 Bool_t inputESD = IsESD();
548 if (!inputESD && !IsAOD()) {
549 AliError("Need to process ESD or AOD input");
553 Double_t ptMax = 0.0;
554 Int_t i, nTracks = fRef->GetNumberOfTracks();
557 AliRsnDaughter leading;
559 for (i = 0; i < nTracks; i++) {
561 SetDaughterESDtrack(leading, i);
563 SetDaughterAODtrack(leading, i);
564 if (!leading.IsOK()) {
565 AliDebugClass(1, Form("Failed assignment of track %d", i));
568 if (cuts && !cuts->IsSelected(&leading)) {
569 AliDebugClass(1, Form("Track %d didn't pass cuts", i));
572 // check if it has largest momentum
573 if (leading.GetRef()->Pt() > ptMax) {
574 ptMax = leading.GetRef()->Pt();