1 /**************************************************************************
2 * Copyright(c) 1998-2009, 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 // Class AliAnalysisTaskVertexESD
18 // AliAnalysisTask to extract from ESD the information for the analysis
19 // of the primary vertex reconstruction efficiency and resolution
20 // (for MC events) and distributions (for real data). Three vertices:
25 // Author: A.Dainese, andrea.dainese@pd.infn.it
26 //*************************************************************************
32 #include <TClonesArray.h>
33 #include <TObjArray.h>
38 #include "AliAnalysisTask.h"
39 #include "AliAnalysisManager.h"
41 #include "AliMultiplicity.h"
42 #include "AliVertexerTracks.h"
43 #include "AliESDtrack.h"
44 #include "AliExternalTrackParam.h"
45 #include "AliESDVertex.h"
46 #include "AliESDEvent.h"
47 #include "AliESDInputHandler.h"
48 #include "AliTrackReference.h"
49 //#include "AliTriggerAnalysis.h"
51 #include "AliMCEventHandler.h"
52 #include "AliMCEvent.h"
56 #include "AliGenEventHeader.h"
57 #include "AliAnalysisTaskVertexESD.h"
60 ClassImp(AliAnalysisTaskVertexESD)
62 //________________________________________________________________________
63 AliAnalysisTaskVertexESD::AliAnalysisTaskVertexESD(const char *name) :
64 AliAnalysisTaskSE(name),
65 fCheckEventType(kTRUE),
68 fRecoVtxITSTPC(kFALSE),
69 fOnlyITSTPCTracks(kFALSE),
70 fOnlyITSSATracks(kFALSE),
88 // Define input and output slots here
89 // Output slot #0 writes into a TList container
90 DefineOutput(1, TList::Class()); //My private output
92 //________________________________________________________________________
93 AliAnalysisTaskVertexESD::~AliAnalysisTaskVertexESD()
97 // histograms are in the output list and deleted when the output
98 // list is deleted by the TSelector dtor
107 //________________________________________________________________________
108 void AliAnalysisTaskVertexESD::UserCreateOutputObjects()
113 // Several histograms are more conveniently managed in a TList
117 fNtupleVertexESD = new TNtuple("fNtupleVertexESD","vertices","run:tstamp:bunchcross:triggered:dndygen:xtrue:ytrue:ztrue:xSPD:xerrSPD:ySPD:yerrSPD:zSPD:zerrSPD:ntrksSPD:SPD3D:dphiSPD:xTPC:xerrTPC:yTPC:yerrTPC:zTPC:zerrTPC:ntrksTPC:constrTPC:xTRK:xerrTRK:yTRK:yerrTRK:zTRK:zerrTRK:ntrksTRK:constrTRK:ntrklets:nESDtracks:nITSrefit5or6:nTPCin:nTPCinEta09:SPD0cls:xSPDp:xerrSPDp:ySPDp:yerrSPDp:zSPDp:zerrSPDp:ntrksSPDp:xTPCnc:xerrTPCnc:yTPCnc:yerrTPCnc:zTPCnc:zerrTPCnc:ntrksTPCnc:xTPCc:xerrTPCc:yTPCc:yerrTPCc:zTPCc:zerrTPCc:ntrksTPCc:xTRKnc:xerrTRKnc:yTRKnc:yerrTRKnc:zTRKnc:zerrTRKnc:ntrksTRKnc:xTRKc:xerrTRKc:yTRKc:yerrTRKc:zTRKc:zerrTRKc:ntrksTRKc");
119 fOutput->Add(fNtupleVertexESD);
121 fhSPDVertexX = new TH1F("fhSPDVertexX","SPDVertex x; x vertex [cm]; events",200,-1,1);
122 fOutput->Add(fhSPDVertexX);
123 fhSPDVertexY = new TH1F("fhSPDVertexY","SPDVertex y; y vertex [cm]; events",200,-1,1);
124 fOutput->Add(fhSPDVertexY);
125 fhSPDVertexZ = new TH1F("fhSPDVertexZ","SPDVertex z; z vertex [cm]; events",200,-20,20);
126 fOutput->Add(fhSPDVertexZ);
127 fhTRKVertexX = new TH1F("fhTRKVertexX","TRKVertex x; x vertex [cm]; events",200,-1,1);
128 fOutput->Add(fhTRKVertexX);
129 fhTRKVertexY = new TH1F("fhTRKVertexY","TRKVertex y; y vertex [cm]; events",200,-1,1);
130 fOutput->Add(fhTRKVertexY);
131 fhTRKVertexZ = new TH1F("fhTRKVertexZ","TRKVertex z; z vertex [cm]; events",200,-20,20);
132 fOutput->Add(fhTRKVertexZ);
133 fhTPCVertexX = new TH1F("fhTPCVertexX","TPCVertex x; x vertex [cm]; events",200,-3,3);
134 fOutput->Add(fhTPCVertexX);
135 fhTPCVertexY = new TH1F("fhTPCVertexY","TPCVertex y; y vertex [cm]; events",200,-3,3);
136 fOutput->Add(fhTPCVertexY);
137 fhTPCVertexZ = new TH1F("fhTPCVertexZ","TPCVertex z; z vertex [cm]; events",200,-20,20);
138 fOutput->Add(fhTPCVertexZ);
140 fhTrackRefs = new TH2F("fhTrackRefs","Track references; x; y",1000,-4,4,1000,-4,4);
141 fOutput->Add(fhTrackRefs);
146 //________________________________________________________________________
147 void AliAnalysisTaskVertexESD::UserExec(Option_t *)
150 // Called for each event
153 Printf("ERROR: fESD not available");
156 AliESDEvent* esdE = (AliESDEvent*) InputEvent();
158 if(fCheckEventType && (esdE->GetEventType())!=7) return;
162 mcVertex[0]=9999.; mcVertex[1]=9999.; mcVertex[2]=9999.;
163 Float_t dNchdy=-999.;
164 // *********** MC info ***************
166 AliMCEventHandler* eventHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
168 Printf("ERROR: Could not retrieve MC event handler");
172 AliMCEvent* mcEvent = eventHandler->MCEvent();
174 Printf("ERROR: Could not retrieve MC event");
178 AliStack* stack = mcEvent->Stack();
180 AliDebug(AliLog::kError, "Stack not available");
184 AliHeader* header = mcEvent->Header();
186 AliDebug(AliLog::kError, "Header not available");
189 AliGenEventHeader* genHeader = header->GenEventHeader();
190 genHeader->PrimaryVertex(mcVertex);
192 Int_t ngenpart = (Int_t)stack->GetNtrack();
193 //printf("# generated particles = %d\n",ngenpart);
195 for(Int_t ip=0; ip<ngenpart; ip++) {
196 TParticle* part = (TParticle*)stack->Particle(ip);
197 // keep only electorns, muons, pions, kaons and protons
198 Int_t apdg = TMath::Abs(part->GetPdgCode());
199 if(apdg!=11 && apdg!=13 && apdg!=211 && apdg!=321 && apdg!=2212) continue;
200 // reject secondaries
201 if(TMath::Sqrt((part->Vx()-mcVertex[0])*(part->Vx()-mcVertex[0])+(part->Vy()-mcVertex[1])*(part->Vy()-mcVertex[1]))>0.0010) continue;
202 // reject incoming protons
203 Double_t energy = part->Energy();
204 if(energy>900.) continue;
205 Double_t pz = part->Pz();
206 Double_t y = 0.5*TMath::Log((energy+pz+1.e-13)/(energy-pz+1.e-13));
207 if(TMath::Abs(y)<1.0) dNchdy += 0.5; // count 1/2 of particles in |y|<1
209 TClonesArray *trefs=0;
210 Int_t ntrefs = mcEvent->GetParticleAndTR(ip,part,trefs);
211 if(ntrefs<0) continue;
212 for(Int_t iref=0; iref<ntrefs; iref++) {
213 AliTrackReference *tref = (AliTrackReference*)trefs->At(iref);
214 if(tref->R()>10.) continue;
215 fhTrackRefs->Fill(tref->X(),tref->Y());
218 //printf("# primary particles = %7.1f\n",dNchdy);
220 // *********** MC info ***************
224 //ULong64_t triggerMask;
225 //ULong64_t spdFO = (1 << 14);
226 //ULong64_t v0left = (1 << 10);
227 //ULong64_t v0right = (1 << 11);
229 //triggerMask=esdE->GetTriggerMask();
230 // MB1: SPDFO || V0L || V0R
231 //Bool_t eventTriggered = (triggerMask & spdFO || ((triggerMask & v0left) || (triggerMask & v0right)));
233 //triggerMask & spdFO && ((triggerMask&v0left) || (triggerMask&v0right))
234 //Bool_t eventTriggered = (triggerMask & spdFO);
236 //static AliTriggerAnalysis* triggerAnalysis = new AliTriggerAnalysis();
237 Bool_t eventTriggered = 0;//triggerAnalysis->IsTriggerFired(esdE, AliTriggerAnalysis::kSPDGFO /*| AliTriggerAnalysis::kOfflineFlag*/);
239 // use response of AliPhysicsSelection
240 eventTriggered = ((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();
242 Int_t ntracks = esdE->GetNumberOfTracks();
243 Int_t nITS5or6=0,nTPCin=0,nTPCinEta09=0;
244 //printf("Tracks # = %d\n",esdE->GetNumberOfTracks());
245 for(Int_t itr=0; itr<ntracks; itr++) {
246 AliESDtrack *t = esdE->GetTrack(itr);
247 if(t->GetNcls(0)>=5) nITS5or6++;
248 Double_t z0; t->GetZAt(0,esdE->GetMagneticField(),z0);
249 if(t->GetNcls(1)>0 && TMath::Abs(t->GetD(0,0,esdE->GetMagneticField()))<2.8 && TMath::Abs(z0)<20) {
251 if(TMath::Abs(t->GetTgl())<1.5) nTPCinEta09++;
256 const AliESDVertex *spdv=esdE->GetPrimaryVertexSPD();
257 const AliESDVertex *spdvp=esdE->GetPileupVertexSPD(0);
258 const AliESDVertex *tpcv=esdE->GetPrimaryVertexTPC();
259 const AliESDVertex *trkv=esdE->GetPrimaryVertexTracks();
261 const AliMultiplicity *alimult = esdE->GetMultiplicity();
262 Int_t ntrklets=0,spd0cls=0;
264 ntrklets = alimult->GetNumberOfTracklets();
265 for(Int_t l=0;l<alimult->GetNumberOfTracklets();l++){
266 if(alimult->GetDeltaPhi(l)<-9998.) ntrklets--;
268 spd0cls = alimult->GetNumberOfSingleClusters()+ntrklets;
274 if(spdv->GetNContributors()>0) {
275 TString title=spdv->GetTitle();
276 if(title.Contains("3D")) {
277 fhSPDVertexX->Fill(spdv->GetXv());
278 fhSPDVertexY->Fill(spdv->GetYv());
280 fhSPDVertexZ->Fill(spdv->GetZv());
285 if(trkv->GetNContributors()>0) {
286 fhTRKVertexX->Fill(trkv->GetXv());
287 fhTRKVertexY->Fill(trkv->GetYv());
288 fhTRKVertexZ->Fill(trkv->GetZv());
293 if(tpcv->GetNContributors()>0) {
294 fhTPCVertexX->Fill(tpcv->GetXv());
295 fhTPCVertexY->Fill(tpcv->GetYv());
296 fhTPCVertexZ->Fill(tpcv->GetZv());
303 Float_t expile=-999.;
304 Float_t eypile=-999.;
305 Float_t ezpile=-999.;
308 if(esdE->GetNumberOfPileupVerticesSPD()>0 && spdvp){
309 xpile=spdvp->GetXv();
310 expile=spdvp->GetXRes();
311 ypile=spdvp->GetYv();
312 eypile=spdvp->GetYRes();
313 zpile=spdvp->GetZv();
314 ezpile=spdvp->GetZRes();
315 ntrkspile=spdvp->GetNContributors();
320 Float_t xnt[74]; for(Int_t iii=0;iii<isize;iii++) xnt[iii]=0.;
324 xnt[index++]=(Float_t)esdE->GetRunNumber();
325 xnt[index++]=(Float_t)esdE->GetTimeStamp();
326 xnt[index++]=(Float_t)esdE->GetBunchCrossNumber();
327 xnt[index++]=(eventTriggered ? 1. : 0.);
329 xnt[index++]=(Float_t)dNchdy;
332 xnt[index++]=mcVertex[0];
333 xnt[index++]=mcVertex[1];
334 xnt[index++]=mcVertex[2];
336 xnt[index++]=spdv->GetXv();
337 xnt[index++]=spdv->GetXRes();
338 xnt[index++]=spdv->GetYv();
339 xnt[index++]=spdv->GetYRes();
340 xnt[index++]=spdv->GetZv();
341 xnt[index++]=spdv->GetZRes();
342 xnt[index++]=spdv->GetNContributors();
343 TString spdtitle = spdv->GetTitle();
344 xnt[index++]=(spdtitle.Contains("vertexer: 3D") ? 1. : 0.);
345 xnt[index++]=spdv->GetDispersion();
347 xnt[index++]=tpcv->GetXv();
348 xnt[index++]=tpcv->GetXRes();
349 xnt[index++]=tpcv->GetYv();
350 xnt[index++]=tpcv->GetYRes();
351 xnt[index++]=tpcv->GetZv();
352 xnt[index++]=tpcv->GetZRes();
353 xnt[index++]=tpcv->GetNContributors();
354 TString tpctitle = tpcv->GetTitle();
355 xnt[index++]=(tpctitle.Contains("WithConstraint") ? 1. : 0.);
357 xnt[index++]=trkv->GetXv();
358 xnt[index++]=trkv->GetXRes();
359 xnt[index++]=trkv->GetYv();
360 xnt[index++]=trkv->GetYRes();
361 xnt[index++]=trkv->GetZv();
362 xnt[index++]=trkv->GetZRes();
363 xnt[index++]=trkv->GetNContributors();// tpccontrorig;
364 TString trktitle = trkv->GetTitle();
365 xnt[index++]=(trktitle.Contains("WithConstraint") ? 1. : 0.);
367 xnt[index++]=float(ntrklets);
368 xnt[index++]=float(ntracks);
369 xnt[index++]=float(nITS5or6);
370 xnt[index++]=float(nTPCin);
371 xnt[index++]=float(nTPCinEta09);
373 xnt[index++]=spd0cls;
381 xnt[index++]=(Float_t)ntrkspile;
385 // add recalculated vertices TRK and TPC
388 AliESDVertex *tpcvnc = ReconstructPrimaryVertexTPC(kFALSE);
389 xnt[index++]=tpcvnc->GetXv();
390 xnt[index++]=tpcvnc->GetXRes();
391 xnt[index++]=tpcvnc->GetYv();
392 xnt[index++]=tpcvnc->GetYRes();
393 xnt[index++]=tpcvnc->GetZv();
394 xnt[index++]=tpcvnc->GetZRes();
395 xnt[index++]=tpcvnc->GetNContributors();
396 delete tpcvnc; tpcvnc=0;
398 AliESDVertex *tpcvc = ReconstructPrimaryVertexTPC(kTRUE);
399 xnt[index++]=tpcvc->GetXv();
400 xnt[index++]=tpcvc->GetXRes();
401 xnt[index++]=tpcvc->GetYv();
402 xnt[index++]=tpcvc->GetYRes();
403 xnt[index++]=tpcvc->GetZv();
404 xnt[index++]=tpcvc->GetZRes();
405 xnt[index++]=tpcvc->GetNContributors();
406 delete tpcvc; tpcvc=0;
410 AliESDVertex *trkvnc = ReconstructPrimaryVertexITSTPC(kFALSE);
411 xnt[index++]=trkvnc->GetXv();
412 xnt[index++]=trkvnc->GetXRes();
413 xnt[index++]=trkvnc->GetYv();
414 xnt[index++]=trkvnc->GetYRes();
415 xnt[index++]=trkvnc->GetZv();
416 xnt[index++]=trkvnc->GetZRes();
417 xnt[index++]=trkvnc->GetNContributors();
418 delete trkvnc; trkvnc=0;
420 AliESDVertex *trkvc = ReconstructPrimaryVertexITSTPC(kTRUE);
421 xnt[index++]=trkvc->GetXv();
422 xnt[index++]=trkvc->GetXRes();
423 xnt[index++]=trkvc->GetYv();
424 xnt[index++]=trkvc->GetYRes();
425 xnt[index++]=trkvc->GetZv();
426 xnt[index++]=trkvc->GetZRes();
427 xnt[index++]=trkvc->GetNContributors();
428 delete trkvc; trkvc=0;
431 if(index>isize) printf("AliAnalysisTaskVertexESD: ERROR, index!=isize\n");
432 if(fFillNtuple) fNtupleVertexESD->Fill(xnt);
434 // Post the data already here
435 PostData(1, fOutput);
440 //________________________________________________________________________
441 void AliAnalysisTaskVertexESD::Terminate(Option_t *)
443 // Draw result to the screen
444 // Called once at the end of the query
445 fOutput = dynamic_cast<TList*> (GetOutputData(1));
447 Printf("ERROR: fOutput not available");
451 fNtupleVertexESD = dynamic_cast<TNtuple*>(fOutput->FindObject("fNtupleVertexESD"));
456 //_________________________________________________________________________
457 AliESDVertex* AliAnalysisTaskVertexESD::ReconstructPrimaryVertexTPC(Bool_t constr) const {
458 // On the fly reco of TPC vertex from ESD
459 AliESDEvent* evt = (AliESDEvent*) fInputEvent;
460 AliVertexerTracks vertexer(evt->GetMagneticField());
461 vertexer.SetTPCMode(); // defaults
462 Float_t diamondcovxy[3]; evt->GetDiamondCovXY(diamondcovxy);
463 Double_t pos[3]={evt->GetDiamondX(),evt->GetDiamondY(),0};
464 Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.*10.};
465 AliESDVertex *initVertex = new AliESDVertex(pos,cov,1.,1);
466 vertexer.SetVtxStart(initVertex);
468 if(!constr) vertexer.SetConstraintOff();
470 return vertexer.FindPrimaryVertex(evt);
473 //_________________________________________________________________________
474 AliESDVertex* AliAnalysisTaskVertexESD::ReconstructPrimaryVertexITSTPC(Bool_t constr) const {
475 // On the fly reco of ITS+TPC vertex from ESD
476 AliESDEvent* evt = (AliESDEvent*) fInputEvent;
477 AliVertexerTracks vertexer(evt->GetMagneticField());
478 vertexer.SetITSMode(); // defaults
479 vertexer.SetMinClusters(4); // default is 5
480 Float_t diamondcovxy[3]; evt->GetDiamondCovXY(diamondcovxy);
481 Double_t pos[3]={evt->GetDiamondX(),evt->GetDiamondY(),0};
482 Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.*10.};
483 AliESDVertex *initVertex = new AliESDVertex(pos,cov,1.,1);
484 vertexer.SetVtxStart(initVertex);
486 if(!constr) vertexer.SetConstraintOff();
488 // use only ITS-TPC or only ITS-SA tracks
489 if(fOnlyITSTPCTracks || fOnlyITSSATracks) {
491 Int_t *skip = new Int_t[evt->GetNumberOfTracks()];
492 for(Int_t itr=0;itr<evt->GetNumberOfTracks(); itr++) {
493 AliESDtrack* track = evt->GetTrack(itr);
494 if(fOnlyITSTPCTracks && track->GetNcls(1)==0) { // skip ITSSA
497 if(fOnlyITSSATracks && track->GetNcls(1)>0) { // skip ITSTPC
501 vertexer.SetSkipTracks(iskip,skip);
502 delete [] skip; skip=NULL;
505 return vertexer.FindPrimaryVertex(evt);