1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
21 #include "AliAnalysisTaskESDfilter.h"
22 #include "AliAnalysisManager.h"
23 #include "AliESDEvent.h"
24 #include "AliAODEvent.h"
25 #include "AliAODHandler.h"
26 #include "AliAnalysisFilter.h"
27 #include "AliESDtrack.h"
28 #include "AliESDMuonTrack.h"
29 #include "AliESDVertex.h"
31 #include "AliESDkink.h"
32 #include "AliESDcascade.h"
35 ClassImp(AliAnalysisTaskESDfilter)
37 ////////////////////////////////////////////////////////////////////////
39 AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter():
49 // Default constructor
52 AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter(const char* name):
53 AliAnalysisTask(name, "AnalysisTaskESDfilter"),
63 // Default constructor
64 DefineInput (0, TChain::Class());
65 DefineOutput(0, TTree::Class());
68 void AliAnalysisTaskESDfilter::CreateOutputObjects()
70 // Create the output container
71 if (fDebug > 1) AliInfo("CreateOutPutData() \n");
72 AliAODHandler* handler = (AliAODHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler());
74 fAOD = handler->GetAOD();
75 fTreeA = handler->GetTree();
76 fTreeA->GetUserInfo()->Add(fTrackFilter);
79 void AliAnalysisTaskESDfilter::Init()
82 if (fDebug > 1) AliInfo("Init() \n");
83 // Call configuration file
86 void AliAnalysisTaskESDfilter::ConnectInputData(Option_t */*option*/)
88 // Connect the input data
90 if (fDebug > 1) AliInfo("ConnectInputData() \n");
91 fChain = (TChain*)GetInputData(0);
92 fESD = new AliESDEvent();
93 fESD->ReadFromTree(fChain);
96 void AliAnalysisTaskESDfilter::Exec(Option_t */*option*/)
98 // Execute analysis for current event
100 AliESD* old = fESD->GetAliESDOld();
101 if (old) fESD->CopyFromOldESD();
103 Long64_t ientry = fChain->GetReadEntry();
104 AliInfo(Form("ESD Filter: Analysing event # %5d\n", (Int_t) ientry));
107 // ESD Filter analysis task executed for each event
109 // set arrays and pointers
116 for (Int_t i = 0; i < 6; i++) covVtx[i] = 0.;
117 for (Int_t i = 0; i < 21; i++) covTr [i] = 0.;
120 // loop over events and fill them
122 // Multiplicity information needed by the header (to be revised!)
123 Int_t nTracks = fESD->GetNumberOfTracks();
124 Int_t nPosTracks = 0;
125 for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack)
126 if (fESD->GetTrack(iTrack)->GetSign()> 0) nPosTracks++;
130 AliAODHeader* header = fAOD->GetHeader();
131 header->SetRunNumber(fESD->GetRunNumber());
133 header->SetBunchCrossNumber(0);
134 header->SetOrbitNumber(0);
135 header->SetPeriodNumber(0);
136 header->SetEventType(0);
137 header->SetMuonMagFieldScale(-999.);
138 header->SetCentrality(-999.);
140 header->SetBunchCrossNumber(fESD->GetBunchCrossNumber());
141 header->SetOrbitNumber(fESD->GetOrbitNumber());
142 header->SetPeriodNumber(fESD->GetPeriodNumber());
143 header->SetEventType(fESD->GetEventType());
144 header->SetMuonMagFieldScale(-999.);
145 header->SetCentrality(-999.);
148 header->SetTriggerMask(fESD->GetTriggerMask());
149 header->SetTriggerCluster(fESD->GetTriggerCluster());
150 header->SetMagneticField(fESD->GetMagneticField());
151 header->SetZDCN1Energy(fESD->GetZDCN1Energy());
152 header->SetZDCP1Energy(fESD->GetZDCP1Energy());
153 header->SetZDCN2Energy(fESD->GetZDCN2Energy());
154 header->SetZDCP2Energy(fESD->GetZDCP2Energy());
155 header->SetZDCEMEnergy(fESD->GetZDCEMEnergy(0),fESD->GetZDCEMEnergy(1));
156 header->SetRefMultiplicity(nTracks);
157 header->SetRefMultiplicityPos(nPosTracks);
158 header->SetRefMultiplicityNeg(nTracks - nPosTracks);
161 Int_t nV0s = fESD->GetNumberOfV0s();
162 Int_t nCascades = fESD->GetNumberOfCascades();
163 Int_t nKinks = fESD->GetNumberOfKinks();
165 printf(" NV0=%d NCASCADES=%d NKINKS=%d\n", nV0s, nCascades, nKinks);
167 Int_t nVertices = nV0s + nCascades + nKinks;
169 fAOD->ResetStd(nTracks, nVertices);
170 AliAODTrack *aodTrack;
173 // Array to take into account the tracks already added to the AOD
174 Bool_t * usedTrack = NULL;
176 usedTrack = new Bool_t[nTracks];
177 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
179 // Array to take into account the V0s already added to the AOD
180 Bool_t * usedV0 = NULL;
182 usedV0 = new Bool_t[nV0s];
183 for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
185 // Array to take into account the kinks already added to the AOD
186 Bool_t * usedKink = NULL;
188 usedKink = new Bool_t[nKinks];
189 for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
192 // Access to the AOD container of vertices
193 TClonesArray &vertices = *(fAOD->GetVertices());
196 // Access to the AOD container of tracks
197 TClonesArray &tracks = *(fAOD->GetTracks());
200 // Add primary vertex. The primary tracks will be defined
201 // after the loops on the composite objects (V0, cascades, kinks)
202 const AliESDVertex *vtx = fESD->GetPrimaryVertex();
204 vtx->GetXYZ(pos); // position
205 vtx->GetCovMatrix(covVtx); //covariance matrix
207 AliAODVertex * primary = new(vertices[jVertices++])
208 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, AliAODVertex::kPrimary);
212 // Create vertices starting from the most complex objects
216 for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
217 AliESDcascade *cascade = fESD->GetCascade(nCascade);
219 cascade->GetXYZ(pos[0], pos[1], pos[2]);
222 chi2 = vtx->GetChi2toNDF();
223 cascade->GetPosCovXi(covVtx);
227 // Add the cascade vertex
228 AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
230 chi2, // = chi2/NDF since NDF = 2*2-3 (AM)
232 AliAODVertex::kCascade);
234 primary->AddDaughter(vcascade);
236 // Add the V0 from the cascade. The ESD class have to be optimized...
237 // Now we have to search for the corresponding Vo in the list of V0s
238 // using the indeces of the positive and negative tracks
240 Int_t posFromV0 = cascade->GetPindex();
241 Int_t negFromV0 = cascade->GetNindex();
247 for (Int_t iV0=0; iV0<nV0s; ++iV0) {
249 v0 = fESD->GetV0(iV0);
250 Int_t posV0 = v0->GetPindex();
251 Int_t negV0 = v0->GetNindex();
253 if (posV0==posFromV0 && negV0==negFromV0) {
259 AliAODVertex * vV0FromCascade = 0x0;
261 if (indV0>-1 && !usedV0[indV0] ) {
263 // the V0 exists in the array of V0s and is not used
265 usedV0[indV0] = kTRUE;
267 v0->GetXYZ(pos[0], pos[1], pos[2]);
269 chi2 = v0->GetChi2V0();
270 v0->GetPosCov(covVtx);
275 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
277 chi2, // = chi2/NDF since NDF = 2*2-3 (AM)
282 // the V0 doesn't exist in the array of V0s or was used
283 // cerr << "Error: event " << fESD->GetEventNumberInFile() << " cascade " << nCascade
284 // << " The V0 " << indV0
285 // << " doesn't exist in the array of V0s or was used!" << endl;
287 cascade->GetXYZ(pos[0], pos[1], pos[2]);
290 chi2 = v0->GetChi2V0();
291 cascade->GetPosCov(covVtx);
296 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
298 chi2, // = chi2/NDF since NDF = 2*2-3 (AM)
301 vcascade->AddDaughter(vV0FromCascade);
304 // Add the positive tracks from the V0
306 if (posFromV0>-1 && !usedTrack[posFromV0]) {
308 usedTrack[posFromV0] = kTRUE;
310 AliESDtrack *esdTrack = fESD->GetTrack(posFromV0);
311 esdTrack->GetPxPyPz(p);
312 esdTrack->GetXYZ(pos);
313 esdTrack->GetCovarianceXYZPxPyPz(covTr);
314 esdTrack->GetESDpid(pid);
316 vV0FromCascade->AddDaughter(aodTrack =
317 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
318 esdTrack->GetLabel(),
324 (Short_t)esdTrack->GetSign(),
325 esdTrack->GetITSClusterMap(),
328 kTRUE, // check if this is right
329 kFALSE, // check if this is right
330 AliAODTrack::kSecondary)
332 aodTrack->ConvertAliPIDtoAODPID();
335 // cerr << "Error: event " << fESD->GetEventNumberInFile() << " cascade " << nCascade
336 // << " track " << posFromV0 << " has already been used!" << endl;
339 // Add the negative tracks from the V0
341 if (negFromV0>-1 && !usedTrack[negFromV0]) {
343 usedTrack[negFromV0] = kTRUE;
345 AliESDtrack *esdTrack = fESD->GetTrack(negFromV0);
346 esdTrack->GetPxPyPz(p);
347 esdTrack->GetXYZ(pos);
348 esdTrack->GetCovarianceXYZPxPyPz(covTr);
349 esdTrack->GetESDpid(pid);
351 vV0FromCascade->AddDaughter(aodTrack =
352 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
353 esdTrack->GetLabel(),
359 (Short_t)esdTrack->GetSign(),
360 esdTrack->GetITSClusterMap(),
363 kTRUE, // check if this is right
364 kFALSE, // check if this is right
365 AliAODTrack::kSecondary)
367 aodTrack->ConvertAliPIDtoAODPID();
370 // cerr << "Error: event " << fESD->GetEventNumberInFile() << " cascade " << nCascade
371 // << " track " << negFromV0 << " has already been used!" << endl;
374 // Add the bachelor track from the cascade
376 Int_t bachelor = cascade->GetBindex();
378 if(bachelor>-1 && !usedTrack[bachelor]) {
380 usedTrack[bachelor] = kTRUE;
382 AliESDtrack *esdTrack = fESD->GetTrack(bachelor);
383 esdTrack->GetPxPyPz(p);
384 esdTrack->GetXYZ(pos);
385 esdTrack->GetCovarianceXYZPxPyPz(covTr);
386 esdTrack->GetESDpid(pid);
388 vcascade->AddDaughter(aodTrack =
389 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
390 esdTrack->GetLabel(),
396 (Short_t)esdTrack->GetSign(),
397 esdTrack->GetITSClusterMap(),
400 kTRUE, // check if this is right
401 kFALSE, // check if this is right
402 AliAODTrack::kSecondary)
404 aodTrack->ConvertAliPIDtoAODPID();
407 // cerr << "Error: event " << fESD->GetEventNumberInFile() << " cascade " << nCascade
408 // << " track " << bachelor << " has already been used!" << endl;
411 // Add the primary track of the cascade (if any)
413 } // end of the loop on cascades
417 for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
419 if (usedV0[nV0]) continue; // skip if aready added to the AOD
421 AliESDv0 *v0 = fESD->GetV0(nV0);
423 v0->GetXYZ(pos[0], pos[1], pos[2]);
426 chi2 = v0->GetChi2V0();
427 v0->GetPosCov(covVtx);
434 new(vertices[jVertices++]) AliAODVertex(pos,
436 chi2, // = chi2/NDF since NDF = 2*2-3
439 primary->AddDaughter(vV0);
441 Int_t posFromV0 = v0->GetPindex();
442 Int_t negFromV0 = v0->GetNindex();
444 // Add the positive tracks from the V0
446 if (posFromV0>-1 && !usedTrack[posFromV0]) {
448 usedTrack[posFromV0] = kTRUE;
450 AliESDtrack *esdTrack = fESD->GetTrack(posFromV0);
451 esdTrack->GetPxPyPz(p);
452 esdTrack->GetXYZ(pos);
453 esdTrack->GetCovarianceXYZPxPyPz(covTr);
454 esdTrack->GetESDpid(pid);
456 vV0->AddDaughter(aodTrack =
457 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
458 esdTrack->GetLabel(),
464 (Short_t)esdTrack->GetSign(),
465 esdTrack->GetITSClusterMap(),
468 kTRUE, // check if this is right
469 kFALSE, // check if this is right
470 AliAODTrack::kSecondary)
472 aodTrack->ConvertAliPIDtoAODPID();
475 // cerr << "Error: event " << fESD->GetEventNumberInFile() << " V0 " << nV0
476 // << " track " << posFromV0 << " has already been used!" << endl;
479 // Add the negative tracks from the V0
481 if (negFromV0>-1 && !usedTrack[negFromV0]) {
483 usedTrack[negFromV0] = kTRUE;
485 AliESDtrack *esdTrack = fESD->GetTrack(negFromV0);
486 esdTrack->GetPxPyPz(p);
487 esdTrack->GetXYZ(pos);
488 esdTrack->GetCovarianceXYZPxPyPz(covTr);
489 esdTrack->GetESDpid(pid);
491 vV0->AddDaughter(aodTrack =
492 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
493 esdTrack->GetLabel(),
499 (Short_t)esdTrack->GetSign(),
500 esdTrack->GetITSClusterMap(),
503 kTRUE, // check if this is right
504 kFALSE, // check if this is right
505 AliAODTrack::kSecondary)
507 aodTrack->ConvertAliPIDtoAODPID();
510 // cerr << "Error: event " << fESD->GetEventNumberInFile() << " V0 " << nV0
511 // << " track " << negFromV0 << " has already been used!" << endl;
514 } // end of the loop on V0s
516 // Kinks: it is a big mess the access to the information in the kinks
517 // The loop is on the tracks in order to find the mother and daugther of each kink
520 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
523 AliESDtrack * esdTrack = fESD->GetTrack(iTrack);
525 Int_t ikink = esdTrack->GetKinkIndex(0);
527 if (ikink && nKinks) {
528 // Negative kink index: mother, positive: daughter
530 // Search for the second track of the kink
532 for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
534 AliESDtrack * esdTrack1 = fESD->GetTrack(jTrack);
536 Int_t jkink = esdTrack1->GetKinkIndex(0);
538 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
540 // The two tracks are from the same kink
542 if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
545 Int_t idaughter = -1;
547 if (ikink<0 && jkink>0) {
552 else if (ikink>0 && jkink<0) {
558 // cerr << "Error: Wrong combination of kink indexes: "
559 // << ikink << " " << jkink << endl;
563 // Add the mother track
565 AliAODTrack * mother = NULL;
567 if (!usedTrack[imother]) {
569 usedTrack[imother] = kTRUE;
571 AliESDtrack *esdTrack = fESD->GetTrack(imother);
572 esdTrack->GetPxPyPz(p);
573 esdTrack->GetXYZ(pos);
574 esdTrack->GetCovarianceXYZPxPyPz(covTr);
575 esdTrack->GetESDpid(pid);
578 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
579 esdTrack->GetLabel(),
585 (Short_t)esdTrack->GetSign(),
586 esdTrack->GetITSClusterMap(),
589 kTRUE, // check if this is right
590 kTRUE, // check if this is right
591 AliAODTrack::kPrimary);
592 primary->AddDaughter(mother);
593 mother->ConvertAliPIDtoAODPID();
596 // cerr << "Error: event " << fESD->GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
597 // << " track " << imother << " has already been used!" << endl;
600 // Add the kink vertex
601 AliESDkink * kink = fESD->GetKink(TMath::Abs(ikink)-1);
603 AliAODVertex * vkink =
604 new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
608 AliAODVertex::kKink);
609 // Add the daughter track
611 AliAODTrack * daughter = NULL;
613 if (!usedTrack[idaughter]) {
615 usedTrack[idaughter] = kTRUE;
617 AliESDtrack *esdTrack = fESD->GetTrack(idaughter);
618 esdTrack->GetPxPyPz(p);
619 esdTrack->GetXYZ(pos);
620 esdTrack->GetCovarianceXYZPxPyPz(covTr);
621 esdTrack->GetESDpid(pid);
624 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
625 esdTrack->GetLabel(),
631 (Short_t)esdTrack->GetSign(),
632 esdTrack->GetITSClusterMap(),
635 kTRUE, // check if this is right
636 kTRUE, // check if this is right
637 AliAODTrack::kPrimary);
638 vkink->AddDaughter(daughter);
639 daughter->ConvertAliPIDtoAODPID();
642 // cerr << "Error: event " << fESD->GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
643 // << " track " << idaughter << " has already been used!" << endl;
651 // Tracks (primary and orphan)
653 printf("NUMBER OF TRACKS %5d\n", nTracks);
655 for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
658 if (usedTrack[nTrack]) continue;
659 AliESDtrack *esdTrack = fESD->GetTrack(nTrack);
660 UInt_t selectInfo = 0;
664 selectInfo = fTrackFilter->IsSelected(esdTrack);
665 if (!selectInfo) continue;
669 esdTrack->GetPxPyPz(p);
670 esdTrack->GetXYZ(pos);
671 esdTrack->GetCovarianceXYZPxPyPz(covTr);
672 esdTrack->GetESDpid(pid);
674 Float_t impactXY, impactZ;
676 esdTrack->GetImpactParameters(impactXY,impactZ);
679 // track inside the beam pipe
681 primary->AddDaughter(aodTrack =
682 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
683 esdTrack->GetLabel(),
689 (Short_t)esdTrack->GetSign(),
690 esdTrack->GetITSClusterMap(),
693 kTRUE, // check if this is right
694 kTRUE, // check if this is right
695 AliAODTrack::kPrimary,
698 aodTrack->ConvertAliPIDtoAODPID();
701 // outside the beam pipe: orphan track
703 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
704 esdTrack->GetLabel(),
710 (Short_t)esdTrack->GetSign(),
711 esdTrack->GetITSClusterMap(),
714 kFALSE, // check if this is right
715 kFALSE, // check if this is right
716 AliAODTrack::kOrphan,
718 aodTrack->ConvertAliPIDtoAODPID();
720 } // end of loop on tracks
723 Int_t nMuTracks = fESD->GetNumberOfMuonTracks();
724 for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
726 AliESDMuonTrack *esdMuTrack = fESD->GetMuonTrack(nMuTrack);
727 p[0] = esdMuTrack->Px();
728 p[1] = esdMuTrack->Py();
729 p[2] = esdMuTrack->Pz();
730 pos[0] = primary->GetX();
731 pos[1] = primary->GetY();
732 pos[2] = primary->GetZ();
734 // has to be changed once the muon pid is provided by the ESD
735 for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
737 primary->AddDaughter(
738 new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
739 0, // no label provided
744 NULL, // no covariance matrix provided
745 (Short_t)-99, // no charge provided
746 0, // no ITSClusterMap
749 kTRUE, // check if this is right
750 kTRUE, // not used for vertex fit
751 AliAODTrack::kPrimary)
765 void AliAnalysisTaskESDfilter::Terminate(Option_t */*option*/)
767 // Terminate analysis
769 if (fDebug > 1) printf("AnalysisESDfilter: Terminate() \n");