1 #include "AliAnalysisTask.h"
2 #include "AliAnalysisManager.h"
3 #include "AliAnalysisDataContainer.h"
4 #include "AliITSRecPoint.h"
5 #include "AliESDEvent.h"
8 #include "AliTrackPointArray.h"
9 #include "AliITSgeomTGeo.h"
10 #include "AliITSTPArrayFit.h"
11 #include "AliESDfriend.h"
12 #include "AliCDBManager.h"
13 #include "AliCDBEntry.h"
14 #include "AliITSCalibrationSDD.h"
15 #include "AliITSresponseSDD.h"
16 #include "AliGeomManager.h"
17 #include "AliMultiplicity.h"
24 #include <TGeoGlobalMagField.h>
25 #include "AliESDInputHandlerRP.h"
26 #include "AliITSSumTP.h"
29 /**************************************************************************
30 * Copyright(c) 1998-2010, ALICE Experiment at CERN, All rights reserved. *
32 * Author: The ALICE Off-line Project. *
33 * Contributors are mentioned in the code where appropriate. *
35 * Permission to use, copy, modify and distribute this software and its *
36 * documentation strictly for non-commercial purposes is hereby granted *
37 * without fee, provided that the above copyright notice appears in all *
38 * copies and that both the copyright notice and this permission notice *
39 * appear in the supporting documentation. The authors make no claims *
40 * about the suitability of this software for any purpose. It is *
41 * provided "as is" without express or implied warranty. *
42 **************************************************************************/
44 //*************************************************************************
45 // Implementation of class AliAnalysiTaskITSAlignQA
46 // AliAnalysisTaskSE to extract from ESD + ESDfriends
47 // the track-to-point residuals and dE/dx vs, time for SDD modules
49 // Author: F. Prino, prino@to.infn.it
50 //*************************************************************************
53 #include "AliAnalysisTaskITSAlignQA.h"
55 ClassImp(AliAnalysisTaskITSAlignQA)
56 //______________________________________________________________________________
57 AliAnalysisTaskITSAlignQA::AliAnalysisTaskITSAlignQA() : AliAnalysisTaskSE("SDD Calibration"),
61 fDoSPDResiduals(kTRUE),
62 fDoSDDResiduals(kTRUE),
63 fDoSSDResiduals(kTRUE),
64 fDoSDDdEdxCalib(kTRUE),
65 fDoSDDVDriftCalib(kTRUE),
66 fDoSDDDriftTime(kTRUE),
67 fDoFillTPTree(kFALSE),
68 fUseITSsaTracks(kFALSE),
69 fLoadGeometry(kFALSE),
71 fUseVertexForZOnly(kFALSE),
72 fUseTPCMomentum(kFALSE),
73 fMinVtxContributors(5),
74 fRemovePileupWithSPD(kTRUE),
87 fOCDBLocation("local://$ALICE_ROOT/OCDB")
90 fFitter = new AliITSTPArrayFit(5);
91 Double_t xbins[9]={0.3,0.5,0.75,1.,1.5,2.,3.,5.,10.};
92 SetPtBinLimits(8,xbins);
93 DefineOutput(1, TList::Class());
97 //___________________________________________________________________________
98 AliAnalysisTaskITSAlignQA::~AliAnalysisTaskITSAlignQA(){
100 if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
108 //___________________________________________________________________________
109 void AliAnalysisTaskITSAlignQA::UserCreateOutputObjects() {
112 if(fLoadGeometry) LoadGeometryFromOCDB();
114 fOutput = new TList();
116 fOutput->SetName("OutputHistos");
118 fHistNEvents = new TH1F("hNEvents", "Number of processed events",kNEvStatBins,-0.5,kNEvStatBins-0.5);
119 fHistNEvents->Sumw2();
120 fHistNEvents->SetMinimum(0);
121 fHistNEvents->GetXaxis()->SetBinLabel(kEvAll+1,"All Events");
122 fHistNEvents->GetXaxis()->SetBinLabel(kEvCnt+1,"After Centrality cut");
123 fHistNEvents->GetXaxis()->SetBinLabel(kEvVtx+1,"After Vertex cut");
124 fHistNEvents->GetXaxis()->SetBinLabel(kEvPlp+1,"After Pileup cut");
125 fHistNEvents->GetXaxis()->SetBinLabel(kNTracks+1,"Tracks Accepted");
126 fOutput->Add(fHistNEvents);
128 fHistPtAccept = new TH1F("hPtAccept","Pt distrib of accepted tracks",50,0.,5.);
129 fHistPtAccept->Sumw2();
130 fHistPtAccept->SetMinimum(0);
131 fOutput->Add(fHistPtAccept);
133 if(fDoSPDResiduals) CreateSPDHistos();
134 if(fDoSDDResiduals || fDoSDDdEdxCalib || fDoSDDVDriftCalib || fDoSDDDriftTime) CreateSDDHistos();
135 if(fDoSSDResiduals) CreateSSDHistos();
138 TFile* troutf = OpenFile(2);
140 AliFatal("Failed to open output file for AliITSSumTP tree");
143 fITSSumTP = new AliITSSumTP();
144 fTPTree = new TTree("ITSSumTP","ITS TP Summary");
145 fTPTree->Branch("AliITSSumTP","AliITSSumTP",&fITSSumTP);
152 //___________________________________________________________________________
153 void AliAnalysisTaskITSAlignQA::CreateSPDHistos(){
157 for(Int_t iMod=0; iMod<kNSPDmods; iMod++){
158 fHistSPDResidX[iMod] = new TH2F(Form("hSPDResidX%d",iMod),
159 Form("hSPDResidX%d",iMod),
160 fNPtBins,fPtBinLimits,
162 fHistSPDResidX[iMod]->Sumw2();
163 fOutput->Add(fHistSPDResidX[iMod]);
165 fHistSPDResidZ[iMod] = new TH2F(Form("hSPDResidZ%d",iMod),
166 Form("hSPDResidZ%d",iMod),
167 fNPtBins,fPtBinLimits,
169 fHistSPDResidZ[iMod]->Sumw2();
170 fOutput->Add(fHistSPDResidZ[iMod]);
175 //___________________________________________________________________________
176 void AliAnalysisTaskITSAlignQA::CreateSDDHistos(){
179 for(Int_t iMod=0; iMod<kNSDDmods; iMod++){
180 if (fDoSDDResiduals) {
181 fHistSDDResidX[iMod] = new TH2F(Form("hSDDResidX%d",iMod+kNSPDmods),
182 Form("hSDDResidX%d",iMod+kNSPDmods),
183 fNPtBins,fPtBinLimits,
185 fHistSDDResidX[iMod]->Sumw2();
186 fOutput->Add(fHistSDDResidX[iMod]);
188 fHistSDDResidZ[iMod] = new TH2F(Form("hSDDResidZ%d",iMod+kNSPDmods),
189 Form("hSDDResidZ%d",iMod+kNSPDmods),
190 fNPtBins,fPtBinLimits,
192 fHistSDDResidZ[iMod]->Sumw2();
193 fOutput->Add(fHistSDDResidZ[iMod]);
195 fHistSDDResidXvsX[iMod] = new TH2F(Form("hSDDResidXvsX%d",iMod+kNSPDmods),
196 Form("hSDDResidXvsX%d",iMod+kNSPDmods),
197 40,-3.5,3.5,300,-0.15,0.15);
198 fHistSDDResidXvsX[iMod]->Sumw2();
199 fOutput->Add(fHistSDDResidXvsX[iMod]);
201 fHistSDDResidXvsZ[iMod] = new TH2F(Form("hSDDResidXvsZ%d",iMod+kNSPDmods),
202 Form("hSDDResidXvsZ%d",iMod+kNSPDmods),
203 10,-3.8,3.8,300,-0.15,0.15);
204 fHistSDDResidXvsZ[iMod]->Sumw2();
205 fOutput->Add(fHistSDDResidXvsZ[iMod]);
207 fHistSDDResidZvsX[iMod] = new TH2F(Form("hSDDResidZvsX%d",iMod+kNSPDmods),
208 Form("hSDDResidZvsX%d",iMod+kNSPDmods),
209 40,-3.5,3.5,200,-0.1,0.1);
210 fHistSDDResidZvsX[iMod]->Sumw2();
211 fOutput->Add(fHistSDDResidZvsX[iMod]);
213 fHistSDDResidZvsZ[iMod] = new TH2F(Form("hSDDResidZvsZ%d",iMod+kNSPDmods),
214 Form("hSDDResidZvsZ%d",iMod+kNSPDmods),
215 10,-3.8,3.8,200,-0.1,0.1);
216 fHistSDDResidZvsZ[iMod]->Sumw2();
217 fOutput->Add(fHistSDDResidZvsZ[iMod]);
221 if (fDoSDDVDriftCalib) {
222 for (int ix=0;ix<2;ix++) { // profile histos per side
224 char* hnm = Form("hpSDDResXvsXD%d_%d",iMod+kNSPDmods,ix);
225 int nbX = 50, nbZ = 20, nbXOffs = 2, nbZOffs = 2;
226 double xRange = 3.5085e4, zRange = 7.5264e4, xOffs = nbXOffs*xRange/nbX, zOffs = nbZOffs*zRange/nbZ;
227 fHProfSDDResidXvsXD[iMod][ix] = new TProfile(hnm, hnm, nbX+2*nbXOffs, -xOffs, xRange + xOffs);
228 fHProfSDDResidXvsXD[iMod][ix]->Sumw2();
229 fOutput->Add(fHProfSDDResidXvsXD[iMod][ix]);
231 hnm = Form("hpSDDDrTimevsXD%d_%d",iMod+kNSPDmods,ix);
232 fHProfSDDDrTimevsXD[iMod][ix] = new TProfile(hnm, hnm, nbX+2*nbXOffs, -xOffs, xRange + xOffs);
233 fHProfSDDDrTimevsXD[iMod][ix]->Sumw2();
234 fOutput->Add(fHProfSDDDrTimevsXD[iMod][ix]);
236 hnm = Form("hpSDDResXvsZ%d_%d",iMod+kNSPDmods,ix);
237 fHProfSDDResidXvsZ[iMod][ix] = new TProfile(hnm, hnm, nbZ+2*nbZOffs, -(0.5*zRange+zOffs),(0.5*zRange+zOffs));
238 fHProfSDDResidXvsZ[iMod][ix]->Sumw2();
239 fOutput->Add(fHProfSDDResidXvsZ[iMod][ix]);
241 hnm = Form("hpSDDDrTimevsZ%d_%d",iMod+kNSPDmods,ix);
242 fHProfSDDDrTimevsZ[iMod][ix] = new TProfile(hnm, hnm, nbZ+2*nbZOffs, -(0.5*zRange+zOffs),(0.5*zRange+zOffs));
243 fHProfSDDDrTimevsZ[iMod][ix]->Sumw2();
244 fOutput->Add(fHProfSDDDrTimevsZ[iMod][ix]);
250 fHistSDDdEdxvsDrTime[iMod] = new TH2F(Form("hSDDdEdxvsDrTime%d",iMod+kNSPDmods),
251 Form("hSDDdEdxvsDrTime%d",iMod+kNSPDmods),
252 16,0.,6400.,100,0.,300.);
253 fHistSDDdEdxvsDrTime[iMod]->Sumw2();
254 fOutput->Add(fHistSDDdEdxvsDrTime[iMod]);
257 if (fDoSDDDriftTime) {
258 fHistSDDDrTimeAll[iMod]=new TH1F(Form("hSDDDrTimeAll%d",iMod+kNSPDmods),
259 Form("hSDDDrTimeAll%d",iMod+kNSPDmods),
261 fHistSDDDrTimeAll[iMod]->Sumw2();
262 fHistSDDDrTimeAll[iMod]->SetMinimum(0.);
263 fOutput->Add(fHistSDDDrTimeAll[iMod]);
265 fHistSDDDrTimeExtra[iMod]=new TH1F(Form("hSDDDrTimeExtra%d",iMod+kNSPDmods),
266 Form("hSDDDrTimeExtra%d",iMod+kNSPDmods),
268 fHistSDDDrTimeExtra[iMod]->Sumw2();
269 fHistSDDDrTimeExtra[iMod]->SetMinimum(0.);
270 fOutput->Add(fHistSDDDrTimeExtra[iMod]);
272 fHistSDDDrTimeAttac[iMod]=new TH1F(Form("hSDDDrTimeAttac%d",iMod+kNSPDmods),
273 Form("hSDDDrTimeAttac%d",iMod+kNSPDmods),
275 fHistSDDDrTimeAttac[iMod]->Sumw2();
276 fHistSDDDrTimeAttac[iMod]->SetMinimum(0.);
277 fOutput->Add(fHistSDDDrTimeAttac[iMod]);
284 //___________________________________________________________________________
285 void AliAnalysisTaskITSAlignQA::CreateSSDHistos(){
287 for(Int_t iMod=0; iMod<kNSSDmods; iMod++){
288 fHistSSDResidX[iMod] = new TH2F(Form("hSSDResidX%d",iMod+kNSPDmods+kNSDDmods),
289 Form("hSSDResidX%d",iMod+kNSPDmods+kNSDDmods),
290 fNPtBins,fPtBinLimits,
292 fHistSSDResidX[iMod]->Sumw2();
293 fOutput->Add(fHistSSDResidX[iMod]);
295 fHistSSDResidZ[iMod] = new TH2F(Form("hSSDResidZ%d",iMod+kNSPDmods+kNSDDmods),
296 Form("hSSDResidZ%d",iMod+kNSPDmods+kNSDDmods),
297 fNPtBins,fPtBinLimits,
299 fHistSSDResidZ[iMod]->Sumw2();
300 fOutput->Add(fHistSSDResidZ[iMod]);
304 //______________________________________________________________________________
305 void AliAnalysisTaskITSAlignQA::UserExec(Option_t *)
308 static AliTrackPointArray* arrayITS = 0;
309 AliTrackPointArray* arrayITSNoVtx = 0;
311 AliESDEvent *esd = (AliESDEvent*) (InputEvent());
312 if (fITSSumTP) fITSSumTP->Reset();
315 printf("AliAnalysisTaskITSAlignQA::Exec(): bad ESD\n");
320 printf("AliAnalysisTaskITSAlignQA::Exec(): bad ESDfriend\n");
324 static Bool_t firstCheck = kTRUE;
327 if (TMath::Abs(esd->GetCurrentL3())<300) { // no field
329 AliInfo("No magnetic field: eliminating pt cut");
331 const AliESDRun *esdrn = esd->GetESDRun();
333 Int_t activeDetectors = esdrn->GetDetectorsInReco();
334 if ( !(activeDetectors & AliDAQ::kTPC) ) {
335 AliInfo("No TPC, suppress TPC points request");
336 SetUseITSstandaloneTracks(kTRUE);
337 SetUseTPCMomentum(kFALSE);
342 if (!AcceptCentrality(esd)) return;
343 fHistNEvents->Fill(kEvCnt);
345 const AliESDVertex* vtx=0,*vtxSPD=0;
346 fHistNEvents->Fill(kEvAll);
347 vtx = esd->GetPrimaryVertex();
348 vtxSPD = esd->GetPrimaryVertexSPD();
350 if (fUseVertex) { // check the vertex if it is requested as an extra point
351 if (!AcceptVertex(vtx,vtxSPD)) return;
354 fHistNEvents->Fill(kEvVtx);
355 if (fRemovePileupWithSPD){
356 // skip events tagged by SPD as pileup
357 if(esd->IsPileupFromSPD()) return;
359 fHistNEvents->Fill(kEvPlp);
362 fFitter->SetBz(esd->GetMagneticField());
364 const AliTrackPointArray *array = 0;
365 Int_t ntracks = esd->GetNumberOfTracks();
367 for (Int_t itrack=0; itrack < ntracks; itrack++) {
369 if (arrayITS) {delete arrayITS; arrayITS = 0;} // reset points from previous tracks
372 AliESDtrack * track = esd->GetTrack(itrack);
374 if(!AcceptTrack(track, vtx)) continue;
375 array = track->GetTrackPointArray();
377 arrayITS = PrepareTrack(array, vtx);
379 arrayITSNoVtx = PrepareTrack(array, 0);
380 arrayITSNoVtx->SetUniqueID(itrack);
381 fITSSumTP->AddTrack(arrayITSNoVtx);
384 fHistNEvents->Fill(kNTracks);
386 Int_t npts = arrayITS->GetNPoints();
387 Int_t npts1 = fUseVertexForZOnly ? npts-1 : npts;
390 FitAndFillSPD(1,arrayITS,npts1,track);
391 FitAndFillSPD(2,arrayITS,npts1,track);
393 if(fDoSDDResiduals || fDoSDDdEdxCalib || fDoSDDVDriftCalib || fDoSDDDriftTime) {
394 FitAndFillSDDrphi(arrayITS,npts,track);
395 if (fDoSDDResiduals) {
396 FitAndFillSDDz(3,arrayITS,npts1,track);
397 FitAndFillSDDz(4,arrayITS,npts1,track);
401 FitAndFillSSD(5,arrayITS,npts1,track);
402 FitAndFillSSD(6,arrayITS,npts1,track);
406 if (fITSSumTP) { // store vertex and mometum info
407 double xyz[3]={0,0,0};
408 fITSSumTP->SetVertex(vtx);
409 TObjArray& tps = fITSSumTP->GetTracks();
410 int ntp = tps.GetEntriesFast();
411 fITSSumTP->BookNTracks(ntp);
412 for (int it=ntp;it--;) {
413 AliTrackPointArray* tp = (AliTrackPointArray*)tps[it];
415 AliESDtrack* esdTr = esd->GetTrack(tp->GetUniqueID());
416 double crv = esdTr->GetC(esd->GetMagneticField());
417 double crve = TMath::Sqrt(esdTr->GetSigma1Pt2()) * esd->GetMagneticField()*kB2C;
418 fITSSumTP->SetCrvGlo(it,crv);
419 fITSSumTP->SetCrvGloErr(it,crve);
420 const AliExternalTrackParam* inTPC = esdTr->GetTPCInnerParam(); // TPC track at vtx
422 crv = inTPC->GetC(esd->GetMagneticField());
423 crve = TMath::Sqrt(inTPC->GetSigma1Pt2()) * TMath::Abs(esd->GetMagneticField()*kB2C);
424 fITSSumTP->SetCrvTPC(it,crv);
425 fITSSumTP->SetCrvTPCErr(it,crve);
427 inTPC = esdTr->GetInnerParam(); // TPC track at the inner wall
430 fITSSumTP->SetTPCInnerXYZ(it,xyz);
433 fITSSumTP->SetUniqueID(fCurrentRunNumber);
434 if (ntp) fTPTree->Fill();
442 //___________________________________________________________________________
443 Bool_t AliAnalysisTaskITSAlignQA::AcceptTrack(const AliESDtrack * track, const AliESDVertex* vtx)
445 // track selection cuts
448 if(track->GetNcls(1)>0) accept=kFALSE;
450 if(track->GetNcls(1)<fMinTPCpts) accept=kFALSE;
452 if(track->GetNcls(0) < fMinITSpts) accept=kFALSE;
453 Int_t trstatus=track->GetStatus();
454 if(!(trstatus&AliESDtrack::kITSrefit)) accept=kFALSE;
456 if (fUseTPCMomentum && track->IsOn(AliESDtrack::kTPCrefit)) pt = track->GetTPCInnerParam()->Pt();
457 else pt = track->Pt();
459 if(pt<fMinPt) accept=kFALSE;
461 // if vertex constraint is used, apply soft DCA cut
463 Double_t dz[2],cov[3];
464 AliExternalTrackParam trc = *track;
465 if (!trc.PropagateToDCA(vtx, fFitter->GetBz(), 3.0, dz, cov)) accept=kFALSE;
467 if (dz[0]*dz[0]/(1e-4+cov[0])>fCutDCAXY) accept=kFALSE;
468 if (dz[1]*dz[1]/(4e-4+cov[2])>fCutDCAZ) accept=kFALSE;
472 if(accept) fHistPtAccept->Fill(pt);
476 //___________________________________________________________________________
477 Bool_t AliAnalysisTaskITSAlignQA::AcceptVertex(const AliESDVertex * vtx, const AliESDVertex * vtxSPD) {
478 // vertex selection cuts
479 if (!vtx || vtx->GetStatus()<1) return kFALSE;
480 if (!vtxSPD || vtxSPD->GetStatus()<1) return kFALSE;
481 if (vtx->GetNContributors()<fMinVtxContributors) return kFALSE;
482 if (TMath::Abs(vtx->GetZ()-vtxSPD->GetZ())>0.3) return kFALSE;
486 //___________________________________________________________________________
487 void AliAnalysisTaskITSAlignQA::FitAndFillSPD(Int_t iLayer, const AliTrackPointArray *array, Int_t npts,AliESDtrack * track){
488 // fit track and fills histos for SPD
489 fFitter->AttachPoints(array,0, npts-1);
490 Int_t iPtSPD[4],modIdSPD[4];
492 Double_t resGlo[3],resLoc[3];
493 for(Int_t ipt=0; ipt<npts; ipt++) {
496 array->GetPoint(point,ipt);
497 Int_t volId = point.GetVolumeID();
498 if (volId == kVtxSensVID) continue; // this is a vertex constraint
499 Int_t layerId = AliGeomManager::VolUIDToLayer(volId,modId);
501 modId+=AliITSgeomTGeo::GetModuleIndex(layerId,1,1);
502 iPtSPD[nPtSPD] = ipt;
503 modIdSPD[nPtSPD] = modId;
505 fFitter->SetCovIScale(ipt,1e-4);
509 double pt = (fUseTPCMomentum && track->IsOn(AliESDtrack::kTPCrefit)) ? track->GetTPCInnerParam()->Pt() : track->Pt();
510 fFitter->Fit(track->Charge(),pt,0.);
511 Double_t chi2=fFitter->GetChi2NDF();
512 if ( chi2<0 || chi2>1e4 ) return; // fit failed, abandon this track
513 for (Int_t ip=0; ip<nPtSPD;ip++) {
514 fFitter->GetResiduals(resGlo,iPtSPD[ip]);
515 TGeoHMatrix *mcurr = AliITSgeomTGeo::GetMatrix(modIdSPD[ip]);
516 mcurr->MasterToLocalVect(resGlo,resLoc);
517 Int_t index=modIdSPD[ip];
518 fHistSPDResidX[index]->Fill(pt,resLoc[0]);
519 fHistSPDResidZ[index]->Fill(pt,resLoc[2]);
523 //___________________________________________________________________________
524 void AliAnalysisTaskITSAlignQA::FitAndFillSDDrphi(const AliTrackPointArray *array, Int_t npts, AliESDtrack * track){
525 // fit track and fills histos for SDD along rphi (drift coord.)
527 track->GetITSdEdxSamples(dedx);
529 fFitter->AttachPoints(array,0, npts-1);
530 Int_t iPtSDD[4],modIdSDD[4],modSide[4];
531 Double_t xLocSDD[4],zLocSDD[4],drTime[4];
534 Double_t resGlo[3],resLoc[3];
536 Double_t posGlo[3],posLoc[3];
538 for(Int_t ipt=0; ipt<npts; ipt++) {
541 array->GetPoint(point,ipt);
542 Int_t volId = point.GetVolumeID();
543 if (volId == kVtxSensVID) continue; // this is a vertex constraint
544 Int_t layerId = AliGeomManager::VolUIDToLayer(volId,modId);
545 if(layerId==3 || layerId==4){
546 drTime[nPtSDD] = point.GetDriftTime();
547 modId+=AliITSgeomTGeo::GetModuleIndex(layerId,1,1);
548 Int_t index=modId-kNSPDmods;
549 if (fDoSDDDriftTime) {
550 fHistSDDDrTimeAll[index]->Fill(drTime[nPtSDD]);
551 if(point.IsExtra()) fHistSDDDrTimeExtra[index]->Fill(drTime[nPtSDD]);
552 else fHistSDDDrTimeAttac[index]->Fill(drTime[nPtSDD]);
554 if (fDoSDDdEdxCalib) {
555 Float_t dedxLay=dedx[layerId-3];
556 if(dedxLay>1.) fHistSDDdEdxvsDrTime[index]->Fill(drTime[nPtSDD],dedxLay);
558 iPtSDD[nPtSDD] = ipt;
559 modIdSDD[nPtSDD] = modId;
560 modSide[nPtSDD] = point.GetClusterType()&BIT(16) ? 0:1;
561 point.GetXYZ(posGloF);
562 for(Int_t icoor=0;icoor<3;icoor++) posGlo[icoor]=posGloF[icoor];
563 AliITSgeomTGeo::GlobalToLocal(modId,posGlo,posLoc);
564 xLocSDD[nPtSDD]=posLoc[0];
565 zLocSDD[nPtSDD]=posLoc[2];
567 fFitter->SetCovIScale(ipt,1e-4); // scaling for inverted errors of SDD
572 if(nPtSDD>0 && nPtSSDSPD>=2){
573 double pt = (fUseTPCMomentum && track->IsOn(AliESDtrack::kTPCrefit)) ? track->GetTPCInnerParam()->Pt() : track->Pt();
574 fFitter->Fit(track->Charge(),pt,0.);
575 Double_t chi2=fFitter->GetChi2NDF();
576 if ( chi2<0 || chi2>1e4 ) return; // fit failed, abandon this track
577 for (Int_t ip=0; ip<nPtSDD;ip++) {
578 fFitter->GetResiduals(resGlo,iPtSDD[ip]);
579 TGeoHMatrix *mcurr = AliITSgeomTGeo::GetMatrix(modIdSDD[ip]);
580 mcurr->MasterToLocalVect(resGlo,resLoc);
581 Int_t index=modIdSDD[ip]-kNSPDmods;
582 if (fDoSDDResiduals) {
583 fHistSDDResidX[index]->Fill(pt,resLoc[0]);
584 fHistSDDResidXvsX[index]->Fill(xLocSDD[ip],resLoc[0]);
585 fHistSDDResidXvsZ[index]->Fill(zLocSDD[ip],resLoc[0]);
588 if (fDoSDDVDriftCalib) {
589 double cf = modSide[ip] ? 1.e4:-1.e4;
590 double xMeas = cf*xLocSDD[ip]; // measured coordinate in microns
591 double xRes = cf*resLoc[0]; // X residual in microns
592 double xDriftTrue = 3.5085e4 - (xMeas + xRes); // "true" drift distance
594 fHProfSDDResidXvsXD[index][modSide[ip]]->Fill(xDriftTrue, xRes);
595 fHProfSDDResidXvsZ[index][modSide[ip]]->Fill(zLocSDD[ip]*1e4, xRes);
596 fHProfSDDDrTimevsXD[index][modSide[ip]]->Fill(xDriftTrue, drTime[ip]);
597 fHProfSDDDrTimevsZ[index][modSide[ip]]->Fill(zLocSDD[ip]*1e4, drTime[ip]);
602 //___________________________________________________________________________
603 void AliAnalysisTaskITSAlignQA::FitAndFillSDDz(Int_t iLayer, const AliTrackPointArray *array, Int_t npts, AliESDtrack * track){
604 // fit track and fills histos for SDD along z
606 fFitter->AttachPoints(array,0, npts-1);
607 Int_t iPtSDD[4],modIdSDD[4];
608 Double_t xLocSDD[4],zLocSDD[4];
610 Double_t resGlo[3],resLoc[3];
612 Double_t posGlo[3],posLoc[3];
613 for(Int_t ipt=0; ipt<npts; ipt++) {
616 array->GetPoint(point,ipt);
617 Int_t volId = point.GetVolumeID();
618 if (volId == kVtxSensVID) continue; // this is a vertex constraint
619 Int_t layerId = AliGeomManager::VolUIDToLayer(volId,modId);
621 modId+=AliITSgeomTGeo::GetModuleIndex(layerId,1,1);
622 iPtSDD[nPtSDD] = ipt;
623 modIdSDD[nPtSDD] = modId;
624 point.GetXYZ(posGloF);
625 for(Int_t icoor=0;icoor<3;icoor++) posGlo[icoor]=posGloF[icoor];
626 AliITSgeomTGeo::GlobalToLocal(modId,posGlo,posLoc);
627 xLocSDD[nPtSDD]=posLoc[0];
628 zLocSDD[nPtSDD]=posLoc[2];
630 fFitter->SetCovIScale(ipt,1e-4); // scaling for inverted errors of SDD
634 double pt = (fUseTPCMomentum && track->IsOn(AliESDtrack::kTPCrefit)) ? track->GetTPCInnerParam()->Pt() : track->Pt();
635 fFitter->Fit(track->Charge(),pt,0.);
636 Double_t chi2=fFitter->GetChi2NDF();
637 if ( chi2<0 || chi2>1e4 ) return; // fit failed, abandon this track
638 for (Int_t ip=0; ip<nPtSDD;ip++) {
639 fFitter->GetResiduals(resGlo,iPtSDD[ip]);
640 TGeoHMatrix *mcurr = AliITSgeomTGeo::GetMatrix(modIdSDD[ip]);
641 mcurr->MasterToLocalVect(resGlo,resLoc);
642 Int_t index=modIdSDD[ip]-kNSPDmods;
643 fHistSDDResidZ[index]->Fill(pt,resLoc[2]);
644 fHistSDDResidZvsX[index]->Fill(xLocSDD[ip],resLoc[2]);
645 fHistSDDResidZvsZ[index]->Fill(zLocSDD[ip],resLoc[2]);
649 //___________________________________________________________________________
650 void AliAnalysisTaskITSAlignQA::FitAndFillSSD(Int_t iLayer, const AliTrackPointArray *array, Int_t npts,AliESDtrack * track){
651 // fit track and fills histos for SSD
652 fFitter->AttachPoints(array,0, npts-1);
653 Int_t iPtSSD[4],modIdSSD[4];
655 Double_t resGlo[3],resLoc[3];
656 for(Int_t ipt=0; ipt<npts; ipt++) {
659 array->GetPoint(point,ipt);
660 Int_t volId = point.GetVolumeID();
661 if (volId == kVtxSensVID) continue; // this is a vertex constraint
662 Int_t layerId = AliGeomManager::VolUIDToLayer(volId,modId);
664 modId+=AliITSgeomTGeo::GetModuleIndex(layerId,1,1);
665 iPtSSD[nPtSSD] = ipt;
666 modIdSSD[nPtSSD] = modId;
668 fFitter->SetCovIScale(ipt,1e-4);
672 double pt = (fUseTPCMomentum && track->IsOn(AliESDtrack::kTPCrefit)) ? track->GetTPCInnerParam()->Pt() : track->Pt();
673 fFitter->Fit(track->Charge(),pt,0.);
674 Double_t chi2=fFitter->GetChi2NDF();
675 if ( chi2<0 || chi2>1e4 ) return; // fit failed, abandon this track
676 for (Int_t ip=0; ip<nPtSSD;ip++) {
677 fFitter->GetResiduals(resGlo,iPtSSD[ip]);
678 TGeoHMatrix *mcurr = AliITSgeomTGeo::GetMatrix(modIdSSD[ip]);
679 mcurr->MasterToLocalVect(resGlo,resLoc);
680 Int_t index=modIdSSD[ip]-kNSPDmods-kNSDDmods;
681 fHistSSDResidX[index]->Fill(pt,resLoc[0]);
682 fHistSSDResidZ[index]->Fill(pt,resLoc[2]);
686 //______________________________________________________________________________
687 void AliAnalysisTaskITSAlignQA::Terminate(Option_t */*option*/)
689 // Terminate analysis
690 fOutput = dynamic_cast<TList*> (GetOutputData(1));
692 printf("ERROR: fOutput not available\n");
696 fHistNEvents = dynamic_cast<TH1F*>(fOutput->FindObject("hNEvents"));
698 AliInfo(Form("Number of analyzed events = %d, %d tracks accepted",
699 (Int_t)fHistNEvents->GetBinContent(kEvAcc+1),(Int_t)fHistNEvents->GetBinContent(kNTracks+1)));
701 printf("Warning: pointer to fHistNEvents is NULL\n");
704 if (fDoFillTPTree) CreateUserInfo();
710 //___________________________________________________________________________
711 void AliAnalysisTaskITSAlignQA::LoadGeometryFromOCDB(){
712 //method to get the gGeomanager
713 // it is called at the CreatedOutputObject stage
714 // to comply with the CAF environment
715 AliInfo("Loading geometry");
717 AliCDBManager *man = AliCDBManager::Instance();
718 man->SetDefaultStorage(fOCDBLocation.Data());
720 AliCDBEntry* obj = man->Get(AliCDBPath("GRP", "Geometry", "Data"));
722 AliGeomManager::SetGeometry((TGeoManager*)obj->GetObject());
723 AliGeomManager::GetNalignable("ITS");
724 AliGeomManager::ApplyAlignObjsFromCDB("ITS");
726 else AliFatal("Geometry object not found in OCDB");
730 //______________________________________________________________________________________
731 AliTrackPointArray* AliAnalysisTaskITSAlignQA::PrepareTrack(const AliTrackPointArray* inp, const AliESDVertex* vtx)
733 // Extract from the global TrackPointArray the ITS part and optionally add vertex as the last measured point
735 int npts = inp->GetNPoints();
736 int modID=0,nptITS = 0;
738 const UShort_t *vids = inp->GetVolumeID();
739 for(int ipt=0; ipt<npts; ipt++) { // count ITS points
740 if (vids[ipt]<=0) continue;
741 int layerId = AliGeomManager::VolUIDToLayer(vids[ipt],modID);
742 if(layerId<1 || layerId>6) continue;
743 itsRefs[nptITS++] = ipt;
746 AliTrackPointArray *trackCopy = new AliTrackPointArray(nptITS + (vtx ? 1:0)); // reserve extra space if vertex provided
748 for(int ipt=0; ipt<nptITS; ipt++) {
749 inp->GetPoint(point,itsRefs[ipt]);
750 trackCopy->AddPoint(ipt,&point);
754 PrepareVertexConstraint(vtx,point);
755 trackCopy->AddPoint(nptITS,&point); // add vertex constraint as a last point
760 //_______________________________________________________________________________________
761 void AliAnalysisTaskITSAlignQA::PrepareVertexConstraint(const AliESDVertex* vtx, AliTrackPoint &point)
763 // convert vertex to measured point with dummy VID
768 point.SetVolumeID(kVtxSensVID);
770 vtx->GetCovMatrix(cmat);
771 cmatF[0] = cmat[0]; // xx
772 cmatF[1] = cmat[1]; // xy
773 cmatF[2] = cmat[3]; // xz
774 cmatF[3] = cmat[2]; // yy
775 cmatF[4] = cmat[4]; // yz
776 cmatF[5] = cmat[5]; // zz
777 point.SetXYZ(vtx->GetX(),vtx->GetY(),vtx->GetZ(), cmatF);
781 //_______________________________________________________________________________________
782 Bool_t AliAnalysisTaskITSAlignQA::AcceptCentrality(const AliESDEvent *esd) const
784 // check if events is in the required multiplicity range
786 const AliMultiplicity *alimult = esd->GetMultiplicity();
787 Int_t nclsSPDouter=0;
788 if(alimult) nclsSPDouter = alimult->GetNumberOfITSClusters(1);
789 if(nclsSPDouter<fMinMult || nclsSPDouter>fMaxMult) return kFALSE;
794 //_______________________________________________________________________________________
795 void AliAnalysisTaskITSAlignQA::CreateUserInfo()
797 // if needed, set user info of the output tree
799 AliError("TrackPoints summary tree does not exist");
803 const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();
804 const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();
806 TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());
807 cdbMapCopy->SetOwner(1);
808 cdbMapCopy->SetName("cdbMap");
809 TIter iter(cdbMap->GetTable());
812 while((pair = dynamic_cast<TPair*> (iter.Next()))){
813 TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());
814 TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());
815 if (keyStr && valStr) {
816 cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));
817 AliInfo(Form("Add %s : %s to cdbMap of ITSTPUserInfo",keyStr->GetName(),valStr->GetName()));
821 TList *cdbListCopy = new TList();
822 cdbListCopy->SetOwner(1);
823 cdbListCopy->SetName("cdbList");
825 TIter iter2(cdbList);
827 while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){
828 cdbListCopy->Add(new TObjString(id->ToString().Data()));
829 AliInfo(Form("Add %s to cdbList of ITSTPUserInfo",id->ToString().Data()));
832 fTPTree->GetUserInfo()->Add(cdbMapCopy);
833 fTPTree->GetUserInfo()->Add(cdbListCopy);
835 AliMagF *fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
836 Double_t bz = fld ? fld->SolenoidField() : 0;
837 TString bzString; bzString+=bz;
838 TObjString *bzObjString = new TObjString(bzString);
839 TList *bzList = new TList();
841 bzList->SetName("BzkGauss");
842 bzList->Add(bzObjString);
843 fTPTree->GetUserInfo()->Add(bzList);