1 /*************************************************************************
2 * Copyright(c) 1998-2011, 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 #include <TObjArray.h>
17 #include <TClonesArray.h>
23 #include "AliVertex.h"
24 #include "AliVVertex.h"
25 #include "AliESDVertex.h"
26 #include "AliVertexerTracks.h"
27 #include "AliAODEvent.h"
28 #include "AliAODTrack.h"
29 #include "AliAODMCParticle.h"
30 #include "AliExternalTrackParam.h"
31 #include "AliAODRecoDecayHF3Prong.h"
32 #include "AliAnalysisTaskSEImproveITS.h"
35 // Implementation of the "hybrid-approach" for ITS upgrade studies.
36 // The tastk smears the track parameters according to estimations
37 // from single-track upgrade studies. Afterwards it recalculates
38 // the parameters of the reconstructed decays.
40 // WARNING: This will affect all tasks in a train after this one
41 // (which is typically desired, though).
44 AliAnalysisTaskSEImproveITS::AliAnalysisTaskSEImproveITS()
64 fRunInVertexing(kFALSE),
71 // Default constructor.
75 AliAnalysisTaskSEImproveITS::AliAnalysisTaskSEImproveITS(const char *name,
76 const char *resfileCurURI,
77 const char *resfileUpgURI,
78 Bool_t isRunInVertexing,
80 :AliAnalysisTaskSE(name),
99 fRunInVertexing(isRunInVertexing),
106 // Constructor to be used to create the task.
107 // The the URIs specify the resolution files to be used.
108 // They are expected to contain TGraphs with the resolutions
109 // for the current and the upgraded ITS (see code for details).
110 // One may also specify for how many tracks debug information
111 // is written to the output.
113 TFile *resfileCur=TFile::Open(resfileCurURI);
114 fD0RPResPCur =new TGraph(*static_cast<TGraph*>(resfileCur->Get("D0RPResP" )));
115 fD0RPResKCur =new TGraph(*static_cast<TGraph*>(resfileCur->Get("D0RPResK" )));
116 fD0RPResPiCur=new TGraph(*static_cast<TGraph*>(resfileCur->Get("D0RPResPi")));
117 fD0ZResPCur =new TGraph(*static_cast<TGraph*>(resfileCur->Get("D0ZResP" )));
118 fD0ZResKCur =new TGraph(*static_cast<TGraph*>(resfileCur->Get("D0ZResK" )));
119 fD0ZResPiCur =new TGraph(*static_cast<TGraph*>(resfileCur->Get("D0ZResPi" )));
120 fPt1ResPCur =new TGraph(*static_cast<TGraph*>(resfileCur->Get("Pt1ResP" )));
121 fPt1ResKCur =new TGraph(*static_cast<TGraph*>(resfileCur->Get("Pt1ResK" )));
122 fPt1ResPiCur =new TGraph(*static_cast<TGraph*>(resfileCur->Get("Pt1ResPi" )));
123 fD0RPResPCur ->SetName("D0RPResPCur" );
124 fD0RPResKCur ->SetName("D0RPResKCur" );
125 fD0RPResPiCur->SetName("D0RPResPiCur");
126 fD0ZResPCur ->SetName("D0ZResPCur" );
127 fD0ZResKCur ->SetName("D0ZResKCur" );
128 fD0ZResPiCur ->SetName("D0ZResPiCur" );
129 fPt1ResPCur ->SetName("Pt1ResPCur" );
130 fPt1ResKCur ->SetName("Pt1ResKCur" );
131 fPt1ResPiCur ->SetName("Pt1ResPiCur" );
133 TFile *resfileUpg=TFile::Open(resfileUpgURI );
134 fD0RPResPUpg =new TGraph(*static_cast<TGraph*>(resfileUpg->Get("D0RPResP" )));
135 fD0RPResKUpg =new TGraph(*static_cast<TGraph*>(resfileUpg->Get("D0RPResK" )));
136 fD0RPResPiUpg=new TGraph(*static_cast<TGraph*>(resfileUpg->Get("D0RPResPi")));
137 fD0ZResPUpg =new TGraph(*static_cast<TGraph*>(resfileUpg->Get("D0ZResP" )));
138 fD0ZResKUpg =new TGraph(*static_cast<TGraph*>(resfileUpg->Get("D0ZResK" )));
139 fD0ZResPiUpg =new TGraph(*static_cast<TGraph*>(resfileUpg->Get("D0ZResPi" )));
140 fPt1ResPUpg =new TGraph(*static_cast<TGraph*>(resfileUpg->Get("Pt1ResP" )));
141 fPt1ResKUpg =new TGraph(*static_cast<TGraph*>(resfileUpg->Get("Pt1ResK" )));
142 fPt1ResPiUpg =new TGraph(*static_cast<TGraph*>(resfileUpg->Get("Pt1ResPi" )));
143 fD0RPResPUpg ->SetName("D0RPResPUpg" );
144 fD0RPResKUpg ->SetName("D0RPResKUpg" );
145 fD0RPResPiUpg->SetName("D0RPResPiUpg");
146 fD0ZResPUpg ->SetName("D0ZResPUpg" );
147 fD0ZResKUpg ->SetName("D0ZResKUpg" );
148 fD0ZResPiUpg ->SetName("D0ZResPiUpg" );
149 fPt1ResPUpg ->SetName("Pt1ResPUpg" );
150 fPt1ResKUpg ->SetName("Pt1ResKUpg" );
151 fPt1ResPiUpg ->SetName("Pt1ResPiUpg" );
154 DefineOutput(1,TNtuple::Class());
157 AliAnalysisTaskSEImproveITS::~AliAnalysisTaskSEImproveITS() {
164 void AliAnalysisTaskSEImproveITS::UserCreateOutputObjects() {
166 // Creation of user output objects.
168 fDebugOutput=new TList();
169 fDebugOutput->SetOwner();
170 fDebugNtuple=new TNtuple("fDebugNtuple","Smearing","pdg:ptmc:d0rpo:d0zo:pt1o:sd0rpo:sd0zo:spt1o:d0rpn:d0zn:pt1n:sd0rpn:sd0zn:spt1n:d0rpmc:d0zmc:pt1mc");
171 fDebugVars=new Float_t[fDebugNtuple->GetNvar()];
173 fDebugOutput->Add(fDebugNtuple );
175 fDebugOutput->Add(fD0RPResPCur );
176 fDebugOutput->Add(fD0RPResKCur );
177 fDebugOutput->Add(fD0RPResPiCur);
178 fDebugOutput->Add(fD0ZResPCur );
179 fDebugOutput->Add(fD0ZResKCur );
180 fDebugOutput->Add(fD0ZResPiCur );
181 fDebugOutput->Add(fPt1ResPCur );
182 fDebugOutput->Add(fPt1ResKCur );
183 fDebugOutput->Add(fPt1ResPiCur );
184 fDebugOutput->Add(fD0RPResPUpg );
185 fDebugOutput->Add(fD0RPResKUpg );
186 fDebugOutput->Add(fD0RPResPiUpg);
187 fDebugOutput->Add(fD0ZResPUpg );
188 fDebugOutput->Add(fD0ZResKUpg );
189 fDebugOutput->Add(fD0ZResPiUpg );
190 fDebugOutput->Add(fPt1ResPUpg );
191 fDebugOutput->Add(fPt1ResKUpg );
192 fDebugOutput->Add(fPt1ResPiUpg );
194 PostData(1,fDebugOutput);
197 void AliAnalysisTaskSEImproveITS::UserExec(Option_t*) {
202 if(!fRunInVertexing) {
203 ev=dynamic_cast<AliAODEvent*>(InputEvent());
205 if(AODEvent() && IsStandardAOD()) ev = dynamic_cast<AliAODEvent*> (AODEvent());
208 Double_t bz=ev->GetMagneticField();
211 TClonesArray *mcs=static_cast<TClonesArray*>(ev->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
213 for(Int_t itrack=0;itrack<ev->GetNumberOfTracks();++itrack)
214 SmearTrack(ev->GetTrack(itrack),mcs);
216 // TODO: recalculated primary vertex
217 AliVVertex *primaryVertex=ev->GetPrimaryVertex();
219 // Recalculate all candidates
220 TClonesArray *array3Prong=static_cast<TClonesArray*>(ev->GetList()->FindObject("Charm3Prong"));
222 for (Int_t icand=0;icand<array3Prong->GetEntries();++icand) {
223 AliAODRecoDecayHF3Prong *decay=static_cast<AliAODRecoDecayHF3Prong*>(array3Prong->At(icand));
225 // recalculate vertices
226 AliVVertex *oldSecondaryVertex=decay->GetSecondaryVtx();
227 AliExternalTrackParam et1; et1.CopyFromVTrack(static_cast<AliAODTrack*>(decay->GetDaughter(0)));
228 AliExternalTrackParam et2; et2.CopyFromVTrack(static_cast<AliAODTrack*>(decay->GetDaughter(1)));
229 AliExternalTrackParam et3; et3.CopyFromVTrack(static_cast<AliAODTrack*>(decay->GetDaughter(2)));
230 TObjArray ta123,ta12,ta23;
231 ta123.Add(&et1);ta123.Add(&et2);ta123.Add(&et3);
232 ta12. Add(&et1);ta12 .Add(&et2);
233 ta23 .Add(&et2);ta23 .Add(&et3);
234 AliESDVertex *v123=RecalculateVertex(oldSecondaryVertex,&ta123,bz);
235 AliESDVertex *v12 =RecalculateVertex(oldSecondaryVertex,&ta12 ,bz);
236 AliESDVertex *v23 =RecalculateVertex(oldSecondaryVertex,&ta23 ,bz);
238 // update secondary vertex
241 decay->GetSecondaryVtx()->SetPosition(pos[0],pos[1],pos[2]);
242 decay->GetSecondaryVtx()->SetChi2perNDF(v123->GetChi2toNDF());
243 //TODO: covariance matrix
245 // update d0 for all progs
246 Double_t d0z0[2],covd0z0[3];
247 Double_t d0[3],d0err[3];
248 et1.PropagateToDCA(primaryVertex,bz,100.,d0z0,covd0z0);
250 d0err[0] = TMath::Sqrt(covd0z0[0]);
251 et2.PropagateToDCA(primaryVertex,bz,100.,d0z0,covd0z0);
253 d0err[1] = TMath::Sqrt(covd0z0[0]);
254 et3.PropagateToDCA(primaryVertex,bz,100.,d0z0,covd0z0);
256 d0err[2] = TMath::Sqrt(covd0z0[0]);
257 decay->Setd0Prongs (3,d0 );
258 decay->Setd0errProngs(3,d0err);
259 // TODO: setter missing
261 // update dca for prong combinations
262 Double_t xdummy=0.,ydummy=0.;
264 dca[0]=et1.GetDCA(&et2,bz,xdummy,ydummy);
265 dca[1]=et3.GetDCA(&et2,bz,xdummy,ydummy);
266 dca[2]=et1.GetDCA(&et3,bz,xdummy,ydummy);
267 decay->SetDCAs(3,dca);
269 // update dist12 and dist23
270 primaryVertex->GetXYZ(pos);
271 decay->SetDist12toPrim(TMath::Sqrt((v12->GetX()-pos[0])*(v12->GetX()-pos[0])
272 +(v12->GetY()-pos[1])*(v12->GetY()-pos[1])
273 +(v12->GetZ()-pos[2])*(v12->GetZ()-pos[2])));
274 decay->SetDist23toPrim(TMath::Sqrt((v23->GetX()-pos[0])*(v23->GetX()-pos[0])
275 +(v23->GetY()-pos[1])*(v23->GetY()-pos[1])
276 +(v23->GetZ()-pos[2])*(v23->GetZ()-pos[2])));
278 delete v123;delete v12;delete v23;
280 Double_t px[3],py[3],pz[3];
281 for (Int_t i=0;i<3;++i) {
282 const AliAODTrack *t=static_cast<AliAODTrack*>(decay->GetDaughter(i));
287 decay->SetPxPyPzProngs(3,px,py,pz);
292 void AliAnalysisTaskSEImproveITS::SmearTrack(AliAODTrack *track,const TClonesArray *mcs) {
293 // Early exit, if this track has nothing in common with the ITS
294 if (!(track->HasPointOnITSLayer(0) || track->HasPointOnITSLayer(1)))
297 // Get reconstructed track parameters
298 AliExternalTrackParam et; et.CopyFromVTrack(track);
299 Double_t *param=const_cast<Double_t*>(et.GetParameter());
300 //TODO: Double_t *covar=const_cast<Double_t*>(et.GetCovariance());
303 Int_t imc=track->GetLabel();
305 const AliAODMCParticle *mc=static_cast<AliAODMCParticle*>(mcs->At(imc));
308 Double_t mccv[36]={0.};
313 AliExternalTrackParam mct(mcx,mcp,mccv,mcc);
314 const Double_t *parammc=mct.GetParameter();
315 //TODO: const Double_t *covermc=mct.GetCovariance();
316 AliVertex vtx(mcx,1.,1);
318 // Correct reference points and frames according to MC
319 // TODO: B-Field correct?
320 // TODO: failing propagation....
321 et.PropagateToDCA(&vtx,track->GetBz(),10.);
322 et.Rotate(mct.GetAlpha());
324 // Select appropriate smearing functions
325 Double_t ptmc=TMath::Abs(mc->Pt());
332 switch (mc->GetPdgCode()) {
333 case 2212: case -2212:
334 sd0rpo=EvalGraph(fD0RPResPCur,ptmc);
335 sd0zo =EvalGraph(fD0ZResPCur ,ptmc);
336 spt1o =EvalGraph(fPt1ResPCur ,ptmc);
337 sd0rpn=EvalGraph(fD0RPResPUpg,ptmc);
338 sd0zn =EvalGraph(fD0ZResPUpg ,ptmc);
339 spt1n =EvalGraph(fPt1ResPUpg ,ptmc);
342 sd0rpo=EvalGraph(fD0RPResKCur,ptmc);
343 sd0zo =EvalGraph(fD0ZResKCur ,ptmc);
344 spt1o =EvalGraph(fPt1ResKCur ,ptmc);
345 sd0rpn=EvalGraph(fD0RPResKUpg,ptmc);
346 sd0zn =EvalGraph(fD0ZResKUpg ,ptmc);
347 spt1n =EvalGraph(fPt1ResKUpg ,ptmc);
350 sd0rpo=EvalGraph(fD0RPResPiCur,ptmc);
351 sd0zo =EvalGraph(fD0ZResPiCur ,ptmc);
352 spt1o =EvalGraph(fPt1ResPiCur ,ptmc);
353 sd0rpn=EvalGraph(fD0RPResPiUpg,ptmc);
354 sd0zn =EvalGraph(fD0ZResPiUpg ,ptmc);
355 spt1n =EvalGraph(fPt1ResPiUpg ,ptmc);
361 // Use the same units (i.e. cm and GeV/c)! TODO: pt!
367 // Apply the smearing
368 Double_t d0zo =param [1];
369 Double_t d0zmc =parammc[1];
370 Double_t d0rpo =param [0];
371 Double_t d0rpmc=parammc[0];
372 Double_t pt1o =param [4];
373 Double_t pt1mc =parammc[4];
374 Double_t dd0zo =d0zo-d0zmc;
375 Double_t dd0zn =dd0zo *(sd0zo >0. ? (sd0zn /sd0zo ) : 1.);
376 Double_t d0zn =d0zmc+dd0zn;
377 Double_t dd0rpo=d0rpo-d0rpmc;
378 Double_t dd0rpn=dd0rpo*(sd0rpo>0. ? (sd0rpn/sd0rpo) : 1.);
379 Double_t d0rpn =d0rpmc+dd0rpn;
380 Double_t dpt1o =pt1o-pt1mc;
381 Double_t dpt1n =dpt1o *(spt1o >0. ? (spt1n /spt1o ) : 1.);
382 Double_t pt1n =pt1mc+dpt1n;
387 // Copy the smeared parameters to the AOD track
392 track->SetPosition(x,kFALSE);
393 track->SetP(p,kTRUE);
395 // write out debug infos
396 if (fDebugNtuple->GetEntries()<fNDebug) {
398 fDebugVars[idbg++]=mc->GetPdgCode();
399 fDebugVars[idbg++]=ptmc ;
400 fDebugVars[idbg++]=d0rpo ;
401 fDebugVars[idbg++]=d0zo ;
402 fDebugVars[idbg++]=pt1o ;
403 fDebugVars[idbg++]=sd0rpo;
404 fDebugVars[idbg++]=sd0zo ;
405 fDebugVars[idbg++]=spt1o ;
406 fDebugVars[idbg++]=d0rpn ;
407 fDebugVars[idbg++]=d0zn ;
408 fDebugVars[idbg++]=pt1n ;
409 fDebugVars[idbg++]=sd0rpn;
410 fDebugVars[idbg++]=sd0zn ;
411 fDebugVars[idbg++]=spt1n ;
412 fDebugVars[idbg++]=d0rpmc;
413 fDebugVars[idbg++]=d0zmc ;
414 fDebugVars[idbg++]=pt1mc ;
415 fDebugNtuple->Fill(fDebugVars);
416 PostData(1,fDebugOutput);
420 AliESDVertex* AliAnalysisTaskSEImproveITS::RecalculateVertex(const AliVVertex *old,TObjArray *tracks,Double_t bField) {
422 // Helper function to recalculate a vertex.
425 static UShort_t ids[]={1,2,3}; //TODO: unsave...
426 AliVertexerTracks vertexer(bField);
427 vertexer.SetVtxStart(old->GetX(),old->GetY(),old->GetZ());
428 AliESDVertex *vertex=vertexer.VertexForSelectedTracks(tracks,ids);
432 Double_t AliAnalysisTaskSEImproveITS::EvalGraph(const TGraph *graph,Double_t x) const {
434 // Evaluates a TGraph without linear extrapolation. Instead the last
435 // valid point of the graph is used when out of range.
436 // The function assumes an ascending order of X.
439 // TODO: find a pretty solution for this:
440 Int_t n =graph->GetN();
441 Double_t xmin=graph->GetX()[0 ];
442 Double_t xmax=graph->GetX()[n-1];
443 if (x<xmin) return graph->Eval(xmin);
444 if (x>xmax) return graph->Eval(xmax);
445 return graph->Eval(x);
448 ClassImp(AliAnalysisTaskSEImproveITS);