1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 //----------------------------------------------------------------------------
17 // Implementation of the D0toKpi reconstruction and analysis class
18 // Note: the two decay tracks are labelled: 0 (positive track)
20 // An example of usage can be found in the macro AliD0toKpiTest.C
21 // Origin: A. Dainese andrea.dainese@pd.infn.it
22 //----------------------------------------------------------------------------
28 #include <TParticle.h>
31 #include "AliRunLoader.h"
32 #include "AliITStrackV2.h"
33 #include "AliITSVertexerTracks.h"
34 #include "AliESDVertex.h"
35 #include "AliV0vertexer.h"
36 #include "AliV0vertex.h"
37 #include "AliD0toKpi.h"
38 #include "AliD0toKpiAnalysis.h"
50 ClassImp(AliD0toKpiAnalysis)
52 //----------------------------------------------------------------------------
53 AliD0toKpiAnalysis::AliD0toKpiAnalysis() {
54 // Default constructor
63 fVertexOnTheFly = kFALSE;
67 //----------------------------------------------------------------------------
68 AliD0toKpiAnalysis::~AliD0toKpiAnalysis() {}
69 //----------------------------------------------------------------------------
70 void AliD0toKpiAnalysis::ApplySelection(const Char_t *inName,const Char_t *outName) const {
71 // select candidates that pass fD0Cuts and write them to a new file
73 TFile *inFile = TFile::Open(inName);
75 TTree *treeD0in=(TTree*)inFile->Get("TreeD0");
76 AliD0toKpiAnalysis *inAnalysis = (AliD0toKpiAnalysis*)inFile->Get("D0toKpiAnalysis");
77 printf("+++\n+++ I N P U T S T A T U S:\n+++\n");
78 inAnalysis->PrintStatus();
82 treeD0in->SetBranchAddress("D0toKpi",&d);
83 Int_t entries = (Int_t)treeD0in->GetEntries();
85 printf("+++\n+++ Number of D0 in input tree: %d\n+++\n",entries);
87 TTree *treeD0out = new TTree("TreeD0","Tree with selected D0 candidates");
88 treeD0out->Branch("D0toKpi","AliD0toKpi",&d,200000,0);
91 Int_t okD0=0,okD0bar=0;
94 for(Int_t i=0; i<entries; i++) {
95 // get event from tree
96 treeD0in->GetEvent(i);
98 if(fSim && fOnlySignal && !d->IsSignal()) continue;
100 // check if candidate passes selection (as D0 or D0bar)
101 if(d->Select(fD0Cuts,okD0,okD0bar)) {
108 AliD0toKpiAnalysis *outAnalysis = (AliD0toKpiAnalysis*)inAnalysis->Clone("D0toKpiAnalysis");
109 outAnalysis->SetD0Cuts(fD0Cuts);
110 printf("------------------------------------------\n");
111 printf("+++\n+++ O U T P U T S T A T U S:\n+++\n");
112 outAnalysis->PrintStatus();
114 printf("+++\n+++ Number of D0 in output tree: %d\n+++\n",nSel);
116 TFile* outFile = new TFile(outName,"recreate");
118 outAnalysis->Write();
123 //----------------------------------------------------------------------------
124 Double_t AliD0toKpiAnalysis::CalculateTOFmass(Double_t mom,Double_t length,
125 Double_t time) const {
126 // calculated the mass from momentum, track length from vertex to TOF
127 // and time measured by the TOF
128 if(length==0.) return -1000.;
129 Double_t a = time*time/length/length;
131 a = TMath::Sqrt(a-1.);
133 a = -TMath::Sqrt(1.-a);
138 //----------------------------------------------------------------------------
139 void AliD0toKpiAnalysis::FindCandidates(Int_t evFirst,Int_t evLast,
140 const Char_t *outName) {
141 // Find D0 candidates and calculate parameters
144 printf("AliD0toKpiAnalysis::FindCandidates(): Set B!\n");
147 AliKalmanTrack::SetConvConst(100/0.299792458/fBz);
149 TString trkName("AliITStracksV2.root");
150 if(gSystem->AccessPathName(trkName.Data(),kFileExists)) {
151 printf("AliD0toKpiAnalysis::FindCandidates(): No tracks file found!\n");
155 TString outName1=outName;
156 TString outName2("nTotEvents.dat");
159 Int_t nTotEv=0,nD0rec=0,nD0rec1ev=0;
161 Double_t v2[3],mom[6],d0[2];
162 Double_t alphaP,alphaN,ptP,ptN,phiP,phiN;
163 Int_t iTrkP,iTrkN,trkEntries;
164 Int_t nTrksP=0,nTrksN=0;
166 Int_t okD0=0,okD0bar=0;
167 Char_t trkTreeName[100],vtxName[100];
168 AliITStrackV2 *postrack = 0;
169 AliITStrackV2 *negtrack = 0;
171 // create the AliITSVertexerTracks object
172 // (it will be used only if fVertexOnTheFly=kTrue)
173 AliITSVertexerTracks *vertexer1 = new AliITSVertexerTracks;
174 vertexer1->SetMinTracks(2);
179 // define the cuts for vertexing
180 Double_t vtxcuts[]={50., // max. allowed chi2
181 0.0, // min. allowed negative daughter's impact param
182 0.0, // min. allowed positive daughter's impact param
183 1.0, // max. allowed DCA between the daughter tracks
184 -1.0, // min. allowed cosine of pointing angle
185 0.0, // min. radius of the fiducial volume
186 2.9};// max. radius of the fiducial volume
188 // create the AliV0vertexer object
189 AliV0vertexer *vertexer2 = new AliV0vertexer(vtxcuts);
191 // create tree for reconstructed D0s
192 AliD0toKpi *ioD0toKpi=0;
193 TTree *treeD0 = new TTree("TreeD0","Tree with D0 candidates");
194 treeD0->Branch("D0toKpi","AliD0toKpi",&ioD0toKpi,200000,0);
196 // open file with tracks
197 TFile *trkFile = TFile::Open(trkName.Data());
199 // loop on events in file
200 for(ev=evFirst; ev<=evLast; ev++) {
201 printf(" --- Looking for D0->Kpi in event %d ---\n",ev);
203 // retrieve primary vertex from file
204 sprintf(vtxName,"VertexTracks_%d",ev);
205 AliESDVertex *vertex1stored = (AliESDVertex*)trkFile->Get(vtxName);
206 vertex1stored->GetXYZ(fV1);
207 delete vertex1stored;
209 // retrieve tracks from file
210 sprintf(trkTreeName,"TreeT_ITS_%d",ev);
211 TTree *trkTree=(TTree*)trkFile->Get(trkTreeName);
213 printf("AliD0toKpiAnalysis::FindCandidates():\n tracks tree not found for evet %d\n",ev);
216 trkEntries = (Int_t)trkTree->GetEntries();
217 printf(" Number of tracks: %d\n",trkEntries);
219 // count the total number of events
222 // call function which applies sigle-track selection and
223 // separetes positives and negatives
224 TObjArray trksP(trkEntries/2);
225 Int_t *trkEntryP = new Int_t[trkEntries];
226 TObjArray trksN(trkEntries/2);
227 Int_t *trkEntryN = new Int_t[trkEntries];
228 SelectTracks(*trkTree,trksP,trkEntryP,nTrksP,trksN,trkEntryN,nTrksN);
232 // loop on positive tracks
233 for(iTrkP=0; iTrkP<nTrksP; iTrkP++) {
234 if(iTrkP%10==0) printf(" Processing positive track number %d of %d\n",iTrkP,nTrksP);
236 // get track from track array
237 postrack = (AliITStrackV2*)trksP.At(iTrkP);
238 trkNum[0] = trkEntryP[iTrkP];
240 // loop on negative tracks
241 for(iTrkN=0; iTrkN<nTrksN; iTrkN++) {
242 // get track from tracks array
243 negtrack = (AliITStrackV2*)trksN.At(iTrkN);
244 trkNum[1] = trkEntryN[iTrkN];
246 AliITStrackV2 nt(*negtrack), pt(*postrack), *pnt=&nt, *ppt=&pt;
249 // ----------- DCA MINIMIZATION ------------------
251 // find the DCA and propagate the tracks to the DCA
252 dca = vertexer2->PropagateToDCA(pnt,ppt);
254 // define the AliV0vertex object
255 AliV0vertex *vertex2 = new AliV0vertex(*pnt,*ppt);
257 // get position of the secondary vertex
258 vertex2->GetXYZ(v2[0],v2[1],v2[2]);
262 // momenta of the tracks at the vertex
263 ptP = 1./TMath::Abs(ppt->Get1Pt());
264 alphaP = ppt->GetAlpha();
265 phiP = alphaP+TMath::ASin(ppt->GetSnp());
266 mom[0] = ptP*TMath::Cos(phiP);
267 mom[1] = ptP*TMath::Sin(phiP);
268 mom[2] = ptP*ppt->GetTgl();
270 ptN = 1./TMath::Abs(pnt->Get1Pt());
271 alphaN = pnt->GetAlpha();
272 phiN = alphaN+TMath::ASin(pnt->GetSnp());
273 mom[3] = ptN*TMath::Cos(phiN);
274 mom[4] = ptN*TMath::Sin(phiN);
275 mom[5] = ptN*pnt->GetTgl();
278 // no vertexing if DeltaMass > fMassCut
279 if(fVertexOnTheFly) {
281 if(SelectInvMass(mom)) {
282 // primary vertex from *other* tracks in event
283 vertexer1->SetVtxStart(fV1[0],fV1[1]);
284 skipped[0] = trkEntryP[iTrkP];
285 skipped[1] = trkEntryN[iTrkN];
286 vertexer1->SetSkipTracks(2,skipped);
287 AliESDVertex *vertex1onfly =
288 (AliESDVertex*)vertexer1->VertexOnTheFly(*trkTree);
289 if(vertex1onfly->GetNContributors()>0) goodVtx1 = kTRUE;
290 vertex1onfly->GetXYZ(fV1);
291 //vertex1onfly->PrintStatus();
296 // impact parameters of the tracks w.r.t. the primary vertex
297 d0[0] = 10000.*ppt->GetD(fV1[0],fV1[1]);
298 d0[1] = -10000.*pnt->GetD(fV1[0],fV1[1]);
300 // create the object AliD0toKpi
301 AliD0toKpi theD0(ev,trkNum,fV1,v2,dca,mom,d0);
304 if(goodVtx1 && theD0.Select(fD0Cuts,okD0,okD0bar)) {
310 nD0rec++; nD0rec1ev++;
315 } // loop on negative tracks
317 } // loop on positive tracks
325 printf(" Number of D0 candidates: %d\n",nD0rec1ev);
326 } // loop on events in file
329 printf("\n+++\n+++ Total number of events: %d\n+++\n",nTotEv);
330 printf("\n+++\n+++ Total number of D0 candidates: %d\n+++\n",nD0rec);
337 // create a copy of this class to be written to output file
338 AliD0toKpiAnalysis *copy = (AliD0toKpiAnalysis*)this->Clone("D0toKpiAnalysis");
341 // add PDG codes to decay tracks in found candidates (in simulation mode)
342 // and store tree in the output file
344 TFile *outroot = new TFile(outName1.Data(),"recreate");
350 printf(" Now adding information from simulation (PDG codes) ...\n");
351 TTree *treeD0sim = new TTree("TreeD0","Tree with D0 candidates");
352 MakeTracksRefFile(evFirst,evLast);
353 SimulationInfo(treeD0,treeD0sim);
355 TFile *outroot = new TFile(outName1.Data(),"recreate");
362 // write to a file the total number of events
363 FILE *outdat = fopen(outName2.Data(),"w");
364 fprintf(outdat,"%d\n",nTotEv);
369 //----------------------------------------------------------------------------
370 void AliD0toKpiAnalysis::FindCandidatesESD(Int_t evFirst,Int_t evLast,
371 const Char_t *outName) {
372 // Find D0 candidates and calculate parameters
375 printf("AliD0toKpiAnalysis::FindCandidatesESD(): Set B!\n");
378 AliKalmanTrack::SetConvConst(100/0.299792458/fBz);
380 TString esdName("AliESDs.root");
381 if(gSystem->AccessPathName(esdName.Data(),kFileExists)) {
382 printf("AliD0toKpiAnalysis::FindCandidatesESD(): No ESDs file found!\n");
386 TString outName1=outName;
387 TString outName2("nTotEvents.dat");
389 Int_t nTotEv=0,nD0rec=0,nD0rec1ev=0;
391 Double_t v2[3],mom[6],d0[2];
392 Double_t alphaP,alphaN,ptP,ptN,phiP,phiN;
393 Int_t iTrkP,iTrkN,trkEntries;
394 Int_t nTrksP=0,nTrksN=0;
397 Int_t okD0=0,okD0bar=0;
398 AliITStrackV2 *postrack = 0;
399 AliITStrackV2 *negtrack = 0;
401 // create the AliITSVertexerTracks object
402 // (it will be used only if fVertexOnTheFly=kTrue)
403 AliITSVertexerTracks *vertexer1 = new AliITSVertexerTracks;
404 vertexer1->SetMinTracks(2);
409 // define the cuts for vertexing
410 Double_t vtxcuts[]={50., // max. allowed chi2
411 0.0, // min. allowed negative daughter's impact param
412 0.0, // min. allowed positive daughter's impact param
413 1.0, // max. allowed DCA between the daughter tracks
414 -1.0, // min. allowed cosine of pointing angle
415 0.0, // min. radius of the fiducial volume
416 2.9};// max. radius of the fiducial volume
418 // create the AliV0vertexer object
419 AliV0vertexer *vertexer2 = new AliV0vertexer(vtxcuts);
421 // create tree for reconstructed D0s
422 AliD0toKpi *ioD0toKpi=0;
423 TTree *treeD0 = new TTree("TreeD0","Tree with D0 candidates");
424 treeD0->Branch("D0toKpi","AliD0toKpi",&ioD0toKpi,200000,0);
426 // open file with tracks
427 TFile *esdFile = TFile::Open(esdName.Data());
428 AliESD* event = new AliESD;
429 TTree* tree = (TTree*) esdFile->Get("esdTree");
431 Error("FindCandidatesESD", "no ESD tree found");
434 tree->SetBranchAddress("ESD", &event);
436 // loop on events in file
437 for (Int_t iEvent = evFirst; iEvent < tree->GetEntries(); iEvent++) {
438 if (iEvent > evLast) break;
439 tree->GetEvent(iEvent);
440 Int_t ev = (Int_t)event->GetEventNumber();
441 printf("--- Finding D0 -> Kpi in event %d\n",ev);
443 // retrieve primary vertex from file
444 //sprintf(vtxName,"Vertex_%d",ev);
445 //AliESDVertex *vertex1stored = (AliESDVertex*)trkFile->Get(vtxName);
446 //vertex1stored->GetXYZ(fV1);
447 //delete vertex1stored;
448 event->GetVertex()->GetXYZ(fV1);
450 trkEntries = event->GetNumberOfTracks();
451 printf(" Number of tracks: %d\n",trkEntries);
453 // count the total number of events
456 // call function which applies sigle-track selection and
457 // separetes positives and negatives
458 TObjArray trksP(trkEntries/2);
459 Int_t *trkEntryP = new Int_t[trkEntries];
460 TObjArray trksN(trkEntries/2);
461 Int_t *trkEntryN = new Int_t[trkEntries];
462 TTree *trkTree = new TTree();
463 if(fVertexOnTheFly) {
464 SelectTracksESDvtx(*event,trkTree,trksP,trkEntryP,nTrksP,
465 trksN,trkEntryN,nTrksN);
467 SelectTracksESD(*event,trksP,trkEntryP,nTrksP,
468 trksN,trkEntryN,nTrksN);
471 AliDebugClass(1,Form(" pos. tracks: %d neg .tracks: %d",nTrksP,nTrksN));
475 // loop on positive tracks
476 for(iTrkP=0; iTrkP<nTrksP; iTrkP++) {
477 if(iTrkP%10==0) AliDebugClass(1,Form(" Processing positive track number %d of %d",iTrkP,nTrksP));
479 // get track from track array
480 postrack = (AliITStrackV2*)trksP.UncheckedAt(iTrkP);
481 trkNum[0] = trkEntryP[iTrkP];
483 // loop on negative tracks
484 for(iTrkN=0; iTrkN<nTrksN; iTrkN++) {
486 // get track from tracks array
487 negtrack = (AliITStrackV2*)trksN.UncheckedAt(iTrkN);
488 trkNum[1] = trkEntryN[iTrkN];
490 AliITStrackV2 nt(*negtrack), pt(*postrack), *pnt=&nt, *ppt=&pt;
493 // ----------- DCA MINIMIZATION ------------------
495 // find the DCA and propagate the tracks to the DCA
496 dca = vertexer2->PropagateToDCA(pnt,ppt);
498 // define the AliV0vertex object
499 AliV0vertex *vertex2 = new AliV0vertex(*pnt,*ppt);
501 // get position of the secondary vertex
502 vertex2->GetXYZ(v2[0],v2[1],v2[2]);
506 // momenta of the tracks at the vertex
507 ptP = 1./TMath::Abs(ppt->Get1Pt());
508 alphaP = ppt->GetAlpha();
509 phiP = alphaP+TMath::ASin(ppt->GetSnp());
510 mom[0] = ptP*TMath::Cos(phiP);
511 mom[1] = ptP*TMath::Sin(phiP);
512 mom[2] = ptP*ppt->GetTgl();
514 ptN = 1./TMath::Abs(pnt->Get1Pt());
515 alphaN = pnt->GetAlpha();
516 phiN = alphaN+TMath::ASin(pnt->GetSnp());
517 mom[3] = ptN*TMath::Cos(phiN);
518 mom[4] = ptN*TMath::Sin(phiN);
519 mom[5] = ptN*pnt->GetTgl();
522 // no vertexing if DeltaMass > fMassCut
523 if(fVertexOnTheFly) {
525 if(SelectInvMass(mom)) {
526 // primary vertex from *other* tracks in event
527 vertexer1->SetVtxStart(fV1[0],fV1[1]);
528 skipped[0] = trkEntryP[iTrkP];
529 skipped[1] = trkEntryN[iTrkN];
530 vertexer1->SetSkipTracks(2,skipped);
531 AliESDVertex *vertex1onfly =
532 (AliESDVertex*)vertexer1->VertexOnTheFly(*trkTree);
533 if(vertex1onfly->GetNContributors()>0) goodVtx1 = kTRUE;
534 vertex1onfly->GetXYZ(fV1);
535 //vertex1onfly->PrintStatus();
540 // impact parameters of the tracks w.r.t. the primary vertex
541 d0[0] = 10000.*ppt->GetD(fV1[0],fV1[1]);
542 d0[1] = -10000.*pnt->GetD(fV1[0],fV1[1]);
544 // create the object AliD0toKpi
545 AliD0toKpi theD0(ev,trkNum,fV1,v2,dca,mom,d0);
548 if(goodVtx1 && theD0.Select(fD0Cuts,okD0,okD0bar)) {
550 // get PID info from ESD
551 AliESDtrack *t0 = (AliESDtrack*)event->GetTrack(trkNum[0]);
553 t0->GetESDpid(esdpid0);
554 if(t0->GetStatus()&AliESDtrack::kTOFpid) {
555 tofmass[0] = CalculateTOFmass(t0->GetP(),
556 t0->GetIntegratedLength(),
561 AliESDtrack *t1 = (AliESDtrack*)event->GetTrack(trkNum[1]);
563 t1->GetESDpid(esdpid1);
564 if(t1->GetStatus()&AliESDtrack::kTOFpid) {
565 tofmass[1] = CalculateTOFmass(t1->GetP(),
566 t1->GetIntegratedLength(),
572 theD0.SetPIDresponse(esdpid0,esdpid1);
573 theD0.SetTOFmasses(tofmass);
579 nD0rec++; nD0rec1ev++;
584 } // loop on negative tracks
586 } // loop on positive tracks
595 printf(" Number of D0 candidates: %d\n",nD0rec1ev);
596 } // loop on events in file
599 printf("\n+++\n+++ Total number of events: %d\n+++\n",nTotEv);
600 printf("\n+++\n+++ Total number of D0 candidates: %d\n+++\n",nD0rec);
607 // create a copy of this class to be written to output file
608 AliD0toKpiAnalysis *copy = (AliD0toKpiAnalysis*)this->Clone("D0toKpiAnalysis");
610 // add PDG codes to decay tracks in found candidates (in simulation mode)
611 // and store tree in the output file
613 TFile *outroot = new TFile(outName1.Data(),"recreate");
619 printf(" Now adding information from simulation (PDG codes) ...\n");
620 TTree *treeD0sim = new TTree("TreeD0","Tree with D0 candidates");
621 MakeTracksRefFileESD();
622 SimulationInfo(treeD0,treeD0sim);
624 TFile *outroot = new TFile(outName1.Data(),"recreate");
631 // write to a file the total number of events
632 FILE *outdat = fopen(outName2.Data(),"w");
633 fprintf(outdat,"%d\n",nTotEv);
638 //-----------------------------------------------------------------------------
639 void AliD0toKpiAnalysis::PrintStatus() const {
640 // Print parameters being used
642 printf(" fBz = %f T\n",fBz);
643 printf("Preselections:\n");
644 printf(" fPtCut = %f GeV\n",fPtCut);
645 printf(" fd0Cut = %f micron\n",fd0Cut);
646 printf(" fMassCut = %f GeV\n",fMassCut);
647 if(fVertexOnTheFly) printf("Primary vertex on the fly\n");
649 printf("Simulation mode\n");
650 if(fOnlySignal) printf(" Only signal goes to file\n");
652 printf("Cuts on candidates:\n");
653 printf(" |M-MD0| [GeV] < %f\n",fD0Cuts[0]);
654 printf(" dca [micron] < %f\n",fD0Cuts[1]);
655 printf(" cosThetaStar < %f\n",fD0Cuts[2]);
656 printf(" pTK [GeV] > %f\n",fD0Cuts[3]);
657 printf(" pTpi [GeV] > %f\n",fD0Cuts[4]);
658 printf(" |d0K| [micron] < %f\n",fD0Cuts[5]);
659 printf(" |d0pi| [micron] < %f\n",fD0Cuts[6]);
660 printf(" d0d0 [micron^2] < %f\n",fD0Cuts[7]);
661 printf(" cosThetaPoint > %f\n",fD0Cuts[8]);
665 //-----------------------------------------------------------------------------
666 Bool_t AliD0toKpiAnalysis::SelectInvMass(const Double_t p[6]) const {
667 // Apply preselection in the invariant mass of the pair
669 Double_t mD0 = 1.8645;
670 Double_t mPi = 0.13957;
671 Double_t mKa = 0.49368;
674 Double_t mom2[2],momTot2;
676 mom2[0] = p[0]*p[0] + p[1]*p[1] + p[2]*p[2];
677 mom2[1] = p[3]*p[3] + p[4]*p[4] + p[5]*p[5];
679 momTot2 = (p[0]+p[3])*(p[0]+p[3])+
680 (p[1]+p[4])*(p[1]+p[4])+
681 (p[2]+p[5])*(p[2]+p[5]);
684 energy[1] = TMath::Sqrt(mKa*mKa+mom2[1]);
685 energy[0] = TMath::Sqrt(mPi*mPi+mom2[0]);
687 Double_t minvD0 = TMath::Sqrt((energy[0]+energy[1])*(energy[0]+energy[1])-momTot2);
690 energy[0] = TMath::Sqrt(mKa*mKa+mom2[0]);
691 energy[1] = TMath::Sqrt(mPi*mPi+mom2[1]);
693 Double_t minvD0bar = TMath::Sqrt((energy[0]+energy[1])*(energy[0]+energy[1])-momTot2);
695 if(TMath::Abs(minvD0-mD0) < fMassCut) return kTRUE;
696 if(TMath::Abs(minvD0bar-mD0) < fMassCut) return kTRUE;
699 //-----------------------------------------------------------------------------
700 void AliD0toKpiAnalysis::SelectTracks(TTree &trkTree,
701 TObjArray &trksP,Int_t *trkEntryP,Int_t &nTrksP,
702 TObjArray &trksN,Int_t *trkEntryN,Int_t &nTrksN) const {
703 // Create two TObjArrays with positive and negative tracks and
704 // apply single-track preselection
708 Int_t entr = (Int_t)trkTree.GetEntries();
710 // trasfer tracks from tree to arrays
711 for(Int_t i=0; i<entr; i++) {
713 AliITStrackV2 *track = new AliITStrackV2;
714 trkTree.SetBranchAddress("tracks",&track);
718 // single track selection
719 if(!SingleTrkCuts(*track)) { delete track; continue; }
721 if(track->Get1Pt()>0.) { // negative track
722 trksN.AddLast(track);
723 trkEntryN[nTrksN] = i;
725 } else { // positive track
726 trksP.AddLast(track);
727 trkEntryP[nTrksP] = i;
735 //-----------------------------------------------------------------------------
736 void AliD0toKpiAnalysis::SelectTracksESD(AliESD &event,
737 TObjArray &trksP,Int_t *trkEntryP,Int_t &nTrksP,
738 TObjArray &trksN,Int_t *trkEntryN,Int_t &nTrksN) const {
739 // Create two TObjArrays with positive and negative tracks and
740 // apply single-track preselection
744 Int_t entr = event.GetNumberOfTracks();
746 // transfer ITS tracks from ESD to arrays and to a tree
747 for(Int_t i=0; i<entr; i++) {
749 AliESDtrack *esdtrack = (AliESDtrack*)event.GetTrack(i);
750 UInt_t status = esdtrack->GetStatus();
752 if(!(status&AliESDtrack::kITSrefit)) continue;
754 AliITStrackV2 *itstrack = new AliITStrackV2(*esdtrack);
756 // single track selection
757 if(!SingleTrkCuts(*itstrack))
758 { delete itstrack; continue; }
760 if(itstrack->Get1Pt()>0.) { // negative track
761 trksN.AddLast(itstrack);
762 trkEntryN[nTrksN] = i;
764 } else { // positive track
765 trksP.AddLast(itstrack);
766 trkEntryP[nTrksP] = i;
770 } // loop on ESD tracks
774 //-----------------------------------------------------------------------------
775 void AliD0toKpiAnalysis::SelectTracksESDvtx(AliESD &event,TTree *trkTree,
776 TObjArray &trksP,Int_t *trkEntryP,Int_t &nTrksP,
777 TObjArray &trksN,Int_t *trkEntryN,Int_t &nTrksN) const {
778 // Create two TObjArrays with positive and negative tracks and
779 // apply single-track preselection
783 Int_t entr = event.GetNumberOfTracks();
785 AliITStrackV2 *itstrackfortree = 0;
786 trkTree->Branch("tracks","AliITStrackV2",&itstrackfortree,entr,0);
789 // transfer ITS tracks from ESD to arrays and to a tree
790 for(Int_t i=0; i<entr; i++) {
792 AliESDtrack *esdtrack = (AliESDtrack*)event.GetTrack(i);
793 UInt_t status = esdtrack->GetStatus();
795 if(!(status&AliESDtrack::kITSrefit)) continue;
797 AliITStrackV2 *itstrack = new AliITStrackV2(*esdtrack);
799 // store track in the tree to be used for primary vertex finding
800 itstrackfortree = new AliITStrackV2(*esdtrack);
804 // single track selection
805 if(!SingleTrkCuts(*itstrack))
806 { delete itstrack; continue; }
808 if(itstrack->Get1Pt()>0.) { // negative track
809 trksN.AddLast(itstrack);
810 trkEntryN[nTrksN] = i;
812 } else { // positive track
813 trksP.AddLast(itstrack);
814 trkEntryP[nTrksP] = i;
818 } // loop on esd tracks
820 delete itstrackfortree;
824 //-----------------------------------------------------------------------------
825 void AliD0toKpiAnalysis::SetD0Cuts(Double_t cut0,Double_t cut1,
826 Double_t cut2,Double_t cut3,Double_t cut4,
827 Double_t cut5,Double_t cut6,
828 Double_t cut7,Double_t cut8) {
829 // Set the cuts for D0 selection
842 //-----------------------------------------------------------------------------
843 void AliD0toKpiAnalysis::SetD0Cuts(const Double_t cuts[9]) {
844 // Set the cuts for D0 selection
846 for(Int_t i=0; i<9; i++) fD0Cuts[i] = cuts[i];
850 //-----------------------------------------------------------------------------
851 Bool_t AliD0toKpiAnalysis::SingleTrkCuts(const AliITStrackV2& trk) const {
852 // Check if track passes some kinematical cuts
854 if(TMath::Abs(1./trk.Get1Pt()) < fPtCut)
856 if(TMath::Abs(10000.*trk.GetD(fV1[0],fV1[1])) < fd0Cut)
861 //----------------------------------------------------------------------------
862 void AliD0toKpiAnalysis::MakeTracksRefFile(Int_t evFirst,Int_t evLast)
864 // Create a file with simulation info for the reconstructed tracks
866 TFile *out = TFile::Open("ITStracksRefFile.root","recreate");
867 TFile *trk = TFile::Open("AliITStracksV2.root");
868 AliRunLoader *rl = AliRunLoader::Open("galice.root");
871 rl->LoadKinematics();
878 for(Int_t ev=evFirst; ev<=evLast; ev++){
880 AliStack *stack = rl->Stack();
886 sprintf(tname,"TreeT_ITS_%d",ev);
888 TTree *tracktree=(TTree*)trk->Get(tname);
889 if(!tracktree) continue;
890 AliITStrackV2 *track = new AliITStrackV2;
891 tracktree->SetBranchAddress("tracks",&track);
892 Int_t nentr=(Int_t)tracktree->GetEntries();
894 // Tree for true track parameters
896 sprintf(ttname,"Tree_Ref_%d",ev);
897 TTree *reftree = new TTree(ttname,"Tree with true track params");
898 reftree->Branch("rectracks",&reftrk,"lab/I:pdg:mumlab:mumpdg:Vx/F:Vy:Vz:Px:Py:Pz");
900 for(Int_t i=0; i<nentr; i++) {
901 tracktree->GetEvent(i);
902 label = TMath::Abs(track->GetLabel());
904 part = (TParticle*)stack->Particle(label);
906 reftrk.pdg = part->GetPdgCode();
907 reftrk.mumlab = part->GetFirstMother();
908 if(part->GetFirstMother()>=0) {
909 mumpart = (TParticle*)stack->Particle(part->GetFirstMother());
910 reftrk.mumpdg = mumpart->GetPdgCode();
914 reftrk.Vx = part->Vx();
915 reftrk.Vy = part->Vy();
916 reftrk.Vz = part->Vz();
917 reftrk.Px = part->Px();
918 reftrk.Py = part->Py();
919 reftrk.Pz = part->Pz();
938 //----------------------------------------------------------------------------
939 void AliD0toKpiAnalysis::MakeTracksRefFileESD() const {
940 // Create a file with simulation info for the reconstructed tracks
942 TFile *outFile = TFile::Open("ITStracksRefFile.root","recreate");
943 TFile *esdFile = TFile::Open("AliESDs.root");
944 AliRunLoader *rl = AliRunLoader::Open("galice.root");
947 rl->LoadKinematics();
955 TIter next(esdFile->GetListOfKeys());
956 // loop on events in file
957 while ((key=(TKey*)next())!=0) {
958 AliESD *event=(AliESD*)key->ReadObj();
959 Int_t ev = (Int_t)event->GetEventNumber();
962 AliStack *stack = rl->Stack();
964 Int_t nentr=(Int_t)event->GetNumberOfTracks();
966 // Tree for true track parameters
968 sprintf(ttname,"Tree_Ref_%d",ev);
969 TTree *reftree = new TTree(ttname,"Tree with true track params");
970 reftree->Branch("rectracks",&reftrk,"lab/I:pdg:mumlab:mumpdg:Vx/F:Vy:Vz:Px:Py:Pz");
972 for(Int_t i=0; i<nentr; i++) {
973 AliESDtrack *esdtrack = (AliESDtrack*)event->GetTrack(i);
974 label = TMath::Abs(esdtrack->GetLabel());
976 part = (TParticle*)stack->Particle(label);
978 reftrk.pdg = part->GetPdgCode();
979 reftrk.mumlab = part->GetFirstMother();
980 if(part->GetFirstMother()>=0) {
981 mumpart = (TParticle*)stack->Particle(part->GetFirstMother());
982 reftrk.mumpdg = mumpart->GetPdgCode();
986 reftrk.Vx = part->Vx();
987 reftrk.Vy = part->Vy();
988 reftrk.Vz = part->Vz();
989 reftrk.Px = part->Px();
990 reftrk.Py = part->Py();
991 reftrk.Pz = part->Pz();
1010 //-----------------------------------------------------------------------------
1011 void AliD0toKpiAnalysis::SimulationInfo(TTree *treeD0in,TTree *treeD0out) const {
1012 // add pdg codes to candidate decay tracks (for sim)
1014 TString refFileName("ITStracksRefFile.root");
1015 if(fSim && gSystem->AccessPathName(refFileName.Data(),kFileExists)) {
1016 printf("AliD0toKpiAnalysis::SimulationInfo: no reference file found!\n");
1019 TFile *refFile = TFile::Open(refFileName.Data());
1021 Char_t refTreeName[100];
1023 Int_t pdg[2],mumpdg[2],mumlab[2];
1026 // read-in reference tree for event 0 (the only event for Pb-Pb)
1027 sprintf(refTreeName,"Tree_Ref_%d",0);
1028 TTree *refTree0 = (TTree*)refFile->Get(refTreeName);
1029 refTree0->SetBranchAddress("rectracks",&reftrk);
1031 AliD0toKpi *theD0 = 0;
1032 treeD0in->SetBranchAddress("D0toKpi",&theD0);
1033 treeD0out->Branch("D0toKpi","AliD0toKpi",&theD0,200000,0);
1035 Int_t entries = (Int_t)treeD0in->GetEntries();
1037 for(Int_t i=0; i<entries; i++) {
1038 if(i%100==0) printf(" done %d candidates of %d\n",i,entries);
1040 treeD0in->GetEvent(i);
1041 event = theD0->EventNo();
1043 if(event==0) { // always true for Pb-Pb (avoid to read-in tree every time)
1044 refTree0->GetEvent(theD0->GetTrkNum(0));
1045 pdg[0] = reftrk.pdg;
1046 mumpdg[0] = reftrk.mumpdg;
1047 mumlab[0] = reftrk.mumlab;
1048 refTree0->GetEvent(theD0->GetTrkNum(1));
1049 pdg[1] = reftrk.pdg;
1050 mumpdg[1] = reftrk.mumpdg;
1051 mumlab[1] = reftrk.mumlab;
1053 sprintf(refTreeName,"Tree_Ref_%d",event);
1054 TTree *refTree = (TTree*)refFile->Get(refTreeName);
1055 refTree->SetBranchAddress("rectracks",&reftrk);
1056 refTree->GetEvent(theD0->GetTrkNum(0));
1057 pdg[0] = reftrk.pdg;
1058 mumpdg[0] = reftrk.mumpdg;
1059 mumlab[0] = reftrk.mumlab;
1060 refTree->GetEvent(theD0->GetTrkNum(1));
1061 pdg[1] = reftrk.pdg;
1062 mumpdg[1] = reftrk.mumpdg;
1063 mumlab[1] = reftrk.mumlab;
1067 theD0->SetPdgCodes(pdg);
1068 theD0->SetMumPdgCodes(mumpdg);
1070 if(TMath::Abs(mumpdg[0])==421 && TMath::Abs(mumpdg[1])==421
1071 && mumlab[0]==mumlab[1]) theD0->SetSignal();
1073 if(!fOnlySignal || theD0->IsSignal()) treeD0out->Fill();