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 **************************************************************************/
22 #include <TParameter.h>
24 #include <TParticle.h>
27 #include "AliAnalysisTaskESDfilter.h"
28 #include "AliAnalysisManager.h"
29 #include "AliESDEvent.h"
30 #include "AliESDRun.h"
32 #include "AliAODEvent.h"
33 #include "AliMCEvent.h"
34 #include "AliMCEventHandler.h"
35 #include "AliESDInputHandler.h"
36 #include "AliAODHandler.h"
37 #include "AliAODMCParticle.h"
38 #include "AliAnalysisFilter.h"
39 #include "AliESDMuonTrack.h"
40 #include "AliESDVertex.h"
41 #include "AliCentrality.h"
42 #include "AliEventplane.h"
44 #include "AliESDkink.h"
45 #include "AliESDcascade.h"
46 #include "AliESDPmdTrack.h"
47 #include "AliESDCaloCluster.h"
48 #include "AliESDCaloCells.h"
49 #include "AliMultiplicity.h"
51 #include "AliCodeTimer.h"
52 #include "AliESDtrackCuts.h"
53 #include "AliESDpid.h"
54 #include "AliV0vertexer.h"
55 #include "AliCascadeVertexer.h"
56 #include "Riostream.h"
57 #include "AliExternalTrackParam.h"
58 #include "AliTrackerBase.h"
60 #include "AliTPCdEdxInfo.h"
64 ClassImp(AliAnalysisTaskESDfilter)
66 ////////////////////////////////////////////////////////////////////////
68 AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter():
76 fEnableFillAOD(kTRUE),
85 fNumberOfPositiveTracks(0),
90 fOldESDformat(kFALSE),
92 fTPCConstrainedFilterMask(0),
93 fHybridFilterMaskTPCCG(0),
94 fWriteHybridTPCCOnly(kFALSE),
95 fGlobalConstrainedFilterMask(0),
96 fHybridFilterMaskGCG(0),
97 fWriteHybridGCOnly(kFALSE),
98 fIsVZEROEnabled(kTRUE),
99 fIsTZEROEnabled(kTRUE),
100 fIsZDCEnabled(kTRUE),
101 fIsV0CascadeRecoEnabled(kFALSE),
102 fAreCascadesEnabled(kTRUE),
103 fAreV0sEnabled(kTRUE),
104 fAreKinksEnabled(kTRUE),
105 fAreTracksEnabled(kTRUE),
106 fArePmdClustersEnabled(kTRUE),
107 fAreCaloClustersEnabled(kTRUE),
108 fAreEMCALCellsEnabled(kTRUE),
109 fArePHOSCellsEnabled(kTRUE),
110 fAreEMCALTriggerEnabled(kTRUE),
111 fArePHOSTriggerEnabled(kTRUE),
112 fAreTrackletsEnabled(kTRUE),
115 fTimeZeroType(AliESDpid::kTOF_T0),
116 fTPCaloneTrackCuts(0),
117 fDoPropagateTrackToEMCal(kTRUE)
119 // Default constructor
120 fV0Cuts[0] = 33. ; // max allowed chi2
121 fV0Cuts[1] = 0.1 ; // min allowed impact parameter for the 1st daughter
122 fV0Cuts[2] = 0.1 ; // min allowed impact parameter for the 2nd daughter
123 fV0Cuts[3] = 1. ; // max allowed DCA between the daughter tracks
124 fV0Cuts[4] = .998; // min allowed cosine of V0's pointing angle
125 fV0Cuts[5] = 0.9 ; // min radius of the fiducial volume
126 fV0Cuts[6] = 100. ; // max radius of the fiducial volume
128 fCascadeCuts[0] = 33. ; // max allowed chi2 (same as PDC07)
129 fCascadeCuts[1] = 0.05 ; // min allowed V0 impact parameter
130 fCascadeCuts[2] = 0.008; // "window" around the Lambda mass
131 fCascadeCuts[3] = 0.03 ; // min allowed bachelor's impact parameter
132 fCascadeCuts[4] = 0.3 ; // max allowed DCA between the V0 and the bachelor
133 fCascadeCuts[5] = 0.999; // min allowed cosine of the cascade pointing angle
134 fCascadeCuts[6] = 0.9 ; // min radius of the fiducial volume
135 fCascadeCuts[7] = 100. ; // max radius of the fiducial volume
138 //______________________________________________________________________________
139 AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter(const char* name):
140 AliAnalysisTaskSE(name),
147 fEnableFillAOD(kTRUE),
156 fNumberOfPositiveTracks(0),
158 fNumberOfVertices(0),
159 fNumberOfCascades(0),
161 fOldESDformat(kFALSE),
163 fTPCConstrainedFilterMask(0),
164 fHybridFilterMaskTPCCG(0),
165 fWriteHybridTPCCOnly(kFALSE),
166 fGlobalConstrainedFilterMask(0),
167 fHybridFilterMaskGCG(0),
168 fWriteHybridGCOnly(kFALSE),
169 fIsVZEROEnabled(kTRUE),
170 fIsTZEROEnabled(kTRUE),
171 fIsZDCEnabled(kTRUE),
172 fIsV0CascadeRecoEnabled(kFALSE),
173 fAreCascadesEnabled(kTRUE),
174 fAreV0sEnabled(kTRUE),
175 fAreKinksEnabled(kTRUE),
176 fAreTracksEnabled(kTRUE),
177 fArePmdClustersEnabled(kTRUE),
178 fAreCaloClustersEnabled(kTRUE),
179 fAreEMCALCellsEnabled(kTRUE),
180 fArePHOSCellsEnabled(kTRUE),
181 fAreEMCALTriggerEnabled(kTRUE),
182 fArePHOSTriggerEnabled(kTRUE),
183 fAreTrackletsEnabled(kTRUE),
186 fTimeZeroType(AliESDpid::kTOF_T0),
187 fTPCaloneTrackCuts(0),
188 fDoPropagateTrackToEMCal(kTRUE)
192 fV0Cuts[0] = 33. ; // max allowed chi2
193 fV0Cuts[1] = 0.1 ; // min allowed impact parameter for the 1st daughter
194 fV0Cuts[2] = 0.1 ; // min allowed impact parameter for the 2nd daughter
195 fV0Cuts[3] = 1. ; // max allowed DCA between the daughter tracks
196 fV0Cuts[4] = .998; // min allowed cosine of V0's pointing angle
197 fV0Cuts[5] = 0.9 ; // min radius of the fiducial volume
198 fV0Cuts[6] = 100. ; // max radius of the fiducial volume
200 fCascadeCuts[0] = 33. ; // max allowed chi2 (same as PDC07)
201 fCascadeCuts[1] = 0.05 ; // min allowed V0 impact parameter
202 fCascadeCuts[2] = 0.008; // "window" around the Lambda mass
203 fCascadeCuts[3] = 0.03 ; // min allowed bachelor's impact parameter
204 fCascadeCuts[4] = 0.3 ; // max allowed DCA between the V0 and the bachelor
205 fCascadeCuts[5] = 0.999; // min allowed cosine of the cascade pointing angle
206 fCascadeCuts[6] = 0.9 ; // min radius of the fiducial volume
207 fCascadeCuts[7] = 100. ; // max radius of the fiducial volume
212 AliAnalysisTaskESDfilter::~AliAnalysisTaskESDfilter(){
213 if(fIsPidOwner) delete fESDpid;
215 //______________________________________________________________________________
216 void AliAnalysisTaskESDfilter::UserCreateOutputObjects()
219 // Create Output Objects conenct filter to outputtree
223 OutputTree()->GetUserInfo()->Add(fTrackFilter);
227 AliError("No OutputTree() for adding the track filter");
229 fTPCaloneTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
232 //______________________________________________________________________________
233 void AliAnalysisTaskESDfilter::Init()
236 if (fDebug > 1) AliInfo("Init() \n");
237 // Call configuration file
240 //______________________________________________________________________________
241 void AliAnalysisTaskESDfilter::PrintTask(Option_t *option, Int_t indent) const
243 // Print selection task information
246 AliAnalysisTaskSE::PrintTask(option,indent);
248 TString spaces(' ',indent+3);
250 cout << spaces.Data() << Form("Cascades are %s",fAreCascadesEnabled ? "ENABLED":"DISABLED") << endl;
251 cout << spaces.Data() << Form("V0s are %s",fAreV0sEnabled ? "ENABLED":"DISABLED") << endl;
252 cout << spaces.Data() << Form("Kinks are %s",fAreKinksEnabled ? "ENABLED":"DISABLED") << endl;
253 cout << spaces.Data() << Form("Tracks are %s",fAreTracksEnabled ? "ENABLED":"DISABLED") << endl;
254 cout << spaces.Data() << Form("PmdClusters are %s",fArePmdClustersEnabled ? "ENABLED":"DISABLED") << endl;
255 cout << spaces.Data() << Form("CaloClusters are %s",fAreCaloClustersEnabled ? "ENABLED":"DISABLED") << endl;
256 cout << spaces.Data() << Form("EMCAL cells are %s",fAreEMCALCellsEnabled ? "ENABLED":"DISABLED") << endl;
257 cout << spaces.Data() << Form("EMCAL triggers are %s",fAreEMCALTriggerEnabled ? "ENABLED":"DISABLED") << endl;
258 cout << spaces.Data() << Form("PHOS triggers are %s",fArePHOSTriggerEnabled ? "ENABLED":"DISABLED") << endl;
259 cout << spaces.Data() << Form("Tracklets are %s",fAreTrackletsEnabled ? "ENABLED":"DISABLED") << endl;
260 cout << spaces.Data() << Form("PropagateTrackToEMCal is %s", fDoPropagateTrackToEMCal ? "ENABLED":"DISABLED") << endl;
263 //______________________________________________________________________________
264 void AliAnalysisTaskESDfilter::UserExec(Option_t */*option*/)
266 // Execute analysis for current event
269 Long64_t ientry = Entry();
272 printf("Filter: Analysing event # %5d\n", (Int_t) ientry);
273 if (fHighPthreshold == 0) AliInfo("detector PID signals are stored in each track");
274 if (!fPtshape) AliInfo("detector PID signals are not stored below the pt threshold");
276 // Filters must explicitely enable AOD filling in their UserExec (AG)
277 if (!AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()) AliFatal("Cannot run ESD filter without an output event handler");
279 AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(kTRUE);
280 AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillExtension(kTRUE);
285 //______________________________________________________________________________
286 TClonesArray& AliAnalysisTaskESDfilter::Cascades()
288 return *(AODEvent()->GetCascades());
291 //______________________________________________________________________________
292 TClonesArray& AliAnalysisTaskESDfilter::Tracks()
294 return *(AODEvent()->GetTracks());
297 //______________________________________________________________________________
298 TClonesArray& AliAnalysisTaskESDfilter::V0s()
300 return *(AODEvent()->GetV0s());
303 //______________________________________________________________________________
304 TClonesArray& AliAnalysisTaskESDfilter::Vertices()
306 return *(AODEvent()->GetVertices());
309 //______________________________________________________________________________
310 AliAODHeader* AliAnalysisTaskESDfilter::ConvertHeader(const AliESDEvent& esd)
312 // Convert header information
314 AliCodeTimerAuto("",0);
316 AliAODHeader* header = AODEvent()->GetHeader();
318 header->SetRunNumber(esd.GetRunNumber());
319 header->SetOfflineTrigger(fInputHandler->IsEventSelected()); // propagate the decision of the physics selection
321 TTree* tree = fInputHandler->GetTree();
323 TFile* file = tree->GetCurrentFile();
324 if (file) header->SetESDFileName(file->GetName());
328 header->SetBunchCrossNumber(0);
329 header->SetOrbitNumber(0);
330 header->SetPeriodNumber(0);
331 header->SetEventType(0);
332 header->SetMuonMagFieldScale(-999.);
333 header->SetCentrality(0);
334 header->SetEventplane(0);
336 header->SetBunchCrossNumber(esd.GetBunchCrossNumber());
337 header->SetOrbitNumber(esd.GetOrbitNumber());
338 header->SetPeriodNumber(esd.GetPeriodNumber());
339 header->SetEventType(esd.GetEventType());
341 header->SetEventNumberESDFile(esd.GetHeader()->GetEventNumberInFile());
342 if(const_cast<AliESDEvent&>(esd).GetCentrality()){
343 header->SetCentrality(const_cast<AliESDEvent&>(esd).GetCentrality());
346 header->SetCentrality(0);
348 if(const_cast<AliESDEvent&>(esd).GetEventplane()){
349 header->SetEventplane(const_cast<AliESDEvent&>(esd).GetEventplane());
352 header->SetEventplane(0);
357 header->SetFiredTriggerClasses(esd.GetFiredTriggerClasses());
358 header->SetTriggerMask(esd.GetTriggerMask());
359 header->SetTriggerCluster(esd.GetTriggerCluster());
360 header->SetL0TriggerInputs(esd.GetHeader()->GetL0TriggerInputs());
361 header->SetL1TriggerInputs(esd.GetHeader()->GetL1TriggerInputs());
362 header->SetL2TriggerInputs(esd.GetHeader()->GetL2TriggerInputs());
364 header->SetMagneticField(esd.GetMagneticField());
365 header->SetMuonMagFieldScale(esd.GetCurrentDip()/6000.);
366 header->SetZDCN1Energy(esd.GetZDCN1Energy());
367 header->SetZDCP1Energy(esd.GetZDCP1Energy());
368 header->SetZDCN2Energy(esd.GetZDCN2Energy());
369 header->SetZDCP2Energy(esd.GetZDCP2Energy());
370 header->SetZDCEMEnergy(esd.GetZDCEMEnergy(0),esd.GetZDCEMEnergy(1));
372 // ITS Cluster Multiplicty
373 const AliMultiplicity *mult = esd.GetMultiplicity();
374 for (Int_t ilay = 0; ilay < 6; ilay++) header->SetITSClusters(ilay, mult->GetNumberOfITSClusters(ilay));
376 // TPC only Reference Multiplicty
377 Int_t refMult = fTPCaloneTrackCuts ? (Short_t)fTPCaloneTrackCuts->GetReferenceMultiplicity(&esd, kTRUE) : -1;
378 header->SetTPConlyRefMultiplicity(refMult);
381 Float_t diamxy[2]={esd.GetDiamondX(),esd.GetDiamondY()};
383 esd.GetDiamondCovXY(diamcov);
384 header->SetDiamond(diamxy,diamcov);
385 header->SetDiamondZ(esd.GetDiamondZ(),esd.GetSigma2DiamondZ());
387 // VZERO channel equalization factors for event-plane reconstruction
388 header->SetVZEROEqFactors(esd.GetVZEROEqFactors());
393 //______________________________________________________________________________
394 void AliAnalysisTaskESDfilter::ConvertCascades(const AliESDEvent& esd)
397 // Convert the cascades part of the ESD.
398 // Return the number of cascades
400 AliCodeTimerAuto("",0);
402 // Create vertices starting from the most complex objects
405 const AliESDVertex* vtx = esd.GetPrimaryVertex();
406 Double_t pos[3] = { 0. };
407 Double_t covVtx[6] = { 0. };
408 Double_t momBach[3]={0.};
409 Double_t covTr[21]={0.};
410 Double_t pid[10]={0.};
411 AliAODPid* detpid(0x0);
412 AliAODVertex* vV0FromCascade(0x0);
413 AliAODv0* aodV0(0x0);
414 AliAODcascade* aodCascade(0x0);
415 AliAODTrack* aodTrack(0x0);
416 Double_t momPos[3]={0.};
417 Double_t momNeg[3] = { 0. };
418 Double_t momPosAtV0vtx[3]={0.};
419 Double_t momNegAtV0vtx[3]={0.};
421 TClonesArray& verticesArray = Vertices();
422 TClonesArray& tracksArray = Tracks();
423 TClonesArray& cascadesArray = Cascades();
425 // Cascades (Modified by A.Maire - February 2009)
426 for (Int_t nCascade = 0; nCascade < esd.GetNumberOfCascades(); ++nCascade) {
430 AliESDcascade *esdCascade = esd.GetCascade(nCascade);
431 Int_t idxPosFromV0Dghter = esdCascade->GetPindex();
432 Int_t idxNegFromV0Dghter = esdCascade->GetNindex();
433 Int_t idxBachFromCascade = esdCascade->GetBindex();
435 AliESDtrack *esdCascadePos = esd.GetTrack( idxPosFromV0Dghter);
436 AliESDtrack *esdCascadeNeg = esd.GetTrack( idxNegFromV0Dghter);
437 AliESDtrack *esdCascadeBach = esd.GetTrack( idxBachFromCascade);
439 // Identification of the V0 within the esdCascade (via both daughter track indices)
440 AliESDv0 * currentV0 = 0x0;
441 Int_t idxV0FromCascade = -1;
443 for (Int_t iV0=0; iV0<esd.GetNumberOfV0s(); ++iV0) {
445 currentV0 = esd.GetV0(iV0);
446 Int_t posCurrentV0 = currentV0->GetPindex();
447 Int_t negCurrentV0 = currentV0->GetNindex();
449 if (posCurrentV0==idxPosFromV0Dghter && negCurrentV0==idxNegFromV0Dghter) {
450 idxV0FromCascade = iV0;
455 if(idxV0FromCascade < 0){
456 printf("Cascade - no matching for the V0 (index V0 = -1) ! Skip ... \n");
458 }// a priori, useless check, but safer ... in case of pb with tracks "out of bounds"
460 AliESDv0 *esdV0FromCascade = esd.GetV0(idxV0FromCascade);
462 // 1 - Cascade selection
464 // AliESDVertex *esdPrimVtx = new AliESDVertex(*(esd.GetPrimaryVertex()));
465 // TList cascadeObjects;
466 // cascadeObjects.AddAt(esdV0FromCascade, 0);
467 // cascadeObjects.AddAt(esdCascadePos, 1);
468 // cascadeObjects.AddAt(esdCascadeNeg, 2);
469 // cascadeObjects.AddAt(esdCascade, 3);
470 // cascadeObjects.AddAt(esdCascadeBach, 4);
471 // cascadeObjects.AddAt(esdPrimVtx, 5);
473 // UInt_t selectCascade = 0;
474 // if (fCascadeFilter) {
475 // // selectCascade = fCascadeFilter->IsSelected(&cascadeObjects);
476 // // FIXME AliESDCascadeCuts to be implemented ...
478 // // Here we may encounter a moot point at the V0 level
479 // // between the cascade selections and the V0 ones :
480 // // the V0 selected along with the cascade (secondary V0) may
481 // // usually be removed from the dedicated V0 selections (prim V0) ...
482 // // -> To be discussed !
484 // // this is a little awkward but otherwise the
485 // // list wants to access the pointer (delete it)
486 // // again when going out of scope
487 // delete cascadeObjects.RemoveAt(5); // esdPrimVtx created via copy construct
489 // if (!selectCascade)
493 // delete cascadeObjects.RemoveAt(5); // esdPrimVtx created via copy construct
497 // 2 - Add the cascade vertex
499 esdCascade->GetXYZcascade(pos[0], pos[1], pos[2]);
500 esdCascade->GetPosCovXi(covVtx);
501 chi2 = esdCascade->GetChi2Xi();
503 AliAODVertex *vCascade = new(verticesArray[fNumberOfVertices++]) AliAODVertex( pos,
505 chi2, // FIXME = Chi2/NDF will be needed
508 AliAODVertex::kCascade);
509 fPrimaryVertex->AddDaughter(vCascade);
512 // printf("---- Cascade / Cascade Vertex (AOD) : \n");
513 // vCascade->Print();
516 // if(esd.GetTOFHeader() && fIsPidOwner) fESDpid->SetTOFResponse(const_cast<AliESDEvent*>(&esd), (AliESDpid::EStartTimeType_t)fTimeZeroType); //in case of AOD production starting form LHC10e without Tender.
519 // 3 - Add the bachelor track from the cascade
521 if (!fUsedTrack[idxBachFromCascade]) {
523 esdCascadeBach->GetPxPyPz(momBach);
524 esdCascadeBach->GetXYZ(pos);
525 esdCascadeBach->GetCovarianceXYZPxPyPz(covTr);
526 esdCascadeBach->GetESDpid(pid);
528 fUsedTrack[idxBachFromCascade] = kTRUE;
529 UInt_t selectInfo = 0;
530 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdCascadeBach);
531 if (fMChandler) fMChandler->SelectParticle(esdCascadeBach->GetLabel());
532 aodTrack = new(tracksArray[fNumberOfTracks++]) AliAODTrack(esdCascadeBach->GetID(),
533 esdCascadeBach->GetLabel(),
537 kFALSE, // Why kFALSE for "isDCA" ? FIXME
539 (Short_t)esdCascadeBach->GetSign(),
540 esdCascadeBach->GetITSClusterMap(),
543 kTRUE, // usedForVtxFit = kFALSE ? FIXME
544 vtx->UsesTrack(esdCascadeBach->GetID()),
545 AliAODTrack::kSecondary,
547 aodTrack->SetTPCFitMap(esdCascadeBach->GetTPCFitMap());
548 aodTrack->SetTPCClusterMap(esdCascadeBach->GetTPCClusterMap());
549 aodTrack->SetTPCSharedMap (esdCascadeBach->GetTPCSharedMap());
550 aodTrack->SetChi2perNDF(Chi2perNDF(esdCascadeBach));
551 aodTrack->SetTPCPointsF(esdCascadeBach->GetTPCNclsF());
552 fAODTrackRefs->AddAt(aodTrack,idxBachFromCascade);
554 if (esdCascadeBach->GetSign() > 0) ++fNumberOfPositiveTracks;
555 aodTrack->ConvertAliPIDtoAODPID();
556 aodTrack->SetFlags(esdCascadeBach->GetStatus());
557 SetAODPID(esdCascadeBach,aodTrack,detpid);
560 aodTrack = static_cast<AliAODTrack*>( fAODTrackRefs->At(idxBachFromCascade) );
563 vCascade->AddDaughter(aodTrack);
566 // printf("---- Cascade / bach dghter : \n");
567 // aodTrack->Print();
571 // 4 - Add the V0 from the cascade.
572 // = V0vtx + both pos and neg daughter tracks + the aodV0 itself
575 if ( !fUsedV0[idxV0FromCascade] ) {
576 // 4.A - if VO structure hasn't been created yet
578 // 4.A.1 - Create the V0 vertex of the cascade
580 esdV0FromCascade->GetXYZ(pos[0], pos[1], pos[2]);
581 esdV0FromCascade->GetPosCov(covVtx);
582 chi2 = esdV0FromCascade->GetChi2V0(); // = chi2/NDF since NDF = 2*2-3 ?
584 vV0FromCascade = new(verticesArray[fNumberOfVertices++]) AliAODVertex(pos,
588 idxV0FromCascade, //id of ESDv0
591 // one V0 can be used by several cascades.
592 // So, one AOD V0 vtx can have several parent vtx.
593 // This is not directly allowed by AliAODvertex.
594 // Setting the parent vtx (here = param "vCascade") doesn't lead to a crash
595 // but to a problem of consistency within AODEvent.
596 // -> See below paragraph 4.B, for the proposed treatment of such a case.
598 // Add the vV0FromCascade to the aodVOVtxRefs
599 fAODV0VtxRefs->AddAt(vV0FromCascade,idxV0FromCascade);
602 // 4.A.2 - Add the positive tracks from the V0
604 esdCascadePos->GetPxPyPz(momPos);
605 esdCascadePos->GetXYZ(pos);
606 esdCascadePos->GetCovarianceXYZPxPyPz(covTr);
607 esdCascadePos->GetESDpid(pid);
610 if (!fUsedTrack[idxPosFromV0Dghter]) {
611 fUsedTrack[idxPosFromV0Dghter] = kTRUE;
613 UInt_t selectInfo = 0;
614 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdCascadePos);
615 if(fMChandler) fMChandler->SelectParticle(esdCascadePos->GetLabel());
616 aodTrack = new(tracksArray[fNumberOfTracks++])
617 AliAODTrack( esdCascadePos->GetID(),
618 esdCascadePos->GetLabel(),
622 kFALSE, // Why kFALSE for "isDCA" ? FIXME
624 (Short_t)esdCascadePos->GetSign(),
625 esdCascadePos->GetITSClusterMap(),
628 kTRUE, // usedForVtxFit = kFALSE ? FIXME
629 vtx->UsesTrack(esdCascadePos->GetID()),
630 AliAODTrack::kSecondary,
632 aodTrack->SetTPCFitMap(esdCascadePos->GetTPCFitMap());
633 aodTrack->SetTPCClusterMap(esdCascadePos->GetTPCClusterMap());
634 aodTrack->SetTPCSharedMap (esdCascadePos->GetTPCSharedMap());
635 aodTrack->SetChi2perNDF(Chi2perNDF(esdCascadePos));
636 aodTrack->SetTPCPointsF(esdCascadePos->GetTPCNclsF());
637 fAODTrackRefs->AddAt(aodTrack,idxPosFromV0Dghter);
639 if (esdCascadePos->GetSign() > 0) ++fNumberOfPositiveTracks;
640 aodTrack->ConvertAliPIDtoAODPID();
641 aodTrack->SetFlags(esdCascadePos->GetStatus());
642 SetAODPID(esdCascadePos,aodTrack,detpid);
645 aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(idxPosFromV0Dghter));
647 vV0FromCascade->AddDaughter(aodTrack);
650 // 4.A.3 - Add the negative tracks from the V0
652 esdCascadeNeg->GetPxPyPz(momNeg);
653 esdCascadeNeg->GetXYZ(pos);
654 esdCascadeNeg->GetCovarianceXYZPxPyPz(covTr);
655 esdCascadeNeg->GetESDpid(pid);
658 if (!fUsedTrack[idxNegFromV0Dghter]) {
659 fUsedTrack[idxNegFromV0Dghter] = kTRUE;
661 UInt_t selectInfo = 0;
662 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdCascadeNeg);
663 if(fMChandler)fMChandler->SelectParticle(esdCascadeNeg->GetLabel());
664 aodTrack = new(tracksArray[fNumberOfTracks++]) AliAODTrack( esdCascadeNeg->GetID(),
665 esdCascadeNeg->GetLabel(),
669 kFALSE, // Why kFALSE for "isDCA" ? FIXME
671 (Short_t)esdCascadeNeg->GetSign(),
672 esdCascadeNeg->GetITSClusterMap(),
675 kTRUE, // usedForVtxFit = kFALSE ? FIXME
676 vtx->UsesTrack(esdCascadeNeg->GetID()),
677 AliAODTrack::kSecondary,
679 aodTrack->SetTPCFitMap(esdCascadeNeg->GetTPCFitMap());
680 aodTrack->SetTPCClusterMap(esdCascadeNeg->GetTPCClusterMap());
681 aodTrack->SetTPCSharedMap (esdCascadeNeg->GetTPCSharedMap());
682 aodTrack->SetChi2perNDF(Chi2perNDF(esdCascadeNeg));
683 aodTrack->SetTPCPointsF(esdCascadeNeg->GetTPCNclsF());
684 fAODTrackRefs->AddAt(aodTrack,idxNegFromV0Dghter);
686 if (esdCascadeNeg->GetSign() > 0) ++fNumberOfPositiveTracks;
687 aodTrack->ConvertAliPIDtoAODPID();
688 aodTrack->SetFlags(esdCascadeNeg->GetStatus());
689 SetAODPID(esdCascadeNeg,aodTrack,detpid);
692 aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(idxNegFromV0Dghter));
695 vV0FromCascade->AddDaughter(aodTrack);
698 // 4.A.4 - Add the V0 from cascade to the V0 array
700 Double_t dcaV0Daughters = esdV0FromCascade->GetDcaV0Daughters();
701 Double_t dcaV0ToPrimVertex = esdV0FromCascade->GetD( esd.GetPrimaryVertex()->GetX(),
702 esd.GetPrimaryVertex()->GetY(),
703 esd.GetPrimaryVertex()->GetZ() );
704 esdV0FromCascade->GetPPxPyPz( momPosAtV0vtx[0],momPosAtV0vtx[1],momPosAtV0vtx[2] );
705 esdV0FromCascade->GetNPxPyPz( momNegAtV0vtx[0],momNegAtV0vtx[1],momNegAtV0vtx[2] );
707 Double_t dcaDaughterToPrimVertex[2] = { 999., 999.}; // ..[0] = DCA in (x,y) for Pos and ..[1] = Neg
708 dcaDaughterToPrimVertex[0] = TMath::Abs(esdCascadePos->GetD( esd.GetPrimaryVertex()->GetX(),
709 esd.GetPrimaryVertex()->GetY(),
710 esd.GetMagneticField()) );
711 dcaDaughterToPrimVertex[1] = TMath::Abs(esdCascadeNeg->GetD( esd.GetPrimaryVertex()->GetX(),
712 esd.GetPrimaryVertex()->GetY(),
713 esd.GetMagneticField()) );
715 aodV0 = new(V0s()[fNumberOfV0s++]) AliAODv0( vV0FromCascade,
720 dcaDaughterToPrimVertex);
721 // set the aod v0 on-the-fly status
722 aodV0->SetOnFlyStatus(esdV0FromCascade->GetOnFlyStatus());
724 // Add the aodV0 to the aodVORefs
725 fAODV0Refs->AddAt(aodV0,idxV0FromCascade);
727 fUsedV0[idxV0FromCascade] = kTRUE;
730 // 4.B - if V0 structure already used
733 // one V0 can be used by several cascades (frequent in PbPb evts) :
734 // same V0 which used but attached to different bachelor tracks
735 // -> aodVORefs and fAODV0VtxRefs are needed.
736 // Goal : avoid a redundancy of the info in "Vertices" and "v0s" clones array.
738 vV0FromCascade = static_cast<AliAODVertex*>( fAODV0VtxRefs->At(idxV0FromCascade) );
739 aodV0 = static_cast<AliAODv0*> ( fAODV0Refs ->At(idxV0FromCascade) );
741 // - Treatment of the parent for such a "re-used" V0 :
742 // Insert the cascade that reuses the V0 vertex in the lineage chain
743 // Before : vV0 -> vCascade1 -> vPrimary
744 // - Hyp : cascade2 uses the same V0 as cascade1
745 // After : vV0 -> vCascade2 -> vCascade1 -> vPrimary
747 AliAODVertex *vCascadePreviousParent = static_cast<AliAODVertex*> (vV0FromCascade->GetParent());
748 vV0FromCascade->SetParent(vCascade);
749 vCascade ->SetParent(vCascadePreviousParent);
752 // printf("---- Cascade / Lineage insertion\n"
753 // "Parent of V0 vtx = Cascade vtx %p\n"
754 // "Parent of the cascade vtx = Cascade vtx %p\n"
755 // "Parent of the parent cascade vtx = Cascade vtx %p\n",
756 // static_cast<void*> (vV0FromCascade->GetParent()),
757 // static_cast<void*> (vCascade->GetParent()),
758 // static_cast<void*> (vCascadePreviousParent->GetParent()) );
760 }// end if V0 structure already used
763 // printf("---- Cascade / V0 vertex: \n");
764 // vV0FromCascade->Print();
768 // printf("---- Cascade / pos dghter : \n");
769 // aodTrack->Print();
770 // printf("---- Cascade / neg dghter : \n");
771 // aodTrack->Print();
772 // printf("---- Cascade / aodV0 : \n");
776 // In any case (used V0 or not), add the V0 vertex to the cascade one.
777 vCascade->AddDaughter(vV0FromCascade);
780 // 5 - Add the primary track of the cascade (if any)
783 // 6 - Add the cascade to the AOD array of cascades
785 Double_t dcaBachToPrimVertexXY = TMath::Abs(esdCascadeBach->GetD(esd.GetPrimaryVertex()->GetX(),
786 esd.GetPrimaryVertex()->GetY(),
787 esd.GetMagneticField()) );
789 Double_t momBachAtCascadeVtx[3]={0.};
791 esdCascade->GetBPxPyPz(momBachAtCascadeVtx[0], momBachAtCascadeVtx[1], momBachAtCascadeVtx[2]);
793 aodCascade = new(cascadesArray[fNumberOfCascades++]) AliAODcascade( vCascade,
794 esdCascade->Charge(),
795 esdCascade->GetDcaXiDaughters(),
797 // DCAXiToPrimVtx -> needs to be calculated ----|
798 // doesn't exist at ESD level;
799 // See AODcascade::DcaXiToPrimVertex(Double, Double, Double)
800 dcaBachToPrimVertexXY,
805 printf("---- Cascade / AOD cascade : \n\n");
806 aodCascade->PrintXi(fPrimaryVertex->GetX(), fPrimaryVertex->GetY(), fPrimaryVertex->GetZ());
809 } // end of the loop on cascades
811 Cascades().Expand(fNumberOfCascades);
814 //______________________________________________________________________________
815 void AliAnalysisTaskESDfilter::ConvertV0s(const AliESDEvent& esd)
817 // Access to the AOD container of V0s
819 AliCodeTimerAuto("",0);
825 Double_t pos[3] = { 0. };
827 Double_t covVtx[6] = { 0. };
828 Double_t momPos[3]={0.};
829 Double_t covTr[21]={0.};
830 Double_t pid[10]={0.};
831 AliAODTrack* aodTrack(0x0);
832 AliAODPid* detpid(0x0);
833 Double_t momNeg[3]={0.};
834 Double_t momPosAtV0vtx[3]={0.};
835 Double_t momNegAtV0vtx[3]={0.};
837 for (Int_t nV0 = 0; nV0 < esd.GetNumberOfV0s(); ++nV0)
839 if (fUsedV0[nV0]) continue; // skip if already added to the AOD
841 AliESDv0 *v0 = esd.GetV0(nV0);
842 Int_t posFromV0 = v0->GetPindex();
843 Int_t negFromV0 = v0->GetNindex();
847 AliESDVertex *esdVtx = new AliESDVertex(*(esd.GetPrimaryVertex()));
848 AliESDtrack *esdV0Pos = esd.GetTrack(posFromV0);
849 AliESDtrack *esdV0Neg = esd.GetTrack(negFromV0);
851 v0objects.AddAt(v0, 0);
852 v0objects.AddAt(esdV0Pos, 1);
853 v0objects.AddAt(esdV0Neg, 2);
854 v0objects.AddAt(esdVtx, 3);
857 selectV0 = fV0Filter->IsSelected(&v0objects);
858 // this is a little awkward but otherwise the
859 // list wants to access the pointer (delete it)
860 // again when going out of scope
861 delete v0objects.RemoveAt(3); // esdVtx created via copy construct
867 delete v0objects.RemoveAt(3); // esdVtx created via copy construct
871 v0->GetXYZ(pos[0], pos[1], pos[2]);
873 if (!fOldESDformat) {
874 chi2 = v0->GetChi2V0(); // = chi2/NDF since NDF = 2*2-3
875 v0->GetPosCov(covVtx);
878 for (Int_t i = 0; i < 6; i++) covVtx[i] = 0.;
883 new(Vertices()[fNumberOfVertices++]) AliAODVertex(pos,
889 fPrimaryVertex->AddDaughter(vV0);
892 // Add the positive tracks from the V0
895 esdV0Pos->GetPxPyPz(momPos);
896 esdV0Pos->GetXYZ(pos);
897 esdV0Pos->GetCovarianceXYZPxPyPz(covTr);
898 esdV0Pos->GetESDpid(pid);
900 const AliESDVertex *vtx = esd.GetPrimaryVertex();
902 if (!fUsedTrack[posFromV0]) {
903 fUsedTrack[posFromV0] = kTRUE;
904 UInt_t selectInfo = 0;
905 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdV0Pos);
906 if(fMChandler)fMChandler->SelectParticle(esdV0Pos->GetLabel());
907 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdV0Pos->GetID(),
908 esdV0Pos->GetLabel(),
914 (Short_t)esdV0Pos->GetSign(),
915 esdV0Pos->GetITSClusterMap(),
918 kTRUE, // check if this is right
919 vtx->UsesTrack(esdV0Pos->GetID()),
920 AliAODTrack::kSecondary,
922 aodTrack->SetTPCFitMap(esdV0Pos->GetTPCFitMap());
923 aodTrack->SetTPCClusterMap(esdV0Pos->GetTPCClusterMap());
924 aodTrack->SetTPCSharedMap (esdV0Pos->GetTPCSharedMap());
925 aodTrack->SetChi2perNDF(Chi2perNDF(esdV0Pos));
926 aodTrack->SetTPCPointsF(esdV0Pos->GetTPCNclsF());
927 fAODTrackRefs->AddAt(aodTrack,posFromV0);
928 // if (fDebug > 0) printf("-------------------Bo: pos track from original pt %.3f \n",aodTrack->Pt());
929 if (esdV0Pos->GetSign() > 0) ++fNumberOfPositiveTracks;
930 aodTrack->ConvertAliPIDtoAODPID();
931 aodTrack->SetFlags(esdV0Pos->GetStatus());
932 SetAODPID(esdV0Pos,aodTrack,detpid);
935 aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(posFromV0));
936 // if (fDebug > 0) printf("-------------------Bo pos track from refArray pt %.3f \n",aodTrack->Pt());
938 vV0->AddDaughter(aodTrack);
940 // Add the negative tracks from the V0
942 esdV0Neg->GetPxPyPz(momNeg);
943 esdV0Neg->GetXYZ(pos);
944 esdV0Neg->GetCovarianceXYZPxPyPz(covTr);
945 esdV0Neg->GetESDpid(pid);
947 if (!fUsedTrack[negFromV0]) {
948 fUsedTrack[negFromV0] = kTRUE;
949 UInt_t selectInfo = 0;
950 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdV0Neg);
951 if(fMChandler)fMChandler->SelectParticle(esdV0Neg->GetLabel());
952 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdV0Neg->GetID(),
953 esdV0Neg->GetLabel(),
959 (Short_t)esdV0Neg->GetSign(),
960 esdV0Neg->GetITSClusterMap(),
963 kTRUE, // check if this is right
964 vtx->UsesTrack(esdV0Neg->GetID()),
965 AliAODTrack::kSecondary,
967 aodTrack->SetTPCFitMap(esdV0Neg->GetTPCFitMap());
968 aodTrack->SetTPCClusterMap(esdV0Neg->GetTPCClusterMap());
969 aodTrack->SetTPCSharedMap (esdV0Neg->GetTPCSharedMap());
970 aodTrack->SetChi2perNDF(Chi2perNDF(esdV0Neg));
971 aodTrack->SetTPCPointsF(esdV0Neg->GetTPCNclsF());
973 fAODTrackRefs->AddAt(aodTrack,negFromV0);
974 // if (fDebug > 0) printf("-------------------Bo: neg track from original pt %.3f \n",aodTrack->Pt());
975 if (esdV0Neg->GetSign() > 0) ++fNumberOfPositiveTracks;
976 aodTrack->ConvertAliPIDtoAODPID();
977 aodTrack->SetFlags(esdV0Neg->GetStatus());
978 SetAODPID(esdV0Neg,aodTrack,detpid);
981 aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(negFromV0));
982 // if (fDebug > 0) printf("-------------------Bo neg track from refArray pt %.3f \n",aodTrack->Pt());
984 vV0->AddDaughter(aodTrack);
987 // Add the V0 the V0 array as well
989 Double_t dcaV0Daughters = v0->GetDcaV0Daughters();
990 Double_t dcaV0ToPrimVertex = v0->GetD(esd.GetPrimaryVertex()->GetX(),
991 esd.GetPrimaryVertex()->GetY(),
992 esd.GetPrimaryVertex()->GetZ());
994 v0->GetPPxPyPz(momPosAtV0vtx[0],momPosAtV0vtx[1],momPosAtV0vtx[2]);
995 v0->GetNPxPyPz(momNegAtV0vtx[0],momNegAtV0vtx[1],momNegAtV0vtx[2]);
997 Double_t dcaDaughterToPrimVertex[2] = { 999., 999.}; // ..[0] = DCA in (x,y) for Pos and ..[1] = Neg
998 dcaDaughterToPrimVertex[0] = TMath::Abs(esdV0Pos->GetD( esd.GetPrimaryVertex()->GetX(),
999 esd.GetPrimaryVertex()->GetY(),
1000 esd.GetMagneticField()) );
1001 dcaDaughterToPrimVertex[1] = TMath::Abs(esdV0Neg->GetD( esd.GetPrimaryVertex()->GetX(),
1002 esd.GetPrimaryVertex()->GetY(),
1003 esd.GetMagneticField()) );
1005 AliAODv0* aodV0 = new(V0s()[fNumberOfV0s++]) AliAODv0(vV0,
1010 dcaDaughterToPrimVertex);
1012 // set the aod v0 on-the-fly status
1013 aodV0->SetOnFlyStatus(v0->GetOnFlyStatus());
1014 }//End of loop on V0s
1016 V0s().Expand(fNumberOfV0s);
1019 //______________________________________________________________________________
1020 void AliAnalysisTaskESDfilter::ConvertTPCOnlyTracks(const AliESDEvent& esd)
1022 // Convert TPC only tracks
1023 // Here we have wo hybrid appraoch to remove fakes
1024 // ******* ITSTPC ********
1025 // Uses a cut on the ITS properties to select global tracks
1026 // which are than marked as HybdridITSTPC for the remainder
1027 // the TPC only tracks are flagged as HybridITSTPConly.
1028 // Note, in order not to get fakes back in the TPC cuts, one needs
1029 // two "ITS" cuts one tight (1) (to throw out fakes) and one lose (2) (to NOT flag the trakcs in the TPC only)
1030 // using cut number (3)
1031 // so fHybridFilterMask == (1)|(2) fTPCFilterMask = (3), Usercode needs to slect with mask = (1)|(3) and track->IsHybridITSTPC()
1032 // ******* TPC ********
1033 // Here, only TPC tracks are flagged that pass the tight ITS cuts and tracks that pass the TPC cuts and NOT the loose ITS cuts
1034 // the ITS cuts neeed to be added to the filter as extra cuts, since here the selections info is reset in the global and put to the TPC only track
1036 AliCodeTimerAuto("",0);
1038 // Loop over the tracks and extract and mask out all aod tracks that pass the selections for AODt racks
1039 for(int it = 0;it < fNumberOfTracks;++it)
1041 AliAODTrack *tr = (AliAODTrack*)(Tracks().At(it));
1043 UInt_t map = tr->GetFilterMap();
1044 if(map&fTPCConstrainedFilterMask){
1045 // we only reset the track select ionfo, no deletion...
1046 tr->SetFilterMap(map&~fTPCConstrainedFilterMask);
1048 if(map&fHybridFilterMaskTPCCG){
1049 // this is one part of the hybrid tracks
1050 // the others not passing the selection will be TPC only selected below
1051 tr->SetIsHybridTPCConstrainedGlobal(kTRUE);
1054 // Loop over the ESD trcks and pick out the tracks passing TPC only cuts
1057 const AliESDVertex *vtxSPD = esd.GetPrimaryVertexSPD();
1058 const AliESDVertex *vtx = esd.GetPrimaryVertex();
1060 Double_t pos[3] = { 0. };
1061 Double_t covTr[21]={0.};
1062 Double_t pid[10]={0.};
1065 Double_t p[3] = { 0. };
1067 Double_t pDCA[3] = { 0. }; // momentum at DCA
1068 Double_t rDCA[3] = { 0. }; // position at DCA
1069 Float_t dDCA[2] = {0.}; // DCA to the vertex d and z
1070 Float_t cDCA[3] = {0.}; // covariance of impact parameters
1073 AliAODTrack* aodTrack(0x0);
1074 // AliAODPid* detpid(0x0);
1076 // account for change in pT after the constraint
1077 Float_t ptMax = 1E10;
1079 for(int i = 0;i<32;i++){
1080 if(fTPCConstrainedFilterMask&(1<<i)){
1081 AliESDtrackCuts*cuts = (AliESDtrackCuts*)fTrackFilter->GetCuts()->At(i);
1082 Float_t tmp1= 0,tmp2 = 0;
1083 cuts->GetPtRange(tmp1,tmp2);
1084 if(tmp1>ptMin)ptMin=tmp1;
1085 if(tmp2<ptMax)ptMax=tmp2;
1089 for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack)
1091 AliESDtrack* esdTrack = esd.GetTrack(nTrack); //carefull do not modify it othwise need to work with a copy
1093 UInt_t selectInfo = 0;
1094 Bool_t isHybridITSTPC = false;
1098 selectInfo = fTrackFilter->IsSelected(esdTrack);
1101 if(!(selectInfo&fHybridFilterMaskTPCCG)){
1102 // not already selected tracks, use second part of hybrid tracks
1103 isHybridITSTPC = true;
1104 // too save space one could only store these...
1107 selectInfo &= fTPCConstrainedFilterMask;
1108 if (!selectInfo)continue;
1109 if (fWriteHybridTPCCOnly&&!isHybridITSTPC)continue; // write only complementary tracks
1110 // create a tpc only tracl
1111 AliESDtrack *track = AliESDtrackCuts::GetTPCOnlyTrack(const_cast<AliESDEvent*>(&esd),esdTrack->GetID());
1112 if(!track) continue;
1116 // only constrain tracks above threshold
1117 AliExternalTrackParam exParam;
1118 // take the B-field from the ESD, no 3D fieldMap available at this point
1119 Bool_t relate = false;
1120 relate = track->RelateToVertexTPC(vtxSPD,esd.GetMagneticField(),kVeryBig,&exParam);
1125 // fetch the track parameters at the DCA (unconstraint)
1126 if(track->GetTPCInnerParam()){
1127 track->GetTPCInnerParam()->GetPxPyPz(pDCA);
1128 track->GetTPCInnerParam()->GetXYZ(rDCA);
1130 // get the DCA to the vertex:
1131 track->GetImpactParametersTPC(dDCA,cDCA);
1132 // set the constrained parameters to the track
1133 track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
1136 track->GetPxPyPz(p);
1138 Float_t pT = track->Pt();
1139 if(pT<ptMin||pT>ptMax){
1148 track->GetCovarianceXYZPxPyPz(covTr);
1149 esdTrack->GetESDpid(pid);// original PID
1151 if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
1152 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack((track->GetID()+1)*-1,
1159 (Short_t)track->GetSign(),
1160 track->GetITSClusterMap(),
1163 kTRUE, // check if this is right
1164 vtx->UsesTrack(track->GetID()),
1165 AliAODTrack::kPrimary,
1167 aodTrack->SetIsHybridTPCConstrainedGlobal(isHybridITSTPC);
1168 aodTrack->SetTPCFitMap(track->GetTPCFitMap());
1169 aodTrack->SetTPCClusterMap(track->GetTPCClusterMap());
1170 aodTrack->SetTPCSharedMap (track->GetTPCSharedMap());
1171 aodTrack->SetIsTPCConstrained(kTRUE);
1172 aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack)); // original track
1173 // set the DCA values to the AOD track
1174 aodTrack->SetPxPyPzAtDCA(pDCA[0],pDCA[1],pDCA[2]);
1175 aodTrack->SetXYAtDCA(rDCA[0],rDCA[1]);
1176 aodTrack->SetDCA(dDCA[0],dDCA[1]);
1178 aodTrack->SetFlags(track->GetStatus());
1179 aodTrack->SetTPCPointsF(track->GetTPCNclsF());
1181 //Perform progagation of tracks if needed
1182 if(fDoPropagateTrackToEMCal) PropagateTrackToEMCal(esdTrack);
1183 aodTrack->SetTrackPhiEtaOnEMCal(esdTrack->GetTrackPhiOnEMCal(),esdTrack->GetTrackEtaOnEMCal());
1185 // do not duplicate PID information
1186 // aodTrack->ConvertAliPIDtoAODPID();
1187 // SetAODPID(esdTrack,aodTrack,detpid);
1190 } // end of loop on tracks
1194 //______________________________________________________________________________
1195 void AliAnalysisTaskESDfilter::ConvertGlobalConstrainedTracks(const AliESDEvent& esd)
1198 // Here we have the option to store the complement from global constraint information
1199 // to tracks passing tight cuts (1) in order not to get fakes back in, one needs
1200 // two sets of cuts one tight (1) (to throw out fakes) and one lose (2) (fakes/bad tracks would pass (2) but not (1))
1201 // using cut number (3) selects the tracks that complement (1) e.g. tracks witout ITS refit or cluster requirement
1204 AliCodeTimerAuto("",0);
1206 // Loop over the tracks and extract and mask out all aod tracks that pass the selections for AODt racks
1207 for(int it = 0;it < fNumberOfTracks;++it)
1209 AliAODTrack *tr = (AliAODTrack*)(Tracks().At(it));
1211 UInt_t map = tr->GetFilterMap();
1212 if(map&fGlobalConstrainedFilterMask){
1213 // we only reset the track select info, no deletion...
1214 // mask reset mask in case track is already taken
1215 tr->SetFilterMap(map&~fGlobalConstrainedFilterMask);
1217 if(map&fHybridFilterMaskGCG){
1218 // this is one part of the hybrid tracks
1219 // the others not passing the selection will be the ones selected below
1220 tr->SetIsHybridGlobalConstrainedGlobal(kTRUE);
1223 // Loop over the ESD trcks and pick out the tracks passing the GlobalConstraint cuts
1226 Double_t pos[3] = { 0. };
1227 Double_t covTr[21]={0.};
1228 Double_t pid[10]={0.};
1229 Double_t p[3] = { 0. };
1231 Double_t pDCA[3] = { 0. }; // momentum at DCA
1232 Double_t rDCA[3] = { 0. }; // position at DCA
1233 Float_t dDCA[2] = {0.}; // DCA to the vertex d and z
1234 Float_t cDCA[3] = {0.}; // covariance of impact parameters
1237 AliAODTrack* aodTrack(0x0);
1238 AliAODPid* detpid(0x0);
1239 const AliESDVertex *vtx = esd.GetPrimaryVertex();
1241 // account for change in pT after the constraint
1242 Float_t ptMax = 1E10;
1244 for(int i = 0;i<32;i++){
1245 if(fGlobalConstrainedFilterMask&(1<<i)){
1246 AliESDtrackCuts*cuts = (AliESDtrackCuts*)fTrackFilter->GetCuts()->At(i);
1247 Float_t tmp1= 0,tmp2 = 0;
1248 cuts->GetPtRange(tmp1,tmp2);
1249 if(tmp1>ptMin)ptMin=tmp1;
1250 if(tmp2<ptMax)ptMax=tmp2;
1256 for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack)
1258 AliESDtrack* esdTrack = esd.GetTrack(nTrack); //carefull do not modify it othwise need to work with a copy
1259 const AliExternalTrackParam * exParamGC = esdTrack->GetConstrainedParam();
1260 if(!exParamGC)continue;
1262 UInt_t selectInfo = 0;
1263 Bool_t isHybridGC = false;
1268 selectInfo = fTrackFilter->IsSelected(esdTrack);
1272 if(!(selectInfo&fHybridFilterMaskGCG))isHybridGC = true;
1273 if (fWriteHybridGCOnly&&!isHybridGC)continue; // write only complementary tracks
1275 selectInfo &= fGlobalConstrainedFilterMask;
1276 if (!selectInfo)continue;
1277 // fetch the track parameters at the DCA (unconstrained)
1278 esdTrack->GetPxPyPz(pDCA);
1279 esdTrack->GetXYZ(rDCA);
1280 // get the DCA to the vertex:
1281 esdTrack->GetImpactParameters(dDCA,cDCA);
1283 if (!esdTrack->GetConstrainedPxPyPz(p)) continue;
1286 Float_t pT = exParamGC->Pt();
1287 if(pT<ptMin||pT>ptMax){
1292 esdTrack->GetConstrainedXYZ(pos);
1293 exParamGC->GetCovarianceXYZPxPyPz(covTr);
1294 esdTrack->GetESDpid(pid);
1295 if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
1296 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack((esdTrack->GetID()+1)*-1,
1297 esdTrack->GetLabel(),
1303 (Short_t)esdTrack->GetSign(),
1304 esdTrack->GetITSClusterMap(),
1307 kTRUE, // check if this is right
1308 vtx->UsesTrack(esdTrack->GetID()),
1309 AliAODTrack::kPrimary,
1311 aodTrack->SetIsHybridGlobalConstrainedGlobal(isHybridGC);
1312 aodTrack->SetIsGlobalConstrained(kTRUE);
1313 aodTrack->SetTPCFitMap(esdTrack->GetTPCFitMap());
1314 aodTrack->SetTPCClusterMap(esdTrack->GetTPCClusterMap());
1315 aodTrack->SetTPCSharedMap (esdTrack->GetTPCSharedMap());
1316 aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack));
1319 // set the DCA values to the AOD track
1320 aodTrack->SetPxPyPzAtDCA(pDCA[0],pDCA[1],pDCA[2]);
1321 aodTrack->SetXYAtDCA(rDCA[0],rDCA[1]);
1322 aodTrack->SetDCA(dDCA[0],dDCA[1]);
1324 aodTrack->SetFlags(esdTrack->GetStatus());
1325 aodTrack->SetTPCPointsF(esdTrack->GetTPCNclsF());
1328 // only copy AOD information for hybrid, no duplicate information
1329 aodTrack->ConvertAliPIDtoAODPID();
1330 SetAODPID(esdTrack,aodTrack,detpid);
1333 //Perform progagation of tracks if needed
1334 if(fDoPropagateTrackToEMCal) PropagateTrackToEMCal(esdTrack);
1335 aodTrack->SetTrackPhiEtaOnEMCal(esdTrack->GetTrackPhiOnEMCal(),esdTrack->GetTrackEtaOnEMCal());
1336 } // end of loop on tracks
1341 //______________________________________________________________________________
1342 void AliAnalysisTaskESDfilter::ConvertTracks(const AliESDEvent& esd)
1344 // Tracks (primary and orphan)
1346 AliCodeTimerAuto("",0);
1348 AliDebug(1,Form("NUMBER OF ESD TRACKS %5d\n", esd.GetNumberOfTracks()));
1350 const AliESDVertex *vtx = esd.GetPrimaryVertex();
1351 Double_t p[3] = { 0. };
1352 Double_t pos[3] = { 0. };
1353 Double_t covTr[21] = { 0. };
1354 Double_t pid[10] = { 0. };
1355 AliAODTrack* aodTrack(0x0);
1356 AliAODPid* detpid(0x0);
1358 for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack)
1360 if (fUsedTrack[nTrack]) continue;
1362 AliESDtrack *esdTrack = esd.GetTrack(nTrack);
1363 UInt_t selectInfo = 0;
1367 selectInfo = fTrackFilter->IsSelected(esdTrack);
1368 if (!selectInfo && !vtx->UsesTrack(esdTrack->GetID())) continue;
1372 esdTrack->GetPxPyPz(p);
1373 esdTrack->GetXYZ(pos);
1374 esdTrack->GetCovarianceXYZPxPyPz(covTr);
1375 esdTrack->GetESDpid(pid);
1376 if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
1377 fPrimaryVertex->AddDaughter(aodTrack =
1378 new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrack->GetID(),
1379 esdTrack->GetLabel(),
1385 (Short_t)esdTrack->GetSign(),
1386 esdTrack->GetITSClusterMap(),
1389 kTRUE, // check if this is right
1390 vtx->UsesTrack(esdTrack->GetID()),
1391 AliAODTrack::kPrimary,
1394 aodTrack->SetTPCFitMap(esdTrack->GetTPCFitMap());
1395 aodTrack->SetTPCClusterMap(esdTrack->GetTPCClusterMap());
1396 aodTrack->SetTPCSharedMap (esdTrack->GetTPCSharedMap());
1397 aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack));
1398 aodTrack->SetTPCPointsF(esdTrack->GetTPCNclsF());
1399 if(esdTrack->IsEMCAL()) aodTrack->SetEMCALcluster(esdTrack->GetEMCALcluster());
1400 if(esdTrack->IsPHOS()) aodTrack->SetPHOScluster(esdTrack->GetPHOScluster());
1402 //Perform progagation of tracks if needed
1403 if(fDoPropagateTrackToEMCal) PropagateTrackToEMCal(esdTrack);
1404 aodTrack->SetTrackPhiEtaOnEMCal(esdTrack->GetTrackPhiOnEMCal(),esdTrack->GetTrackEtaOnEMCal());
1406 fAODTrackRefs->AddAt(aodTrack, nTrack);
1409 if (esdTrack->GetSign() > 0) ++fNumberOfPositiveTracks;
1410 aodTrack->SetFlags(esdTrack->GetStatus());
1411 aodTrack->ConvertAliPIDtoAODPID();
1412 SetAODPID(esdTrack,aodTrack,detpid);
1413 } // end of loop on tracks
1416 //______________________________________________________________________________
1417 void AliAnalysisTaskESDfilter::PropagateTrackToEMCal(AliESDtrack *esdTrack)
1419 Double_t trkPos[3] = {0.,0.,0.};
1420 Double_t EMCalEta=-999, EMCalPhi=-999;
1421 Double_t trkphi = esdTrack->Phi()*TMath::RadToDeg();
1422 if(TMath::Abs(esdTrack->Eta())<0.9 && trkphi > 10 && trkphi < 250 )
1424 AliExternalTrackParam *trkParam = const_cast<AliExternalTrackParam*>(esdTrack->GetInnerParam());
1427 AliExternalTrackParam trkParamTmp(*trkParam);
1428 if(AliTrackerBase::PropagateTrackToBxByBz(&trkParamTmp, 430, esdTrack->GetMass(), 20, kTRUE, 0.8, -1))
1430 trkParamTmp.GetXYZ(trkPos);
1431 TVector3 trkPosVec(trkPos[0],trkPos[1],trkPos[2]);
1432 EMCalEta = trkPosVec.Eta();
1433 EMCalPhi = trkPosVec.Phi();
1434 if(EMCalPhi<0) EMCalPhi += 2*TMath::Pi();
1435 esdTrack->SetTrackPhiEtaOnEMCal(EMCalPhi,EMCalEta);
1441 //______________________________________________________________________________
1442 void AliAnalysisTaskESDfilter::ConvertPmdClusters(const AliESDEvent& esd)
1444 // Convert PMD Clusters
1445 AliCodeTimerAuto("",0);
1446 Int_t jPmdClusters=0;
1447 // Access to the AOD container of PMD clusters
1448 TClonesArray &pmdClusters = *(AODEvent()->GetPmdClusters());
1449 for (Int_t iPmd = 0; iPmd < esd.GetNumberOfPmdTracks(); ++iPmd) {
1450 // file pmd clusters, to be revised!
1451 AliESDPmdTrack *pmdTrack = esd.GetPmdTrack(iPmd);
1454 Double_t posPmd[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ()};
1455 Double_t pidPmd[13] = { 0.}; // to be revised!
1457 // assoc cluster not set
1458 new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), posPmd, pidPmd);
1463 //______________________________________________________________________________
1464 void AliAnalysisTaskESDfilter::ConvertCaloClusters(const AliESDEvent& esd)
1466 // Convert Calorimeter Clusters
1467 AliCodeTimerAuto("",0);
1469 // Access to the AOD container of clusters
1470 TClonesArray &caloClusters = *(AODEvent()->GetCaloClusters());
1473 for (Int_t iClust=0; iClust<esd.GetNumberOfCaloClusters(); ++iClust) {
1475 AliESDCaloCluster * cluster = esd.GetCaloCluster(iClust);
1477 Int_t id = cluster->GetID();
1478 Int_t nLabel = cluster->GetNLabels();
1479 Int_t *labels = cluster->GetLabels();
1481 for(int i = 0;i < nLabel;++i){
1482 if(fMChandler)fMChandler->SelectParticle(labels[i]);
1486 Float_t energy = cluster->E();
1487 Float_t posF[3] = { 0.};
1488 cluster->GetPosition(posF);
1490 AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
1496 cluster->GetType(),0);
1498 caloCluster->SetCaloCluster(cluster->GetDistanceToBadChannel(),
1499 cluster->GetDispersion(),
1500 cluster->GetM20(), cluster->GetM02(),
1501 cluster->GetEmcCpvDistance(),
1502 cluster->GetNExMax(),cluster->GetTOF()) ;
1504 caloCluster->SetPIDFromESD(cluster->GetPID());
1505 caloCluster->SetNCells(cluster->GetNCells());
1506 caloCluster->SetCellsAbsId(cluster->GetCellsAbsId());
1507 caloCluster->SetCellsAmplitudeFraction(cluster->GetCellsAmplitudeFraction());
1509 caloCluster->SetTrackDistance(cluster->GetTrackDx(), cluster->GetTrackDz());
1511 Int_t nMatchCount = 0;
1512 TArrayI* matchedT = cluster->GetTracksMatched();
1513 if (fNumberOfTracks>0 && matchedT && cluster->GetTrackMatchedIndex() >= 0) {
1514 for (Int_t im = 0; im < matchedT->GetSize(); im++) {
1515 Int_t iESDtrack = matchedT->At(im);;
1516 if (fAODTrackRefs->At(iESDtrack) != 0) {
1517 caloCluster->AddTrackMatched((AliAODTrack*)fAODTrackRefs->At(iESDtrack));
1523 caloCluster->SetTrackDistance(-999,-999);
1526 caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters
1529 //______________________________________________________________________________
1530 void AliAnalysisTaskESDfilter::ConvertCaloTrigger(TString calo, const AliESDEvent& esd)
1532 AliCodeTimerAuto("",0);
1536 AliAODCaloTrigger &aodTrigger = *(AODEvent()->GetCaloTrigger(calo));
1537 AliESDCaloTrigger &esdTrigger = *(esd.GetCaloTrigger(calo));
1539 aodTrigger.Allocate(esdTrigger.GetEntries());
1545 while (esdTrigger.Next()) {
1546 esdTrigger.GetPosition(tmod,tabsId);
1547 esdTrigger.GetAmplitude(a);
1548 aodTrigger.Add(tmod,tabsId,a,0.,(Int_t*)NULL,0,0,0);
1554 AliAODHandler *aodHandler = dynamic_cast<AliAODHandler*>(AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler());
1558 TTree *aodTree = aodHandler->GetTree();
1562 Int_t *type = esd.GetCaloTriggerType();
1564 for (Int_t i = 0; i < 15; i++)
1566 aodTree->GetUserInfo()->Add(new TParameter<int>(Form("EMCALCaloTrigger%d",i), type[i]));
1571 AliAODCaloTrigger &aodTrigger = *(AODEvent()->GetCaloTrigger(calo));
1573 AliESDCaloTrigger &esdTrigger = *(esd.GetCaloTrigger(calo));
1575 aodTrigger.Allocate(esdTrigger.GetEntries());
1578 while (esdTrigger.Next())
1580 Int_t px, py, ts, nTimes, times[10], b;
1583 esdTrigger.GetPosition(px, py);
1585 esdTrigger.GetAmplitude(a);
1586 esdTrigger.GetTime(t);
1588 esdTrigger.GetL0Times(times);
1589 esdTrigger.GetNL0Times(nTimes);
1591 esdTrigger.GetL1TimeSum(ts);
1593 esdTrigger.GetTriggerBits(b);
1595 aodTrigger.Add(px, py, a, t, times, nTimes, ts, b);
1598 for (int i = 0; i < 4; i++) aodTrigger.SetL1Threshold(i, esdTrigger.GetL1Threshold(i));
1602 esdTrigger.GetL1V0(0),
1603 esdTrigger.GetL1V0(1)
1606 aodTrigger.SetL1V0(v0);
1607 aodTrigger.SetL1FrameMask(esdTrigger.GetL1FrameMask());
1610 //______________________________________________________________________________
1611 void AliAnalysisTaskESDfilter::ConvertEMCALCells(const AliESDEvent& esd)
1613 // Convert EMCAL Cells
1614 AliCodeTimerAuto("",0);
1615 // fill EMCAL cell info
1616 if (esd.GetEMCALCells()) { // protection against missing ESD information
1617 AliESDCaloCells &esdEMcells = *(esd.GetEMCALCells());
1618 Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
1620 AliAODCaloCells &aodEMcells = *(AODEvent()->GetEMCALCells());
1621 aodEMcells.CreateContainer(nEMcell);
1622 aodEMcells.SetType(AliAODCaloCells::kEMCALCell);
1623 for (Int_t iCell = 0; iCell < nEMcell; iCell++) {
1624 aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell),
1625 esdEMcells.GetTime(iCell), esdEMcells.GetMCLabel(iCell), esdEMcells.GetEFraction(iCell));
1631 //______________________________________________________________________________
1632 void AliAnalysisTaskESDfilter::ConvertPHOSCells(const AliESDEvent& esd)
1634 // Convert PHOS Cells
1635 AliCodeTimerAuto("",0);
1636 // fill PHOS cell info
1637 if (esd.GetPHOSCells()) { // protection against missing ESD information
1638 AliESDCaloCells &esdPHcells = *(esd.GetPHOSCells());
1639 Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
1641 AliAODCaloCells &aodPHcells = *(AODEvent()->GetPHOSCells());
1642 aodPHcells.CreateContainer(nPHcell);
1643 aodPHcells.SetType(AliAODCaloCells::kPHOSCell);
1644 for (Int_t iCell = 0; iCell < nPHcell; iCell++) {
1645 aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell),
1646 esdPHcells.GetTime(iCell), esdPHcells.GetMCLabel(iCell), esdPHcells.GetEFraction(iCell));
1652 //______________________________________________________________________________
1653 void AliAnalysisTaskESDfilter::ConvertTracklets(const AliESDEvent& esd)
1656 AliCodeTimerAuto("",0);
1658 AliAODTracklets &SPDTracklets = *(AODEvent()->GetTracklets());
1659 const AliMultiplicity *mult = esd.GetMultiplicity();
1661 if (mult->GetNumberOfTracklets()>0) {
1662 SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
1664 for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
1666 fMChandler->SelectParticle(mult->GetLabel(n, 0));
1667 fMChandler->SelectParticle(mult->GetLabel(n, 1));
1669 SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n, 0),mult->GetLabel(n, 1));
1673 //Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
1677 //______________________________________________________________________________
1678 void AliAnalysisTaskESDfilter::ConvertKinks(const AliESDEvent& esd)
1680 AliCodeTimerAuto("",0);
1682 // Kinks: it is a big mess the access to the information in the kinks
1683 // The loop is on the tracks in order to find the mother and daugther of each kink
1685 Double_t covTr[21]={0.};
1686 Double_t pid[10]={0.};
1687 AliAODPid* detpid(0x0);
1689 fNumberOfKinks = esd.GetNumberOfKinks();
1691 const AliESDVertex* vtx = esd.GetPrimaryVertex();
1693 for (Int_t iTrack=0; iTrack<esd.GetNumberOfTracks(); ++iTrack)
1695 AliESDtrack * esdTrack = esd.GetTrack(iTrack);
1697 Int_t ikink = esdTrack->GetKinkIndex(0);
1699 if (ikink && fNumberOfKinks) {
1700 // Negative kink index: mother, positive: daughter
1702 // Search for the second track of the kink
1704 for (Int_t jTrack = iTrack+1; jTrack<esd.GetNumberOfTracks(); ++jTrack) {
1706 AliESDtrack * esdTrack1 = esd.GetTrack(jTrack);
1708 Int_t jkink = esdTrack1->GetKinkIndex(0);
1710 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
1712 // The two tracks are from the same kink
1714 if (fUsedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
1717 Int_t idaughter = -1;
1719 if (ikink<0 && jkink>0) {
1724 else if (ikink>0 && jkink<0) {
1730 // cerr << "Error: Wrong combination of kink indexes: "
1731 // << ikink << " " << jkink << endl;
1735 // Add the mother track if it passed primary track selection cuts
1737 AliAODTrack * mother = NULL;
1739 UInt_t selectInfo = 0;
1741 selectInfo = fTrackFilter->IsSelected(esd.GetTrack(imother));
1742 if (!selectInfo) continue;
1745 if (!fUsedTrack[imother]) {
1747 fUsedTrack[imother] = kTRUE;
1749 AliESDtrack *esdTrackM = esd.GetTrack(imother);
1750 Double_t p[3] = { 0. };
1751 Double_t pos[3] = { 0. };
1752 esdTrackM->GetPxPyPz(p);
1753 esdTrackM->GetXYZ(pos);
1754 esdTrackM->GetCovarianceXYZPxPyPz(covTr);
1755 esdTrackM->GetESDpid(pid);
1756 if(fMChandler)fMChandler->SelectParticle(esdTrackM->GetLabel());
1758 new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrackM->GetID(),
1759 esdTrackM->GetLabel(),
1765 (Short_t)esdTrackM->GetSign(),
1766 esdTrackM->GetITSClusterMap(),
1769 kTRUE, // check if this is right
1770 vtx->UsesTrack(esdTrack->GetID()),
1771 AliAODTrack::kPrimary,
1773 mother->SetTPCFitMap(esdTrackM->GetTPCFitMap());
1774 mother->SetTPCClusterMap(esdTrackM->GetTPCClusterMap());
1775 mother->SetTPCSharedMap (esdTrackM->GetTPCSharedMap());
1776 mother->SetChi2perNDF(Chi2perNDF(esdTrackM));
1777 mother->SetTPCPointsF(esdTrackM->GetTPCNclsF());
1779 fAODTrackRefs->AddAt(mother, imother);
1781 if (esdTrackM->GetSign() > 0) ++fNumberOfPositiveTracks;
1782 mother->SetFlags(esdTrackM->GetStatus());
1783 mother->ConvertAliPIDtoAODPID();
1784 fPrimaryVertex->AddDaughter(mother);
1785 mother->ConvertAliPIDtoAODPID();
1786 SetAODPID(esdTrackM,mother,detpid);
1789 // cerr << "Error: event " << esd.GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
1790 // << " track " << imother << " has already been used!" << endl;
1793 // Add the kink vertex
1794 AliESDkink * kink = esd.GetKink(TMath::Abs(ikink)-1);
1796 AliAODVertex * vkink =
1797 new(Vertices()[fNumberOfVertices++]) AliAODVertex(kink->GetPosition(),
1801 esdTrack->GetID(), // This is the track ID of the mother's track!
1802 AliAODVertex::kKink);
1803 // Add the daughter track
1805 AliAODTrack * daughter = NULL;
1807 if (!fUsedTrack[idaughter]) {
1809 fUsedTrack[idaughter] = kTRUE;
1811 AliESDtrack *esdTrackD = esd.GetTrack(idaughter);
1812 Double_t p[3] = { 0. };
1813 Double_t pos[3] = { 0. };
1815 esdTrackD->GetPxPyPz(p);
1816 esdTrackD->GetXYZ(pos);
1817 esdTrackD->GetCovarianceXYZPxPyPz(covTr);
1818 esdTrackD->GetESDpid(pid);
1820 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdTrackD);
1821 if(fMChandler)fMChandler->SelectParticle(esdTrackD->GetLabel());
1823 new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrackD->GetID(),
1824 esdTrackD->GetLabel(),
1830 (Short_t)esdTrackD->GetSign(),
1831 esdTrackD->GetITSClusterMap(),
1834 kTRUE, // check if this is right
1835 vtx->UsesTrack(esdTrack->GetID()),
1836 AliAODTrack::kSecondary,
1838 daughter->SetTPCFitMap(esdTrackD->GetTPCFitMap());
1839 daughter->SetTPCClusterMap(esdTrackD->GetTPCClusterMap());
1840 daughter->SetTPCSharedMap (esdTrackD->GetTPCSharedMap());
1841 daughter->SetTPCPointsF(esdTrackD->GetTPCNclsF());
1842 fAODTrackRefs->AddAt(daughter, idaughter);
1844 if (esdTrackD->GetSign() > 0) ++fNumberOfPositiveTracks;
1845 daughter->SetFlags(esdTrackD->GetStatus());
1846 daughter->ConvertAliPIDtoAODPID();
1847 vkink->AddDaughter(daughter);
1848 daughter->ConvertAliPIDtoAODPID();
1849 SetAODPID(esdTrackD,daughter,detpid);
1852 // cerr << "Error: event " << esd.GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
1853 // << " track " << idaughter << " has already been used!" << endl;
1861 //______________________________________________________________________________
1862 void AliAnalysisTaskESDfilter::ConvertPrimaryVertices(const AliESDEvent& esd)
1864 AliCodeTimerAuto("",0);
1866 // Access to the AOD container of vertices
1867 fNumberOfVertices = 0;
1869 Double_t pos[3] = { 0. };
1870 Double_t covVtx[6] = { 0. };
1872 // Add primary vertex. The primary tracks will be defined
1873 // after the loops on the composite objects (V0, cascades, kinks)
1874 const AliESDVertex *vtx = esd.GetPrimaryVertex();
1876 vtx->GetXYZ(pos); // position
1877 vtx->GetCovMatrix(covVtx); //covariance matrix
1879 fPrimaryVertex = new(Vertices()[fNumberOfVertices++])
1880 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
1881 fPrimaryVertex->SetName(vtx->GetName());
1882 fPrimaryVertex->SetTitle(vtx->GetTitle());
1884 TString vtitle = vtx->GetTitle();
1885 if (!vtitle.Contains("VertexerTracks"))
1886 fPrimaryVertex->SetNContributors(vtx->GetNContributors());
1888 if (fDebug > 0) fPrimaryVertex->Print();
1890 // Add SPD "main" vertex
1891 const AliESDVertex *vtxS = esd.GetPrimaryVertexSPD();
1892 vtxS->GetXYZ(pos); // position
1893 vtxS->GetCovMatrix(covVtx); //covariance matrix
1894 AliAODVertex * mVSPD = new(Vertices()[fNumberOfVertices++])
1895 AliAODVertex(pos, covVtx, vtxS->GetChi2toNDF(), NULL, -1, AliAODVertex::kMainSPD);
1896 mVSPD->SetName(vtxS->GetName());
1897 mVSPD->SetTitle(vtxS->GetTitle());
1898 mVSPD->SetNContributors(vtxS->GetNContributors());
1900 // Add SPD pileup vertices
1901 for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesSPD(); ++iV)
1903 const AliESDVertex *vtxP = esd.GetPileupVertexSPD(iV);
1904 vtxP->GetXYZ(pos); // position
1905 vtxP->GetCovMatrix(covVtx); //covariance matrix
1906 AliAODVertex * pVSPD = new(Vertices()[fNumberOfVertices++])
1907 AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupSPD);
1908 pVSPD->SetName(vtxP->GetName());
1909 pVSPD->SetTitle(vtxP->GetTitle());
1910 pVSPD->SetNContributors(vtxP->GetNContributors());
1911 pVSPD->SetBC(vtxP->GetBC());
1914 // Add TRK pileup vertices
1915 for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesTracks(); ++iV)
1917 const AliESDVertex *vtxP = esd.GetPileupVertexTracks(iV);
1918 vtxP->GetXYZ(pos); // position
1919 vtxP->GetCovMatrix(covVtx); //covariance matrix
1920 AliAODVertex * pVTRK = new(Vertices()[fNumberOfVertices++])
1921 AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupTracks);
1922 pVTRK->SetName(vtxP->GetName());
1923 pVTRK->SetTitle(vtxP->GetTitle());
1924 pVTRK->SetNContributors(vtxP->GetNContributors());
1925 pVTRK->SetBC(vtxP->GetBC());
1929 //______________________________________________________________________________
1930 void AliAnalysisTaskESDfilter::ConvertVZERO(const AliESDEvent& esd)
1932 // Convert VZERO data
1933 AliAODVZERO* vzeroData = AODEvent()->GetVZEROData();
1934 *vzeroData = *(esd.GetVZEROData());
1937 //______________________________________________________________________________
1938 void AliAnalysisTaskESDfilter::ConvertTZERO(const AliESDEvent& esd)
1940 // Convert TZERO data
1941 const AliESDTZERO* esdTzero = esd.GetESDTZERO();
1942 AliAODTZERO* aodTzero = AODEvent()->GetTZEROData();
1944 for (Int_t icase=0; icase<3; icase++){
1945 aodTzero->SetT0TOF( icase, esdTzero->GetT0TOF(icase));
1946 aodTzero->SetT0TOFbest(icase, esdTzero->GetT0TOFbest(icase));
1948 aodTzero->SetBackgroundFlag(esdTzero->GetBackgroundFlag());
1949 aodTzero->SetPileupFlag(esdTzero->GetPileupFlag());
1950 aodTzero->SetSatelliteFlag(esdTzero->GetSatellite());
1952 Float_t rawTime[24];
1953 for(Int_t ipmt=0; ipmt<24; ipmt++)
1954 rawTime[ipmt] = esdTzero->GetTimeFull(ipmt,0);
1956 Int_t idxOfFirstPmtA = -1, idxOfFirstPmtC = -1;
1957 Float_t timeOfFirstPmtA = 9999, timeOfFirstPmtC = 9999;
1958 for(int ipmt=0; ipmt<12; ipmt++){
1959 if( rawTime[ipmt] > -200 && rawTime[ipmt] < timeOfFirstPmtC && rawTime[ipmt]!=0){
1960 timeOfFirstPmtC = rawTime[ipmt];
1961 idxOfFirstPmtC = ipmt;
1964 for(int ipmt=12; ipmt<24; ipmt++){
1965 if( rawTime[ipmt] > -200 && rawTime[ipmt] < timeOfFirstPmtA && rawTime[ipmt]!=0 ){
1966 timeOfFirstPmtA = rawTime[ipmt];
1967 idxOfFirstPmtA = ipmt;
1971 if(idxOfFirstPmtA != -1 && idxOfFirstPmtC != -1){
1972 //speed of light in cm/ns TMath::C()*1e-7
1973 Float_t vertexraw = TMath::C()*1e-7 * (rawTime[idxOfFirstPmtA] - rawTime[idxOfFirstPmtC])/2;
1974 aodTzero->SetT0VertexRaw( vertexraw );
1976 aodTzero->SetT0VertexRaw(99999);
1982 //______________________________________________________________________________
1983 void AliAnalysisTaskESDfilter::ConvertZDC(const AliESDEvent& esd)
1986 AliESDZDC* esdZDC = esd.GetZDCData();
1988 const Double_t zem1Energy = esdZDC->GetZEM1Energy();
1989 const Double_t zem2Energy = esdZDC->GetZEM2Energy();
1991 const Double_t *towZNC = esdZDC->GetZNCTowerEnergy();
1992 const Double_t *towZPC = esdZDC->GetZPCTowerEnergy();
1993 const Double_t *towZNA = esdZDC->GetZNATowerEnergy();
1994 const Double_t *towZPA = esdZDC->GetZPATowerEnergy();
1995 const Double_t *towZNCLG = esdZDC->GetZNCTowerEnergyLR();
1996 const Double_t *towZNALG = esdZDC->GetZNATowerEnergyLR();
1998 AliAODZDC* zdcAOD = AODEvent()->GetZDCData();
2000 zdcAOD->SetZEM1Energy(zem1Energy);
2001 zdcAOD->SetZEM2Energy(zem2Energy);
2002 zdcAOD->SetZNCTowers(towZNC, towZNCLG);
2003 zdcAOD->SetZNATowers(towZNA, towZNALG);
2004 zdcAOD->SetZPCTowers(towZPC);
2005 zdcAOD->SetZPATowers(towZPA);
2007 zdcAOD->SetZDCParticipants(esdZDC->GetZDCParticipants(), esdZDC->GetZDCPartSideA(), esdZDC->GetZDCPartSideC());
2008 zdcAOD->SetZDCImpactParameter(esdZDC->GetImpactParameter(), esdZDC->GetImpactParamSideA(),
2009 esdZDC->GetImpactParamSideC());
2010 zdcAOD->SetZDCTDCSum(esdZDC->GetZNTDCSum(0));
2011 zdcAOD->SetZDCTDCDiff(esdZDC->GetZNTDCDiff(0));
2015 //______________________________________________________________________________
2016 void AliAnalysisTaskESDfilter::ConvertESDtoAOD()
2018 // ESD Filter analysis task executed for each event
2020 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
2024 AliCodeTimerAuto("",0);
2026 fOldESDformat = ( esd->GetAliESDOld() != 0x0 );
2028 // Reconstruct cascades and V0 here
2029 if (fIsV0CascadeRecoEnabled) {
2030 esd->ResetCascades();
2033 AliV0vertexer lV0vtxer;
2034 AliCascadeVertexer lCascVtxer;
2036 lV0vtxer.SetCuts(fV0Cuts);
2037 lCascVtxer.SetCuts(fCascadeCuts);
2040 lV0vtxer.Tracks2V0vertices(esd);
2041 lCascVtxer.V0sTracks2CascadeVertices(esd);
2045 fNumberOfTracks = 0;
2046 fNumberOfPositiveTracks = 0;
2048 fNumberOfVertices = 0;
2049 fNumberOfCascades = 0;
2052 AliAODHeader* header = ConvertHeader(*esd);
2054 if ( fIsVZEROEnabled ) ConvertVZERO(*esd);
2055 if ( fIsTZEROEnabled ) ConvertTZERO(*esd);
2057 // Fetch Stack for debuggging if available
2061 fMChandler = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler());
2064 // loop over events and fill them
2065 // Multiplicity information needed by the header (to be revised!)
2066 Int_t nTracks = esd->GetNumberOfTracks();
2067 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) esd->GetTrack(iTrack)->SetESDEvent(esd);
2069 // Update the header
2071 Int_t nV0s = esd->GetNumberOfV0s();
2072 Int_t nCascades = esd->GetNumberOfCascades();
2073 Int_t nKinks = esd->GetNumberOfKinks();
2074 Int_t nVertices = nV0s + nCascades /*V0 wihtin cascade already counted*/+ nKinks + 1 /* = prim. vtx*/;
2075 Int_t nPileSPDVertices=1+esd->GetNumberOfPileupVerticesSPD(); // also SPD main vertex
2076 Int_t nPileTrkVertices=esd->GetNumberOfPileupVerticesTracks();
2077 nVertices+=nPileSPDVertices;
2078 nVertices+=nPileTrkVertices;
2080 Int_t nCaloClus = esd->GetNumberOfCaloClusters();
2082 Int_t nPmdClus = esd->GetNumberOfPmdTracks();
2084 AliDebug(1,Form(" NV0=%d NCASCADES=%d NKINKS=%d", nV0s, nCascades, nKinks));
2086 AODEvent()->ResetStd(nTracks, nVertices, nV0s, nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
2090 // RefArray to store a mapping between esd V0 number and newly created AOD-Vertex V0
2091 fAODV0VtxRefs = new TRefArray(nV0s);
2092 // RefArray to store the mapping between esd V0 number and newly created AOD-V0
2093 fAODV0Refs = new TRefArray(nV0s);
2094 // Array to take into account the V0s already added to the AOD (V0 within cascades)
2095 fUsedV0 = new Bool_t[nV0s];
2096 for (Int_t iV0=0; iV0<nV0s; ++iV0) fUsedV0[iV0]=kFALSE;
2101 // RefArray to store the mapping between esd track number and newly created AOD-Track
2103 fAODTrackRefs = new TRefArray(nTracks);
2105 // Array to take into account the tracks already added to the AOD
2106 fUsedTrack = new Bool_t[nTracks];
2107 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) fUsedTrack[iTrack]=kFALSE;
2110 // Array to take into account the kinks already added to the AOD
2113 fUsedKink = new Bool_t[nKinks];
2114 for (Int_t iKink=0; iKink<nKinks; ++iKink) fUsedKink[iKink]=kFALSE;
2117 ConvertPrimaryVertices(*esd);
2119 //setting best TOF PID
2120 AliESDInputHandler* esdH = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
2122 fESDpid = esdH->GetESDpid();
2124 if (fIsPidOwner && fESDpid){
2129 { //in case of no Tender attached
2130 fESDpid = new AliESDpid;
2131 fIsPidOwner = kTRUE;
2134 if(!esd->GetTOFHeader())
2135 { //protection in case the pass2 LHC10b,c,d have been processed without tender.
2136 Float_t t0spread[10];
2137 Float_t intrinsicTOFres=100; //ps ok for LHC10b,c,d pass2!!
2138 for (Int_t i=0; i<10; i++) t0spread[i] = (TMath::Sqrt(esd->GetSigma2DiamondZ()))/0.03; //0.03 to convert from cm to ps
2139 fESDpid->GetTOFResponse().SetT0resolution(t0spread);
2140 fESDpid->GetTOFResponse().SetTimeResolution(intrinsicTOFres);
2141 // fESDpid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType);
2142 AliTOFHeader tmpTOFHeader(0,t0spread[0],0,NULL,NULL,NULL,intrinsicTOFres,t0spread[0]);
2143 AODEvent()->SetTOFHeader(&tmpTOFHeader); // write dummy TOF header in AOD
2145 AODEvent()->SetTOFHeader(esd->GetTOFHeader()); // write TOF header in AOD
2148 // if(esd->GetTOFHeader() && fIsPidOwner) fESDpid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType); //in case of AOD production strating form LHC10e without Tender.
2150 if ( fAreCascadesEnabled ) ConvertCascades(*esd);
2152 if ( fAreV0sEnabled ) ConvertV0s(*esd);
2154 if ( fAreKinksEnabled ) ConvertKinks(*esd);
2156 if ( fAreTracksEnabled ) ConvertTracks(*esd);
2158 // Update number of AOD tracks in header at the end of track loop (M.G.)
2159 header->SetRefMultiplicity(fNumberOfTracks);
2160 header->SetRefMultiplicityPos(fNumberOfPositiveTracks);
2161 header->SetRefMultiplicityNeg(fNumberOfTracks - fNumberOfPositiveTracks);
2163 if ( fTPCConstrainedFilterMask ) ConvertTPCOnlyTracks(*esd);
2164 if( fGlobalConstrainedFilterMask) ConvertGlobalConstrainedTracks(*esd);
2166 if ( fArePmdClustersEnabled ) ConvertPmdClusters(*esd);
2168 if ( fAreCaloClustersEnabled ) ConvertCaloClusters(*esd);
2170 if ( fAreEMCALCellsEnabled )ConvertEMCALCells(*esd);
2172 if ( fArePHOSCellsEnabled )ConvertPHOSCells(*esd);
2174 if ( fAreEMCALTriggerEnabled )ConvertCaloTrigger(TString("EMCAL"), *esd);
2176 if ( fArePHOSTriggerEnabled )ConvertCaloTrigger(TString("PHOS"), *esd);
2178 if ( fAreTrackletsEnabled ) ConvertTracklets(*esd);
2179 if ( fIsZDCEnabled ) ConvertZDC(*esd);
2181 delete fAODTrackRefs; fAODTrackRefs=0x0;
2182 delete fAODV0VtxRefs; fAODV0VtxRefs=0x0;
2183 delete fAODV0Refs; fAODV0Refs=0x0;
2185 delete[] fUsedTrack; fUsedTrack=0x0;
2186 delete[] fUsedV0; fUsedV0=0x0;
2187 delete[] fUsedKink; fUsedKink=0x0;
2198 //______________________________________________________________________________
2199 void AliAnalysisTaskESDfilter::SetAODPID(AliESDtrack *esdtrack, AliAODTrack *aodtrack, AliAODPid *detpid)
2202 // Setter for the raw PID detector signals
2205 // Save PID object for candidate electrons
2206 Bool_t pidSave = kFALSE;
2208 Bool_t selectInfo = fTrackFilter->IsSelected((char*) "Electrons");
2209 if (selectInfo) pidSave = kTRUE;
2213 // Tracks passing pt cut
2214 if(esdtrack->Pt()>fHighPthreshold) {
2218 if(esdtrack->Pt()> fPtshape->GetXmin()){
2219 Double_t y = fPtshape->Eval(esdtrack->Pt())/fPtshape->Eval(fHighPthreshold);
2220 if(gRandom->Rndm(0)<1./y){
2224 }//end if p function
2228 if(!aodtrack->GetDetPid()){// prevent memory leak when calling SetAODPID twice for the same track
2229 detpid = new AliAODPid();
2230 SetDetectorRawSignals(detpid,esdtrack);
2231 aodtrack->SetDetPID(detpid);
2236 //______________________________________________________________________________
2237 void AliAnalysisTaskESDfilter::SetDetectorRawSignals(AliAODPid *aodpid, AliESDtrack *track)
2240 //assignment of the detector signals (AliXXXesdPID inspired)
2243 AliInfo("no ESD track found. .....exiting");
2247 const AliExternalTrackParam *in=track->GetInnerParam();
2249 aodpid->SetTPCmomentum(in->GetP());
2251 aodpid->SetTPCmomentum(-1.);
2255 aodpid->SetITSsignal(track->GetITSsignal());
2256 Double_t itsdedx[4]; // dE/dx samples for individual ITS layers
2257 track->GetITSdEdxSamples(itsdedx);
2258 aodpid->SetITSdEdxSamples(itsdedx);
2260 aodpid->SetTPCsignal(track->GetTPCsignal());
2261 aodpid->SetTPCsignalN(track->GetTPCsignalN());
2262 if(track->GetTPCdEdxInfo()) aodpid->SetTPCdEdxInfo(track->GetTPCdEdxInfo());
2265 Int_t nslices = track->GetNumberOfTRDslices()*6;
2266 TArrayD trdslices(nslices);
2267 for(Int_t iSl =0; iSl < track->GetNumberOfTRDslices(); iSl++) {
2268 for(Int_t iPl =0; iPl<6; iPl++) trdslices[iPl*track->GetNumberOfTRDslices()+iSl] = track->GetTRDslice(iPl,iSl);
2272 for(Int_t iPl=0;iPl<6;iPl++){
2273 Double_t trdmom=track->GetTRDmomentum(iPl);
2274 aodpid->SetTRDmomentum(iPl,trdmom);
2277 aodpid->SetTRDsignal(track->GetNumberOfTRDslices()*6,trdslices.GetArray());
2279 //TRD clusters and tracklets
2280 aodpid->SetTRDncls(track->GetTRDncls());
2281 aodpid->SetTRDntrackletsPID(track->GetTRDntrackletsPID());
2284 Double_t times[AliAODPid::kSPECIES]; track->GetIntegratedTimes(times);
2285 aodpid->SetIntegratedTimes(times);
2287 // Float_t tzeroTrack = fESDpid->GetTOFResponse().GetStartTime(track->P());
2288 // aodpid->SetTOFsignal(track->GetTOFsignal()-tzeroTrack);
2289 aodpid->SetTOFsignal(track->GetTOFsignal());
2292 for (Int_t iMass=0; iMass<5; iMass++){
2293 // tofRes[iMass]=(Double_t)fESDpid->GetTOFResponse().GetExpectedSigma(track->P(), times[iMass], AliPID::ParticleMass(iMass));
2294 tofRes[iMass]=0; //backward compatibility
2296 aodpid->SetTOFpidResolution(tofRes);
2298 // aodpid->SetHMPIDsignal(track->GetHMPIDsignal());
2302 Double_t AliAnalysisTaskESDfilter::Chi2perNDF(AliESDtrack* track)
2304 // Calculate chi2 per ndf for track
2305 Int_t nClustersTPC = track->GetTPCNcls();
2307 if ( nClustersTPC > 5) {
2308 return (track->GetTPCchi2()/Float_t(nClustersTPC - 5));
2315 //______________________________________________________________________________
2316 void AliAnalysisTaskESDfilter::Terminate(Option_t */*option*/)
2318 // Terminate analysis
2320 if (fDebug > 1) printf("AnalysisESDfilter: Terminate() \n");
2323 //______________________________________________________________________________
2324 void AliAnalysisTaskESDfilter::PrintMCInfo(AliStack *pStack,Int_t label){
2327 label = TMath::Abs(label);
2328 TParticle *part = pStack->Particle(label);
2329 Printf("########################");
2330 Printf("%s:%d %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,label,part->GetUniqueID(),part->GetPdgCode(),part->P());
2332 TParticle* mother = part;
2333 Int_t imo = part->GetFirstMother();
2334 Int_t nprim = pStack->GetNprimary();
2335 // while((imo >= nprim) && (mother->GetUniqueID() == 4)) {
2336 while((imo >= nprim)) {
2337 mother = pStack->Particle(imo);
2338 Printf("Mother %s:%d Label %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,imo,mother->GetUniqueID(),mother->GetPdgCode(),mother->P());
2340 imo = mother->GetFirstMother();
2342 Printf("########################");
2345 //______________________________________________________