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 /////////////////////////////////////////////////////////////
18 // AliAnalysisTask to extract from ESD tracks the AliTrackPointArrays
19 // with ITS points for selected tracks. This are the input data for alignment
21 // Author: A.Dainese, andrea.dainese@pd.infn.it
22 /////////////////////////////////////////////////////////////
31 #include <TGeoManager.h>
34 #include "AliGeomManager.h"
35 #include "AliITSgeomTGeo.h"
36 #include "AliTrackPointArray.h"
37 #include "AliESDInputHandler.h"
38 #include "AliESDVertex.h"
39 #include "AliESDtrack.h"
40 #include "AliESDEvent.h"
41 #include "AliESDfriend.h"
42 #include "AliAnalysisTask.h"
43 #include "AliAnalysisManager.h"
44 #include "AliAlignmentDataFilterITS.h"
47 ClassImp(AliAlignmentDataFilterITS)
50 //________________________________________________________________________
51 AliAlignmentDataFilterITS::AliAlignmentDataFilterITS(const char *name):
52 AliAnalysisTask(name,"task"),
54 fGeometryFileName("geometry.root"),
73 // Define input and output slots here
74 // Input slot #0 works with a TChain
75 DefineInput(0, TChain::Class());
76 // Output slot #0 writes into a TTree
77 DefineOutput(0,TTree::Class()); //My private output
78 // Output slot #1 writes into a TList
79 DefineOutput(1,TList::Class()); //My private output
82 //________________________________________________________________________
83 AliAlignmentDataFilterITS::~AliAlignmentDataFilterITS()
130 if (fntCosmicMatching) {
131 delete fntCosmicMatching;
132 fntCosmicMatching = 0;
135 //________________________________________________________________________
136 void AliAlignmentDataFilterITS::ConnectInputData(Option_t *)
141 TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
143 printf("ERROR: Could not read chain from input slot 0\n");
145 // Disable all branches and enable only the needed ones
147 tree->SetBranchStatus("fTriggerMask", 1);
148 tree->SetBranchStatus("fSPDVertex*", 1);
150 tree->SetBranchStatus("ESDfriend*", 1);
151 tree->SetBranchAddress("ESDfriend.",&fESDfriend);
153 tree->SetBranchStatus("fSPDMult*", 1);
155 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
158 printf("ERROR: Could not get ESDInputHandler\n");
160 fESD = esdH->GetEvent();
167 //________________________________________________________________________
168 void AliAlignmentDataFilterITS::Init()
175 //________________________________________________________________________
176 void AliAlignmentDataFilterITS::CreateOutputObjects()
178 // Create the output container
181 // Several histograms are more conveniently managed in a TList
182 fListOfHistos = new TList();
183 fListOfHistos->SetOwner();
185 fHistNpoints = new TH1F("fHistNpoints", "Number of AliTrackPoints per track; N points; tracks",25,-0.5,24.5);
186 fHistNpoints->Sumw2();
187 fHistNpoints->SetMinimum(0);
188 fListOfHistos->Add(fHistNpoints);
190 fHistPt = new TH1F("fHistPt", "p_{t} of tracks; p_{t} [GeV/c]; tracks",100,0,50);
192 fHistPt->SetMinimum(0);
193 fListOfHistos->Add(fHistPt);
197 Int_t nbinsphi=20,nbinsz=4;
198 fHistLayer0 = new TH2F("fHistLayer0","Points in layer inner SPD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
199 fListOfHistos->Add(fHistLayer0);
201 nbinsphi=40;nbinsz=4;
202 fHistLayer1 = new TH2F("fHistLayer1","Points in layer outer SPD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
203 fListOfHistos->Add(fHistLayer1);
205 nbinsphi=14;nbinsz=6;
206 fHistLayer2 = new TH2F("fHistLayer2","Points in layer inner SDD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
207 fListOfHistos->Add(fHistLayer2);
209 nbinsphi=22;nbinsz=8;
210 fHistLayer3 = new TH2F("fHistLayer3","Points in layer outer SDD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
211 fListOfHistos->Add(fHistLayer3);
213 nbinsphi=34;nbinsz=23;
214 fHistLayer4 = new TH2F("fHistLayer4","Points in layer inner SSD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
215 fListOfHistos->Add(fHistLayer4);
217 nbinsphi=38;nbinsz=26;
218 fHistLayer5 = new TH2F("fHistLayer5","Points in layer outer SSD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
219 fListOfHistos->Add(fHistLayer5);
222 fntExtra = new TNtuple("fntExtra","extra clusters in ITS","ncls:layer:ladder:volid:phi:x:y:z:xloc:zloc:dxy:dz:d0mu:z0mu");
223 fListOfHistos->Add(fntExtra);
225 fntCosmicMatching = new TNtuple("fntCosmicMatching","cosmic tracks matching in ITS","ncls1:ncls2:pt1:pt2:sigmad01:sigmad02:sigmaz01:sigmaz02:dxy:dz:phimu:thetamu:d0mu:z0mu");
226 fListOfHistos->Add(fntCosmicMatching);
228 fspTree = new TTree("spTree","Tree with ITS track points");
229 const AliTrackPointArray *array = 0;
230 Float_t curv,curverr;
231 fspTree->Branch("SP","AliTrackPointArray",&array);
232 fspTree->Branch("curv",&curv);
233 fspTree->Branch("curverr",&curverr);
238 //________________________________________________________________________
239 void AliAlignmentDataFilterITS::Exec(Option_t */*option*/)
241 // Execute analysis for current event:
242 // write ITS AliTrackPoints for selected tracks to fspTree
246 AliGeomManager::LoadGeometry(fGeometryFileName.Data());
248 printf("AliAlignmentDataFilterITS::Exec(): no geometry loaded \n");
253 // check if we have AliITSRecoParam
254 if(!AliITSReconstructor::GetRecoParam()) {
256 printf("AliAlignmentDataFilterITS::Exec(): no AliITSRecoParam\n");
262 printf("AliAlignmentDataFilterITS::Exec(): no ESD \n");
266 printf("AliAlignmentDataFilterITS::Exec(): no ESDfriend \n");
270 fESD->SetESDfriend(fESDfriend);
273 // Process event as Cosmic or Collision
274 //if(esd->GetEventType()== ???? ) {
275 printf("AliAlignmentDataFilterITS::Exec(): MOVE ASAP TO esd->GetEventType() !\n");
276 if(GetRecoParam()->GetAlignFilterCosmics()) {
279 FilterCollision(fESD);
285 //________________________________________________________________________
286 void AliAlignmentDataFilterITS::FilterCosmic(const AliESDEvent *esd)
288 // Extract ITS AliTrackPoints for Cosmics (check angular matching
289 // of top and bottom track, merge the two tracks, if requested)
292 // Set branch addresses for space points tree
293 AliTrackPointArray *arrayForTree=0;
294 Float_t curv,curverr;
295 fspTree->SetBranchAddress("SP",&arrayForTree);
296 fspTree->SetBranchAddress("curv",&curv);
297 fspTree->SetBranchAddress("curverr",&curverr);
299 TString triggeredClass = fESD->GetFiredTriggerClasses();
300 if(fOnlySPDFO && !triggeredClass.Contains("C0SCO-ABCE-NOPF-CENT")) return;
303 Int_t ntracks = esd->GetNumberOfTracks();
304 if(ntracks<2) return;
306 if(esd->GetPrimaryVertexSPD()->GetNContributors()<0) return;
308 Double_t vtxpos[3]; esd->GetPrimaryVertexSPD()->GetXYZ(vtxpos);
310 Int_t *goodtracksArray = new Int_t[ntracks];
311 Float_t *phiArray = new Float_t[ntracks];
312 Float_t *thetaArray = new Float_t[ntracks];
313 Int_t *nclsArray = new Int_t[ntracks];
316 for (itrack=0; itrack < ntracks; itrack++) {
317 AliESDtrack *track = esd->GetTrack(itrack);
318 if (!track) continue;
321 if(track->GetNcls(0)<GetRecoParam()->GetAlignFilterMinITSPoints()) continue;
323 if(GetRecoParam()->GetAlignFilterOnlyITSSATracks() && track->GetNcls(1)>0) continue;
324 if(GetRecoParam()->GetAlignFilterOnlyITSTPCTracks() && track->GetNcls(1)==0) continue;
326 Float_t phi = track->GetAlpha()+TMath::ASin(track->GetSnp());
327 Float_t theta = 0.5*TMath::Pi()-TMath::ATan(track->GetTgl());
329 if(track->Pt()<GetRecoParam()->GetAlignFilterMinPt() ||
330 track->Pt()>GetRecoParam()->GetAlignFilterMaxPt()) continue;
332 goodtracksArray[ngt] = itrack;
334 thetaArray[ngt] = theta;
335 nclsArray[ngt] = track->GetNcls(0);
340 delete [] goodtracksArray; goodtracksArray=0;
341 delete [] phiArray; phiArray=0;
342 delete [] thetaArray; thetaArray=0;
343 delete [] nclsArray; nclsArray=0;
347 // check matching of the two tracks from the muon
348 Float_t min = 10000000.;
350 Int_t good1 = -1, good2 = -1;
351 for(Int_t itr1=0; itr1<ngt-1; itr1++) {
352 for(Int_t itr2=itr1+1; itr2<ngt; itr2++) {
353 Float_t deltatheta = TMath::Abs(TMath::Pi()-thetaArray[itr1]-thetaArray[itr2]);
354 if(deltatheta>GetRecoParam()->GetAlignFilterMaxMatchingAngle()) continue;
355 Float_t deltaphi = TMath::Abs(TMath::Abs(phiArray[itr1]-phiArray[itr2])-TMath::Pi());
356 if(deltaphi>GetRecoParam()->GetAlignFilterMaxMatchingAngle()) continue;
357 if(nclsArray[itr1]+nclsArray[itr2] > maxCls) {
358 maxCls = nclsArray[itr1]+nclsArray[itr2];
359 min = deltatheta+deltaphi;
360 good1 = goodtracksArray[itr1];
361 good2 = goodtracksArray[itr2];
362 } else if(nclsArray[itr1]+nclsArray[itr2] == maxCls) {
363 if(deltatheta+deltaphi < min) {
364 min = deltatheta+deltaphi;
365 good1 = goodtracksArray[itr1];
366 good2 = goodtracksArray[itr2];
372 delete [] goodtracksArray; goodtracksArray=0;
373 delete [] phiArray; phiArray=0;
374 delete [] thetaArray; thetaArray=0;
375 delete [] nclsArray; nclsArray=0;
378 AliDebug(2,"ok track matching");
380 // track1 will be the inward track (top)
381 // track2 the outward (bottom)
382 AliESDtrack *track1=0;
383 AliESDtrack *track2=0;
384 AliESDtrack *track = esd->GetTrack(good1);
386 track1 = esd->GetTrack(good1);
387 track2 = esd->GetTrack(good2);
389 track1 = esd->GetTrack(good2);
390 track2 = esd->GetTrack(good1);
394 const AliTrackPointArray *array=0;
395 Int_t ipt,volId,modId,layerId,lay,lad,det;
397 Bool_t layerOK[6][2];
398 Int_t nclsTrk[2]={0,0};
400 for(Int_t l1=0;l1<6;l1++) for(Int_t l2=0;l2<2;l2++) layerOK[l1][l2]=kFALSE;
402 for(itrack=0; itrack<2; itrack++) {
408 array = track->GetTrackPointArray();
410 AliWarning("No tracks points avaialble");
413 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
414 array->GetPoint(point,ipt);
415 volId = point.GetVolumeID();
416 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
417 AliDebug(2,Form("%d %d\n",ipt,layerId-1));
418 if(point.IsExtra() &&
419 GetRecoParam()->GetAlignFilterSkipExtra()) continue;
420 if(layerId>6) continue;
421 if(!GetRecoParam()->GetAlignFilterUseLayer(layerId-1)) continue;
422 // check minAngleWrtITSModulePlanes
423 Double_t p[3]; track->GetDirection(p);
424 TVector3 pvec(p[0],p[1],p[2]);
425 Double_t rot[9]; AliGeomManager::GetOrigRotation(volId,rot);
426 TVector3 normvec(rot[1],rot[4],rot[7]);
427 Double_t angle = pvec.Angle(normvec);
428 if(angle>0.5*TMath::Pi()) angle = TMath::Pi()-angle;
429 angle = 0.5*TMath::Pi()-angle;
430 if(angle<GetRecoParam()->GetAlignFilterMinAngleWrtModulePlanes()) continue;
431 layerOK[layerId-1][itrack]=kTRUE;
436 AliDebug(2,Form("nClsTrk1 %d nClsTrk2 %d\n",nclsTrk[0],nclsTrk[1]));
438 // read ITS cluster maps
439 Int_t map1[6],map2[6];
440 for(Int_t ilay=0;ilay<6;ilay++) {
441 map1[ilay]=0; map2[ilay]=0;
442 if(track1->HasPointOnITSLayer(ilay)) map1[ilay]=1;
443 if(track2->HasPointOnITSLayer(ilay)) map2[ilay]=1;
445 AliDebug(2,Form("ITS map 1: %d %d %d %d %d %d pt %f\n",map1[0],map1[1],map1[2],map1[3],map1[4],map1[5],track1->Pt()));
446 AliDebug(2,Form("ITS map 2: %d %d %d %d %d %d pt %f\n",map2[0],map2[1],map2[2],map2[3],map2[4],map2[5],track2->Pt()));
447 Int_t idx1[12],idx2[12];
448 track1->GetITSclusters(idx1);
449 track2->GetITSclusters(idx2);
450 AliDebug(2,Form("cls idx 1 %d %d %d %d %d %d %d %d %d %d %d %d\n",idx1[0],idx1[1],idx1[2],idx1[3],idx1[4],idx1[5],idx1[6],idx1[7],idx1[8],idx1[9],idx1[10],idx1[11]));
451 AliDebug(2,Form("cls idx 2 %d %d %d %d %d %d %d %d %d %d %d %d\n",idx2[0],idx2[1],idx2[2],idx2[3],idx2[4],idx2[5],idx2[6],idx2[7],idx2[8],idx2[9],idx2[10],idx2[11]));
454 if(jpt<GetRecoParam()->GetAlignFilterMinITSPointsMerged()) return;
455 AliDebug(2,Form(" Total points %d, accepted\n",jpt));
456 fHistNpoints->Fill(jpt);
457 fHistPt->Fill(0.5*(track1->Pt()+track2->Pt()));
460 track1->GetDZ(0,0,0,esd->GetMagneticField(),d0z0mu);
461 //printf("d0mu %f z0mu %f\n",d0z0mu[0],d0z0mu[1]);
463 Float_t dzOverlap[2];
464 Float_t curvArray[2],curverrArray[2];
465 Double_t globExtra[3],locExtra[3];
466 if(GetRecoParam()->GetAlignFilterCosmicMergeTracks())
467 arrayForTree = new AliTrackPointArray(jpt);
470 for(itrack=0; itrack<2; itrack++) {
476 curvArray[itrack] = track->GetC(esd->GetMagneticField());
477 curverrArray[itrack] = TMath::Sqrt(track->GetSigma1Pt2())*track->GetC(esd->GetMagneticField())/track->OneOverPt();
479 if(!GetRecoParam()->GetAlignFilterCosmicMergeTracks()) {
481 arrayForTree = new AliTrackPointArray(nclsTrk[itrack]);
483 array = track->GetTrackPointArray();
484 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
485 array->GetPoint(point,ipt);
486 volId = point.GetVolumeID();
487 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
488 if(layerId>6 || !layerOK[layerId-1][itrack]) continue;
489 arrayForTree->AddPoint(jpt,&point);
493 fHistLayer0->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
496 fHistLayer1->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
499 fHistLayer2->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
502 fHistLayer3->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
505 fHistLayer4->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
508 fHistLayer5->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
511 // Post the data for slot 0
512 if(jpt==1) PostData(1,fListOfHistos); // only if this is the first points
513 if(!point.IsExtra() ||
514 !GetRecoParam()->GetAlignFilterFillQANtuples()) continue;
516 for(Int_t ll=1;ll<layerId;ll++) modId+=AliITSgeomTGeo::GetNLadders(ll)*AliITSgeomTGeo::GetNDetectors(ll);
517 AliITSgeomTGeo::GetModuleId(modId,lay,lad,det);
518 globExtra[0]=point.GetX();
519 globExtra[1]=point.GetY();
520 globExtra[2]=point.GetZ();
521 AliITSgeomTGeo::GlobalToLocal(lay,lad,det,globExtra,locExtra);
522 //printf("%d %d %d %d %d %f %f %f\n",volId,modId,lay,lad,det,locExtra[0],locExtra[1],locExtra[2]);
523 track->GetDZ(point.GetX(),point.GetY(),point.GetZ(),esd->GetMagneticField(),dzOverlap);
524 AliTrackPoint pointT;
525 Float_t radius,radiusT,phiv,phivT,thetav,thetavT;
526 for(Int_t lll=0;lll<ipt;lll++) {
527 array->GetPoint(pointT,lll);
528 Int_t layerIdT = AliGeomManager::VolUIDToLayer(pointT.GetVolumeID(),modId);
529 if(layerIdT!=layerId) continue;
530 radius=TMath::Sqrt((point.GetX()-vtxpos[0])*(point.GetX()-vtxpos[0])+(point.GetY()-vtxpos[1])*(point.GetY()-vtxpos[1]));
531 radiusT=TMath::Sqrt((pointT.GetX()-vtxpos[0])*(pointT.GetX()-vtxpos[0])+(pointT.GetY()-vtxpos[1])*(pointT.GetY()-vtxpos[1]));
532 phiv=TMath::ATan2(point.GetY()-vtxpos[1],point.GetX()-vtxpos[0]);
533 phivT=TMath::ATan2(pointT.GetY()-vtxpos[1],pointT.GetX()-vtxpos[0]);
534 if(TMath::Abs(point.GetZ()-vtxpos[2])<0.00001 || TMath::Abs(pointT.GetZ()-vtxpos[2])<0.00001) continue;
535 thetav=TMath::ATan(radius/(point.GetZ()-vtxpos[2]));
536 thetavT=TMath::ATan(radiusT/(pointT.GetZ()-vtxpos[2]));
537 dzOverlap[0]=(Float_t)((phivT-phiv)*0.5*(radiusT+radius));
538 if(TMath::Abs(TMath::Tan(0.5*(thetav+thetavT)))<0.00001) continue;
539 dzOverlap[1]=(Float_t)((pointT.GetZ()-point.GetZ())-(radiusT-radius)/TMath::Tan(0.5*(thetav+thetavT)));
540 fntExtra->Fill((Float_t)nclsTrk[itrack],(Float_t)(layerId-1),lad,volId,TMath::ATan2(point.GetY(),point.GetX()),point.GetX(),point.GetY(),point.GetZ(),locExtra[0],locExtra[2],dzOverlap[0],dzOverlap[1],d0z0mu[0],d0z0mu[1]);
544 if(!GetRecoParam()->GetAlignFilterCosmicMergeTracks()) {
545 curv = curvArray[itrack];
546 curverr = curverrArray[itrack];
551 if(GetRecoParam()->GetAlignFilterCosmicMergeTracks()) {
552 curv = 0.5*(curvArray[0]+curvArray[1]);
553 curverr = 0.5*TMath::Sqrt(curverrArray[0]*curverrArray[0]+curverrArray[1]*curverrArray[1]);
554 /*AliTrackPoint pppt;
555 for(Int_t iii=0;iii<arrayForTree->GetNPoints();iii++) {
556 arrayForTree->GetPoint(pppt,iii);
563 if(!GetRecoParam()->GetAlignFilterFillQANtuples()) return;
564 // fill ntuple with track-to-track matching
565 Float_t phimu,thetamu,phiout,thetaout,dphi,dtheta,rotymu,rotyout,droty;
567 Float_t sigmad0[2],sigmaz0[2];
568 phimu = track1->GetAlpha()+TMath::ASin(track1->GetSnp());
569 thetamu = 0.5*TMath::Pi()-TMath::ATan(track1->GetTgl());
570 phiout = track2->GetAlpha()+TMath::ASin(track2->GetSnp());
571 thetaout = 0.5*TMath::Pi()-TMath::ATan(track2->GetTgl());
572 rotymu = TMath::ATan2(track1->Px(),track1->Pz());
573 rotyout = TMath::ATan2(track2->Px(),track2->Pz());
575 dphi = phimu - (phiout+TMath::Pi());
576 dtheta = thetamu - (TMath::Pi()-thetaout);
578 droty = rotymu - (rotyout+TMath::Pi());
580 droty = rotymu - (rotyout-TMath::Pi());
583 Double_t alpha = TMath::ATan2(track1->Py(),track1->Px());
585 track1->Propagate(alpha,0.,esd->GetMagneticField());
586 track2->Propagate(alpha,0.,esd->GetMagneticField());
587 d0[0] = track1->GetY();
588 z0[0] = track1->GetZ();
589 d0[1] = track2->GetY();
590 z0[1] = track2->GetZ();
591 Float_t dxy = -(d0[0]-d0[1]);
592 Float_t dz = z0[0]-z0[1];
593 sigmad0[0] = TMath::Sqrt(track1->GetSigmaY2());
594 sigmaz0[0] = TMath::Sqrt(track1->GetSigmaZ2());
595 sigmad0[1] = TMath::Sqrt(track2->GetSigmaY2());
596 sigmaz0[1] = TMath::Sqrt(track2->GetSigmaZ2());
598 Double_t xyz1atxl0[3],xyz1atxl1[3],xyz2atxl0[3],xyz2atxl1[3];
599 track1->GetXYZAt(0.,esd->GetMagneticField(),xyz1atxl0);
600 track1->GetXYZAt(1.,esd->GetMagneticField(),xyz1atxl1);
601 track2->GetXYZAt(0.,esd->GetMagneticField(),xyz2atxl0);
602 track2->GetXYZAt(1.,esd->GetMagneticField(),xyz2atxl1);
603 Float_t x1aty0 = (xyz1atxl0[0]*xyz1atxl1[1]-xyz1atxl0[1]*xyz1atxl1[0])/(xyz1atxl1[1]-xyz1atxl0[1]);
604 Float_t x2aty0 = (xyz2atxl0[0]*xyz2atxl1[1]-xyz2atxl0[1]*xyz2atxl1[0])/(xyz2atxl1[1]-xyz2atxl0[1]);
605 Float_t dxaty0 = x1aty0-x2aty0;
607 fntCosmicMatching->Fill((Float_t)nclsTrk[0],(Float_t)nclsTrk[1],track1->Pt(),track2->Pt(),sigmad0[0],sigmad0[1],sigmaz0[0],sigmaz0[1],dxy,dz,phimu,thetamu,TMath::Abs(d0z0mu[0]),d0z0mu[1]);
612 //________________________________________________________________________
613 void AliAlignmentDataFilterITS::FilterCollision(const AliESDEvent *esd)
615 // Extract ITS AliTrackPoints for Cosmics (check angular matching
616 // of top and bottom track, merge the two tracks, if requested)
619 // Set branch addresses for space points tree
620 AliTrackPointArray *arrayForTree=0;
621 Float_t curv,curverr;
622 fspTree->SetBranchAddress("SP",&arrayForTree);
623 fspTree->SetBranchAddress("curv",&curv);
624 fspTree->SetBranchAddress("curverr",&curverr);
626 Int_t ntracks = esd->GetNumberOfTracks();
628 if(ntracks==0) return;
630 if(esd->GetPrimaryVertexTracks()->GetNContributors()<=0) return;
632 Double_t vtxpos[3]; esd->GetPrimaryVertexTracks()->GetXYZ(vtxpos);
636 Double_t d0z0[2],covd0z0[3];
637 const AliTrackPointArray *array = 0;
639 for (Int_t itrack=0; itrack < ntracks; itrack++) {
640 AliESDtrack * track = esd->GetTrack(itrack);
641 if (!track) continue;
643 if(track->GetNcls(0)<GetRecoParam()->GetAlignFilterMinITSPoints()) continue;
645 if(GetRecoParam()->GetAlignFilterOnlyITSSATracks() && track->GetNcls(1)>0) continue;
646 if(GetRecoParam()->GetAlignFilterOnlyITSTPCTracks() && track->GetNcls(1)==0) continue;
648 if(track->Pt()<GetRecoParam()->GetAlignFilterMinPt() ||
649 track->Pt()>GetRecoParam()->GetAlignFilterMaxPt()) continue;
652 ncls = track->GetNcls(0);
653 Double_t maxd=10000.;
654 track->PropagateToDCA(esd->GetPrimaryVertex(),esd->GetMagneticField(),maxd,d0z0,covd0z0);
656 // read ITS cluster map
658 for(Int_t ilay=0;ilay<6;ilay++) {
660 if(track->HasPointOnITSLayer(ilay)) map[ilay]=1;
662 AliDebug(2,Form("ITS map : %d %d %d %d %d %d pt %f\n",map[0],map[1],map[2],map[3],map[4],map[5],track->Pt()));
664 track->GetITSclusters(idx);
665 AliDebug(2,Form("cls idx %d %d %d %d %d %d %d %d %d %d %d %d\n",idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],idx[6],idx[7],idx[8],idx[9],idx[10],idx[11]));
669 Int_t ipt,volId,modId,layerId,lay,lad,det;
671 Bool_t layerOK[6]; for(Int_t l1=0;l1<6;l1++) layerOK[l1]=kFALSE;
673 array = track->GetTrackPointArray();
675 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
676 array->GetPoint(point,ipt);
677 volId = point.GetVolumeID();
678 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
679 if(layerId<1 || layerId>6) continue;
680 if(point.IsExtra() &&
681 GetRecoParam()->GetAlignFilterSkipExtra()) continue;
682 layerOK[layerId-1]=kTRUE;
686 if(jpt < GetRecoParam()->GetAlignFilterMinITSPoints()) continue;
688 fHistNpoints->Fill(jpt);
690 PostData(1,fListOfHistos);
692 Float_t dzOverlap[2];
693 Double_t globExtra[3],locExtra[3];
694 arrayForTree = new AliTrackPointArray(jpt);
696 array = track->GetTrackPointArray();
698 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
699 array->GetPoint(point,ipt);
700 volId = point.GetVolumeID();
701 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
702 if(layerId<1 || layerId>6 || !layerOK[layerId-1]) continue;
703 if(!point.IsExtra() ||
704 !GetRecoParam()->GetAlignFilterFillQANtuples()) continue;
706 for(Int_t ll=1;ll<layerId;ll++) modId+=AliITSgeomTGeo::GetNLadders(ll)*AliITSgeomTGeo::GetNDetectors(ll);
707 AliITSgeomTGeo::GetModuleId(modId,lay,lad,det);
708 globExtra[0]=point.GetX();
709 globExtra[1]=point.GetY();
710 globExtra[2]=point.GetZ();
711 AliITSgeomTGeo::GlobalToLocal(lay,lad,det,globExtra,locExtra);
712 track->GetDZ(point.GetX(),point.GetY(),point.GetZ(),esd->GetMagneticField(),dzOverlap);
713 AliTrackPoint pointT;
714 Float_t radius,radiusT,phiv,phivT,thetav,thetavT;
715 for(Int_t lll=0;lll<ipt;lll++) {
716 array->GetPoint(pointT,lll);
717 Int_t layerIdT = AliGeomManager::VolUIDToLayer(pointT.GetVolumeID(),modId);
718 if(layerIdT!=layerId) continue;
719 radius=TMath::Sqrt((point.GetX()-vtxpos[0])*(point.GetX()-vtxpos[0])+(point.GetY()-vtxpos[1])*(point.GetY()-vtxpos[1]));
720 radiusT=TMath::Sqrt((pointT.GetX()-vtxpos[0])*(pointT.GetX()-vtxpos[0])+(pointT.GetY()-vtxpos[1])*(pointT.GetY()-vtxpos[1]));
721 phiv=TMath::ATan2(point.GetY()-vtxpos[1],point.GetX()-vtxpos[0]);
722 phivT=TMath::ATan2(pointT.GetY()-vtxpos[1],pointT.GetX()-vtxpos[0]);
723 if(TMath::Abs(point.GetZ()-vtxpos[2])<0.00001 || TMath::Abs(pointT.GetZ()-vtxpos[2])<0.00001) continue;
724 thetav=TMath::ATan(radius/(point.GetZ()-vtxpos[2]));
725 thetavT=TMath::ATan(radiusT/(pointT.GetZ()-vtxpos[2]));
726 dzOverlap[0]=(Float_t)((phivT-phiv)*0.5*(radiusT+radius));
727 if(TMath::Abs(TMath::Tan(0.5*(thetav+thetavT)))<0.00001) continue;
728 dzOverlap[1]=(Float_t)((pointT.GetZ()-point.GetZ())-(radiusT-radius)/TMath::Tan(0.5*(thetav+thetavT)));
729 fntExtra->Fill((Float_t)ncls,(Float_t)(layerId-1),lad,volId,TMath::ATan2(point.GetY(),point.GetX()),point.GetX(),point.GetY(),point.GetZ(),locExtra[0],locExtra[2],dzOverlap[0],dzOverlap[1],d0z0[0],d0z0[1]);
731 arrayForTree->AddPoint(jpt,&point);
734 fHistLayer0->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
737 fHistLayer1->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
740 fHistLayer2->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
743 fHistLayer3->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
746 fHistLayer4->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
749 fHistLayer5->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
755 curv = track->GetC(esd->GetMagneticField());
756 curverr = TMath::Sqrt(track->GetSigma1Pt2())*track->GetC(esd->GetMagneticField())/track->OneOverPt();
760 } // end of tracks loop
767 //________________________________________________________________________
768 void AliAlignmentDataFilterITS::Terminate(Option_t */*option*/)
770 // Terminate analysis
772 AliDebug(2,"AliITSAlignmentDataFiler: Terminate() \n");
774 fspTree = dynamic_cast<TTree*> (GetOutputData(0));
776 printf("ERROR: fspTree not available\n");
780 fListOfHistos = dynamic_cast<TList*> (GetOutputData(1));
781 if (!fListOfHistos) {
782 printf("ERROR: fListOfHistos not available\n");
786 fHistNpoints = dynamic_cast<TH1F*>(fListOfHistos->FindObject("fHistNpoints"));
787 fHistPt = dynamic_cast<TH1F*>(fListOfHistos->FindObject("fHistPt"));
788 fHistLayer0 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer0"));
789 fHistLayer1 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer1"));
790 fHistLayer2 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer2"));
791 fHistLayer3 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer3"));
792 fHistLayer4 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer4"));
793 fHistLayer5 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer5"));
794 fntExtra = dynamic_cast<TNtuple*>(fListOfHistos->FindObject("fntExtra"));
795 fntCosmicMatching = dynamic_cast<TNtuple*>(fListOfHistos->FindObject("fntCosmicMatching"));