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"
50 #include "AliMCEventHandler.h"
51 #include "AliMCEvent.h"
55 #include "AliGenEventHeader.h"
56 #include "AliAnalysisTaskVertexESD.h"
59 ClassImp(AliAnalysisTaskVertexESD)
61 //________________________________________________________________________
62 AliAnalysisTaskVertexESD::AliAnalysisTaskVertexESD(const char *name) :
63 AliAnalysisTask(name, "VertexESDTask"),
72 // Define input and output slots here
73 // Input slot #0 works with a TChain
74 DefineInput(0, TChain::Class());
75 // Output slot #0 writes into a TList container
76 DefineOutput(0, TList::Class()); //My private output
78 //________________________________________________________________________
79 AliAnalysisTaskVertexESD::~AliAnalysisTaskVertexESD()
83 // histograms are in the output list and deleted when the output
84 // list is deleted by the TSelector dtor
92 //________________________________________________________________________
93 void AliAnalysisTaskVertexESD::ConnectInputData(Option_t *)
95 // Connect ESD or AOD here
98 TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
100 Printf("ERROR: Could not read chain from input slot 0");
103 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
106 Printf("ERROR: Could not get ESDInputHandler");
108 fESD = esdH->GetEvent();
116 //________________________________________________________________________
117 void AliAnalysisTaskVertexESD::CreateOutputObjects()
122 // Several histograms are more conveniently managed in a TList
126 fNtupleVertexESD = new TNtuple("fNtupleVertexESD","vertices","run:tstamp:xtrue:ytrue:ztrue:xSPD:xerrSPD:ySPD:yerrSPD:zSPD:zerrSPD:ntrksSPD:xTPC:xerrTPC:yTPC:yerrTPC:zTPC:zerrTPC:ntrksTPC:xTRK:xerrTRK:yTRK:yerrTRK:zTRK:zerrTRK:ntrksTRK:ntrklets:nESDtracks:nITSrefit5or6:nTPCin:nTPCinEta09:dndygen:triggered:SPD3D:SPD0cls:constrTRK:constrTPC");
128 fOutput->Add(fNtupleVertexESD);
130 fhTrackRefs = new TH2F("fhTrackRefs","Track references; x; y",1000,-4,4,1000,-4,4);
131 fOutput->Add(fhTrackRefs);
136 //________________________________________________________________________
137 void AliAnalysisTaskVertexESD::Exec(Option_t *)
140 // Called for each event
143 Printf("ERROR: fESD not available");
149 mcVertex[0]=9999.; mcVertex[1]=9999.; mcVertex[2]=9999.;
150 Float_t dNchdy=-999.;
152 // *********** MC info ***************
154 AliMCEventHandler* eventHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
156 Printf("ERROR: Could not retrieve MC event handler");
160 AliMCEvent* mcEvent = eventHandler->MCEvent();
162 Printf("ERROR: Could not retrieve MC event");
166 AliStack* stack = mcEvent->Stack();
168 AliDebug(AliLog::kError, "Stack not available");
172 AliHeader* header = mcEvent->Header();
174 AliDebug(AliLog::kError, "Header not available");
177 AliGenEventHeader* genHeader = header->GenEventHeader();
178 genHeader->PrimaryVertex(mcVertex);
180 Int_t ngenpart = (Int_t)stack->GetNtrack();
181 //printf("# generated particles = %d\n",ngenpart);
183 for(Int_t ip=0; ip<ngenpart; ip++) {
184 TParticle* part = (TParticle*)stack->Particle(ip);
185 // keep only electorns, muons, pions, kaons and protons
186 Int_t apdg = TMath::Abs(part->GetPdgCode());
187 if(apdg!=11 && apdg!=13 && apdg!=211 && apdg!=321 && apdg!=2212) continue;
188 // reject secondaries
189 if(TMath::Sqrt((part->Vx()-mcVertex[0])*(part->Vx()-mcVertex[0])+(part->Vy()-mcVertex[1])*(part->Vy()-mcVertex[1]))>0.0010) continue;
190 // reject incoming protons
191 Double_t energy = part->Energy();
192 if(energy>900.) continue;
193 Double_t pz = part->Pz();
194 Double_t y = 0.5*TMath::Log((energy+pz+1.e-13)/(energy-pz+1.e-13));
195 if(TMath::Abs(y)<1.0) dNchdy += 0.5; // count 1/2 of particles in |y|<1
197 TClonesArray *trefs=0;
198 Int_t ntrefs = mcEvent->GetParticleAndTR(ip,part,trefs);
199 if(ntrefs<0) continue;
200 for(Int_t iref=0; iref<ntrefs; iref++) {
201 AliTrackReference *tref = (AliTrackReference*)trefs->At(iref);
202 if(tref->R()>10.) continue;
203 fhTrackRefs->Fill(tref->X(),tref->Y());
206 //printf("# primary particles = %7.1f\n",dNchdy);
208 // *********** MC info ***************
212 ULong64_t triggerMask;
213 ULong64_t spdFO = (1 << 14);
214 ULong64_t v0left = (1 << 11);
215 ULong64_t v0right = (1 << 12);
217 triggerMask=fESD->GetTriggerMask();
218 // MB1: SPDFO || V0L || V0R
219 Bool_t eventTriggered = (triggerMask & spdFO || ((triggerMask & v0left) || (triggerMask & v0right)));
221 //triggerMask & spdFO && ((triggerMask&v0left) || (triggerMask&v0right))
224 Int_t ntracks = fESD->GetNumberOfTracks();
225 Int_t nITS5or6=0,nTPCin=0,nTPCinEta09=0;
226 //printf("Tracks # = %d\n",fESD->GetNumberOfTracks());
227 for(Int_t itr=0; itr<ntracks; itr++) {
228 AliESDtrack *t = fESD->GetTrack(itr);
229 if(t->GetNcls(0)>=5) nITS5or6++;
230 Double_t z0; t->GetZAt(0,fESD->GetMagneticField(),z0);
231 if(t->GetNcls(1)>0 && TMath::Abs(t->GetD(0,0,fESD->GetMagneticField()))<2.8 && TMath::Abs(z0)<20) {
233 if(TMath::Abs(t->GetTgl())<1.5) nTPCinEta09++;
238 const AliESDVertex *spdv=fESD->GetPrimaryVertexSPD();
239 const AliESDVertex *tpcv=fESD->GetPrimaryVertexTPC();
240 const AliESDVertex *trkv=fESD->GetPrimaryVertex();
242 //Float_t tpccontrorig=tpcv->GetNContributors();
245 //tpcv = ReconstructPrimaryVertexTPC();
247 const AliMultiplicity *alimult = fESD->GetMultiplicity();
248 Int_t ntrklets=0,spd0cls=0;
250 ntrklets = alimult->GetNumberOfTracklets();
251 for(Int_t l=0;l<alimult->GetNumberOfTracklets();l++){
252 if(alimult->GetDeltaPhi(l)<-9998.) ntrklets--;
254 spd0cls = alimult->GetNumberOfSingleClusters()+ntrklets;
263 xnt[index++]=(Float_t)fESD->GetRunNumber();
264 xnt[index++]=(Float_t)fESD->GetTimeStamp();
266 xnt[index++]=mcVertex[0];
267 xnt[index++]=mcVertex[1];
268 xnt[index++]=mcVertex[2];
270 xnt[index++]=spdv->GetXv();
271 xnt[index++]=spdv->GetXRes();
272 xnt[index++]=spdv->GetYv();
273 xnt[index++]=spdv->GetYRes();
274 xnt[index++]=spdv->GetZv();
275 xnt[index++]=spdv->GetZRes();
276 xnt[index++]=spdv->GetNContributors();
278 xnt[index++]=tpcv->GetXv();
279 xnt[index++]=tpcv->GetXRes();
280 xnt[index++]=tpcv->GetYv();
281 xnt[index++]=tpcv->GetYRes();
282 xnt[index++]=tpcv->GetZv();
283 xnt[index++]=tpcv->GetZRes();
284 xnt[index++]=tpcv->GetNContributors();
286 xnt[index++]=trkv->GetXv();
287 xnt[index++]=trkv->GetXRes();
288 xnt[index++]=trkv->GetYv();
289 xnt[index++]=trkv->GetYRes();
290 xnt[index++]=trkv->GetZv();
291 xnt[index++]=trkv->GetZRes();
292 xnt[index++]=trkv->GetNContributors();// tpccontrorig;
295 xnt[index++]=float(ntrklets);
296 xnt[index++]=float(ntracks);
297 xnt[index++]=float(nITS5or6);
298 xnt[index++]=float(nTPCin);
299 xnt[index++]=float(nTPCinEta09);
301 xnt[index++]=float(dNchdy);
303 xnt[index++]=(eventTriggered ? 1. : 0.);
305 TString spdtitle = spdv->GetTitle();
306 xnt[index++]=(spdtitle.Contains("vertexer: 3D") ? 1. : 0.);
308 xnt[index++]=spd0cls;
310 TString trktitle = trkv->GetTitle();
311 xnt[index++]=(trktitle.Contains("WithConstraint") ? 1. : 0.);
313 TString tpctitle = tpcv->GetTitle();
314 xnt[index++]=(tpctitle.Contains("WithConstraint") ? 1. : 0.);
317 if(index!=isize) printf("AliAnalysisTaskVertexESD: ERROR, index!=isize\n");
319 fNtupleVertexESD->Fill(xnt);
321 // Post the data already here
322 PostData(0, fOutput);
327 //________________________________________________________________________
328 void AliAnalysisTaskVertexESD::Terminate(Option_t *)
330 // Draw result to the screen
331 // Called once at the end of the query
332 fOutput = dynamic_cast<TList*> (GetOutputData(0));
334 Printf("ERROR: fOutput not available");
338 fNtupleVertexESD = dynamic_cast<TNtuple*>(fOutput->FindObject("fNtupleVertexESD"));
343 //_________________________________________________________________________
344 AliESDVertex* AliAnalysisTaskVertexESD::ReconstructPrimaryVertexTPC() const {
345 // On the fly reco of TPC vertex from ESD
347 AliVertexerTracks vertexer(fESD->GetMagneticField());
348 vertexer.SetTPCMode(); // defaults
349 //vertexer.SetTPCMode(0.1,1.0,5.,0,1,3.,0.1,1.5);
350 Double_t pos[3]={+0.0220,-0.0340,+0.270};
351 Double_t err[3]={0.0200,0.0200,7.5};
352 AliESDVertex *initVertex = new AliESDVertex(pos,err);
353 vertexer.SetVtxStart(initVertex);
355 vertexer.SetConstraintOff();
357 return vertexer.FindPrimaryVertex(fESD);