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
1000 Double_t p[3] = { 0. };
\r
1002 Double_t pDCA[3] = { 0. }; // momentum at DCA
\r
1003 Double_t rDCA[3] = { 0. }; // position at DCA
\r
1004 Float_t dDCA[2] = {0.}; // DCA to the vertex d and z
\r
1005 Float_t cDCA[3] = {0.}; // covariance of impact parameters
\r
1008 AliAODTrack* aodTrack(0x0);
\r
1009 AliAODPid* detpid(0x0);
\r
1011 // account for change in pT after the constraint
\r
1012 Float_t ptMax = 1E10;
\r
1013 Float_t ptMin = 0;
\r
1014 for(int i = 0;i<32;i++){
\r
1015 if(fTPCConstrainedFilterMask&(1<<i)){
\r
1016 AliESDtrackCuts*cuts = (AliESDtrackCuts*)fTrackFilter->GetCuts()->At(i);
\r
1017 Float_t tmp1= 0,tmp2 = 0;
\r
1018 cuts->GetPtRange(tmp1,tmp2);
\r
1019 if(tmp1>ptMin)ptMin=tmp1;
\r
1020 if(tmp2<ptMax)ptMax=tmp2;
\r
1024 for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack)
\r
1026 AliESDtrack* esdTrack = esd.GetTrack(nTrack); //carefull do not modify it othwise need to work with a copy
\r
1028 UInt_t selectInfo = 0;
\r
1029 Bool_t isHybridITSTPC = false;
\r
1031 // Track selection
\r
1032 if (fTrackFilter) {
\r
1033 selectInfo = fTrackFilter->IsSelected(esdTrack);
\r
1036 if(!(selectInfo&fHybridFilterMaskTPCCG)){
\r
1037 // not already selected tracks, use second part of hybrid tracks
\r
1038 isHybridITSTPC = true;
\r
1039 // too save space one could only store these...
\r
1042 selectInfo &= fTPCConstrainedFilterMask;
\r
1043 if (!selectInfo)continue;
\r
1044 if (fWriteHybridTPCCOnly&&!isHybridITSTPC)continue; // write only complementary tracks
\r
1045 // create a tpc only tracl
\r
1046 AliESDtrack *track = AliESDtrackCuts::GetTPCOnlyTrack(const_cast<AliESDEvent*>(&esd),esdTrack->GetID());
\r
1047 if(!track) continue;
\r
1049 if(track->Pt()>0.)
\r
1051 // only constrain tracks above threshold
\r
1052 AliExternalTrackParam exParam;
\r
1053 // take the B-field from the ESD, no 3D fieldMap available at this point
\r
1054 Bool_t relate = false;
\r
1055 relate = track->RelateToVertexTPC(vtxSPD,esd.GetMagneticField(),kVeryBig,&exParam);
\r
1060 // fetch the track parameters at the DCA (unconstraint)
\r
1061 if(track->GetTPCInnerParam()){
\r
1062 track->GetTPCInnerParam()->GetPxPyPz(pDCA);
\r
1063 track->GetTPCInnerParam()->GetXYZ(rDCA);
\r
1065 // get the DCA to the vertex:
\r
1066 track->GetImpactParametersTPC(dDCA,cDCA);
\r
1067 // set the constrained parameters to the track
\r
1068 track->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),exParam.GetCovariance());
\r
1071 track->GetPxPyPz(p);
\r
1073 Float_t pT = track->Pt();
\r
1074 if(pT<ptMin||pT>ptMax){
\r
1082 track->GetXYZ(pos);
\r
1083 track->GetCovarianceXYZPxPyPz(covTr);
\r
1084 esdTrack->GetESDpid(pid);// original PID
\r
1086 if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
\r
1087 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack((track->GetID()+1)*-1,
\r
1088 track->GetLabel(),
\r
1094 (Short_t)track->GetSign(),
\r
1095 track->GetITSClusterMap(),
\r
1098 kTRUE, // check if this is right
\r
1099 vtx->UsesTrack(track->GetID()),
\r
1100 AliAODTrack::kPrimary,
\r
1102 aodTrack->SetIsHybridTPCConstrainedGlobal(isHybridITSTPC);
\r
1103 aodTrack->SetTPCClusterMap(track->GetTPCClusterMap());
\r
1104 aodTrack->SetTPCSharedMap (track->GetTPCSharedMap());
\r
1105 aodTrack->SetIsTPCConstrained(kTRUE);
\r
1106 aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack)); // original track
\r
1107 // set the DCA values to the AOD track
\r
1108 aodTrack->SetPxPyPzAtDCA(pDCA[0],pDCA[1],pDCA[2]);
\r
1109 aodTrack->SetXYAtDCA(rDCA[0],rDCA[1]);
\r
1110 aodTrack->SetDCA(dDCA[0],dDCA[1]);
\r
1112 aodTrack->SetFlags(track->GetStatus());
\r
1113 aodTrack->SetTPCPointsF(track->GetTPCNclsF());
\r
1115 // do not duplicate PID information
\r
1116 // aodTrack->ConvertAliPIDtoAODPID();
\r
1117 // SetAODPID(esdTrack,aodTrack,detpid);
\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 AliAODPid* detpid(0x0);
\r
1169 const AliESDVertex *vtx = esd.GetPrimaryVertex();
\r
1171 // account for change in pT after the constraint
\r
1172 Float_t ptMax = 1E10;
\r
1173 Float_t ptMin = 0;
\r
1174 for(int i = 0;i<32;i++){
\r
1175 if(fGlobalConstrainedFilterMask&(1<<i)){
\r
1176 AliESDtrackCuts*cuts = (AliESDtrackCuts*)fTrackFilter->GetCuts()->At(i);
\r
1177 Float_t tmp1= 0,tmp2 = 0;
\r
1178 cuts->GetPtRange(tmp1,tmp2);
\r
1179 if(tmp1>ptMin)ptMin=tmp1;
\r
1180 if(tmp2<ptMax)ptMax=tmp2;
\r
1186 for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack)
\r
1188 AliESDtrack* esdTrack = esd.GetTrack(nTrack); //carefull do not modify it othwise need to work with a copy
\r
1189 const AliExternalTrackParam * exParamGC = esdTrack->GetConstrainedParam();
\r
1190 if(!exParamGC)continue;
\r
1192 UInt_t selectInfo = 0;
\r
1193 Bool_t isHybridGC = false;
\r
1196 // Track selection
\r
1197 if (fTrackFilter) {
\r
1198 selectInfo = fTrackFilter->IsSelected(esdTrack);
\r
1202 if(!(selectInfo&fHybridFilterMaskGCG))isHybridGC = true;
\r
1203 if (fWriteHybridGCOnly&&!isHybridGC)continue; // write only complementary tracks
\r
1205 selectInfo &= fGlobalConstrainedFilterMask;
\r
1206 if (!selectInfo)continue;
\r
1207 // fetch the track parameters at the DCA (unconstrained)
\r
1208 esdTrack->GetPxPyPz(pDCA);
\r
1209 esdTrack->GetXYZ(rDCA);
\r
1210 // get the DCA to the vertex:
\r
1211 esdTrack->GetImpactParameters(dDCA,cDCA);
\r
1213 esdTrack->GetConstrainedPxPyPz(p);
\r
1216 Float_t pT = exParamGC->Pt();
\r
1217 if(pT<ptMin||pT>ptMax){
\r
1222 esdTrack->GetConstrainedXYZ(pos);
\r
1223 exParamGC->GetCovarianceXYZPxPyPz(covTr);
\r
1224 esdTrack->GetESDpid(pid);
\r
1225 if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
\r
1226 aodTrack = new(Tracks()[fNumberOfTracks++]) AliAODTrack((esdTrack->GetID()+1)*-1,
\r
1227 esdTrack->GetLabel(),
\r
1233 (Short_t)esdTrack->GetSign(),
\r
1234 esdTrack->GetITSClusterMap(),
\r
1237 kTRUE, // check if this is right
\r
1238 vtx->UsesTrack(esdTrack->GetID()),
\r
1239 AliAODTrack::kPrimary,
\r
1241 aodTrack->SetIsHybridGlobalConstrainedGlobal(isHybridGC);
\r
1242 aodTrack->SetIsGlobalConstrained(kTRUE);
\r
1243 aodTrack->SetTPCClusterMap(esdTrack->GetTPCClusterMap());
\r
1244 aodTrack->SetTPCSharedMap (esdTrack->GetTPCSharedMap());
\r
1245 aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack));
\r
1248 // set the DCA values to the AOD track
\r
1249 aodTrack->SetPxPyPzAtDCA(pDCA[0],pDCA[1],pDCA[2]);
\r
1250 aodTrack->SetXYAtDCA(rDCA[0],rDCA[1]);
\r
1251 aodTrack->SetDCA(dDCA[0],dDCA[1]);
\r
1253 aodTrack->SetFlags(esdTrack->GetStatus());
\r
1254 aodTrack->SetTPCPointsF(esdTrack->GetTPCNclsF());
\r
1257 // only copy AOD information for hybrid, no duplicate information
\r
1258 aodTrack->ConvertAliPIDtoAODPID();
\r
1259 SetAODPID(esdTrack,aodTrack,detpid);
\r
1261 } // end of loop on tracks
\r
1266 //______________________________________________________________________________
\r
1267 void AliAnalysisTaskESDfilter::ConvertTracks(const AliESDEvent& esd)
\r
1269 // Tracks (primary and orphan)
\r
1271 AliCodeTimerAuto("",0);
\r
1273 AliDebug(1,Form("NUMBER OF ESD TRACKS %5d\n", esd.GetNumberOfTracks()));
\r
1275 const AliESDVertex *vtx = esd.GetPrimaryVertex();
\r
1276 Double_t p[3] = { 0. };
\r
1277 Double_t pos[3] = { 0. };
\r
1278 Double_t covTr[21] = { 0. };
\r
1279 Double_t pid[10] = { 0. };
\r
1280 AliAODTrack* aodTrack(0x0);
\r
1281 AliAODPid* detpid(0x0);
\r
1283 for (Int_t nTrack = 0; nTrack < esd.GetNumberOfTracks(); ++nTrack)
\r
1285 if (fUsedTrack[nTrack]) continue;
\r
1287 AliESDtrack *esdTrack = esd.GetTrack(nTrack);
\r
1288 UInt_t selectInfo = 0;
\r
1290 // Track selection
\r
1291 if (fTrackFilter) {
\r
1292 selectInfo = fTrackFilter->IsSelected(esdTrack);
\r
1293 if (!selectInfo && !vtx->UsesTrack(esdTrack->GetID())) continue;
\r
1297 esdTrack->GetPxPyPz(p);
\r
1298 esdTrack->GetXYZ(pos);
\r
1299 esdTrack->GetCovarianceXYZPxPyPz(covTr);
\r
1300 esdTrack->GetESDpid(pid);
\r
1301 if(fMChandler)fMChandler->SelectParticle(esdTrack->GetLabel());
\r
1302 fPrimaryVertex->AddDaughter(aodTrack =
\r
1303 new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrack->GetID(),
\r
1304 esdTrack->GetLabel(),
\r
1310 (Short_t)esdTrack->GetSign(),
\r
1311 esdTrack->GetITSClusterMap(),
\r
1314 kTRUE, // check if this is right
\r
1315 vtx->UsesTrack(esdTrack->GetID()),
\r
1316 AliAODTrack::kPrimary,
\r
1319 aodTrack->SetTPCClusterMap(esdTrack->GetTPCClusterMap());
\r
1320 aodTrack->SetTPCSharedMap (esdTrack->GetTPCSharedMap());
\r
1321 aodTrack->SetChi2perNDF(Chi2perNDF(esdTrack));
\r
1322 aodTrack->SetTPCPointsF(esdTrack->GetTPCNclsF());
\r
1323 if(esdTrack->IsEMCAL()) aodTrack->SetEMCALcluster(esdTrack->GetEMCALcluster());
\r
1324 if(esdTrack->IsPHOS()) aodTrack->SetPHOScluster(esdTrack->GetPHOScluster());
\r
1326 fAODTrackRefs->AddAt(aodTrack, nTrack);
\r
1329 if (esdTrack->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
1330 aodTrack->SetFlags(esdTrack->GetStatus());
\r
1331 aodTrack->ConvertAliPIDtoAODPID();
\r
1332 SetAODPID(esdTrack,aodTrack,detpid);
\r
1333 } // end of loop on tracks
\r
1336 //______________________________________________________________________________
\r
1337 void AliAnalysisTaskESDfilter::ConvertPmdClusters(const AliESDEvent& esd)
\r
1339 // Convert PMD Clusters
\r
1340 AliCodeTimerAuto("",0);
\r
1341 Int_t jPmdClusters=0;
\r
1342 // Access to the AOD container of PMD clusters
\r
1343 TClonesArray &pmdClusters = *(AODEvent()->GetPmdClusters());
\r
1344 for (Int_t iPmd = 0; iPmd < esd.GetNumberOfPmdTracks(); ++iPmd) {
\r
1345 // file pmd clusters, to be revised!
\r
1346 AliESDPmdTrack *pmdTrack = esd.GetPmdTrack(iPmd);
\r
1348 Int_t *label = 0x0;
\r
1349 Double_t posPmd[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ()};
\r
1350 Double_t pidPmd[13] = { 0.}; // to be revised!
\r
1352 // assoc cluster not set
\r
1353 new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), posPmd, pidPmd);
\r
1357 //______________________________________________________________________________
\r
1358 void AliAnalysisTaskESDfilter::ConvertCaloClusters(const AliESDEvent& esd)
\r
1360 // Convert Calorimeter Clusters
\r
1361 AliCodeTimerAuto("",0);
\r
1363 // Access to the AOD container of clusters
\r
1364 TClonesArray &caloClusters = *(AODEvent()->GetCaloClusters());
\r
1365 Int_t jClusters(0);
\r
1367 for (Int_t iClust=0; iClust<esd.GetNumberOfCaloClusters(); ++iClust) {
\r
1369 AliESDCaloCluster * cluster = esd.GetCaloCluster(iClust);
\r
1371 Int_t id = cluster->GetID();
\r
1372 Int_t nLabel = cluster->GetNLabels();
\r
1373 Int_t *labels = cluster->GetLabels();
\r
1375 for(int i = 0;i < nLabel;++i){
\r
1376 if(fMChandler)fMChandler->SelectParticle(labels[i]);
\r
1380 Float_t energy = cluster->E();
\r
1381 Float_t posF[3] = { 0.};
\r
1382 cluster->GetPosition(posF);
\r
1384 AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
\r
1390 cluster->GetType(),0);
\r
1392 caloCluster->SetCaloCluster(cluster->GetDistanceToBadChannel(),
\r
1393 cluster->GetDispersion(),
\r
1394 cluster->GetM20(), cluster->GetM02(),
\r
1395 cluster->GetEmcCpvDistance(),
\r
1396 cluster->GetNExMax(),cluster->GetTOF()) ;
\r
1398 caloCluster->SetPIDFromESD(cluster->GetPID());
\r
1399 caloCluster->SetNCells(cluster->GetNCells());
\r
1400 caloCluster->SetCellsAbsId(cluster->GetCellsAbsId());
\r
1401 caloCluster->SetCellsAmplitudeFraction(cluster->GetCellsAmplitudeFraction());
\r
1403 TArrayI* matchedT = cluster->GetTracksMatched();
\r
1404 if (fNumberOfTracks>0 && matchedT && cluster->GetTrackMatchedIndex() >= 0) {
\r
1405 for (Int_t im = 0; im < matchedT->GetSize(); im++) {
\r
1406 Int_t iESDtrack = matchedT->At(im);;
\r
1407 if (fAODTrackRefs->At(iESDtrack) != 0) {
\r
1408 caloCluster->AddTrackMatched((AliAODTrack*)fAODTrackRefs->At(iESDtrack));
\r
1414 caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters
\r
1417 //______________________________________________________________________________
\r
1418 void AliAnalysisTaskESDfilter::ConvertEMCALCells(const AliESDEvent& esd)
\r
1420 // Convert EMCAL Cells
\r
1421 AliCodeTimerAuto("",0);
\r
1422 // fill EMCAL cell info
\r
1423 if (esd.GetEMCALCells()) { // protection against missing ESD information
\r
1424 AliESDCaloCells &esdEMcells = *(esd.GetEMCALCells());
\r
1425 Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
\r
1427 AliAODCaloCells &aodEMcells = *(AODEvent()->GetEMCALCells());
\r
1428 aodEMcells.CreateContainer(nEMcell);
\r
1429 aodEMcells.SetType(AliAODCaloCells::kEMCALCell);
\r
1430 for (Int_t iCell = 0; iCell < nEMcell; iCell++) {
\r
1431 aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell));
\r
1433 aodEMcells.Sort();
\r
1437 //______________________________________________________________________________
\r
1438 void AliAnalysisTaskESDfilter::ConvertPHOSCells(const AliESDEvent& esd)
\r
1440 // Convert PHOS Cells
\r
1441 AliCodeTimerAuto("",0);
\r
1442 // fill PHOS cell info
\r
1443 if (esd.GetPHOSCells()) { // protection against missing ESD information
\r
1444 AliESDCaloCells &esdPHcells = *(esd.GetPHOSCells());
\r
1445 Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
\r
1447 AliAODCaloCells &aodPHcells = *(AODEvent()->GetPHOSCells());
\r
1448 aodPHcells.CreateContainer(nPHcell);
\r
1449 aodPHcells.SetType(AliAODCaloCells::kPHOSCell);
\r
1450 for (Int_t iCell = 0; iCell < nPHcell; iCell++) {
\r
1451 aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell));
\r
1453 aodPHcells.Sort();
\r
1457 //______________________________________________________________________________
\r
1458 void AliAnalysisTaskESDfilter::ConvertTracklets(const AliESDEvent& esd)
\r
1461 AliCodeTimerAuto("",0);
\r
1463 AliAODTracklets &SPDTracklets = *(AODEvent()->GetTracklets());
\r
1464 const AliMultiplicity *mult = esd.GetMultiplicity();
\r
1466 if (mult->GetNumberOfTracklets()>0) {
\r
1467 SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
\r
1469 for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
\r
1471 fMChandler->SelectParticle(mult->GetLabel(n, 0));
\r
1472 fMChandler->SelectParticle(mult->GetLabel(n, 1));
\r
1474 SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n, 0),mult->GetLabel(n, 1));
\r
1478 //Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
\r
1482 //______________________________________________________________________________
\r
1483 void AliAnalysisTaskESDfilter::ConvertKinks(const AliESDEvent& esd)
\r
1485 AliCodeTimerAuto("",0);
\r
1487 // Kinks: it is a big mess the access to the information in the kinks
\r
1488 // The loop is on the tracks in order to find the mother and daugther of each kink
\r
1490 Double_t covTr[21]={0.};
\r
1491 Double_t pid[10]={0.};
\r
1492 AliAODPid* detpid(0x0);
\r
1494 fNumberOfKinks = esd.GetNumberOfKinks();
\r
1496 const AliESDVertex* vtx = esd.GetPrimaryVertex();
\r
1498 for (Int_t iTrack=0; iTrack<esd.GetNumberOfTracks(); ++iTrack)
\r
1500 AliESDtrack * esdTrack = esd.GetTrack(iTrack);
\r
1502 Int_t ikink = esdTrack->GetKinkIndex(0);
\r
1504 if (ikink && fNumberOfKinks) {
\r
1505 // Negative kink index: mother, positive: daughter
\r
1507 // Search for the second track of the kink
\r
1509 for (Int_t jTrack = iTrack+1; jTrack<esd.GetNumberOfTracks(); ++jTrack) {
\r
1511 AliESDtrack * esdTrack1 = esd.GetTrack(jTrack);
\r
1513 Int_t jkink = esdTrack1->GetKinkIndex(0);
\r
1515 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
\r
1517 // The two tracks are from the same kink
\r
1519 if (fUsedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
\r
1521 Int_t imother = -1;
\r
1522 Int_t idaughter = -1;
\r
1524 if (ikink<0 && jkink>0) {
\r
1527 idaughter = jTrack;
\r
1529 else if (ikink>0 && jkink<0) {
\r
1532 idaughter = iTrack;
\r
1535 // cerr << "Error: Wrong combination of kink indexes: "
\r
1536 // << ikink << " " << jkink << endl;
\r
1540 // Add the mother track if it passed primary track selection cuts
\r
1542 AliAODTrack * mother = NULL;
\r
1544 UInt_t selectInfo = 0;
\r
1545 if (fTrackFilter) {
\r
1546 selectInfo = fTrackFilter->IsSelected(esd.GetTrack(imother));
\r
1547 if (!selectInfo) continue;
\r
1550 if (!fUsedTrack[imother]) {
\r
1552 fUsedTrack[imother] = kTRUE;
\r
1554 AliESDtrack *esdTrackM = esd.GetTrack(imother);
\r
1555 Double_t p[3] = { 0. };
\r
1556 Double_t pos[3] = { 0. };
\r
1557 esdTrackM->GetPxPyPz(p);
\r
1558 esdTrackM->GetXYZ(pos);
\r
1559 esdTrackM->GetCovarianceXYZPxPyPz(covTr);
\r
1560 esdTrackM->GetESDpid(pid);
\r
1561 if(fMChandler)fMChandler->SelectParticle(esdTrackM->GetLabel());
\r
1563 new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrackM->GetID(),
\r
1564 esdTrackM->GetLabel(),
\r
1570 (Short_t)esdTrackM->GetSign(),
\r
1571 esdTrackM->GetITSClusterMap(),
\r
1574 kTRUE, // check if this is right
\r
1575 vtx->UsesTrack(esdTrack->GetID()),
\r
1576 AliAODTrack::kPrimary,
\r
1578 mother->SetTPCClusterMap(esdTrackM->GetTPCClusterMap());
\r
1579 mother->SetTPCSharedMap (esdTrackM->GetTPCSharedMap());
\r
1580 mother->SetChi2perNDF(Chi2perNDF(esdTrackM));
\r
1581 mother->SetTPCPointsF(esdTrackM->GetTPCNclsF());
\r
1583 fAODTrackRefs->AddAt(mother, imother);
\r
1585 if (esdTrackM->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
1586 mother->SetFlags(esdTrackM->GetStatus());
\r
1587 mother->ConvertAliPIDtoAODPID();
\r
1588 fPrimaryVertex->AddDaughter(mother);
\r
1589 mother->ConvertAliPIDtoAODPID();
\r
1590 SetAODPID(esdTrackM,mother,detpid);
\r
1593 // cerr << "Error: event " << esd.GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
\r
1594 // << " track " << imother << " has already been used!" << endl;
\r
1597 // Add the kink vertex
\r
1598 AliESDkink * kink = esd.GetKink(TMath::Abs(ikink)-1);
\r
1600 AliAODVertex * vkink =
\r
1601 new(Vertices()[fNumberOfVertices++]) AliAODVertex(kink->GetPosition(),
\r
1605 esdTrack->GetID(), // This is the track ID of the mother's track!
\r
1606 AliAODVertex::kKink);
\r
1607 // Add the daughter track
\r
1609 AliAODTrack * daughter = NULL;
\r
1611 if (!fUsedTrack[idaughter]) {
\r
1613 fUsedTrack[idaughter] = kTRUE;
\r
1615 AliESDtrack *esdTrackD = esd.GetTrack(idaughter);
\r
1616 Double_t p[3] = { 0. };
\r
1617 Double_t pos[3] = { 0. };
\r
1619 esdTrackD->GetPxPyPz(p);
\r
1620 esdTrackD->GetXYZ(pos);
\r
1621 esdTrackD->GetCovarianceXYZPxPyPz(covTr);
\r
1622 esdTrackD->GetESDpid(pid);
\r
1624 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdTrackD);
\r
1625 if(fMChandler)fMChandler->SelectParticle(esdTrackD->GetLabel());
\r
1627 new(Tracks()[fNumberOfTracks++]) AliAODTrack(esdTrackD->GetID(),
\r
1628 esdTrackD->GetLabel(),
\r
1634 (Short_t)esdTrackD->GetSign(),
\r
1635 esdTrackD->GetITSClusterMap(),
\r
1638 kTRUE, // check if this is right
\r
1639 vtx->UsesTrack(esdTrack->GetID()),
\r
1640 AliAODTrack::kSecondary,
\r
1642 daughter->SetTPCClusterMap(esdTrackD->GetTPCClusterMap());
\r
1643 daughter->SetTPCSharedMap (esdTrackD->GetTPCSharedMap());
\r
1644 daughter->SetTPCPointsF(esdTrackD->GetTPCNclsF());
\r
1645 fAODTrackRefs->AddAt(daughter, idaughter);
\r
1647 if (esdTrackD->GetSign() > 0) ++fNumberOfPositiveTracks;
\r
1648 daughter->SetFlags(esdTrackD->GetStatus());
\r
1649 daughter->ConvertAliPIDtoAODPID();
\r
1650 vkink->AddDaughter(daughter);
\r
1651 daughter->ConvertAliPIDtoAODPID();
\r
1652 SetAODPID(esdTrackD,daughter,detpid);
\r
1655 // cerr << "Error: event " << esd.GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
\r
1656 // << " track " << idaughter << " has already been used!" << endl;
\r
1664 //______________________________________________________________________________
\r
1665 void AliAnalysisTaskESDfilter::ConvertPrimaryVertices(const AliESDEvent& esd)
\r
1667 AliCodeTimerAuto("",0);
\r
1669 // Access to the AOD container of vertices
\r
1670 fNumberOfVertices = 0;
\r
1672 Double_t pos[3] = { 0. };
\r
1673 Double_t covVtx[6] = { 0. };
\r
1675 // Add primary vertex. The primary tracks will be defined
\r
1676 // after the loops on the composite objects (V0, cascades, kinks)
\r
1677 const AliESDVertex *vtx = esd.GetPrimaryVertex();
\r
1679 vtx->GetXYZ(pos); // position
\r
1680 vtx->GetCovMatrix(covVtx); //covariance matrix
\r
1682 fPrimaryVertex = new(Vertices()[fNumberOfVertices++])
\r
1683 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
\r
1684 fPrimaryVertex->SetName(vtx->GetName());
\r
1685 fPrimaryVertex->SetTitle(vtx->GetTitle());
\r
1687 TString vtitle = vtx->GetTitle();
\r
1688 if (!vtitle.Contains("VertexerTracks"))
\r
1689 fPrimaryVertex->SetNContributors(vtx->GetNContributors());
\r
1691 if (fDebug > 0) fPrimaryVertex->Print();
\r
1693 // Add SPD "main" vertex
\r
1694 const AliESDVertex *vtxS = esd.GetPrimaryVertexSPD();
\r
1695 vtxS->GetXYZ(pos); // position
\r
1696 vtxS->GetCovMatrix(covVtx); //covariance matrix
\r
1697 AliAODVertex * mVSPD = new(Vertices()[fNumberOfVertices++])
\r
1698 AliAODVertex(pos, covVtx, vtxS->GetChi2toNDF(), NULL, -1, AliAODVertex::kMainSPD);
\r
1699 mVSPD->SetName(vtxS->GetName());
\r
1700 mVSPD->SetTitle(vtxS->GetTitle());
\r
1701 mVSPD->SetNContributors(vtxS->GetNContributors());
\r
1703 // Add SPD pileup vertices
\r
1704 for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesSPD(); ++iV)
\r
1706 const AliESDVertex *vtxP = esd.GetPileupVertexSPD(iV);
\r
1707 vtxP->GetXYZ(pos); // position
\r
1708 vtxP->GetCovMatrix(covVtx); //covariance matrix
\r
1709 AliAODVertex * pVSPD = new(Vertices()[fNumberOfVertices++])
\r
1710 AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupSPD);
\r
1711 pVSPD->SetName(vtxP->GetName());
\r
1712 pVSPD->SetTitle(vtxP->GetTitle());
\r
1713 pVSPD->SetNContributors(vtxP->GetNContributors());
\r
1714 pVSPD->SetBC(vtxP->GetBC());
\r
1717 // Add TRK pileup vertices
\r
1718 for(Int_t iV=0; iV<esd.GetNumberOfPileupVerticesTracks(); ++iV)
\r
1720 const AliESDVertex *vtxP = esd.GetPileupVertexTracks(iV);
\r
1721 vtxP->GetXYZ(pos); // position
\r
1722 vtxP->GetCovMatrix(covVtx); //covariance matrix
\r
1723 AliAODVertex * pVTRK = new(Vertices()[fNumberOfVertices++])
\r
1724 AliAODVertex(pos, covVtx, vtxP->GetChi2toNDF(), NULL, -1, AliAODVertex::kPileupTracks);
\r
1725 pVTRK->SetName(vtxP->GetName());
\r
1726 pVTRK->SetTitle(vtxP->GetTitle());
\r
1727 pVTRK->SetNContributors(vtxP->GetNContributors());
\r
1728 pVTRK->SetBC(vtxP->GetBC());
\r
1732 //______________________________________________________________________________
\r
1733 void AliAnalysisTaskESDfilter::ConvertVZERO(const AliESDEvent& esd)
\r
1735 // Convert VZERO data
\r
1736 AliAODVZERO* vzeroData = AODEvent()->GetVZEROData();
\r
1737 *vzeroData = *(esd.GetVZEROData());
\r
1740 //______________________________________________________________________________
\r
1741 void AliAnalysisTaskESDfilter::ConvertTZERO(const AliESDEvent& esd)
\r
1743 // Convert TZERO data
\r
1744 const AliESDTZERO* esdTzero = esd.GetESDTZERO();
\r
1745 AliAODTZERO* aodTzero = AODEvent()->GetTZEROData();
\r
1747 for (Int_t icase=0; icase<3; icase++){
\r
1748 aodTzero->SetT0TOF( icase, esdTzero->GetT0TOF(icase));
\r
1749 aodTzero->SetT0TOFbest(icase, esdTzero->GetT0TOFbest(icase));
\r
1751 aodTzero->SetBackgroundFlag(esdTzero->GetBackgroundFlag());
\r
1752 aodTzero->SetPileupFlag(esdTzero->GetPileupFlag());
\r
1753 aodTzero->SetSatelliteFlag(esdTzero->GetSatellite());
\r
1758 //______________________________________________________________________________
\r
1759 void AliAnalysisTaskESDfilter::ConvertZDC(const AliESDEvent& esd)
\r
1761 // Convert ZDC data
\r
1762 AliESDZDC* esdZDC = esd.GetZDCData();
\r
1764 const Double_t zem1Energy = esdZDC->GetZEM1Energy();
\r
1765 const Double_t zem2Energy = esdZDC->GetZEM2Energy();
\r
1767 const Double_t *towZNC = esdZDC->GetZNCTowerEnergy();
\r
1768 const Double_t *towZPC = esdZDC->GetZPCTowerEnergy();
\r
1769 const Double_t *towZNA = esdZDC->GetZNATowerEnergy();
\r
1770 const Double_t *towZPA = esdZDC->GetZPATowerEnergy();
\r
1771 const Double_t *towZNCLG = esdZDC->GetZNCTowerEnergyLR();
\r
1772 const Double_t *towZNALG = esdZDC->GetZNATowerEnergyLR();
\r
1774 AliAODZDC* zdcAOD = AODEvent()->GetZDCData();
\r
1776 zdcAOD->SetZEM1Energy(zem1Energy);
\r
1777 zdcAOD->SetZEM2Energy(zem2Energy);
\r
1778 zdcAOD->SetZNCTowers(towZNC, towZNCLG);
\r
1779 zdcAOD->SetZNATowers(towZNA, towZNALG);
\r
1780 zdcAOD->SetZPCTowers(towZPC);
\r
1781 zdcAOD->SetZPATowers(towZPA);
\r
1783 zdcAOD->SetZDCParticipants(esdZDC->GetZDCParticipants(), esdZDC->GetZDCPartSideA(), esdZDC->GetZDCPartSideC());
\r
1784 zdcAOD->SetZDCImpactParameter(esdZDC->GetImpactParameter(), esdZDC->GetImpactParamSideA(),
\r
1785 esdZDC->GetImpactParamSideC());
\r
1786 zdcAOD->SetZDCTDCSum(esdZDC->GetZNTDCSum(0));
\r
1787 zdcAOD->SetZDCTDCDiff(esdZDC->GetZNTDCDiff(0));
\r
1791 //______________________________________________________________________________
\r
1792 void AliAnalysisTaskESDfilter::ConvertESDtoAOD()
\r
1794 // ESD Filter analysis task executed for each event
\r
1796 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
\r
1800 AliCodeTimerAuto("",0);
\r
1802 fOldESDformat = ( esd->GetAliESDOld() != 0x0 );
\r
1804 fNumberOfTracks = 0;
\r
1805 fNumberOfPositiveTracks = 0;
\r
1807 fNumberOfVertices = 0;
\r
1808 fNumberOfCascades = 0;
\r
1809 fNumberOfKinks = 0;
\r
1811 AliAODHeader* header = ConvertHeader(*esd);
\r
1813 if ( fIsVZEROEnabled ) ConvertVZERO(*esd);
\r
1814 if ( fIsTZEROEnabled ) ConvertTZERO(*esd);
\r
1816 // Fetch Stack for debuggging if available
\r
1820 fMChandler = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler());
\r
1823 // loop over events and fill them
\r
1824 // Multiplicity information needed by the header (to be revised!)
\r
1825 Int_t nTracks = esd->GetNumberOfTracks();
\r
1826 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) esd->GetTrack(iTrack)->SetESDEvent(esd);
\r
1828 // Update the header
\r
1830 Int_t nV0s = esd->GetNumberOfV0s();
\r
1831 Int_t nCascades = esd->GetNumberOfCascades();
\r
1832 Int_t nKinks = esd->GetNumberOfKinks();
\r
1833 Int_t nVertices = nV0s + nCascades /*V0 wihtin cascade already counted*/+ nKinks + 1 /* = prim. vtx*/;
\r
1834 Int_t nPileSPDVertices=1+esd->GetNumberOfPileupVerticesSPD(); // also SPD main vertex
\r
1835 Int_t nPileTrkVertices=esd->GetNumberOfPileupVerticesTracks();
\r
1836 nVertices+=nPileSPDVertices;
\r
1837 nVertices+=nPileTrkVertices;
\r
1839 Int_t nCaloClus = esd->GetNumberOfCaloClusters();
\r
1840 Int_t nFmdClus = 0;
\r
1841 Int_t nPmdClus = esd->GetNumberOfPmdTracks();
\r
1843 AliDebug(1,Form(" NV0=%d NCASCADES=%d NKINKS=%d", nV0s, nCascades, nKinks));
\r
1845 AODEvent()->ResetStd(nTracks, nVertices, nV0s, nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
\r
1849 // RefArray to store a mapping between esd V0 number and newly created AOD-Vertex V0
\r
1850 fAODV0VtxRefs = new TRefArray(nV0s);
\r
1851 // RefArray to store the mapping between esd V0 number and newly created AOD-V0
\r
1852 fAODV0Refs = new TRefArray(nV0s);
\r
1853 // Array to take into account the V0s already added to the AOD (V0 within cascades)
\r
1854 fUsedV0 = new Bool_t[nV0s];
\r
1855 for (Int_t iV0=0; iV0<nV0s; ++iV0) fUsedV0[iV0]=kFALSE;
\r
1860 // RefArray to store the mapping between esd track number and newly created AOD-Track
\r
1862 fAODTrackRefs = new TRefArray(nTracks);
\r
1864 // Array to take into account the tracks already added to the AOD
\r
1865 fUsedTrack = new Bool_t[nTracks];
\r
1866 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) fUsedTrack[iTrack]=kFALSE;
\r
1869 // Array to take into account the kinks already added to the AOD
\r
1872 fUsedKink = new Bool_t[nKinks];
\r
1873 for (Int_t iKink=0; iKink<nKinks; ++iKink) fUsedKink[iKink]=kFALSE;
\r
1876 ConvertPrimaryVertices(*esd);
\r
1878 //setting best TOF PID
\r
1879 AliESDInputHandler* esdH = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
\r
1881 fESDpid = esdH->GetESDpid();
\r
1883 if (fIsPidOwner && fESDpid){
\r
1888 { //in case of no Tender attached
\r
1889 fESDpid = new AliESDpid;
\r
1890 fIsPidOwner = kTRUE;
\r
1893 if(!esd->GetTOFHeader())
\r
1894 { //protection in case the pass2 LHC10b,c,d have been processed without tender.
\r
1895 Float_t t0spread[10];
\r
1896 Float_t intrinsicTOFres=100; //ps ok for LHC10b,c,d pass2!!
\r
1897 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
1898 fESDpid->GetTOFResponse().SetT0resolution(t0spread);
\r
1899 fESDpid->GetTOFResponse().SetTimeResolution(intrinsicTOFres);
\r
1901 fESDpid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType);
\r
1904 if(esd->GetTOFHeader() && fIsPidOwner) fESDpid->SetTOFResponse(esd, (AliESDpid::EStartTimeType_t)fTimeZeroType); //in case of AOD production strating form LHC10e without Tender.
\r
1906 if ( fAreCascadesEnabled ) ConvertCascades(*esd);
\r
1908 if ( fAreV0sEnabled ) ConvertV0s(*esd);
\r
1910 if ( fAreKinksEnabled ) ConvertKinks(*esd);
\r
1912 if ( fAreTracksEnabled ) ConvertTracks(*esd);
\r
1914 // Update number of AOD tracks in header at the end of track loop (M.G.)
\r
1915 header->SetRefMultiplicity(fNumberOfTracks);
\r
1916 header->SetRefMultiplicityPos(fNumberOfPositiveTracks);
\r
1917 header->SetRefMultiplicityNeg(fNumberOfTracks - fNumberOfPositiveTracks);
\r
1919 if ( fTPCConstrainedFilterMask ) ConvertTPCOnlyTracks(*esd);
\r
1920 if( fGlobalConstrainedFilterMask) ConvertGlobalConstrainedTracks(*esd);
\r
1922 if ( fArePmdClustersEnabled ) ConvertPmdClusters(*esd);
\r
1924 if ( fAreCaloClustersEnabled ) ConvertCaloClusters(*esd);
\r
1926 if ( fAreEMCALCellsEnabled )ConvertEMCALCells(*esd);
\r
1928 if ( fArePHOSCellsEnabled )ConvertPHOSCells(*esd);
\r
1930 if ( fAreTrackletsEnabled ) ConvertTracklets(*esd);
\r
1932 delete fAODTrackRefs; fAODTrackRefs=0x0;
\r
1933 delete fAODV0VtxRefs; fAODV0VtxRefs=0x0;
\r
1934 delete fAODV0Refs; fAODV0Refs=0x0;
\r
1936 delete[] fUsedTrack; fUsedTrack=0x0;
\r
1937 delete[] fUsedV0; fUsedV0=0x0;
\r
1938 delete[] fUsedKink; fUsedKink=0x0;
\r
1940 if ( fIsPidOwner){
\r
1949 //______________________________________________________________________________
\r
1950 void AliAnalysisTaskESDfilter::SetAODPID(AliESDtrack *esdtrack, AliAODTrack *aodtrack, AliAODPid *detpid)
\r
1953 // Setter for the raw PID detector signals
\r
1956 // Save PID object for candidate electrons
\r
1957 Bool_t pidSave = kFALSE;
\r
1958 if (fTrackFilter) {
\r
1959 Bool_t selectInfo = fTrackFilter->IsSelected((char*) "Electrons");
\r
1960 if (selectInfo) pidSave = kTRUE;
\r
1964 // Tracks passing pt cut
\r
1965 if(esdtrack->Pt()>fHighPthreshold) {
\r
1969 if(esdtrack->Pt()> fPtshape->GetXmin()){
\r
1970 Double_t y = fPtshape->Eval(esdtrack->Pt())/fPtshape->Eval(fHighPthreshold);
\r
1971 if(gRandom->Rndm(0)<1./y){
\r
1974 }//end if p < pmin
\r
1975 }//end if p function
\r
1979 if(!aodtrack->GetDetPid()){// prevent memory leak when calling SetAODPID twice for the same track
\r
1980 detpid = new AliAODPid();
\r
1981 SetDetectorRawSignals(detpid,esdtrack);
\r
1982 aodtrack->SetDetPID(detpid);
\r
1987 //______________________________________________________________________________
\r
1988 void AliAnalysisTaskESDfilter::SetDetectorRawSignals(AliAODPid *aodpid, AliESDtrack *track)
\r
1991 //assignment of the detector signals (AliXXXesdPID inspired)
\r
1994 AliInfo("no ESD track found. .....exiting");
\r
1998 const AliExternalTrackParam *in=track->GetInnerParam();
\r
2000 aodpid->SetTPCmomentum(in->GetP());
\r
2002 aodpid->SetTPCmomentum(-1.);
\r
2006 aodpid->SetITSsignal(track->GetITSsignal());
\r
2007 Double_t itsdedx[4]; // dE/dx samples for individual ITS layers
\r
2008 track->GetITSdEdxSamples(itsdedx);
\r
2009 aodpid->SetITSdEdxSamples(itsdedx);
\r
2011 aodpid->SetTPCsignal(track->GetTPCsignal());
\r
2012 aodpid->SetTPCsignalN(track->GetTPCsignalN());
\r
2014 //n TRD planes = 6
\r
2015 Int_t nslices = track->GetNumberOfTRDslices()*6;
\r
2016 TArrayD trdslices(nslices);
\r
2017 for(Int_t iSl =0; iSl < track->GetNumberOfTRDslices(); iSl++) {
\r
2018 for(Int_t iPl =0; iPl<6; iPl++) trdslices[iPl*track->GetNumberOfTRDslices()+iSl] = track->GetTRDslice(iPl,iSl);
\r
2022 for(Int_t iPl=0;iPl<6;iPl++){
\r
2023 Double_t trdmom=track->GetTRDmomentum(iPl);
\r
2024 aodpid->SetTRDmomentum(iPl,trdmom);
\r
2027 aodpid->SetTRDsignal(track->GetNumberOfTRDslices()*6,trdslices.GetArray());
\r
2029 //TRD clusters and tracklets
\r
2030 aodpid->SetTRDncls(track->GetTRDncls());
\r
2031 aodpid->SetTRDntrackletsPID(track->GetTRDntrackletsPID());
\r
2034 Double_t times[AliAODPid::kSPECIES]; track->GetIntegratedTimes(times);
\r
2035 aodpid->SetIntegratedTimes(times);
\r
2037 Float_t tzeroTrack = fESDpid->GetTOFResponse().GetStartTime(track->P());
\r
2038 aodpid->SetTOFsignal(track->GetTOFsignal()-tzeroTrack);
\r
2040 Double_t tofRes[5];
\r
2041 for (Int_t iMass=0; iMass<5; iMass++){
\r
2042 tofRes[iMass]=(Double_t)fESDpid->GetTOFResponse().GetExpectedSigma(track->P(), times[iMass], AliPID::ParticleMass(iMass));
\r
2044 aodpid->SetTOFpidResolution(tofRes);
\r
2046 aodpid->SetHMPIDsignal(track->GetHMPIDsignal());
\r
2048 //Extrapolate track to EMCAL surface for AOD-level track-cluster matching
\r
2049 Double_t emcpos[3] = {0.,0.,0.};
\r
2050 Double_t emcmom[3] = {0.,0.,0.};
\r
2051 aodpid->SetEMCALPosition(emcpos);
\r
2052 aodpid->SetEMCALMomentum(emcmom);
\r
2054 Double_t hmpPid[5] = {0};
\r
2055 track->GetHMPIDpid(hmpPid);
\r
2056 aodpid->SetHMPIDprobs(hmpPid);
\r
2058 AliExternalTrackParam *outerparam = (AliExternalTrackParam*)track->GetOuterParam();
\r
2059 if(!outerparam) return;
\r
2061 //To be replaced by call to AliEMCALGeoUtils when the class becomes available
\r
2062 Bool_t okpos = outerparam->GetXYZ(emcpos);
\r
2063 Bool_t okmom = outerparam->GetPxPyPz(emcmom);
\r
2064 if(!(okpos && okmom)) return;
\r
2066 aodpid->SetEMCALPosition(emcpos);
\r
2067 aodpid->SetEMCALMomentum(emcmom);
\r
2071 Double_t AliAnalysisTaskESDfilter::Chi2perNDF(AliESDtrack* track)
\r
2073 // Calculate chi2 per ndf for track
\r
2074 Int_t nClustersTPC = track->GetTPCNcls();
\r
2076 if ( nClustersTPC > 5) {
\r
2077 return (track->GetTPCchi2()/Float_t(nClustersTPC - 5));
\r
2084 //______________________________________________________________________________
\r
2085 void AliAnalysisTaskESDfilter::Terminate(Option_t */*option*/)
\r
2087 // Terminate analysis
\r
2089 if (fDebug > 1) printf("AnalysisESDfilter: Terminate() \n");
\r
2092 //______________________________________________________________________________
\r
2093 void AliAnalysisTaskESDfilter::PrintMCInfo(AliStack *pStack,Int_t label){
\r
2095 if(!pStack)return;
\r
2096 label = TMath::Abs(label);
\r
2097 TParticle *part = pStack->Particle(label);
\r
2098 Printf("########################");
\r
2099 Printf("%s:%d %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,label,part->GetUniqueID(),part->GetPdgCode(),part->P());
\r
2101 TParticle* mother = part;
\r
2102 Int_t imo = part->GetFirstMother();
\r
2103 Int_t nprim = pStack->GetNprimary();
\r
2104 // while((imo >= nprim) && (mother->GetUniqueID() == 4)) {
\r
2105 while((imo >= nprim)) {
\r
2106 mother = pStack->Particle(imo);
\r
2107 Printf("Mother %s:%d Label %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,imo,mother->GetUniqueID(),mother->GetPdgCode(),mother->P());
\r
2109 imo = mother->GetFirstMother();
\r
2111 Printf("########################");
\r