1 /**************************************************************************
\r
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
\r
4 * Author: The ALICE Off-line Project. *
\r
5 * Contributors are mentioned in the code where appropriate. *
\r
7 * Permission to use, copy, modify and distribute this software and its *
\r
8 * documentation strictly for non-commercial purposes is hereby granted *
\r
9 * without fee, provided that the above copyright notice appears in all *
\r
10 * copies and that both the copyright notice and this permission notice *
\r
11 * appear in the supporting documentation. The authors make no claims *
\r
12 * about the suitability of this software for any purpose. It is *
\r
13 * provided "as is" without express or implied warranty. *
\r
14 **************************************************************************/
\r
21 #include <TArrayI.h>
\r
22 #include <TRandom.h>
\r
23 #include <TParticle.h>
\r
26 #include "AliAnalysisTaskESDfilter.h"
\r
27 #include "AliAnalysisManager.h"
\r
28 #include "AliESDEvent.h"
\r
29 #include "AliESDRun.h"
\r
30 #include "AliStack.h"
\r
31 #include "AliAODEvent.h"
\r
32 #include "AliMCEvent.h"
\r
33 #include "AliMCEventHandler.h"
\r
34 #include "AliESDInputHandler.h"
\r
35 #include "AliAODHandler.h"
\r
36 #include "AliAODMCParticle.h"
\r
37 #include "AliAnalysisFilter.h"
\r
38 #include "AliESDMuonTrack.h"
\r
39 #include "AliESDVertex.h"
\r
40 #include "AliCentrality.h"
\r
41 #include "AliEventplane.h"
\r
42 #include "AliESDv0.h"
\r
43 #include "AliESDkink.h"
\r
44 #include "AliESDcascade.h"
\r
45 #include "AliESDPmdTrack.h"
\r
46 #include "AliESDCaloCluster.h"
\r
47 #include "AliESDCaloCells.h"
\r
48 #include "AliMultiplicity.h"
\r
50 #include "AliCodeTimer.h"
\r
51 #include "AliESDtrackCuts.h"
\r
52 #include "AliESDpid.h"
\r
53 #include "Riostream.h"
\r
55 ClassImp(AliAnalysisTaskESDfilter)
\r
57 ////////////////////////////////////////////////////////////////////////
\r
59 AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter():
\r
60 AliAnalysisTaskSE(),
\r
64 fCascadeFilter(0x0),
\r
67 fEnableFillAOD(kTRUE),
\r
76 fNumberOfPositiveTracks(0),
\r
78 fNumberOfVertices(0),
\r
79 fNumberOfCascades(0),
\r
81 fOldESDformat(kFALSE),
\r
82 fPrimaryVertex(0x0),
\r
83 fTPCConstrainedFilterMask(0),
\r
84 fHybridFilterMaskTPCCG(0),
\r
85 fWriteHybridTPCCOnly(kFALSE),
\r
86 fGlobalConstrainedFilterMask(0),
\r
87 fHybridFilterMaskGCG(0),
\r
88 fWriteHybridGCOnly(kFALSE),
\r
89 fIsVZEROEnabled(kTRUE),
\r
90 fIsTZEROEnabled(kTRUE),
\r
91 fIsZDCEnabled(kTRUE),
\r
92 fAreCascadesEnabled(kTRUE),
\r
93 fAreV0sEnabled(kTRUE),
\r
94 fAreKinksEnabled(kTRUE),
\r
95 fAreTracksEnabled(kTRUE),
\r
96 fArePmdClustersEnabled(kTRUE),
\r
97 fAreCaloClustersEnabled(kTRUE),
\r
98 fAreEMCALCellsEnabled(kTRUE),
\r
99 fArePHOSCellsEnabled(kTRUE),
\r
100 fAreTrackletsEnabled(kTRUE),
\r
102 fIsPidOwner(kFALSE),
\r
103 fTimeZeroType(AliESDpid::kTOF_T0),
\r
104 fTPCaloneTrackCuts(0)
\r
106 // Default constructor
\r
109 //______________________________________________________________________________
\r
110 AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter(const char* name):
\r
111 AliAnalysisTaskSE(name),
\r
115 fCascadeFilter(0x0),
\r
116 fHighPthreshold(0),
\r
118 fEnableFillAOD(kTRUE),
\r
122 fAODTrackRefs(0x0),
\r
123 fAODV0VtxRefs(0x0),
\r
126 fNumberOfTracks(0),
\r
127 fNumberOfPositiveTracks(0),
\r
129 fNumberOfVertices(0),
\r
130 fNumberOfCascades(0),
\r
132 fOldESDformat(kFALSE),
\r
133 fPrimaryVertex(0x0),
\r
134 fTPCConstrainedFilterMask(0),
\r
135 fHybridFilterMaskTPCCG(0),
\r
136 fWriteHybridTPCCOnly(kFALSE),
\r
137 fGlobalConstrainedFilterMask(0),
\r
138 fHybridFilterMaskGCG(0),
\r
139 fWriteHybridGCOnly(kFALSE),
\r
140 fIsVZEROEnabled(kTRUE),
\r
141 fIsTZEROEnabled(kTRUE),
\r
142 fIsZDCEnabled(kTRUE),
\r
143 fAreCascadesEnabled(kTRUE),
\r
144 fAreV0sEnabled(kTRUE),
\r
145 fAreKinksEnabled(kTRUE),
\r
146 fAreTracksEnabled(kTRUE),
\r
147 fArePmdClustersEnabled(kTRUE),
\r
148 fAreCaloClustersEnabled(kTRUE),
\r
149 fAreEMCALCellsEnabled(kTRUE),
\r
150 fArePHOSCellsEnabled(kTRUE),
\r
151 fAreTrackletsEnabled(kTRUE),
\r
153 fIsPidOwner(kFALSE),
\r
154 fTimeZeroType(AliESDpid::kTOF_T0),
\r
155 fTPCaloneTrackCuts(0)
\r
159 AliAnalysisTaskESDfilter::~AliAnalysisTaskESDfilter(){
\r
160 if(fIsPidOwner) delete fESDpid;
\r
162 //______________________________________________________________________________
\r
163 void AliAnalysisTaskESDfilter::UserCreateOutputObjects()
\r
166 // Create Output Objects conenct filter to outputtree
\r
170 OutputTree()->GetUserInfo()->Add(fTrackFilter);
\r
174 AliError("No OutputTree() for adding the track filter");
\r
176 fTPCaloneTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
\r
179 //______________________________________________________________________________
\r
180 void AliAnalysisTaskESDfilter::Init()
\r
183 if (fDebug > 1) AliInfo("Init() \n");
\r
184 // Call configuration file
\r
187 //______________________________________________________________________________
\r
188 void AliAnalysisTaskESDfilter::PrintTask(Option_t *option, Int_t indent) const
\r
190 // Print selection task information
\r
193 AliAnalysisTaskSE::PrintTask(option,indent);
\r
195 TString spaces(' ',indent+3);
\r
197 cout << spaces.Data() << Form("Cascades are %s",fAreCascadesEnabled ? "ENABLED":"DISABLED") << endl;
\r
198 cout << spaces.Data() << Form("V0s are %s",fAreV0sEnabled ? "ENABLED":"DISABLED") << endl;
\r
199 cout << spaces.Data() << Form("Kinks are %s",fAreKinksEnabled ? "ENABLED":"DISABLED") << endl;
\r
200 cout << spaces.Data() << Form("Tracks are %s",fAreTracksEnabled ? "ENABLED":"DISABLED") << endl;
\r
201 cout << spaces.Data() << Form("PmdClusters are %s",fArePmdClustersEnabled ? "ENABLED":"DISABLED") << endl;
\r
202 cout << spaces.Data() << Form("CaloClusters are %s",fAreCaloClustersEnabled ? "ENABLED":"DISABLED") << endl;
\r
203 cout << spaces.Data() << Form("EMCAL cells are %s",fAreEMCALCellsEnabled ? "ENABLED":"DISABLED") << endl;
\r
204 cout << spaces.Data() << Form("Tracklets are %s",fAreTrackletsEnabled ? "ENABLED":"DISABLED") << endl;
\r
207 //______________________________________________________________________________
\r
208 void AliAnalysisTaskESDfilter::UserExec(Option_t */*option*/)
\r
210 // Execute analysis for current event
\r
213 Long64_t ientry = Entry();
\r
216 printf("Filter: Analysing event # %5d\n", (Int_t) ientry);
\r
217 if (fHighPthreshold == 0) AliInfo("detector PID signals are stored in each track");
\r
218 if (!fPtshape) AliInfo("detector PID signals are not stored below the pt threshold");
\r
220 // Filters must explicitely enable AOD filling in their UserExec (AG)
\r
221 if (!AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()) AliFatal("Cannot run ESD filter without an output event handler");
\r
222 if(fEnableFillAOD) {
\r
223 AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(kTRUE);
\r
224 AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillExtension(kTRUE);
\r
229 //______________________________________________________________________________
\r
230 TClonesArray& AliAnalysisTaskESDfilter::Cascades()
\r
232 return *(AODEvent()->GetCascades());
\r
235 //______________________________________________________________________________
\r
236 TClonesArray& AliAnalysisTaskESDfilter::Tracks()
\r
238 return *(AODEvent()->GetTracks());
\r
241 //______________________________________________________________________________
\r
242 TClonesArray& AliAnalysisTaskESDfilter::V0s()
\r
244 return *(AODEvent()->GetV0s());
\r
247 //______________________________________________________________________________
\r
248 TClonesArray& AliAnalysisTaskESDfilter::Vertices()
\r
250 return *(AODEvent()->GetVertices());
\r
253 //______________________________________________________________________________
\r
254 AliAODHeader* AliAnalysisTaskESDfilter::ConvertHeader(const AliESDEvent& esd)
\r
256 // Convert header information
\r
258 AliCodeTimerAuto("",0);
\r
260 AliAODHeader* header = AODEvent()->GetHeader();
\r
262 header->SetRunNumber(esd.GetRunNumber());
\r
263 header->SetOfflineTrigger(fInputHandler->IsEventSelected()); // propagate the decision of the physics selection
\r
265 TTree* tree = fInputHandler->GetTree();
\r
267 TFile* file = tree->GetCurrentFile();
\r
268 if (file) header->SetESDFileName(file->GetName());
\r
271 if (fOldESDformat) {
\r
272 header->SetBunchCrossNumber(0);
\r
273 header->SetOrbitNumber(0);
\r
274 header->SetPeriodNumber(0);
\r
275 header->SetEventType(0);
\r
276 header->SetMuonMagFieldScale(-999.);
\r
277 header->SetCentrality(0);
\r
278 header->SetEventplane(0);
\r
280 header->SetBunchCrossNumber(esd.GetBunchCrossNumber());
\r
281 header->SetOrbitNumber(esd.GetOrbitNumber());
\r
282 header->SetPeriodNumber(esd.GetPeriodNumber());
\r
283 header->SetEventType(esd.GetEventType());
\r
285 header->SetEventNumberESDFile(esd.GetHeader()->GetEventNumberInFile());
\r
286 if(const_cast<AliESDEvent&>(esd).GetCentrality()){
\r
287 header->SetCentrality(const_cast<AliESDEvent&>(esd).GetCentrality());
\r
290 header->SetCentrality(0);
\r
292 if(const_cast<AliESDEvent&>(esd).GetEventplane()){
\r
293 header->SetEventplane(const_cast<AliESDEvent&>(esd).GetEventplane());
\r
296 header->SetEventplane(0);
\r
301 header->SetFiredTriggerClasses(esd.GetFiredTriggerClasses());
\r
302 header->SetTriggerMask(esd.GetTriggerMask());
\r
303 header->SetTriggerCluster(esd.GetTriggerCluster());
\r
304 header->SetL0TriggerInputs(esd.GetHeader()->GetL0TriggerInputs());
\r
305 header->SetL1TriggerInputs(esd.GetHeader()->GetL1TriggerInputs());
\r
306 header->SetL2TriggerInputs(esd.GetHeader()->GetL2TriggerInputs());
\r
308 header->SetMagneticField(esd.GetMagneticField());
\r
309 header->SetMuonMagFieldScale(esd.GetCurrentDip()/6000.);
\r
310 header->SetZDCN1Energy(esd.GetZDCN1Energy());
\r
311 header->SetZDCP1Energy(esd.GetZDCP1Energy());
\r
312 header->SetZDCN2Energy(esd.GetZDCN2Energy());
\r
313 header->SetZDCP2Energy(esd.GetZDCP2Energy());
\r
314 header->SetZDCEMEnergy(esd.GetZDCEMEnergy(0),esd.GetZDCEMEnergy(1));
\r
316 // ITS Cluster Multiplicty
\r
317 const AliMultiplicity *mult = esd.GetMultiplicity();
\r
318 for (Int_t ilay = 0; ilay < 6; ilay++) header->SetITSClusters(ilay, mult->GetNumberOfITSClusters(ilay));
\r
320 // TPC only Reference Multiplicty
\r
321 Int_t refMult = fTPCaloneTrackCuts ? (Short_t)fTPCaloneTrackCuts->GetReferenceMultiplicity(&esd, kTRUE) : -1;
\r
322 header->SetTPConlyRefMultiplicity(refMult);
\r
325 Float_t diamxy[2]={esd.GetDiamondX(),esd.GetDiamondY()};
\r
326 Float_t diamcov[3];
\r
327 esd.GetDiamondCovXY(diamcov);
\r
328 header->SetDiamond(diamxy,diamcov);
\r
329 header->SetDiamondZ(esd.GetDiamondZ(),esd.GetSigma2DiamondZ());
\r
334 //______________________________________________________________________________
\r
335 void AliAnalysisTaskESDfilter::ConvertCascades(const AliESDEvent& esd)
\r
337 // Convert the cascades part of the ESD.
\r
338 // Return the number of cascades
\r
340 AliCodeTimerAuto("",0);
\r
342 // Create vertices starting from the most complex objects
\r
343 Double_t chi2 = 0.;
\r
345 const AliESDVertex* vtx = esd.GetPrimaryVertex();
\r
346 Double_t pos[3] = { 0. };
\r
347 Double_t covVtx[6] = { 0. };
\r
348 Double_t momBach[3]={0.};
\r
349 Double_t covTr[21]={0.};
\r
350 Double_t pid[10]={0.};
\r
351 AliAODPid* detpid(0x0);
\r
352 AliAODVertex* vV0FromCascade(0x0);
\r
353 AliAODv0* aodV0(0x0);
\r
354 AliAODcascade* aodCascade(0x0);
\r
355 AliAODTrack* aodTrack(0x0);
\r
356 Double_t momPos[3]={0.};
\r
357 Double_t momNeg[3] = { 0. };
\r
358 Double_t momPosAtV0vtx[3]={0.};
\r
359 Double_t momNegAtV0vtx[3]={0.};
\r
361 TClonesArray& verticesArray = Vertices();
\r
362 TClonesArray& tracksArray = Tracks();
\r
363 TClonesArray& cascadesArray = Cascades();
\r
365 // Cascades (Modified by A.Maire - February 2009)
\r
366 for (Int_t nCascade = 0; nCascade < esd.GetNumberOfCascades(); ++nCascade) {
\r
370 AliESDcascade *esdCascade = esd.GetCascade(nCascade);
\r
371 Int_t idxPosFromV0Dghter = esdCascade->GetPindex();
\r
372 Int_t idxNegFromV0Dghter = esdCascade->GetNindex();
\r
373 Int_t idxBachFromCascade = esdCascade->GetBindex();
\r
375 AliESDtrack *esdCascadePos = esd.GetTrack( idxPosFromV0Dghter);
\r
376 AliESDtrack *esdCascadeNeg = esd.GetTrack( idxNegFromV0Dghter);
\r
377 AliESDtrack *esdCascadeBach = esd.GetTrack( idxBachFromCascade);
\r
379 // Identification of the V0 within the esdCascade (via both daughter track indices)
\r
380 AliESDv0 * currentV0 = 0x0;
\r
381 Int_t idxV0FromCascade = -1;
\r
383 for (Int_t iV0=0; iV0<esd.GetNumberOfV0s(); ++iV0) {
\r
385 currentV0 = esd.GetV0(iV0);
\r
386 Int_t posCurrentV0 = currentV0->GetPindex();
\r
387 Int_t negCurrentV0 = currentV0->GetNindex();
\r
389 if (posCurrentV0==idxPosFromV0Dghter && negCurrentV0==idxNegFromV0Dghter) {
\r
390 idxV0FromCascade = iV0;
\r
395 if(idxV0FromCascade < 0){
\r
396 printf("Cascade - no matching for the V0 (index V0 = -1) ! Skip ... \n");
\r
398 }// a priori, useless check, but safer ... in case of pb with tracks "out of bounds"
\r
400 AliESDv0 *esdV0FromCascade = esd.GetV0(idxV0FromCascade);
\r
402 // 1 - Cascade selection
\r
404 // AliESDVertex *esdPrimVtx = new AliESDVertex(*(esd.GetPrimaryVertex()));
\r
405 // TList cascadeObjects;
\r
406 // cascadeObjects.AddAt(esdV0FromCascade, 0);
\r
407 // cascadeObjects.AddAt(esdCascadePos, 1);
\r
408 // cascadeObjects.AddAt(esdCascadeNeg, 2);
\r
409 // cascadeObjects.AddAt(esdCascade, 3);
\r
410 // cascadeObjects.AddAt(esdCascadeBach, 4);
\r
411 // cascadeObjects.AddAt(esdPrimVtx, 5);
\r
413 // UInt_t selectCascade = 0;
\r
414 // if (fCascadeFilter) {
\r
415 // // selectCascade = fCascadeFilter->IsSelected(&cascadeObjects);
\r
416 // // FIXME AliESDCascadeCuts to be implemented ...
\r
418 // // Here we may encounter a moot point at the V0 level
\r
419 // // between the cascade selections and the V0 ones :
\r
420 // // the V0 selected along with the cascade (secondary V0) may
\r
421 // // usually be removed from the dedicated V0 selections (prim V0) ...
\r
422 // // -> To be discussed !
\r
424 // // this is a little awkward but otherwise the
\r
425 // // list wants to access the pointer (delete it)
\r
426 // // again when going out of scope
\r
427 // delete cascadeObjects.RemoveAt(5); // esdPrimVtx created via copy construct
\r
429 // if (!selectCascade)
\r
433 // delete cascadeObjects.RemoveAt(5); // esdPrimVtx created via copy construct
\r
437 // 2 - Add the cascade vertex
\r
439 esdCascade->GetXYZcascade(pos[0], pos[1], pos[2]);
\r
440 esdCascade->GetPosCovXi(covVtx);
\r
441 chi2 = esdCascade->GetChi2Xi();
\r
443 AliAODVertex *vCascade = new(verticesArray[fNumberOfVertices++]) AliAODVertex( pos,
\r
445 chi2, // FIXME = Chi2/NDF will be needed
\r
448 AliAODVertex::kCascade);
\r
449 fPrimaryVertex->AddDaughter(vCascade);
\r
451 // if (fDebug > 2) {
\r
452 // printf("---- Cascade / Cascade Vertex (AOD) : \n");
\r
453 // vCascade->Print();
\r
456 if(esd.GetTOFHeader() && fIsPidOwner) fESDpid->SetTOFResponse(const_cast<AliESDEvent*>(&esd), (AliESDpid::EStartTimeType_t)fTimeZeroType); //in case of AOD production strating form LHC10e without Tender.
\r
459 // 3 - Add the bachelor track from the cascade
\r
461 if (!fUsedTrack[idxBachFromCascade]) {
\r
463 esdCascadeBach->GetPxPyPz(momBach);
\r
464 esdCascadeBach->GetXYZ(pos);
\r
465 esdCascadeBach->GetCovarianceXYZPxPyPz(covTr);
\r
466 esdCascadeBach->GetESDpid(pid);
\r
468 fUsedTrack[idxBachFromCascade] = kTRUE;
\r
469 UInt_t selectInfo = 0;
\r
470 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdCascadeBach);
\r
471 if (fMChandler) fMChandler->SelectParticle(esdCascadeBach->GetLabel());
\r
472 aodTrack = new(tracksArray[fNumberOfTracks++]) AliAODTrack(esdCascadeBach->GetID(),
\r
473 esdCascadeBach->GetLabel(),
\r
477 kFALSE, // Why kFALSE for "isDCA" ? FIXME
\r
479 (Short_t)esdCascadeBach->GetSign(),
\r
480 esdCascadeBach->GetITSClusterMap(),
\r
483 kTRUE, // usedForVtxFit = kFALSE ? FIXME
\r
484 vtx->UsesTrack(esdCascadeBach->GetID()),
\r
485 AliAODTrack::kSecondary,
\r
487 aodTrack->SetTPCClusterMap(esdCascadeBach->GetTPCClusterMap());
\r
488 aodTrack->SetTPCSharedMap (esdCascadeBach->GetTPCSharedMap());
\r
489 aodTrack->SetChi2perNDF(Chi2perNDF(esdCascadeBach));
\r
490 aodTrack->SetTPCPointsF(esdCascadeBach->GetTPCNclsF());
\r
491 fAODTrackRefs->AddAt(aodTrack,idxBachFromCascade);
\r
493 if (esdCascadeBach->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
494 aodTrack->ConvertAliPIDtoAODPID();
\r
495 aodTrack->SetFlags(esdCascadeBach->GetStatus());
\r
496 SetAODPID(esdCascadeBach,aodTrack,detpid);
\r
499 aodTrack = static_cast<AliAODTrack*>( fAODTrackRefs->At(idxBachFromCascade) );
\r
502 vCascade->AddDaughter(aodTrack);
\r
504 // if (fDebug > 4) {
\r
505 // printf("---- Cascade / bach dghter : \n");
\r
506 // aodTrack->Print();
\r
510 // 4 - Add the V0 from the cascade.
\r
511 // = V0vtx + both pos and neg daughter tracks + the aodV0 itself
\r
514 if ( !fUsedV0[idxV0FromCascade] ) {
\r
515 // 4.A - if VO structure hasn't been created yet
\r
517 // 4.A.1 - Create the V0 vertex of the cascade
\r
519 esdV0FromCascade->GetXYZ(pos[0], pos[1], pos[2]);
\r
520 esdV0FromCascade->GetPosCov(covVtx);
\r
521 chi2 = esdV0FromCascade->GetChi2V0(); // = chi2/NDF since NDF = 2*2-3 ?
\r
523 vV0FromCascade = new(verticesArray[fNumberOfVertices++]) AliAODVertex(pos,
\r
527 idxV0FromCascade, //id of ESDv0
\r
528 AliAODVertex::kV0);
\r
530 // one V0 can be used by several cascades.
\r
531 // So, one AOD V0 vtx can have several parent vtx.
\r
532 // This is not directly allowed by AliAODvertex.
\r
533 // Setting the parent vtx (here = param "vCascade") doesn't lead to a crash
\r
534 // but to a problem of consistency within AODEvent.
\r
535 // -> See below paragraph 4.B, for the proposed treatment of such a case.
\r
537 // Add the vV0FromCascade to the aodVOVtxRefs
\r
538 fAODV0VtxRefs->AddAt(vV0FromCascade,idxV0FromCascade);
\r
541 // 4.A.2 - Add the positive tracks from the V0
\r
543 esdCascadePos->GetPxPyPz(momPos);
\r
544 esdCascadePos->GetXYZ(pos);
\r
545 esdCascadePos->GetCovarianceXYZPxPyPz(covTr);
\r
546 esdCascadePos->GetESDpid(pid);
\r
549 if (!fUsedTrack[idxPosFromV0Dghter]) {
\r
550 fUsedTrack[idxPosFromV0Dghter] = kTRUE;
\r
552 UInt_t selectInfo = 0;
\r
553 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdCascadePos);
\r
554 if(fMChandler) fMChandler->SelectParticle(esdCascadePos->GetLabel());
\r
555 aodTrack = new(tracksArray[fNumberOfTracks++])
\r
556 AliAODTrack( esdCascadePos->GetID(),
\r
557 esdCascadePos->GetLabel(),
\r
561 kFALSE, // Why kFALSE for "isDCA" ? FIXME
\r
563 (Short_t)esdCascadePos->GetSign(),
\r
564 esdCascadePos->GetITSClusterMap(),
\r
567 kTRUE, // usedForVtxFit = kFALSE ? FIXME
\r
568 vtx->UsesTrack(esdCascadePos->GetID()),
\r
569 AliAODTrack::kSecondary,
\r
571 aodTrack->SetTPCClusterMap(esdCascadePos->GetTPCClusterMap());
\r
572 aodTrack->SetTPCSharedMap (esdCascadePos->GetTPCSharedMap());
\r
573 aodTrack->SetChi2perNDF(Chi2perNDF(esdCascadePos));
\r
574 aodTrack->SetTPCPointsF(esdCascadePos->GetTPCNclsF());
\r
575 fAODTrackRefs->AddAt(aodTrack,idxPosFromV0Dghter);
\r
577 if (esdCascadePos->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
578 aodTrack->ConvertAliPIDtoAODPID();
\r
579 aodTrack->SetFlags(esdCascadePos->GetStatus());
\r
580 SetAODPID(esdCascadePos,aodTrack,detpid);
\r
583 aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(idxPosFromV0Dghter));
\r
585 vV0FromCascade->AddDaughter(aodTrack);
\r
588 // 4.A.3 - Add the negative tracks from the V0
\r
590 esdCascadeNeg->GetPxPyPz(momNeg);
\r
591 esdCascadeNeg->GetXYZ(pos);
\r
592 esdCascadeNeg->GetCovarianceXYZPxPyPz(covTr);
\r
593 esdCascadeNeg->GetESDpid(pid);
\r
596 if (!fUsedTrack[idxNegFromV0Dghter]) {
\r
597 fUsedTrack[idxNegFromV0Dghter] = kTRUE;
\r
599 UInt_t selectInfo = 0;
\r
600 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdCascadeNeg);
\r
601 if(fMChandler)fMChandler->SelectParticle(esdCascadeNeg->GetLabel());
\r
602 aodTrack = new(tracksArray[fNumberOfTracks++]) AliAODTrack( esdCascadeNeg->GetID(),
\r
603 esdCascadeNeg->GetLabel(),
\r
607 kFALSE, // Why kFALSE for "isDCA" ? FIXME
\r
609 (Short_t)esdCascadeNeg->GetSign(),
\r
610 esdCascadeNeg->GetITSClusterMap(),
\r
613 kTRUE, // usedForVtxFit = kFALSE ? FIXME
\r
614 vtx->UsesTrack(esdCascadeNeg->GetID()),
\r
615 AliAODTrack::kSecondary,
\r
617 aodTrack->SetTPCClusterMap(esdCascadeNeg->GetTPCClusterMap());
\r
618 aodTrack->SetTPCSharedMap (esdCascadeNeg->GetTPCSharedMap());
\r
619 aodTrack->SetChi2perNDF(Chi2perNDF(esdCascadeNeg));
\r
620 aodTrack->SetTPCPointsF(esdCascadeNeg->GetTPCNclsF());
\r
621 fAODTrackRefs->AddAt(aodTrack,idxNegFromV0Dghter);
\r
623 if (esdCascadeNeg->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
624 aodTrack->ConvertAliPIDtoAODPID();
\r
625 aodTrack->SetFlags(esdCascadeNeg->GetStatus());
\r
626 SetAODPID(esdCascadeNeg,aodTrack,detpid);
\r
629 aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(idxNegFromV0Dghter));
\r
632 vV0FromCascade->AddDaughter(aodTrack);
\r
635 // 4.A.4 - Add the V0 from cascade to the V0 array
\r
637 Double_t dcaV0Daughters = esdV0FromCascade->GetDcaV0Daughters();
\r
638 Double_t dcaV0ToPrimVertex = esdV0FromCascade->GetD( esd.GetPrimaryVertex()->GetX(),
\r
639 esd.GetPrimaryVertex()->GetY(),
\r
640 esd.GetPrimaryVertex()->GetZ() );
\r
641 esdV0FromCascade->GetPPxPyPz( momPosAtV0vtx[0],momPosAtV0vtx[1],momPosAtV0vtx[2] );
\r
642 esdV0FromCascade->GetNPxPyPz( momNegAtV0vtx[0],momNegAtV0vtx[1],momNegAtV0vtx[2] );
\r
644 Double_t dcaDaughterToPrimVertex[2] = { 999., 999.}; // ..[0] = DCA in (x,y) for Pos and ..[1] = Neg
\r
645 dcaDaughterToPrimVertex[0] = TMath::Abs(esdCascadePos->GetD( esd.GetPrimaryVertex()->GetX(),
\r
646 esd.GetPrimaryVertex()->GetY(),
\r
647 esd.GetMagneticField()) );
\r
648 dcaDaughterToPrimVertex[1] = TMath::Abs(esdCascadeNeg->GetD( esd.GetPrimaryVertex()->GetX(),
\r
649 esd.GetPrimaryVertex()->GetY(),
\r
650 esd.GetMagneticField()) );
\r
652 aodV0 = new(V0s()[fNumberOfV0s++]) AliAODv0( vV0FromCascade,
\r
654 dcaV0ToPrimVertex,
\r
657 dcaDaughterToPrimVertex);
\r
658 // set the aod v0 on-the-fly status
\r
659 aodV0->SetOnFlyStatus(esdV0FromCascade->GetOnFlyStatus());
\r
661 // Add the aodV0 to the aodVORefs
\r
662 fAODV0Refs->AddAt(aodV0,idxV0FromCascade);
\r
664 fUsedV0[idxV0FromCascade] = kTRUE;
\r
667 // 4.B - if V0 structure already used
\r
670 // one V0 can be used by several cascades (frequent in PbPb evts) :
\r
671 // same V0 which used but attached to different bachelor tracks
\r
672 // -> aodVORefs and fAODV0VtxRefs are needed.
\r
673 // Goal : avoid a redundancy of the info in "Vertices" and "v0s" clones array.
\r
675 vV0FromCascade = static_cast<AliAODVertex*>( fAODV0VtxRefs->At(idxV0FromCascade) );
\r
676 aodV0 = static_cast<AliAODv0*> ( fAODV0Refs ->At(idxV0FromCascade) );
\r
678 // - Treatment of the parent for such a "re-used" V0 :
\r
679 // Insert the cascade that reuses the V0 vertex in the lineage chain
\r
680 // Before : vV0 -> vCascade1 -> vPrimary
\r
681 // - Hyp : cascade2 uses the same V0 as cascade1
\r
682 // After : vV0 -> vCascade2 -> vCascade1 -> vPrimary
\r
684 AliAODVertex *vCascadePreviousParent = static_cast<AliAODVertex*> (vV0FromCascade->GetParent());
\r
685 vV0FromCascade->SetParent(vCascade);
\r
686 vCascade ->SetParent(vCascadePreviousParent);
\r
689 // printf("---- Cascade / Lineage insertion\n"
\r
690 // "Parent of V0 vtx = Cascade vtx %p\n"
\r
691 // "Parent of the cascade vtx = Cascade vtx %p\n"
\r
692 // "Parent of the parent cascade vtx = Cascade vtx %p\n",
\r
693 // static_cast<void*> (vV0FromCascade->GetParent()),
\r
694 // static_cast<void*> (vCascade->GetParent()),
\r
695 // static_cast<void*> (vCascadePreviousParent->GetParent()) );
\r
697 }// end if V0 structure already used
\r
699 // if (fDebug > 2) {
\r
700 // printf("---- Cascade / V0 vertex: \n");
\r
701 // vV0FromCascade->Print();
\r
704 // if (fDebug > 4) {
\r
705 // printf("---- Cascade / pos dghter : \n");
\r
706 // aodTrack->Print();
\r
707 // printf("---- Cascade / neg dghter : \n");
\r
708 // aodTrack->Print();
\r
709 // printf("---- Cascade / aodV0 : \n");
\r
713 // In any case (used V0 or not), add the V0 vertex to the cascade one.
\r
714 vCascade->AddDaughter(vV0FromCascade);
\r
717 // 5 - Add the primary track of the cascade (if any)
\r
720 // 6 - Add the cascade to the AOD array of cascades
\r
722 Double_t dcaBachToPrimVertexXY = TMath::Abs(esdCascadeBach->GetD(esd.GetPrimaryVertex()->GetX(),
\r
723 esd.GetPrimaryVertex()->GetY(),
\r
724 esd.GetMagneticField()) );
\r
726 Double_t momBachAtCascadeVtx[3]={0.};
\r
728 esdCascade->GetBPxPyPz(momBachAtCascadeVtx[0], momBachAtCascadeVtx[1], momBachAtCascadeVtx[2]);
\r
730 aodCascade = new(cascadesArray[fNumberOfCascades++]) AliAODcascade( vCascade,
\r
731 esdCascade->Charge(),
\r
732 esdCascade->GetDcaXiDaughters(),
\r
734 // DCAXiToPrimVtx -> needs to be calculated ----|
\r
735 // doesn't exist at ESD level;
\r
736 // See AODcascade::DcaXiToPrimVertex(Double, Double, Double)
\r
737 dcaBachToPrimVertexXY,
\r
738 momBachAtCascadeVtx,
\r
742 printf("---- Cascade / AOD cascade : \n\n");
\r
743 aodCascade->PrintXi(fPrimaryVertex->GetX(), fPrimaryVertex->GetY(), fPrimaryVertex->GetZ());
\r
746 } // end of the loop on cascades
\r
748 Cascades().Expand(fNumberOfCascades);
\r
751 //______________________________________________________________________________
\r
752 void AliAnalysisTaskESDfilter::ConvertV0s(const AliESDEvent& esd)
\r
754 // Access to the AOD container of V0s
\r
756 AliCodeTimerAuto("",0);
\r
762 Double_t pos[3] = { 0. };
\r
763 Double_t chi2(0.0);
\r
764 Double_t covVtx[6] = { 0. };
\r
765 Double_t momPos[3]={0.};
\r
766 Double_t covTr[21]={0.};
\r
767 Double_t pid[10]={0.};
\r
768 AliAODTrack* aodTrack(0x0);
\r
769 AliAODPid* detpid(0x0);
\r
770 Double_t momNeg[3]={0.};
\r
771 Double_t momPosAtV0vtx[3]={0.};
\r
772 Double_t momNegAtV0vtx[3]={0.};
\r
774 for (Int_t nV0 = 0; nV0 < esd.GetNumberOfV0s(); ++nV0)
\r
776 if (fUsedV0[nV0]) continue; // skip if already added to the AOD
\r
778 AliESDv0 *v0 = esd.GetV0(nV0);
\r
779 Int_t posFromV0 = v0->GetPindex();
\r
780 Int_t negFromV0 = v0->GetNindex();
\r
784 AliESDVertex *esdVtx = new AliESDVertex(*(esd.GetPrimaryVertex()));
\r
785 AliESDtrack *esdV0Pos = esd.GetTrack(posFromV0);
\r
786 AliESDtrack *esdV0Neg = esd.GetTrack(negFromV0);
\r
788 v0objects.AddAt(v0, 0);
\r
789 v0objects.AddAt(esdV0Pos, 1);
\r
790 v0objects.AddAt(esdV0Neg, 2);
\r
791 v0objects.AddAt(esdVtx, 3);
\r
792 UInt_t selectV0 = 0;
\r
794 selectV0 = fV0Filter->IsSelected(&v0objects);
\r
795 // this is a little awkward but otherwise the
\r
796 // list wants to access the pointer (delete it)
\r
797 // again when going out of scope
\r
798 delete v0objects.RemoveAt(3); // esdVtx created via copy construct
\r
804 delete v0objects.RemoveAt(3); // esdVtx created via copy construct
\r
808 v0->GetXYZ(pos[0], pos[1], pos[2]);
\r
810 if (!fOldESDformat) {
\r
811 chi2 = v0->GetChi2V0(); // = chi2/NDF since NDF = 2*2-3
\r
812 v0->GetPosCov(covVtx);
\r
815 for (Int_t i = 0; i < 6; i++) covVtx[i] = 0.;
\r
819 AliAODVertex * vV0 =
\r
820 new(Vertices()[fNumberOfVertices++]) AliAODVertex(pos,
\r
825 AliAODVertex::kV0);
\r
826 fPrimaryVertex->AddDaughter(vV0);
\r
829 // Add the positive tracks from the V0
\r
832 esdV0Pos->GetPxPyPz(momPos);
\r
833 esdV0Pos->GetXYZ(pos);
\r
834 esdV0Pos->GetCovarianceXYZPxPyPz(covTr);
\r
835 esdV0Pos->GetESDpid(pid);
\r
837 const AliESDVertex *vtx = esd.GetPrimaryVertex();
\r
839 if (!fUsedTrack[posFromV0]) {
\r
840 fUsedTrack[posFromV0] = kTRUE;
\r
841 UInt_t selectInfo = 0;
\r
842 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdV0Pos);
\r
843 if(fMChandler)fMChandler->SelectParticle(esdV0Pos->GetLabel());
\r
844 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdV0Pos->GetID(),
\r
845 esdV0Pos->GetLabel(),
\r
851 (Short_t)esdV0Pos->GetSign(),
\r
852 esdV0Pos->GetITSClusterMap(),
\r
855 kTRUE, // check if this is right
\r
856 vtx->UsesTrack(esdV0Pos->GetID()),
\r
857 AliAODTrack::kSecondary,
\r
859 aodTrack->SetTPCClusterMap(esdV0Pos->GetTPCClusterMap());
\r
860 aodTrack->SetTPCSharedMap (esdV0Pos->GetTPCSharedMap());
\r
861 aodTrack->SetChi2perNDF(Chi2perNDF(esdV0Pos));
\r
862 aodTrack->SetTPCPointsF(esdV0Pos->GetTPCNclsF());
\r
863 fAODTrackRefs->AddAt(aodTrack,posFromV0);
\r
864 // if (fDebug > 0) printf("-------------------Bo: pos track from original pt %.3f \n",aodTrack->Pt());
\r
865 if (esdV0Pos->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
866 aodTrack->ConvertAliPIDtoAODPID();
\r
867 aodTrack->SetFlags(esdV0Pos->GetStatus());
\r
868 SetAODPID(esdV0Pos,aodTrack,detpid);
\r
871 aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(posFromV0));
\r
872 // if (fDebug > 0) printf("-------------------Bo pos track from refArray pt %.3f \n",aodTrack->Pt());
\r
874 vV0->AddDaughter(aodTrack);
\r
876 // Add the negative tracks from the V0
\r
878 esdV0Neg->GetPxPyPz(momNeg);
\r
879 esdV0Neg->GetXYZ(pos);
\r
880 esdV0Neg->GetCovarianceXYZPxPyPz(covTr);
\r
881 esdV0Neg->GetESDpid(pid);
\r
883 if (!fUsedTrack[negFromV0]) {
\r
884 fUsedTrack[negFromV0] = kTRUE;
\r
885 UInt_t selectInfo = 0;
\r
886 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdV0Neg);
\r
887 if(fMChandler)fMChandler->SelectParticle(esdV0Neg->GetLabel());
\r
888 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdV0Neg->GetID(),
\r
889 esdV0Neg->GetLabel(),
\r
895 (Short_t)esdV0Neg->GetSign(),
\r
896 esdV0Neg->GetITSClusterMap(),
\r
899 kTRUE, // check if this is right
\r
900 vtx->UsesTrack(esdV0Neg->GetID()),
\r
901 AliAODTrack::kSecondary,
\r
903 aodTrack->SetTPCClusterMap(esdV0Neg->GetTPCClusterMap());
\r
904 aodTrack->SetTPCSharedMap (esdV0Neg->GetTPCSharedMap());
\r
905 aodTrack->SetChi2perNDF(Chi2perNDF(esdV0Neg));
\r
906 aodTrack->SetTPCPointsF(esdV0Neg->GetTPCNclsF());
\r
908 fAODTrackRefs->AddAt(aodTrack,negFromV0);
\r
909 // if (fDebug > 0) printf("-------------------Bo: neg track from original pt %.3f \n",aodTrack->Pt());
\r
910 if (esdV0Neg->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
911 aodTrack->ConvertAliPIDtoAODPID();
\r
912 aodTrack->SetFlags(esdV0Neg->GetStatus());
\r
913 SetAODPID(esdV0Neg,aodTrack,detpid);
\r
916 aodTrack = static_cast<AliAODTrack*>(fAODTrackRefs->At(negFromV0));
\r
917 // if (fDebug > 0) printf("-------------------Bo neg track from refArray pt %.3f \n",aodTrack->Pt());
\r
919 vV0->AddDaughter(aodTrack);
\r
922 // Add the V0 the V0 array as well
\r
924 Double_t dcaV0Daughters = v0->GetDcaV0Daughters();
\r
925 Double_t dcaV0ToPrimVertex = v0->GetD(esd.GetPrimaryVertex()->GetX(),
\r
926 esd.GetPrimaryVertex()->GetY(),
\r
927 esd.GetPrimaryVertex()->GetZ());
\r
929 v0->GetPPxPyPz(momPosAtV0vtx[0],momPosAtV0vtx[1],momPosAtV0vtx[2]);
\r
930 v0->GetNPxPyPz(momNegAtV0vtx[0],momNegAtV0vtx[1],momNegAtV0vtx[2]);
\r
932 Double_t dcaDaughterToPrimVertex[2] = { 999., 999.}; // ..[0] = DCA in (x,y) for Pos and ..[1] = Neg
\r
933 dcaDaughterToPrimVertex[0] = TMath::Abs(esdV0Pos->GetD( esd.GetPrimaryVertex()->GetX(),
\r
934 esd.GetPrimaryVertex()->GetY(),
\r
935 esd.GetMagneticField()) );
\r
936 dcaDaughterToPrimVertex[1] = TMath::Abs(esdV0Neg->GetD( esd.GetPrimaryVertex()->GetX(),
\r
937 esd.GetPrimaryVertex()->GetY(),
\r
938 esd.GetMagneticField()) );
\r
940 AliAODv0* aodV0 = new(V0s()[fNumberOfV0s++]) AliAODv0(vV0,
\r
945 dcaDaughterToPrimVertex);
\r
947 // set the aod v0 on-the-fly status
\r
948 aodV0->SetOnFlyStatus(v0->GetOnFlyStatus());
\r
949 }//End of loop on V0s
\r
951 V0s().Expand(fNumberOfV0s);
\r
954 //______________________________________________________________________________
\r
955 void AliAnalysisTaskESDfilter::ConvertTPCOnlyTracks(const AliESDEvent& esd)
\r
957 // Convert TPC only tracks
\r
958 // Here we have wo hybrid appraoch to remove fakes
\r
959 // ******* ITSTPC ********
\r
960 // Uses a cut on the ITS properties to select global tracks
\r
961 // which are than marked as HybdridITSTPC for the remainder
\r
962 // the TPC only tracks are flagged as HybridITSTPConly.
\r
963 // Note, in order not to get fakes back in the TPC cuts, one needs
\r
964 // two "ITS" cuts one tight (1) (to throw out fakes) and one lose (2) (to NOT flag the trakcs in the TPC only)
\r
965 // using cut number (3)
\r
966 // so fHybridFilterMask == (1)|(2) fTPCFilterMask = (3), Usercode needs to slect with mask = (1)|(3) and track->IsHybridITSTPC()
\r
967 // ******* TPC ********
\r
968 // 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
\r
969 // 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
\r
971 AliCodeTimerAuto("",0);
\r
973 // Loop over the tracks and extract and mask out all aod tracks that pass the selections for AODt racks
\r
974 for(int it = 0;it < fNumberOfTracks;++it)
\r
976 AliAODTrack *tr = (AliAODTrack*)(Tracks().At(it));
\r
978 UInt_t map = tr->GetFilterMap();
\r
979 if(map&fTPCConstrainedFilterMask){
\r
980 // we only reset the track select ionfo, no deletion...
\r
981 tr->SetFilterMap(map&~fTPCConstrainedFilterMask);
\r
983 if(map&fHybridFilterMaskTPCCG){
\r
984 // this is one part of the hybrid tracks
\r
985 // the others not passing the selection will be TPC only selected below
\r
986 tr->SetIsHybridTPCConstrainedGlobal(kTRUE);
\r
989 // Loop over the ESD trcks and pick out the tracks passing TPC only cuts
\r
992 const AliESDVertex *vtxSPD = esd.GetPrimaryVertexSPD();
\r
993 const AliESDVertex *vtx = esd.GetPrimaryVertex();
\r
995 Double_t pos[3] = { 0. };
\r
996 Double_t covTr[21]={0.};
\r
997 Double_t pid[10]={0.};
\r
998 Double_t p[3] = { 0. };
\r
1000 Double_t pDCA[3] = { 0. }; // momentum at DCA
\r
1001 Double_t rDCA[3] = { 0. }; // position at DCA
\r
1002 Float_t dDCA[2] = {0.}; // DCA to the vertex d and z
\r
1003 Float_t cDCA[3] = {0.}; // covariance of impact parameters
\r
1006 AliAODTrack* aodTrack(0x0);
\r
1008 // account for change in pT after the constraint
\r
1009 Float_t ptMax = 1E10;
\r
1010 Float_t ptMin = 0;
\r
1011 for(int i = 0;i<32;i++){
\r
1012 if(fTPCConstrainedFilterMask&(1<<i)){
\r
1013 AliESDtrackCuts*cuts = (AliESDtrackCuts*)fTrackFilter->GetCuts()->At(i);
\r
1014 Float_t tmp1= 0,tmp2 = 0;
\r
1015 cuts->GetPtRange(tmp1,tmp2);
\r
1016 if(tmp1>ptMin)ptMin=tmp1;
\r
1017 if(tmp2<ptMax)ptMax=tmp2;
\r
1021 for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack)
\r
1023 AliESDtrack* esdTrack = esd.GetTrack(nTrack); //carefull do not modify it othwise need to work with a copy
\r
1025 UInt_t selectInfo = 0;
\r
1026 Bool_t isHybridITSTPC = false;
\r
1028 // Track selection
\r
1029 if (fTrackFilter) {
\r
1030 selectInfo = fTrackFilter->IsSelected(esdTrack);
\r
1033 if(!(selectInfo&fHybridFilterMaskTPCCG)){
\r
1034 // not already selected tracks, use second part of hybrid tracks
\r
1035 isHybridITSTPC = true;
\r
1036 // too save space one could only store these...
\r
1039 selectInfo &= fTPCConstrainedFilterMask;
\r
1040 if (!selectInfo)continue;
\r
1041 if (fWriteHybridTPCCOnly&&!isHybridITSTPC)continue; // write only complementary tracks
\r
1042 // create a tpc only tracl
\r
1043 AliESDtrack *track = AliESDtrackCuts::GetTPCOnlyTrack(const_cast<AliESDEvent*>(&esd),esdTrack->GetID());
\r
1044 if(!track) continue;
\r
1046 if(track->Pt()>0.)
\r
1048 // only constrain tracks above threshold
\r
1049 AliExternalTrackParam exParam;
\r
1050 // take the B-field from the ESD, no 3D fieldMap available at this point
\r
1051 Bool_t relate = false;
\r
1052 relate = track->RelateToVertexTPC(vtxSPD,esd.GetMagneticField(),kVeryBig,&exParam);
\r
1057 // fetch the track parameters at the DCA (unconstraint)
\r
1058 if(track->GetTPCInnerParam()){
\r
1059 track->GetTPCInnerParam()->GetPxPyPz(pDCA);
\r
1060 track->GetTPCInnerParam()->GetXYZ(rDCA);
\r
1062 // get the DCA to the vertex:
\r
1063 track->GetImpactParametersTPC(dDCA,cDCA);
\r
1064 // set the constrained parameters to the track
\r
1065 track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
\r
1068 track->GetPxPyPz(p);
\r
1070 Float_t pT = track->Pt();
\r
1071 if(pT<ptMin||pT>ptMax){
\r
1079 track->GetXYZ(pos);
\r
1080 track->GetCovarianceXYZPxPyPz(covTr);
\r
1081 track->GetESDpid(pid);
\r
1083 if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
\r
1084 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack((track->GetID()+1)*-1,
\r
1085 track->GetLabel(),
\r
1091 (Short_t)track->GetSign(),
\r
1092 track->GetITSClusterMap(),
\r
1095 kTRUE, // check if this is right
\r
1096 vtx->UsesTrack(track->GetID()),
\r
1097 AliAODTrack::kPrimary,
\r
1099 aodTrack->SetIsHybridTPCConstrainedGlobal(isHybridITSTPC);
\r
1100 aodTrack->SetTPCClusterMap(track->GetTPCClusterMap());
\r
1101 aodTrack->SetTPCSharedMap (track->GetTPCSharedMap());
\r
1102 aodTrack->SetIsTPCConstrained(kTRUE);
\r
1103 Float_t ndf = track->GetTPCNcls()+1 - 5 ;
\r
1105 aodTrack->SetChi2perNDF(track->GetConstrainedChi2TPC());
\r
1108 aodTrack->SetChi2perNDF(-1);
\r
1111 // set the DCA values to the AOD track
\r
1112 aodTrack->SetPxPyPzAtDCA(pDCA[0],pDCA[1],pDCA[2]);
\r
1113 aodTrack->SetXYAtDCA(rDCA[0],rDCA[1]);
\r
1114 aodTrack->SetDCA(dDCA[0],dDCA[1]);
\r
1116 aodTrack->SetFlags(track->GetStatus());
\r
1117 aodTrack->SetTPCPointsF(track->GetTPCNclsF());
\r
1120 } // end of loop on tracks
\r
1125 void AliAnalysisTaskESDfilter::ConvertGlobalConstrainedTracks(const AliESDEvent& esd)
\r
1128 // Here we have the option to store the complement from global constraint information
\r
1129 // to tracks passing tight cuts (1) in order not to get fakes back in, one needs
\r
1130 // two sets of cuts one tight (1) (to throw out fakes) and one lose (2) (fakes/bad tracks would pass (2) but not (1))
\r
1131 // using cut number (3) selects the tracks that complement (1) e.g. tracks witout ITS refit or cluster requirement
\r
1134 AliCodeTimerAuto("",0);
\r
1136 // Loop over the tracks and extract and mask out all aod tracks that pass the selections for AODt racks
\r
1137 for(int it = 0;it < fNumberOfTracks;++it)
\r
1139 AliAODTrack *tr = (AliAODTrack*)(Tracks().At(it));
\r
1141 UInt_t map = tr->GetFilterMap();
\r
1142 if(map&fGlobalConstrainedFilterMask){
\r
1143 // we only reset the track select info, no deletion...
\r
1144 // mask reset mask in case track is already taken
\r
1145 tr->SetFilterMap(map&~fGlobalConstrainedFilterMask);
\r
1147 if(map&fHybridFilterMaskGCG){
\r
1148 // this is one part of the hybrid tracks
\r
1149 // the others not passing the selection will be the ones selected below
\r
1150 tr->SetIsHybridGlobalConstrainedGlobal(kTRUE);
\r
1153 // Loop over the ESD trcks and pick out the tracks passing the GlobalConstraint cuts
\r
1156 Double_t pos[3] = { 0. };
\r
1157 Double_t covTr[21]={0.};
\r
1158 Double_t pid[10]={0.};
\r
1159 Double_t p[3] = { 0. };
\r
1161 Double_t pDCA[3] = { 0. }; // momentum at DCA
\r
1162 Double_t rDCA[3] = { 0. }; // position at DCA
\r
1163 Float_t dDCA[2] = {0.}; // DCA to the vertex d and z
\r
1164 Float_t cDCA[3] = {0.}; // covariance of impact parameters
\r
1167 AliAODTrack* aodTrack(0x0);
\r
1168 const AliESDVertex *vtx = esd.GetPrimaryVertex();
\r
1170 // account for change in pT after the constraint
\r
1171 Float_t ptMax = 1E10;
\r
1172 Float_t ptMin = 0;
\r
1173 for(int i = 0;i<32;i++){
\r
1174 if(fGlobalConstrainedFilterMask&(1<<i)){
\r
1175 AliESDtrackCuts*cuts = (AliESDtrackCuts*)fTrackFilter->GetCuts()->At(i);
\r
1176 Float_t tmp1= 0,tmp2 = 0;
\r
1177 cuts->GetPtRange(tmp1,tmp2);
\r
1178 if(tmp1>ptMin)ptMin=tmp1;
\r
1179 if(tmp2<ptMax)ptMax=tmp2;
\r
1185 for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack)
\r
1187 AliESDtrack* esdTrack = esd.GetTrack(nTrack); //carefull do not modify it othwise need to work with a copy
\r
1188 const AliExternalTrackParam * exParamGC = esdTrack->GetConstrainedParam();
\r
1189 if(!exParamGC)continue;
\r
1191 UInt_t selectInfo = 0;
\r
1192 Bool_t isHybridGC = false;
\r
1195 // Track selection
\r
1196 if (fTrackFilter) {
\r
1197 selectInfo = fTrackFilter->IsSelected(esdTrack);
\r
1201 if(!(selectInfo&fHybridFilterMaskGCG))isHybridGC = true;
\r
1202 if (fWriteHybridGCOnly&&!isHybridGC)continue; // write only complementary tracks
\r
1204 selectInfo &= fGlobalConstrainedFilterMask;
\r
1205 if (!selectInfo)continue;
\r
1206 // fetch the track parameters at the DCA (unconstrained)
\r
1207 esdTrack->GetPxPyPz(pDCA);
\r
1208 esdTrack->GetXYZ(rDCA);
\r
1209 // get the DCA to the vertex:
\r
1210 esdTrack->GetImpactParameters(dDCA,cDCA);
\r
1212 esdTrack->GetConstrainedPxPyPz(p);
\r
1215 Float_t pT = exParamGC->Pt();
\r
1216 if(pT<ptMin||pT>ptMax){
\r
1221 esdTrack->GetConstrainedXYZ(pos);
\r
1222 exParamGC->GetCovarianceXYZPxPyPz(covTr);
\r
1223 esdTrack->GetESDpid(pid);
\r
1224 if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
\r
1225 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack((esdTrack->GetID()+1)*-1,
\r
1226 esdTrack->GetLabel(),
\r
1232 (Short_t)esdTrack->GetSign(),
\r
1233 esdTrack->GetITSClusterMap(),
\r
1236 kTRUE, // check if this is right
\r
1237 vtx->UsesTrack(esdTrack->GetID()),
\r
1238 AliAODTrack::kPrimary,
\r
1240 aodTrack->SetIsHybridGlobalConstrainedGlobal(isHybridGC);
\r
1241 aodTrack->SetIsGlobalConstrained(kTRUE);
\r
1242 aodTrack->SetTPCClusterMap(esdTrack->GetTPCClusterMap());
\r
1243 aodTrack->SetTPCSharedMap (esdTrack->GetTPCSharedMap());
\r
1244 Float_t ndf = esdTrack->GetTPCNcls()+1 - 5 ;
\r
1246 aodTrack->SetChi2perNDF(esdTrack->GetConstrainedChi2TPC());
\r
1249 aodTrack->SetChi2perNDF(-1);
\r
1252 // set the DCA values to the AOD track
\r
1253 aodTrack->SetPxPyPzAtDCA(pDCA[0],pDCA[1],pDCA[2]);
\r
1254 aodTrack->SetXYAtDCA(rDCA[0],rDCA[1]);
\r
1255 aodTrack->SetDCA(dDCA[0],dDCA[1]);
\r
1257 aodTrack->SetFlags(esdTrack->GetStatus());
\r
1258 aodTrack->SetTPCPointsF(esdTrack->GetTPCNclsF());
\r
1259 } // end of loop on tracks
\r
1264 //______________________________________________________________________________
\r
1265 void AliAnalysisTaskESDfilter::ConvertTracks(const AliESDEvent& esd)
\r
1267 // Tracks (primary and orphan)
\r
1269 AliCodeTimerAuto("",0);
\r
1271 AliDebug(1,Form("NUMBER OF ESD TRACKS %5d\n", esd.GetNumberOfTracks()));
\r
1273 const AliESDVertex *vtx = esd.GetPrimaryVertex();
\r
1274 Double_t p[3] = { 0. };
\r
1275 Double_t pos[3] = { 0. };
\r
1276 Double_t covTr[21] = { 0. };
\r
1277 Double_t pid[10] = { 0. };
\r
1278 AliAODTrack* aodTrack(0x0);
\r
1279 AliAODPid* detpid(0x0);
\r
1281 for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack)
\r
1283 if (fUsedTrack[nTrack]) continue;
\r
1285 AliESDtrack *esdTrack = esd.GetTrack(nTrack);
\r
1286 UInt_t selectInfo = 0;
\r
1288 // Track selection
\r
1289 if (fTrackFilter) {
\r
1290 selectInfo = fTrackFilter->IsSelected(esdTrack);
\r
1291 if (!selectInfo && !vtx->UsesTrack(esdTrack->GetID())) continue;
\r
1295 esdTrack->GetPxPyPz(p);
\r
1296 esdTrack->GetXYZ(pos);
\r
1297 esdTrack->GetCovarianceXYZPxPyPz(covTr);
\r
1298 esdTrack->GetESDpid(pid);
\r
1299 if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
\r
1300 fPrimaryVertex->AddDaughter(aodTrack =
\r
1301 new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrack->GetID(),
\r
1302 esdTrack->GetLabel(),
\r
1308 (Short_t)esdTrack->GetSign(),
\r
1309 esdTrack->GetITSClusterMap(),
\r
1312 kTRUE, // check if this is right
\r
1313 vtx->UsesTrack(esdTrack->GetID()),
\r
1314 AliAODTrack::kPrimary,
\r
1317 aodTrack->SetTPCClusterMap(esdTrack->GetTPCClusterMap());
\r
1318 aodTrack->SetTPCSharedMap (esdTrack->GetTPCSharedMap());
\r
1319 aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack));
\r
1320 aodTrack->SetTPCPointsF(esdTrack->GetTPCNclsF());
\r
1321 if(esdTrack->IsEMCAL()) aodTrack->SetEMCALcluster(esdTrack->GetEMCALcluster());
\r
1322 if(esdTrack->IsPHOS()) aodTrack->SetPHOScluster(esdTrack->GetPHOScluster());
\r
1324 fAODTrackRefs->AddAt(aodTrack, nTrack);
\r
1327 if (esdTrack->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
1328 aodTrack->SetFlags(esdTrack->GetStatus());
\r
1329 aodTrack->ConvertAliPIDtoAODPID();
\r
1330 SetAODPID(esdTrack,aodTrack,detpid);
\r
1331 } // end of loop on tracks
\r
1334 //______________________________________________________________________________
\r
1335 void AliAnalysisTaskESDfilter::ConvertPmdClusters(const AliESDEvent& esd)
\r
1337 // Convert PMD Clusters
\r
1338 AliCodeTimerAuto("",0);
\r
1339 Int_t jPmdClusters=0;
\r
1340 // Access to the AOD container of PMD clusters
\r
1341 TClonesArray &pmdClusters = *(AODEvent()->GetPmdClusters());
\r
1342 for (Int_t iPmd = 0; iPmd < esd.GetNumberOfPmdTracks(); ++iPmd) {
\r
1343 // file pmd clusters, to be revised!
\r
1344 AliESDPmdTrack *pmdTrack = esd.GetPmdTrack(iPmd);
\r
1346 Int_t *label = 0x0;
\r
1347 Double_t posPmd[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ()};
\r
1348 Double_t pidPmd[13] = { 0.}; // to be revised!
\r
1350 // assoc cluster not set
\r
1351 new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), posPmd, pidPmd);
\r
1355 //______________________________________________________________________________
\r
1356 void AliAnalysisTaskESDfilter::ConvertCaloClusters(const AliESDEvent& esd)
\r
1358 // Convert Calorimeter Clusters
\r
1359 AliCodeTimerAuto("",0);
\r
1361 // Access to the AOD container of clusters
\r
1362 TClonesArray &caloClusters = *(AODEvent()->GetCaloClusters());
\r
1363 Int_t jClusters(0);
\r
1365 for (Int_t iClust=0; iClust<esd.GetNumberOfCaloClusters(); ++iClust) {
\r
1367 AliESDCaloCluster * cluster = esd.GetCaloCluster(iClust);
\r
1369 Int_t id = cluster->GetID();
\r
1370 Int_t nLabel = cluster->GetNLabels();
\r
1371 Int_t *labels = cluster->GetLabels();
\r
1373 for(int i = 0;i < nLabel;++i){
\r
1374 if(fMChandler)fMChandler->SelectParticle(labels[i]);
\r
1378 Float_t energy = cluster->E();
\r
1379 Float_t posF[3] = { 0.};
\r
1380 cluster->GetPosition(posF);
\r
1382 AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
\r
1388 cluster->GetType(),0);
\r
1390 caloCluster->SetCaloCluster(cluster->GetDistanceToBadChannel(),
\r
1391 cluster->GetDispersion(),
\r
1392 cluster->GetM20(), cluster->GetM02(),
\r
1393 cluster->GetEmcCpvDistance(),
\r
1394 cluster->GetNExMax(),cluster->GetTOF()) ;
\r
1396 caloCluster->SetPIDFromESD(cluster->GetPID());
\r
1397 caloCluster->SetNCells(cluster->GetNCells());
\r
1398 caloCluster->SetCellsAbsId(cluster->GetCellsAbsId());
\r
1399 caloCluster->SetCellsAmplitudeFraction(cluster->GetCellsAmplitudeFraction());
\r
1401 TArrayI* matchedT = cluster->GetTracksMatched();
\r
1402 if (fNumberOfTracks>0 && matchedT && cluster->GetTrackMatchedIndex() >= 0) {
\r
1403 for (Int_t im = 0; im < matchedT->GetSize(); im++) {
\r
1404 Int_t iESDtrack = matchedT->At(im);;
\r
1405 if (fAODTrackRefs->At(iESDtrack) != 0) {
\r
1406 caloCluster->AddTrackMatched((AliAODTrack*)fAODTrackRefs->At(iESDtrack));
\r
1412 caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters
\r
1415 //______________________________________________________________________________
\r
1416 void AliAnalysisTaskESDfilter::ConvertEMCALCells(const AliESDEvent& esd)
\r
1418 // Convert EMCAL Cells
\r
1419 AliCodeTimerAuto("",0);
\r
1420 // fill EMCAL cell info
\r
1421 if (esd.GetEMCALCells()) { // protection against missing ESD information
\r
1422 AliESDCaloCells &esdEMcells = *(esd.GetEMCALCells());
\r
1423 Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
\r
1425 AliAODCaloCells &aodEMcells = *(AODEvent()->GetEMCALCells());
\r
1426 aodEMcells.CreateContainer(nEMcell);
\r
1427 aodEMcells.SetType(AliAODCaloCells::kEMCALCell);
\r
1428 for (Int_t iCell = 0; iCell < nEMcell; iCell++) {
\r
1429 aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell));
\r
1431 aodEMcells.Sort();
\r
1435 //______________________________________________________________________________
\r
1436 void AliAnalysisTaskESDfilter::ConvertPHOSCells(const AliESDEvent& esd)
\r
1438 // Convert PHOS Cells
\r
1439 AliCodeTimerAuto("",0);
\r
1440 // fill PHOS cell info
\r
1441 if (esd.GetPHOSCells()) { // protection against missing ESD information
\r
1442 AliESDCaloCells &esdPHcells = *(esd.GetPHOSCells());
\r
1443 Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
\r
1445 AliAODCaloCells &aodPHcells = *(AODEvent()->GetPHOSCells());
\r
1446 aodPHcells.CreateContainer(nPHcell);
\r
1447 aodPHcells.SetType(AliAODCaloCells::kPHOSCell);
\r
1448 for (Int_t iCell = 0; iCell < nPHcell; iCell++) {
\r
1449 aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell));
\r
1451 aodPHcells.Sort();
\r
1455 //______________________________________________________________________________
\r
1456 void AliAnalysisTaskESDfilter::ConvertTracklets(const AliESDEvent& esd)
\r
1459 AliCodeTimerAuto("",0);
\r
1461 AliAODTracklets &SPDTracklets = *(AODEvent()->GetTracklets());
\r
1462 const AliMultiplicity *mult = esd.GetMultiplicity();
\r
1464 if (mult->GetNumberOfTracklets()>0) {
\r
1465 SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
\r
1467 for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
\r
1469 fMChandler->SelectParticle(mult->GetLabel(n, 0));
\r
1470 fMChandler->SelectParticle(mult->GetLabel(n, 1));
\r
1472 SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n, 0),mult->GetLabel(n, 1));
\r
1476 //Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
\r
1480 //______________________________________________________________________________
\r
1481 void AliAnalysisTaskESDfilter::ConvertKinks(const AliESDEvent& esd)
\r
1483 AliCodeTimerAuto("",0);
\r
1485 // Kinks: it is a big mess the access to the information in the kinks
\r
1486 // The loop is on the tracks in order to find the mother and daugther of each kink
\r
1488 Double_t covTr[21]={0.};
\r
1489 Double_t pid[10]={0.};
\r
1490 AliAODPid* detpid(0x0);
\r
1492 fNumberOfKinks = esd.GetNumberOfKinks();
\r
1494 const AliESDVertex* vtx = esd.GetPrimaryVertex();
\r
1496 for (Int_t iTrack=0; iTrack<esd.GetNumberOfTracks(); ++iTrack)
\r
1498 AliESDtrack * esdTrack = esd.GetTrack(iTrack);
\r
1500 Int_t ikink = esdTrack->GetKinkIndex(0);
\r
1502 if (ikink && fNumberOfKinks) {
\r
1503 // Negative kink index: mother, positive: daughter
\r
1505 // Search for the second track of the kink
\r
1507 for (Int_t jTrack = iTrack+1; jTrack<esd.GetNumberOfTracks(); ++jTrack) {
\r
1509 AliESDtrack * esdTrack1 = esd.GetTrack(jTrack);
\r
1511 Int_t jkink = esdTrack1->GetKinkIndex(0);
\r
1513 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
\r
1515 // The two tracks are from the same kink
\r
1517 if (fUsedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
\r
1519 Int_t imother = -1;
\r
1520 Int_t idaughter = -1;
\r
1522 if (ikink<0 && jkink>0) {
\r
1525 idaughter = jTrack;
\r
1527 else if (ikink>0 && jkink<0) {
\r
1530 idaughter = iTrack;
\r
1533 // cerr << "Error: Wrong combination of kink indexes: "
\r
1534 // << ikink << " " << jkink << endl;
\r
1538 // Add the mother track if it passed primary track selection cuts
\r
1540 AliAODTrack * mother = NULL;
\r
1542 UInt_t selectInfo = 0;
\r
1543 if (fTrackFilter) {
\r
1544 selectInfo = fTrackFilter->IsSelected(esd.GetTrack(imother));
\r
1545 if (!selectInfo) continue;
\r
1548 if (!fUsedTrack[imother]) {
\r
1550 fUsedTrack[imother] = kTRUE;
\r
1552 AliESDtrack *esdTrackM = esd.GetTrack(imother);
\r
1553 Double_t p[3] = { 0. };
\r
1554 Double_t pos[3] = { 0. };
\r
1555 esdTrackM->GetPxPyPz(p);
\r
1556 esdTrackM->GetXYZ(pos);
\r
1557 esdTrackM->GetCovarianceXYZPxPyPz(covTr);
\r
1558 esdTrackM->GetESDpid(pid);
\r
1559 if(fMChandler)fMChandler->SelectParticle(esdTrackM->GetLabel());
\r
1561 new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrackM->GetID(),
\r
1562 esdTrackM->GetLabel(),
\r
1568 (Short_t)esdTrackM->GetSign(),
\r
1569 esdTrackM->GetITSClusterMap(),
\r
1572 kTRUE, // check if this is right
\r
1573 vtx->UsesTrack(esdTrack->GetID()),
\r
1574 AliAODTrack::kPrimary,
\r
1576 mother->SetTPCClusterMap(esdTrackM->GetTPCClusterMap());
\r
1577 mother->SetTPCSharedMap (esdTrackM->GetTPCSharedMap());
\r
1578 mother->SetChi2perNDF(Chi2perNDF(esdTrackM));
\r
1579 mother->SetTPCPointsF(esdTrackM->GetTPCNclsF());
\r
1581 fAODTrackRefs->AddAt(mother, imother);
\r
1583 if (esdTrackM->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
1584 mother->SetFlags(esdTrackM->GetStatus());
\r
1585 mother->ConvertAliPIDtoAODPID();
\r
1586 fPrimaryVertex->AddDaughter(mother);
\r
1587 mother->ConvertAliPIDtoAODPID();
\r
1588 SetAODPID(esdTrackM,mother,detpid);
\r
1591 // cerr << "Error: event " << esd.GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
\r
1592 // << " track " << imother << " has already been used!" << endl;
\r
1595 // Add the kink vertex
\r
1596 AliESDkink * kink = esd.GetKink(TMath::Abs(ikink)-1);
\r
1598 AliAODVertex * vkink =
\r
1599 new(Vertices()[fNumberOfVertices++]) AliAODVertex(kink->GetPosition(),
\r
1603 esdTrack->GetID(), // This is the track ID of the mother's track!
\r
1604 AliAODVertex::kKink);
\r
1605 // Add the daughter track
\r
1607 AliAODTrack * daughter = NULL;
\r
1609 if (!fUsedTrack[idaughter]) {
\r
1611 fUsedTrack[idaughter] = kTRUE;
\r
1613 AliESDtrack *esdTrackD = esd.GetTrack(idaughter);
\r
1614 Double_t p[3] = { 0. };
\r
1615 Double_t pos[3] = { 0. };
\r
1617 esdTrackD->GetPxPyPz(p);
\r
1618 esdTrackD->GetXYZ(pos);
\r
1619 esdTrackD->GetCovarianceXYZPxPyPz(covTr);
\r
1620 esdTrackD->GetESDpid(pid);
\r
1622 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdTrackD);
\r
1623 if(fMChandler)fMChandler->SelectParticle(esdTrackD->GetLabel());
\r
1625 new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrackD->GetID(),
\r
1626 esdTrackD->GetLabel(),
\r
1632 (Short_t)esdTrackD->GetSign(),
\r
1633 esdTrackD->GetITSClusterMap(),
\r
1636 kTRUE, // check if this is right
\r
1637 vtx->UsesTrack(esdTrack->GetID()),
\r
1638 AliAODTrack::kSecondary,
\r
1640 daughter->SetTPCClusterMap(esdTrackD->GetTPCClusterMap());
\r
1641 daughter->SetTPCSharedMap (esdTrackD->GetTPCSharedMap());
\r
1642 daughter->SetTPCPointsF(esdTrackD->GetTPCNclsF());
\r
1643 fAODTrackRefs->AddAt(daughter, idaughter);
\r
1645 if (esdTrackD->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
1646 daughter->SetFlags(esdTrackD->GetStatus());
\r
1647 daughter->ConvertAliPIDtoAODPID();
\r
1648 vkink->AddDaughter(daughter);
\r
1649 daughter->ConvertAliPIDtoAODPID();
\r
1650 SetAODPID(esdTrackD,daughter,detpid);
\r
1653 // cerr << "Error: event " << esd.GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
\r
1654 // << " track " << idaughter << " has already been used!" << endl;
\r
1662 //______________________________________________________________________________
\r
1663 void AliAnalysisTaskESDfilter::ConvertPrimaryVertices(const AliESDEvent& esd)
\r
1665 AliCodeTimerAuto("",0);
\r
1667 // Access to the AOD container of vertices
\r
1668 fNumberOfVertices = 0;
\r
1670 Double_t pos[3] = { 0. };
\r
1671 Double_t covVtx[6] = { 0. };
\r
1673 // Add primary vertex. The primary tracks will be defined
\r
1674 // after the loops on the composite objects (V0, cascades, kinks)
\r
1675 const AliESDVertex *vtx = esd.GetPrimaryVertex();
\r
1677 vtx->GetXYZ(pos); // position
\r
1678 vtx->GetCovMatrix(covVtx); //covariance matrix
\r
1680 fPrimaryVertex = new(Vertices()[fNumberOfVertices++])
\r
1681 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
\r
1682 fPrimaryVertex->SetName(vtx->GetName());
\r
1683 fPrimaryVertex->SetTitle(vtx->GetTitle());
\r
1685 TString vtitle = vtx->GetTitle();
\r
1686 if (!vtitle.Contains("VertexerTracks"))
\r
1687 fPrimaryVertex->SetNContributors(vtx->GetNContributors());
\r
1689 if (fDebug > 0) fPrimaryVertex->Print();
\r
1691 // Add SPD "main" vertex
\r
1692 const AliESDVertex *vtxS = esd.GetPrimaryVertexSPD();
\r
1693 vtxS->GetXYZ(pos); // position
\r
1694 vtxS->GetCovMatrix(covVtx); //covariance matrix
\r
1695 AliAODVertex * mVSPD = new(Vertices()[fNumberOfVertices++])
\r
1696 AliAODVertex(pos, covVtx, vtxS->GetChi2toNDF(), NULL, -1, AliAODVertex::kMainSPD);
\r
1697 mVSPD->SetName(vtxS->GetName());
\r
1698 mVSPD->SetTitle(vtxS->GetTitle());
\r
1699 mVSPD->SetNContributors(vtxS->GetNContributors());
\r
1701 // Add SPD pileup vertices
\r
1702 for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesSPD(); ++iV)
\r
1704 const AliESDVertex *vtxP = esd.GetPileupVertexSPD(iV);
\r
1705 vtxP->GetXYZ(pos); // position
\r
1706 vtxP->GetCovMatrix(covVtx); //covariance matrix
\r
1707 AliAODVertex * pVSPD = new(Vertices()[fNumberOfVertices++])
\r
1708 AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupSPD);
\r
1709 pVSPD->SetName(vtxP->GetName());
\r
1710 pVSPD->SetTitle(vtxP->GetTitle());
\r
1711 pVSPD->SetNContributors(vtxP->GetNContributors());
\r
1712 pVSPD->SetBC(vtxP->GetBC());
\r
1715 // Add TRK pileup vertices
\r
1716 for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesTracks(); ++iV)
\r
1718 const AliESDVertex *vtxP = esd.GetPileupVertexTracks(iV);
\r
1719 vtxP->GetXYZ(pos); // position
\r
1720 vtxP->GetCovMatrix(covVtx); //covariance matrix
\r
1721 AliAODVertex * pVTRK = new(Vertices()[fNumberOfVertices++])
\r
1722 AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupTracks);
\r
1723 pVTRK->SetName(vtxP->GetName());
\r
1724 pVTRK->SetTitle(vtxP->GetTitle());
\r
1725 pVTRK->SetNContributors(vtxP->GetNContributors());
\r
1726 pVTRK->SetBC(vtxP->GetBC());
\r
1730 //______________________________________________________________________________
\r
1731 void AliAnalysisTaskESDfilter::ConvertVZERO(const AliESDEvent& esd)
\r
1733 // Convert VZERO data
\r
1734 AliAODVZERO* vzeroData = AODEvent()->GetVZEROData();
\r
1735 *vzeroData = *(esd.GetVZEROData());
\r
1738 //______________________________________________________________________________
\r
1739 void AliAnalysisTaskESDfilter::ConvertTZERO(const AliESDEvent& esd)
\r
1741 // Convert TZERO data
\r
1742 const AliESDTZERO* esdTzero = esd.GetESDTZERO();
\r
1743 AliAODTZERO* aodTzero = AODEvent()->GetTZEROData();
\r
1745 for (Int_t icase=0; icase<3; icase++){
\r
1746 aodTzero->SetT0TOF( icase, esdTzero->GetT0TOF(icase));
\r
1747 aodTzero->SetT0TOFbest(icase, esdTzero->GetT0TOFbest(icase));
\r
1749 aodTzero->SetBackgroundFlag(esdTzero->GetBackgroundFlag());
\r
1750 aodTzero->SetPileupFlag(esdTzero->GetPileupFlag());
\r
1751 aodTzero->SetSatelliteFlag(esdTzero->GetSatellite());
\r
1756 //______________________________________________________________________________
\r
1757 void AliAnalysisTaskESDfilter::ConvertZDC(const AliESDEvent& esd)
\r
1759 // Convert ZDC data
\r
1760 AliESDZDC* esdZDC = esd.GetZDCData();
\r
1762 const Double_t zem1Energy = esdZDC->GetZEM1Energy();
\r
1763 const Double_t zem2Energy = esdZDC->GetZEM2Energy();
\r
1765 const Double_t *towZNC = esdZDC->GetZNCTowerEnergy();
\r
1766 const Double_t *towZPC = esdZDC->GetZPCTowerEnergy();
\r
1767 const Double_t *towZNA = esdZDC->GetZNATowerEnergy();
\r
1768 const Double_t *towZPA = esdZDC->GetZPATowerEnergy();
\r
1769 const Double_t *towZNCLG = esdZDC->GetZNCTowerEnergyLR();
\r
1770 const Double_t *towZNALG = esdZDC->GetZNATowerEnergyLR();
\r
1772 AliAODZDC* zdcAOD = AODEvent()->GetZDCData();
\r
1774 zdcAOD->SetZEM1Energy(zem1Energy);
\r
1775 zdcAOD->SetZEM2Energy(zem2Energy);
\r
1776 zdcAOD->SetZNCTowers(towZNC, towZNCLG);
\r
1777 zdcAOD->SetZNATowers(towZNA, towZNALG);
\r
1778 zdcAOD->SetZPCTowers(towZPC);
\r
1779 zdcAOD->SetZPATowers(towZPA);
\r
1781 zdcAOD->SetZDCParticipants(esdZDC->GetZDCParticipants(), esdZDC->GetZDCPartSideA(), esdZDC->GetZDCPartSideC());
\r
1782 zdcAOD->SetZDCImpactParameter(esdZDC->GetImpactParameter(), esdZDC->GetImpactParamSideA(),
\r
1783 esdZDC->GetImpactParamSideC());
\r
1784 zdcAOD->SetZDCTDCSum(esdZDC->GetZNTDCSum(0));
\r
1785 zdcAOD->SetZDCTDCDiff(esdZDC->GetZNTDCDiff(0));
\r
1789 //______________________________________________________________________________
\r
1790 void AliAnalysisTaskESDfilter::ConvertESDtoAOD()
\r
1792 // ESD Filter analysis task executed for each event
\r
1794 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
\r
1798 AliCodeTimerAuto("",0);
\r
1800 fOldESDformat = ( esd->GetAliESDOld() != 0x0 );
\r
1802 fNumberOfTracks = 0;
\r
1803 fNumberOfPositiveTracks = 0;
\r
1805 fNumberOfVertices = 0;
\r
1806 fNumberOfCascades = 0;
\r
1807 fNumberOfKinks = 0;
\r
1809 AliAODHeader* header = ConvertHeader(*esd);
\r
1811 if ( fIsVZEROEnabled ) ConvertVZERO(*esd);
\r
1812 if ( fIsTZEROEnabled ) ConvertTZERO(*esd);
\r
1814 // Fetch Stack for debuggging if available
\r
1818 fMChandler = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler());
\r
1821 // loop over events and fill them
\r
1822 // Multiplicity information needed by the header (to be revised!)
\r
1823 Int_t nTracks = esd->GetNumberOfTracks();
\r
1824 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) esd->GetTrack(iTrack)->SetESDEvent(esd);
\r
1826 // Update the header
\r
1828 Int_t nV0s = esd->GetNumberOfV0s();
\r
1829 Int_t nCascades = esd->GetNumberOfCascades();
\r
1830 Int_t nKinks = esd->GetNumberOfKinks();
\r
1831 Int_t nVertices = nV0s + nCascades /*V0 wihtin cascade already counted*/+ nKinks + 1 /* = prim. vtx*/;
\r
1832 Int_t nPileSPDVertices=1+esd->GetNumberOfPileupVerticesSPD(); // also SPD main vertex
\r
1833 Int_t nPileTrkVertices=esd->GetNumberOfPileupVerticesTracks();
\r
1834 nVertices+=nPileSPDVertices;
\r
1835 nVertices+=nPileTrkVertices;
\r
1837 Int_t nCaloClus = esd->GetNumberOfCaloClusters();
\r
1838 Int_t nFmdClus = 0;
\r
1839 Int_t nPmdClus = esd->GetNumberOfPmdTracks();
\r
1841 AliDebug(1,Form(" NV0=%d NCASCADES=%d NKINKS=%d", nV0s, nCascades, nKinks));
\r
1843 AODEvent()->ResetStd(nTracks, nVertices, nV0s, nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
\r
1847 // RefArray to store a mapping between esd V0 number and newly created AOD-Vertex V0
\r
1848 fAODV0VtxRefs = new TRefArray(nV0s);
\r
1849 // RefArray to store the mapping between esd V0 number and newly created AOD-V0
\r
1850 fAODV0Refs = new TRefArray(nV0s);
\r
1851 // Array to take into account the V0s already added to the AOD (V0 within cascades)
\r
1852 fUsedV0 = new Bool_t[nV0s];
\r
1853 for (Int_t iV0=0; iV0<nV0s; ++iV0) fUsedV0[iV0]=kFALSE;
\r
1858 // RefArray to store the mapping between esd track number and newly created AOD-Track
\r
1860 fAODTrackRefs = new TRefArray(nTracks);
\r
1862 // Array to take into account the tracks already added to the AOD
\r
1863 fUsedTrack = new Bool_t[nTracks];
\r
1864 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) fUsedTrack[iTrack]=kFALSE;
\r
1867 // Array to take into account the kinks already added to the AOD
\r
1870 fUsedKink = new Bool_t[nKinks];
\r
1871 for (Int_t iKink=0; iKink<nKinks; ++iKink) fUsedKink[iKink]=kFALSE;
\r
1874 ConvertPrimaryVertices(*esd);
\r
1876 //setting best TOF PID
\r
1877 AliESDInputHandler* esdH = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
\r
1879 fESDpid = esdH->GetESDpid();
\r
1881 if (fIsPidOwner && fESDpid){
\r
1886 { //in case of no Tender attached
\r
1887 fESDpid = new AliESDpid;
\r
1888 fIsPidOwner = kTRUE;
\r
1891 if(!esd->GetTOFHeader())
\r
1892 { //protection in case the pass2 LHC10b,c,d have been processed without tender.
\r
1893 Float_t t0spread[10];
\r
1894 Float_t intrinsicTOFres=100; //ps ok for LHC10b,c,d pass2!!
\r
1895 for (Int_t i=0; i<10; i++) t0spread[i] = (TMath::Sqrt(esd->GetSigma2DiamondZ()))/0.03; //0.03 to convert from cm to ps
\r
1896 fESDpid->GetTOFResponse().SetT0resolution(t0spread);
\r
1897 fESDpid->GetTOFResponse().SetTimeResolution(intrinsicTOFres);
\r
1899 fESDpid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType);
\r
1902 if(esd->GetTOFHeader() && fIsPidOwner) fESDpid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType); //in case of AOD production strating form LHC10e without Tender.
\r
1904 if ( fAreCascadesEnabled ) ConvertCascades(*esd);
\r
1906 if ( fAreV0sEnabled ) ConvertV0s(*esd);
\r
1908 if ( fAreKinksEnabled ) ConvertKinks(*esd);
\r
1910 if ( fAreTracksEnabled ) ConvertTracks(*esd);
\r
1912 // Update number of AOD tracks in header at the end of track loop (M.G.)
\r
1913 header->SetRefMultiplicity(fNumberOfTracks);
\r
1914 header->SetRefMultiplicityPos(fNumberOfPositiveTracks);
\r
1915 header->SetRefMultiplicityNeg(fNumberOfTracks - fNumberOfPositiveTracks);
\r
1917 if ( fTPCConstrainedFilterMask ) ConvertTPCOnlyTracks(*esd);
\r
1918 if( fGlobalConstrainedFilterMask) ConvertGlobalConstrainedTracks(*esd);
\r
1920 if ( fArePmdClustersEnabled ) ConvertPmdClusters(*esd);
\r
1922 if ( fAreCaloClustersEnabled ) ConvertCaloClusters(*esd);
\r
1924 if ( fAreEMCALCellsEnabled )ConvertEMCALCells(*esd);
\r
1926 if ( fArePHOSCellsEnabled )ConvertPHOSCells(*esd);
\r
1928 if ( fAreTrackletsEnabled ) ConvertTracklets(*esd);
\r
1930 delete fAODTrackRefs; fAODTrackRefs=0x0;
\r
1931 delete fAODV0VtxRefs; fAODV0VtxRefs=0x0;
\r
1932 delete fAODV0Refs; fAODV0Refs=0x0;
\r
1934 delete[] fUsedTrack; fUsedTrack=0x0;
\r
1935 delete[] fUsedV0; fUsedV0=0x0;
\r
1936 delete[] fUsedKink; fUsedKink=0x0;
\r
1938 if ( fIsPidOwner){
\r
1947 //______________________________________________________________________________
\r
1948 void AliAnalysisTaskESDfilter::SetAODPID(AliESDtrack *esdtrack, AliAODTrack *aodtrack, AliAODPid *detpid)
\r
1951 // Setter for the raw PID detector signals
\r
1954 // Save PID object for candidate electrons
\r
1955 Bool_t pidSave = kFALSE;
\r
1956 if (fTrackFilter) {
\r
1957 Bool_t selectInfo = fTrackFilter->IsSelected((char*) "Electrons");
\r
1958 if (selectInfo) pidSave = kTRUE;
\r
1962 // Tracks passing pt cut
\r
1963 if(esdtrack->Pt()>fHighPthreshold) {
\r
1967 if(esdtrack->Pt()> fPtshape->GetXmin()){
\r
1968 Double_t y = fPtshape->Eval(esdtrack->Pt())/fPtshape->Eval(fHighPthreshold);
\r
1969 if(gRandom->Rndm(0)<1./y){
\r
1972 }//end if p < pmin
\r
1973 }//end if p function
\r
1977 if(!aodtrack->GetDetPid()){// prevent memory leak when calling SetAODPID twice for the same track
\r
1978 detpid = new AliAODPid();
\r
1979 SetDetectorRawSignals(detpid,esdtrack);
\r
1980 aodtrack->SetDetPID(detpid);
\r
1985 //______________________________________________________________________________
\r
1986 void AliAnalysisTaskESDfilter::SetDetectorRawSignals(AliAODPid *aodpid, AliESDtrack *track)
\r
1989 //assignment of the detector signals (AliXXXesdPID inspired)
\r
1992 AliInfo("no ESD track found. .....exiting");
\r
1996 const AliExternalTrackParam *in=track->GetInnerParam();
\r
1998 aodpid->SetTPCmomentum(in->GetP());
\r
2000 aodpid->SetTPCmomentum(-1.);
\r
2004 aodpid->SetITSsignal(track->GetITSsignal());
\r
2005 Double_t itsdedx[4]; // dE/dx samples for individual ITS layers
\r
2006 track->GetITSdEdxSamples(itsdedx);
\r
2007 aodpid->SetITSdEdxSamples(itsdedx);
\r
2009 aodpid->SetTPCsignal(track->GetTPCsignal());
\r
2010 aodpid->SetTPCsignalN(track->GetTPCsignalN());
\r
2012 //n TRD planes = 6
\r
2013 Int_t nslices = track->GetNumberOfTRDslices()*6;
\r
2014 TArrayD trdslices(nslices);
\r
2015 for(Int_t iSl =0; iSl < track->GetNumberOfTRDslices(); iSl++) {
\r
2016 for(Int_t iPl =0; iPl<6; iPl++) trdslices[iPl*track->GetNumberOfTRDslices()+iSl] = track->GetTRDslice(iPl,iSl);
\r
2020 for(Int_t iPl=0;iPl<6;iPl++){
\r
2021 Double_t trdmom=track->GetTRDmomentum(iPl);
\r
2022 aodpid->SetTRDmomentum(iPl,trdmom);
\r
2025 aodpid->SetTRDsignal(track->GetNumberOfTRDslices()*6,trdslices.GetArray());
\r
2027 //TRD clusters and tracklets
\r
2028 aodpid->SetTRDncls(track->GetTRDncls());
\r
2029 aodpid->SetTRDntrackletsPID(track->GetTRDntrackletsPID());
\r
2032 Double_t times[AliAODPid::kSPECIES]; track->GetIntegratedTimes(times);
\r
2033 aodpid->SetIntegratedTimes(times);
\r
2035 Float_t tzeroTrack = fESDpid->GetTOFResponse().GetStartTime(track->P());
\r
2036 aodpid->SetTOFsignal(track->GetTOFsignal()-tzeroTrack);
\r
2038 Double_t tofRes[5];
\r
2039 for (Int_t iMass=0; iMass<5; iMass++){
\r
2040 tofRes[iMass]=(Double_t)fESDpid->GetTOFResponse().GetExpectedSigma(track->P(), times[iMass], AliPID::ParticleMass(iMass));
\r
2042 aodpid->SetTOFpidResolution(tofRes);
\r
2044 aodpid->SetHMPIDsignal(track->GetHMPIDsignal());
\r
2046 //Extrapolate track to EMCAL surface for AOD-level track-cluster matching
\r
2047 Double_t emcpos[3] = {0.,0.,0.};
\r
2048 Double_t emcmom[3] = {0.,0.,0.};
\r
2049 aodpid->SetEMCALPosition(emcpos);
\r
2050 aodpid->SetEMCALMomentum(emcmom);
\r
2052 Double_t hmpPid[5] = {0};
\r
2053 track->GetHMPIDpid(hmpPid);
\r
2054 aodpid->SetHMPIDprobs(hmpPid);
\r
2056 AliExternalTrackParam *outerparam = (AliExternalTrackParam*)track->GetOuterParam();
\r
2057 if(!outerparam) return;
\r
2059 //To be replaced by call to AliEMCALGeoUtils when the class becomes available
\r
2060 Bool_t okpos = outerparam->GetXYZ(emcpos);
\r
2061 Bool_t okmom = outerparam->GetPxPyPz(emcmom);
\r
2062 if(!(okpos && okmom)) return;
\r
2064 aodpid->SetEMCALPosition(emcpos);
\r
2065 aodpid->SetEMCALMomentum(emcmom);
\r
2069 Double_t AliAnalysisTaskESDfilter::Chi2perNDF(AliESDtrack* track)
\r
2071 // Calculate chi2 per ndf for track
\r
2072 Int_t nClustersTPC = track->GetTPCNcls();
\r
2074 if ( nClustersTPC > 5) {
\r
2075 return (track->GetTPCchi2()/Float_t(nClustersTPC - 5));
\r
2082 //______________________________________________________________________________
\r
2083 void AliAnalysisTaskESDfilter::Terminate(Option_t */*option*/)
\r
2085 // Terminate analysis
\r
2087 if (fDebug > 1) printf("AnalysisESDfilter: Terminate() \n");
\r
2090 //______________________________________________________________________________
\r
2091 void AliAnalysisTaskESDfilter::PrintMCInfo(AliStack *pStack,Int_t label){
\r
2093 if(!pStack)return;
\r
2094 label = TMath::Abs(label);
\r
2095 TParticle *part = pStack->Particle(label);
\r
2096 Printf("########################");
\r
2097 Printf("%s:%d %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,label,part->GetUniqueID(),part->GetPdgCode(),part->P());
\r
2099 TParticle* mother = part;
\r
2100 Int_t imo = part->GetFirstMother();
\r
2101 Int_t nprim = pStack->GetNprimary();
\r
2102 // while((imo >= nprim) && (mother->GetUniqueID() == 4)) {
\r
2103 while((imo >= nprim)) {
\r
2104 mother = pStack->Particle(imo);
\r
2105 Printf("Mother %s:%d Label %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,imo,mother->GetUniqueID(),mother->GetPdgCode(),mother->P());
\r
2107 imo = mother->GetFirstMother();
\r
2109 Printf("########################");
\r