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 /////////////////////////////////////////////////////////////
34 #include <TGeoManager.h>
37 #include "AliCDBEntry.h"
38 #include "AliGeomManager.h"
39 #include "AliITSReconstructor.h"
40 #include "AliITSAlignMille2Module.h"
41 #include "AliITSgeomTGeo.h"
42 #include "AliTrackPointArray.h"
43 #include "AliESDInputHandler.h"
44 #include "AliESDVertex.h"
45 #include "AliESDtrack.h"
46 #include "AliESDEvent.h"
47 #include "AliESDfriend.h"
48 #include "AliAnalysisTask.h"
49 #include "AliAnalysisManager.h"
50 #include "AliAlignmentDataFilterITS.h"
53 ClassImp(AliAlignmentDataFilterITS)
56 //________________________________________________________________________
57 AliAlignmentDataFilterITS::AliAlignmentDataFilterITS(const char *name):
58 AliAnalysisTask(name,"task"),
60 fGeometryFileName("geometry.root"),
80 // Define input and output slots here
81 // Input slot #0 works with a TChain
82 DefineInput(0, TChain::Class());
83 // Output slot #0 writes into a TTree
84 DefineOutput(0,TTree::Class()); //My private output
85 // Output slot #1 writes into a TList
86 DefineOutput(1,TList::Class()); //My private output
89 //________________________________________________________________________
90 AliAlignmentDataFilterITS::~AliAlignmentDataFilterITS()
141 if (fntCosmicMatching) {
142 delete fntCosmicMatching;
143 fntCosmicMatching = 0;
147 //________________________________________________________________________
148 void AliAlignmentDataFilterITS::ConnectInputData(Option_t *)
153 TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
155 printf("ERROR: Could not read chain from input slot 0\n");
157 // Get the OCDB path and the list of OCDB objects used for reco
158 TMap *cdbMap = (TMap*)(tree->GetTree()->GetUserInfo())->FindObject("cdbMap");
159 TList *cdbList = (TList*)(tree->GetTree()->GetUserInfo())->FindObject("cdbList");
162 // write the list to the user info of the output tree
164 printf("ERROR: fspTree does not exist\n");
166 TMap *cdbMapCopy = new TMap(cdbMap->GetEntries());
167 cdbMapCopy->SetOwner(1);
168 cdbMapCopy->SetName("cdbMap");
169 TIter iter1(cdbMap->GetTable());
172 while((pair = dynamic_cast<TPair*> (iter1.Next()))){
173 TObjString* keyStr = dynamic_cast<TObjString*> (pair->Key());
174 TObjString* valStr = dynamic_cast<TObjString*> (pair->Value());
175 cdbMapCopy->Add(new TObjString(keyStr->GetName()), new TObjString(valStr->GetName()));
178 TList *cdbListCopy = new TList();
179 cdbListCopy->SetOwner(1);
180 cdbListCopy->SetName("cdbList");
182 TIter iter2(cdbList);
184 TObjString* cdbEntry=0;
185 while((cdbEntry =(TObjString*)(iter2.Next()))) {
186 cdbListCopy->Add(new TObjString(*cdbEntry));
188 cdbListCopy->Print();
191 fspTree->GetUserInfo()->Add(cdbMapCopy);
192 fspTree->GetUserInfo()->Add(cdbListCopy);
195 // Disable all branches and enable only the needed ones
196 tree->SetBranchStatus("fTriggerMask", 1);
197 tree->SetBranchStatus("fSPDVertex*", 1);
198 tree->SetBranchStatus("ESDfriend*", 1);
199 tree->SetBranchAddress("ESDfriend.",&fESDfriend);
200 tree->SetBranchStatus("fSPDMult*", 1);
202 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
205 printf("ERROR: Could not get ESDInputHandler\n");
207 fESD = esdH->GetEvent();
214 //________________________________________________________________________
215 void AliAlignmentDataFilterITS::Init()
222 //________________________________________________________________________
223 void AliAlignmentDataFilterITS::CreateOutputObjects()
225 // Create the output container
230 printf("AliAlignmentDataFilterITS::CreateOutputObjects(): loading geometry from %s\n",fGeometryFileName.Data());
231 AliGeomManager::LoadGeometry(fGeometryFileName.Data());
233 printf("AliAlignmentDataFilterITS::CreateOutputObjects(): no geometry loaded \n");
238 // Several histograms are more conveniently managed in a TList
239 fListOfHistos = new TList();
240 fListOfHistos->SetOwner();
242 fHistNevents = new TH1F("fHistNevents", "Number of processed events; N events; bin",5,-0.5,4.5);
243 fHistNevents->Sumw2();
244 fHistNevents->SetMinimum(0);
245 fListOfHistos->Add(fHistNevents);
247 fHistNpoints = new TH1F("fHistNpoints", "Number of AliTrackPoints per track; N points; tracks",25,-0.5,24.5);
248 fHistNpoints->Sumw2();
249 fHistNpoints->SetMinimum(0);
250 fListOfHistos->Add(fHistNpoints);
252 fHistPt = new TH1F("fHistPt", "p_{t} of tracks; p_{t} [GeV/c]; tracks",100,0,50);
254 fHistPt->SetMinimum(0);
255 fListOfHistos->Add(fHistPt);
259 Int_t nbinsphi=20,nbinsz=4;
260 fHistLayer0 = new TH2F("fHistLayer0","Points in layer inner SPD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
261 fListOfHistos->Add(fHistLayer0);
263 nbinsphi=40;nbinsz=4;
264 fHistLayer1 = new TH2F("fHistLayer1","Points in layer outer SPD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
265 fListOfHistos->Add(fHistLayer1);
267 nbinsphi=14;nbinsz=6;
268 fHistLayer2 = new TH2F("fHistLayer2","Points in layer inner SDD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
269 fListOfHistos->Add(fHistLayer2);
271 nbinsphi=22;nbinsz=8;
272 fHistLayer3 = new TH2F("fHistLayer3","Points in layer outer SDD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
273 fListOfHistos->Add(fHistLayer3);
275 nbinsphi=34;nbinsz=23;
276 fHistLayer4 = new TH2F("fHistLayer4","Points in layer inner SSD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
277 fListOfHistos->Add(fHistLayer4);
279 nbinsphi=38;nbinsz=26;
280 fHistLayer5 = new TH2F("fHistLayer5","Points in layer outer SSD; global #phi; global z [cm]",nbinsphi,-3.14,3.14,nbinsz,-zmax,zmax);
281 fListOfHistos->Add(fHistLayer5);
284 fntExtra = new TNtuple("fntExtra","extra clusters in ITS","ncls:layer:ladder:volid:phi:x:y:z:xloc:zloc:dxy:dz:d0mu:z0mu");
285 fListOfHistos->Add(fntExtra);
287 fntCosmicMatching = new TNtuple("fntCosmicMatching","cosmic tracks matching in ITS","ncls1:ncls2:pt1:pt2:sigmad01:sigmad02:sigmaz01:sigmaz02:dxy:dz:phimu:thetamu:d0mu:z0mu");
288 fListOfHistos->Add(fntCosmicMatching);
290 fspTree = new TTree("spTree","Tree with ITS track points");
291 AliTrackPointArray *array = 0;
292 Float_t curv=0,curverr=0,runNumber=0;
293 TObjString *itsaligndata = 0;
294 TObjString *itscalibrespsdd = 0;
295 fspTree->Branch("SP","AliTrackPointArray",&array);
296 fspTree->Branch("curv",&curv);
297 fspTree->Branch("curverr",&curverr);
298 fspTree->Branch("run",&runNumber);
299 fspTree->Branch("ITSAlignData",&itsaligndata);
300 fspTree->Branch("ITSCalibRespSDD",&itscalibrespsdd);
305 //________________________________________________________________________
306 void AliAlignmentDataFilterITS::Exec(Option_t */*option*/)
308 // Execute analysis for current event:
309 // write ITS AliTrackPoints for selected tracks to fspTree
311 // check the geometry
313 printf("AliAlignmentDataFilterITS::Exec(): no geometry loaded \n");
317 // check if we have AliITSRecoParam
318 if(!GetRecoParam()) {
320 printf("AliAlignmentDataFilterITS::Exec(): no AliITSRecoParam\n");
327 printf("AliAlignmentDataFilterITS::Exec(): no ESD \n");
331 printf("AliAlignmentDataFilterITS::Exec(): no ESDfriend \n");
335 fESD->SetESDfriend(fESDfriend);
337 // Post the data for slot 0
338 fHistNevents->Fill(0);
341 // write field value to spTree UserInfo
342 if(!((fspTree->GetUserInfo())->FindObject("BzkGauss"))) {
343 Double_t bz=fESD->GetMagneticField();
344 TString bzString; bzString+=bz;
345 TObjString *bzObjString = new TObjString(bzString);
346 TList *bzList = new TList();
348 bzList->SetName("BzkGauss");
349 bzList->Add(bzObjString);
350 fspTree->GetUserInfo()->Add(bzList);
354 // Process event as Cosmic or Collision
355 //if(esd->GetEventType()== ???? ) {
356 printf("AliAlignmentDataFilterITS::Exec(): MOVE ASAP TO esd->GetEventType() !\n");
357 if(GetRecoParam()->GetAlignFilterCosmics()) {
360 FilterCollision(fESD);
363 PostData(1,fListOfHistos);
368 //________________________________________________________________________
369 void AliAlignmentDataFilterITS::FilterCosmic(const AliESDEvent *esd)
371 // Extract ITS AliTrackPoints for Cosmics (check angular matching
372 // of top and bottom track, merge the two tracks, if requested)
375 // Set branch addresses for space points tree
376 AliTrackPointArray *arrayForTree=0;
377 Float_t curv,curverr,runNumber;
378 TObjString *itsaligndata=0;
379 TObjString *itscalibrespsdd = 0;
380 fspTree->SetBranchAddress("SP",&arrayForTree);
381 fspTree->SetBranchAddress("curv",&curv);
382 fspTree->SetBranchAddress("curverr",&curverr);
383 fspTree->SetBranchAddress("run",&runNumber);
384 fspTree->SetBranchAddress("ITSAlignData",&itsaligndata);
385 fspTree->SetBranchAddress("ITSCalibRespSDD",&itscalibrespsdd);
388 runNumber = (Float_t)esd->GetRunNumber();
390 TTree* esdTree = dynamic_cast<TTree*> (GetInputData(0));
391 // Get the list of OCDB objects used for reco
392 TList *cdbList = (TList*)(esdTree->GetTree()->GetUserInfo())->FindObject("cdbList");
393 TIter iter2(cdbList);
394 TObjString* cdbEntry=0;
395 TString cdbEntryString;
396 while((cdbEntry =(TObjString*)(iter2.Next()))) {
397 cdbEntryString = cdbEntry->GetString();
398 if(cdbEntryString.Contains("ITS/Align/Data"))
399 itsaligndata = new TObjString(*cdbEntry);
400 if(cdbEntryString.Contains("ITS/Calib/RespSDD"))
401 itscalibrespsdd = new TObjString(*cdbEntry);
405 TString triggeredClass = fESD->GetFiredTriggerClasses();
406 if(fOnlySPDFO && !triggeredClass.Contains("C0SCO-ABCE-NOPF-CENT")) return;
409 Int_t ntracks = esd->GetNumberOfTracks();
410 if(ntracks<2) return;
412 if(esd->GetPrimaryVertexSPD()->GetNContributors()<0) return;
414 Double_t vtxpos[3]; esd->GetPrimaryVertexSPD()->GetXYZ(vtxpos);
416 Int_t *goodtracksArray = new Int_t[ntracks];
417 Float_t *phiArray = new Float_t[ntracks];
418 Float_t *thetaArray = new Float_t[ntracks];
419 Int_t *nclsArray = new Int_t[ntracks];
422 for (itrack=0; itrack < ntracks; itrack++) {
423 AliESDtrack *track = esd->GetTrack(itrack);
424 if (!track) continue;
427 if(track->GetNcls(0)<GetRecoParam()->GetAlignFilterMinITSPoints()) continue;
429 if((GetRecoParam()->GetAlignFilterOnlyITSSATracks()) && track->GetNcls(1)>0) continue;
430 if((GetRecoParam()->GetAlignFilterOnlyITSTPCTracks()) && track->GetNcls(1)==0) continue;
432 Float_t phi = track->GetAlpha()+TMath::ASin(track->GetSnp());
433 Float_t theta = 0.5*TMath::Pi()-TMath::ATan(track->GetTgl());
435 if(track->Pt()<GetRecoParam()->GetAlignFilterMinPt() ||
436 track->Pt()>GetRecoParam()->GetAlignFilterMaxPt()) continue;
438 goodtracksArray[ngt] = itrack;
440 thetaArray[ngt] = theta;
441 nclsArray[ngt] = track->GetNcls(0);
446 delete [] goodtracksArray; goodtracksArray=0;
447 delete [] phiArray; phiArray=0;
448 delete [] thetaArray; thetaArray=0;
449 delete [] nclsArray; nclsArray=0;
453 // check matching of the two tracks from the muon
454 Float_t min = 10000000.;
456 Int_t good1 = -1, good2 = -1;
457 for(Int_t itr1=0; itr1<ngt-1; itr1++) {
458 for(Int_t itr2=itr1+1; itr2<ngt; itr2++) {
459 Float_t deltatheta = TMath::Abs(TMath::Pi()-thetaArray[itr1]-thetaArray[itr2]);
460 if(deltatheta>GetRecoParam()->GetAlignFilterMaxMatchingAngle()) continue;
461 Float_t deltaphi = TMath::Abs(TMath::Abs(phiArray[itr1]-phiArray[itr2])-TMath::Pi());
462 if(deltaphi>GetRecoParam()->GetAlignFilterMaxMatchingAngle()) continue;
463 if(nclsArray[itr1]+nclsArray[itr2] > maxCls) {
464 maxCls = nclsArray[itr1]+nclsArray[itr2];
465 min = deltatheta+deltaphi;
466 good1 = goodtracksArray[itr1];
467 good2 = goodtracksArray[itr2];
468 } else if(nclsArray[itr1]+nclsArray[itr2] == maxCls) {
469 if(deltatheta+deltaphi < min) {
470 min = deltatheta+deltaphi;
471 good1 = goodtracksArray[itr1];
472 good2 = goodtracksArray[itr2];
478 delete [] goodtracksArray; goodtracksArray=0;
479 delete [] phiArray; phiArray=0;
480 delete [] thetaArray; thetaArray=0;
481 delete [] nclsArray; nclsArray=0;
484 AliDebug(2,"ok track matching");
486 // track1 will be the inward track (top)
487 // track2 the outward (bottom)
488 AliESDtrack *track1=0;
489 AliESDtrack *track2=0;
490 AliESDtrack *track = esd->GetTrack(good1);
492 track1 = esd->GetTrack(good1);
493 track2 = esd->GetTrack(good2);
495 track1 = esd->GetTrack(good2);
496 track2 = esd->GetTrack(good1);
500 const AliTrackPointArray *array=0;
501 Int_t ipt,volId,modId,layerId,lay,lad,det;
503 Bool_t layerOK[6][2];
504 Int_t nclsTrk[2]={0,0};
506 for(Int_t l1=0;l1<6;l1++) for(Int_t l2=0;l2<2;l2++) layerOK[l1][l2]=kFALSE;
508 for(itrack=0; itrack<2; itrack++) {
514 array = track->GetTrackPointArray();
516 AliWarning("No tracks points avaialble");
519 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
520 array->GetPoint(point,ipt);
521 volId = point.GetVolumeID();
522 if(volId<=0) continue;
523 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
524 AliDebug(2,Form("%d %d %d %f\n",ipt,layerId-1,volId,TMath::Sqrt(point.GetX()*point.GetX()+point.GetY()*point.GetY())));
525 if(point.IsExtra() &&
526 (GetRecoParam()->GetAlignFilterSkipExtra())) continue;
527 if(layerId<1 || layerId>6) continue;
528 if(!GetRecoParam()->GetAlignFilterUseLayer(layerId-1)) continue;
529 // check minAngleWrtITSModulePlanes
530 Double_t p[3]; track->GetDirection(p);
531 TVector3 pvec(p[0],p[1],p[2]);
532 Double_t rot[9]; AliGeomManager::GetOrigRotation(volId,rot);
533 TVector3 normvec(rot[1],rot[4],rot[7]);
534 Double_t angle = pvec.Angle(normvec);
535 if(angle>0.5*TMath::Pi()) angle = TMath::Pi()-angle;
536 angle = 0.5*TMath::Pi()-angle;
537 if(angle<GetRecoParam()->GetAlignFilterMinAngleWrtModulePlanes()) continue;
538 layerOK[layerId-1][itrack]=kTRUE;
543 AliDebug(2,Form("nClsTrk1 %d nClsTrk2 %d\n",nclsTrk[0],nclsTrk[1]));
545 // read ITS cluster maps
546 Int_t map1[6],map2[6];
547 for(Int_t ilay=0;ilay<6;ilay++) {
548 map1[ilay]=0; map2[ilay]=0;
549 if(track1->HasPointOnITSLayer(ilay)) map1[ilay]=1;
550 if(track2->HasPointOnITSLayer(ilay)) map2[ilay]=1;
552 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()));
553 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()));
554 Int_t idx1[12],idx2[12];
555 track1->GetITSclusters(idx1);
556 track2->GetITSclusters(idx2);
557 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]));
558 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]));
561 if(jpt<GetRecoParam()->GetAlignFilterMinITSPointsMerged()) return;
562 AliDebug(2,Form(" Total points %d, accepted\n",jpt));
563 fHistNpoints->Fill(jpt);
564 fHistPt->Fill(0.5*(track1->Pt()+track2->Pt()));
567 track1->GetDZ(0,0,0,esd->GetMagneticField(),d0z0mu);
568 //printf("d0mu %f z0mu %f\n",d0z0mu[0],d0z0mu[1]);
570 Float_t dzOverlap[2];
571 Float_t curvArray[2],curverrArray[2];
572 Double_t globExtra[3],locExtra[3];
573 if(GetRecoParam()->GetAlignFilterCosmicMergeTracks())
574 arrayForTree = new AliTrackPointArray(jpt);
577 for(itrack=0; itrack<2; itrack++) {
583 curvArray[itrack] = track->GetC(esd->GetMagneticField());
584 curverrArray[itrack] = TMath::Sqrt(track->GetSigma1Pt2())*track->GetC(esd->GetMagneticField())/track->OneOverPt();
586 if(!(GetRecoParam()->GetAlignFilterCosmicMergeTracks())) {
588 arrayForTree = new AliTrackPointArray(nclsTrk[itrack]);
590 array = track->GetTrackPointArray();
591 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
592 array->GetPoint(point,ipt);
593 volId = point.GetVolumeID();
594 if(volId<=0) continue;
595 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
596 if(layerId<1 || layerId>6 || !layerOK[layerId-1][itrack]) continue;
597 arrayForTree->AddPoint(jpt,&point);
601 fHistLayer0->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
604 fHistLayer1->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
607 fHistLayer2->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
610 fHistLayer3->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
613 fHistLayer4->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
616 fHistLayer5->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
619 // Post the data for slot 0
620 if(jpt==1) PostData(1,fListOfHistos); // only if this is the first points
621 if(!point.IsExtra() ||
622 !(GetRecoParam()->GetAlignFilterFillQANtuples())) continue;
624 for(Int_t ll=1;ll<layerId;ll++) modId+=AliITSgeomTGeo::GetNLadders(ll)*AliITSgeomTGeo::GetNDetectors(ll);
625 AliITSgeomTGeo::GetModuleId(modId,lay,lad,det);
626 globExtra[0]=point.GetX();
627 globExtra[1]=point.GetY();
628 globExtra[2]=point.GetZ();
629 AliITSgeomTGeo::GlobalToLocal(lay,lad,det,globExtra,locExtra);
630 //printf("%d %d %d %d %d %f %f %f\n",volId,modId,lay,lad,det,locExtra[0],locExtra[1],locExtra[2]);
631 track->GetDZ(point.GetX(),point.GetY(),point.GetZ(),esd->GetMagneticField(),dzOverlap);
632 AliTrackPoint pointT;
633 Float_t radius,radiusT,phiv,phivT,thetav,thetavT;
634 for(Int_t lll=0;lll<ipt;lll++) {
635 array->GetPoint(pointT,lll);
636 if(pointT.GetVolumeID()<=0) continue;
637 Int_t layerIdT = AliGeomManager::VolUIDToLayer(pointT.GetVolumeID(),modId);
638 if(layerIdT!=layerId) continue;
639 radius=TMath::Sqrt((point.GetX()-vtxpos[0])*(point.GetX()-vtxpos[0])+(point.GetY()-vtxpos[1])*(point.GetY()-vtxpos[1]));
640 radiusT=TMath::Sqrt((pointT.GetX()-vtxpos[0])*(pointT.GetX()-vtxpos[0])+(pointT.GetY()-vtxpos[1])*(pointT.GetY()-vtxpos[1]));
641 phiv=TMath::ATan2(point.GetY()-vtxpos[1],point.GetX()-vtxpos[0]);
642 phivT=TMath::ATan2(pointT.GetY()-vtxpos[1],pointT.GetX()-vtxpos[0]);
643 if(TMath::Abs(point.GetZ()-vtxpos[2])<0.00001 || TMath::Abs(pointT.GetZ()-vtxpos[2])<0.00001) continue;
644 thetav=TMath::ATan(radius/(point.GetZ()-vtxpos[2]));
645 thetavT=TMath::ATan(radiusT/(pointT.GetZ()-vtxpos[2]));
646 dzOverlap[0]=(Float_t)((phivT-phiv)*0.5*(radiusT+radius));
647 if(TMath::Abs(TMath::Tan(0.5*(thetav+thetavT)))<0.00001) continue;
648 dzOverlap[1]=(Float_t)((pointT.GetZ()-point.GetZ())-(radiusT-radius)/TMath::Tan(0.5*(thetav+thetavT)));
649 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]);
653 if(!(GetRecoParam()->GetAlignFilterCosmicMergeTracks())) {
654 curv = curvArray[itrack];
655 curverr = curverrArray[itrack];
660 if(GetRecoParam()->GetAlignFilterCosmicMergeTracks()) {
661 curv = 0.5*(curvArray[0]-curvArray[1]); // the "-" is because the two tracks have opposite curvature!
662 curverr = 0.5*TMath::Sqrt(curverrArray[0]*curverrArray[0]+curverrArray[1]*curverrArray[1]);
667 if(!(GetRecoParam()->GetAlignFilterFillQANtuples())) return;
668 // fill ntuple with track-to-track matching
669 Float_t phimu,thetamu,phiout,thetaout,dphi,dtheta,rotymu,rotyout,droty;
671 Float_t sigmad0[2],sigmaz0[2];
672 phimu = track1->GetAlpha()+TMath::ASin(track1->GetSnp());
673 thetamu = 0.5*TMath::Pi()-TMath::ATan(track1->GetTgl());
674 phiout = track2->GetAlpha()+TMath::ASin(track2->GetSnp());
675 thetaout = 0.5*TMath::Pi()-TMath::ATan(track2->GetTgl());
676 rotymu = TMath::ATan2(track1->Px(),track1->Pz());
677 rotyout = TMath::ATan2(track2->Px(),track2->Pz());
679 dphi = phimu - (phiout+TMath::Pi());
680 dtheta = thetamu - (TMath::Pi()-thetaout);
682 droty = rotymu - (rotyout+TMath::Pi());
684 droty = rotymu - (rotyout-TMath::Pi());
687 Double_t alpha = TMath::ATan2(track1->Py(),track1->Px());
689 track1->Propagate(alpha,0.,esd->GetMagneticField());
690 track2->Propagate(alpha,0.,esd->GetMagneticField());
691 d0[0] = track1->GetY();
692 z0[0] = track1->GetZ();
693 d0[1] = track2->GetY();
694 z0[1] = track2->GetZ();
695 Float_t dxy = -(d0[0]-d0[1]);
696 Float_t dz = z0[0]-z0[1];
697 sigmad0[0] = TMath::Sqrt(track1->GetSigmaY2());
698 sigmaz0[0] = TMath::Sqrt(track1->GetSigmaZ2());
699 sigmad0[1] = TMath::Sqrt(track2->GetSigmaY2());
700 sigmaz0[1] = TMath::Sqrt(track2->GetSigmaZ2());
702 Double_t xyz1atxl0[3],xyz1atxl1[3],xyz2atxl0[3],xyz2atxl1[3];
703 track1->GetXYZAt(0.,esd->GetMagneticField(),xyz1atxl0);
704 track1->GetXYZAt(1.,esd->GetMagneticField(),xyz1atxl1);
705 track2->GetXYZAt(0.,esd->GetMagneticField(),xyz2atxl0);
706 track2->GetXYZAt(1.,esd->GetMagneticField(),xyz2atxl1);
707 Float_t x1aty0 = (xyz1atxl0[0]*xyz1atxl1[1]-xyz1atxl0[1]*xyz1atxl1[0])/(xyz1atxl1[1]-xyz1atxl0[1]);
708 Float_t x2aty0 = (xyz2atxl0[0]*xyz2atxl1[1]-xyz2atxl0[1]*xyz2atxl1[0])/(xyz2atxl1[1]-xyz2atxl0[1]);
709 Float_t dxaty0 = x1aty0-x2aty0;
711 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]);
716 //________________________________________________________________________
717 void AliAlignmentDataFilterITS::FilterCollision(const AliESDEvent *esd)
719 // Extract ITS AliTrackPoints for Cosmics (check angular matching
720 // of top and bottom track, merge the two tracks, if requested)
723 // Set branch addresses for space points tree
724 AliTrackPointArray *arrayForTree=0;
725 Float_t curv,curverr,runNumber;
726 TObjString *itsaligndata=0;
727 TObjString *itscalibrespsdd = 0;
728 fspTree->SetBranchAddress("SP",&arrayForTree);
729 fspTree->SetBranchAddress("curv",&curv);
730 fspTree->SetBranchAddress("curverr",&curverr);
731 fspTree->SetBranchAddress("run",&runNumber);
732 fspTree->SetBranchAddress("ITSAlignData",&itsaligndata);
733 fspTree->SetBranchAddress("ITSCalibRespSDD",&itscalibrespsdd);
736 runNumber = (Float_t)esd->GetRunNumber();
738 TTree* esdTree = dynamic_cast<TTree*> (GetInputData(0));
739 // Get the list of OCDB objects used for reco
740 TList *cdbList = (TList*)(esdTree->GetTree()->GetUserInfo())->FindObject("cdbList");
741 TIter iter2(cdbList);
742 TObjString* cdbEntry=0;
743 TString cdbEntryString;
744 while((cdbEntry =(TObjString*)(iter2.Next()))) {
745 cdbEntryString = cdbEntry->GetString();
746 if(cdbEntryString.Contains("ITS/Align/Data"))
747 itsaligndata = new TObjString(*cdbEntry);
748 if(cdbEntryString.Contains("ITS/Calib/RespSDD"))
749 itscalibrespsdd = new TObjString(*cdbEntry);
752 Int_t ntracks = esd->GetNumberOfTracks();
754 if(ntracks==0) return;
756 if(esd->GetPrimaryVertexSPD()->GetNContributors()<=0) return;
757 TString vtitle = esd->GetPrimaryVertexSPD()->GetTitle();
758 if(!vtitle.Contains("3D")) return;
760 Double_t vtxpos[3]; esd->GetPrimaryVertexSPD()->GetXYZ(vtxpos);
764 Double_t d0z0[2],covd0z0[3];
765 const AliTrackPointArray *array = 0;
767 for (Int_t itrack=0; itrack < ntracks; itrack++) {
768 AliESDtrack * track = esd->GetTrack(itrack);
769 if (!track) continue;
771 if(track->GetNcls(0)<GetRecoParam()->GetAlignFilterMinITSPoints()) continue;
773 if((GetRecoParam()->GetAlignFilterOnlyITSSATracks()) && track->GetNcls(1)>0) continue;
774 if((GetRecoParam()->GetAlignFilterOnlyITSTPCTracks()) && track->GetNcls(1)==0) continue;
776 if(track->Pt()<GetRecoParam()->GetAlignFilterMinPt() ||
777 track->Pt()>GetRecoParam()->GetAlignFilterMaxPt()) continue;
780 ncls = track->GetNcls(0);
781 Double_t maxd=10000.;
782 track->PropagateToDCA(esd->GetPrimaryVertex(),esd->GetMagneticField(),maxd,d0z0,covd0z0);
784 // read ITS cluster map
786 for(Int_t ilay=0;ilay<6;ilay++) {
788 if(track->HasPointOnITSLayer(ilay)) map[ilay]=1;
790 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()));
792 track->GetITSclusters(idx);
793 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]));
797 Int_t ipt,volId,modId,layerId,lay,lad,det;
799 Bool_t layerOK[6]; for(Int_t l1=0;l1<6;l1++) layerOK[l1]=kFALSE;
801 array = track->GetTrackPointArray();
803 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
804 array->GetPoint(point,ipt);
805 volId = point.GetVolumeID();
806 if(volId<=0) continue;
807 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
808 if(layerId<1 || layerId>6) continue;
809 if(point.IsExtra() &&
810 (GetRecoParam()->GetAlignFilterSkipExtra())) continue;
811 layerOK[layerId-1]=kTRUE;
815 if(jpt < GetRecoParam()->GetAlignFilterMinITSPoints()) continue;
817 fHistNpoints->Fill(jpt);
819 PostData(1,fListOfHistos);
821 Float_t dzOverlap[2];
822 Double_t globExtra[3],locExtra[3];
823 arrayForTree = new AliTrackPointArray(jpt);
825 array = track->GetTrackPointArray();
827 for(ipt=0; ipt<array->GetNPoints(); ipt++) {
828 array->GetPoint(point,ipt);
829 volId = point.GetVolumeID();
830 layerId = AliGeomManager::VolUIDToLayer(volId,modId);
831 if(layerId<1 || layerId>6 || !layerOK[layerId-1]) continue;
832 arrayForTree->AddPoint(jpt,&point);
835 fHistLayer0->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
838 fHistLayer1->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
841 fHistLayer2->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
844 fHistLayer3->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
847 fHistLayer4->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
850 fHistLayer5->Fill(TMath::ATan2(point.GetY(),point.GetX()),point.GetZ());
854 if(!point.IsExtra() ||
855 !(GetRecoParam()->GetAlignFilterFillQANtuples())) continue;
857 for(Int_t ll=1;ll<layerId;ll++) modId+=AliITSgeomTGeo::GetNLadders(ll)*AliITSgeomTGeo::GetNDetectors(ll);
858 AliITSgeomTGeo::GetModuleId(modId,lay,lad,det);
859 globExtra[0]=point.GetX();
860 globExtra[1]=point.GetY();
861 globExtra[2]=point.GetZ();
862 AliITSgeomTGeo::GlobalToLocal(lay,lad,det,globExtra,locExtra);
863 track->GetDZ(point.GetX(),point.GetY(),point.GetZ(),esd->GetMagneticField(),dzOverlap);
864 AliTrackPoint pointT;
865 Float_t radius,radiusT,phiv,phivT,thetav,thetavT;
866 for(Int_t lll=0;lll<ipt;lll++) {
867 array->GetPoint(pointT,lll);
868 Int_t layerIdT = AliGeomManager::VolUIDToLayer(pointT.GetVolumeID(),modId);
869 if(layerIdT!=layerId) continue;
870 radius=TMath::Sqrt((point.GetX()-vtxpos[0])*(point.GetX()-vtxpos[0])+(point.GetY()-vtxpos[1])*(point.GetY()-vtxpos[1]));
871 radiusT=TMath::Sqrt((pointT.GetX()-vtxpos[0])*(pointT.GetX()-vtxpos[0])+(pointT.GetY()-vtxpos[1])*(pointT.GetY()-vtxpos[1]));
872 phiv=TMath::ATan2(point.GetY()-vtxpos[1],point.GetX()-vtxpos[0]);
873 phivT=TMath::ATan2(pointT.GetY()-vtxpos[1],pointT.GetX()-vtxpos[0]);
874 if(TMath::Abs(point.GetZ()-vtxpos[2])<0.00001 || TMath::Abs(pointT.GetZ()-vtxpos[2])<0.00001) continue;
875 thetav=TMath::ATan(radius/(point.GetZ()-vtxpos[2]));
876 thetavT=TMath::ATan(radiusT/(pointT.GetZ()-vtxpos[2]));
877 dzOverlap[0]=(Float_t)((phivT-phiv)*0.5*(radiusT+radius));
878 if(TMath::Abs(TMath::Tan(0.5*(thetav+thetavT)))<0.00001) continue;
879 dzOverlap[1]=(Float_t)((pointT.GetZ()-point.GetZ())-(radiusT-radius)/TMath::Tan(0.5*(thetav+thetavT)));
880 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]);
884 curv = track->GetC(esd->GetMagneticField());
885 curverr = TMath::Sqrt(track->GetSigma1Pt2())*track->GetC(esd->GetMagneticField())/track->OneOverPt();
889 } // end of tracks loop
896 //________________________________________________________________________
897 void AliAlignmentDataFilterITS::Terminate(Option_t */*option*/)
899 // Terminate analysis
901 AliDebug(2,"AliITSAlignmentDataFiler: Terminate() \n");
903 fspTree = dynamic_cast<TTree*> (GetOutputData(0));
905 printf("ERROR: fspTree not available\n");
909 fListOfHistos = dynamic_cast<TList*> (GetOutputData(1));
910 if (!fListOfHistos) {
911 printf("ERROR: fListOfHistos not available\n");
915 fHistNevents = dynamic_cast<TH1F*>(fListOfHistos->FindObject("fHistNevents"));
916 fHistNpoints = dynamic_cast<TH1F*>(fListOfHistos->FindObject("fHistNpoints"));
917 fHistPt = dynamic_cast<TH1F*>(fListOfHistos->FindObject("fHistPt"));
918 fHistLayer0 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer0"));
919 fHistLayer1 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer1"));
920 fHistLayer2 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer2"));
921 fHistLayer3 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer3"));
922 fHistLayer4 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer4"));
923 fHistLayer5 = dynamic_cast<TH2F*>(fListOfHistos->FindObject("fHistLayer5"));
924 fntExtra = dynamic_cast<TNtuple*>(fListOfHistos->FindObject("fntExtra"));
925 fntCosmicMatching = dynamic_cast<TNtuple*>(fListOfHistos->FindObject("fntCosmicMatching"));
931 //-------------------------------------------------------------------------------
932 const AliITSRecoParam *AliAlignmentDataFilterITS::GetRecoParam() const
935 // Return the ITSRecoParam object
937 if(AliITSReconstructor::GetRecoParam()) {
938 return AliITSReconstructor::GetRecoParam();
939 } else if(fITSRecoParam) {
940 return fITSRecoParam;
943 //--------------------------------------------------------------------------------
944 Int_t AliAlignmentDataFilterITS::WriteTrackPointsInIdealGeom(Char_t *fin,
951 // Convert AliTrackPoints in fin, reconstructed with fmis, back
961 if (gSystem->AccessPathName(fgeo)) {
962 printf("couldn't find geometry file %s - skipping...\n",fmis);
966 TFile *geofile=TFile::Open(fgeo);
967 TGeoManager *fgGeometry=NULL;
969 fgGeometry=(TGeoManager*)geofile->Get("ALICE");
972 fgGeometry=(TGeoManager*)geofile->Get("Geometry");
975 AliCDBEntry *entry = (AliCDBEntry*)geofile->Get("AliCDBEntry");
977 fgGeometry = (TGeoManager*)entry->GetObject();
980 if (!fgGeometry) return -1;
981 AliGeomManager::SetGeometry(fgGeometry);
982 if(!AliGeomManager::GetGeometry()) return -1;
985 // open alignment file
986 if (gSystem->AccessPathName(fmis)) {
987 printf("couldn't open alignment file %s - skipping...\n",fmis);
990 TFile *pref = TFile::Open(fmis);
991 if (!pref->IsOpen()) return -2;
994 /// apply alignment to ideal geometry
995 TClonesArray *prea=(TClonesArray*)pref->Get("ITSAlignObjs");
997 if (pref->Get("AliCDBEntry"))
998 prea = (TClonesArray*) ((AliCDBEntry*)pref->Get("AliCDBEntry"))->GetObject();
1000 if (!prea) return -3;
1001 Int_t nprea=prea->GetEntriesFast();
1002 printf("Array of input misalignments with %d entries\n",nprea);
1003 AliGeomManager::ApplyAlignObjsToGeom(*prea); // apply all levels of objs
1005 AliTrackPointArray *tpain=NULL;
1006 TFile *tpainfile=NULL;
1008 AliTrackPoint point;
1009 AliITSAlignMille2Module *m2[2200];
1010 for (Int_t i=0; i<2198; i++)
1011 m2[i]=new AliITSAlignMille2Module(AliITSAlignMille2Module::GetVolumeIDFromIndex(i));
1014 if (gSystem->AccessPathName(fin)) {
1015 printf("couldn't open file %s - skipping...\n",fin);
1018 tpainfile = TFile::Open(fin);
1019 if (!tpainfile->IsOpen()) return -4;
1021 treein=(TTree*)tpainfile->Get("spTree");
1022 if (!treein) return -5;
1023 Float_t curv,curverr,runNumber;
1024 TObjString *itsaligndata=0;
1025 TObjString *itscalibrespsdd = 0;
1026 treein->SetBranchAddress("SP", &tpain);
1027 treein->SetBranchAddress("curv", &curv);
1028 treein->SetBranchAddress("curverr", &curverr);
1029 treein->SetBranchAddress("run",&runNumber);
1030 treein->SetBranchAddress("ITSAlignData",&itsaligndata);
1031 treein->SetBranchAddress("ITSCalibRespSDD",&itscalibrespsdd);
1033 int ntrks=treein->GetEntries();
1034 printf("Reading %d tracks from %s\n",ntrks,fin);
1038 TFile *pointsFile = TFile::Open(fout,"RECREATE");
1039 if (!pointsFile || !pointsFile->IsOpen()) {
1040 printf("Can't open output file %s !",fout);
1043 AliTrackPointArray *array = new AliTrackPointArray();
1046 TTree *treeout=(TTree*)treein->Clone("spTree");
1048 treeout->SetBranchAddress("SP", &array);
1049 treeout->SetBranchAddress("curv", &curv);
1050 treeout->SetBranchAddress("curverr", &curverr);
1051 treeout->SetBranchAddress("run",&runNumber);
1052 treeout->SetBranchAddress("ITSAlignData",&itsaligndata);
1053 treeout->SetBranchAddress("ITSCalibRespSDD",&itscalibrespsdd);
1056 for (Int_t it=0; it<ntrks; it++) {
1057 if (!(it%5000) ) printf("...processing track n. %d\n",it);
1059 treein->GetEvent(it);
1061 //////////////////////////////
1063 AliTrackPointArray *atp=tpain;
1064 AliTrackPointArray *atps=NULL;
1065 Int_t npts=atp->GetNPoints();
1068 // check points in specific places
1070 // build a new track
1071 atps=new AliTrackPointArray(npts);
1074 for (int i=0; i<npts; i++) {
1077 UShort_t volid=atp->GetVolumeID()[i];
1078 Int_t index=AliITSAlignMille2Module::GetIndexFromVolumeID(volid);
1082 // get MODIFIED matrix
1083 TGeoHMatrix *svMatrix = m2[index]->GetSensitiveVolumeMatrix(p.GetVolumeID());
1084 //TGeoHMatrix *svOrigMatrix = mm->GetSensitiveVolumeOrigGlobalMatrix(p.GetVolumeID());
1086 Double_t pg[3],pl[3];
1090 if (prn) printf("Global coordinates of measured point : X=%f Y=%f Z=%f \n",pg[0],pg[1],pg[2]);
1091 svMatrix->MasterToLocal(pg,pl);
1093 // check that things went OK: local y should be 0.
1094 if(TMath::Abs(pl[1])>1.e-6) {
1095 printf("AliAlignmentDataFilterITS::WriteTrackPointsInIdealGeom: ERROR, local y = %f (should be zero)\n",pl[1]);
1099 if (prn) printf("Local coordinates of measured point : X=%f Y=%f Z=%f \n",pl[0],pl[1],pl[2]);
1101 // update covariance matrix
1104 hcovel[0]=(Double_t)(p.GetCov()[0]);
1105 hcovel[1]=(Double_t)(p.GetCov()[1]);
1106 hcovel[2]=(Double_t)(p.GetCov()[2]);
1107 hcovel[3]=(Double_t)(p.GetCov()[1]);
1108 hcovel[4]=(Double_t)(p.GetCov()[3]);
1109 hcovel[5]=(Double_t)(p.GetCov()[4]);
1110 hcovel[6]=(Double_t)(p.GetCov()[2]);
1111 hcovel[7]=(Double_t)(p.GetCov()[4]);
1112 hcovel[8]=(Double_t)(p.GetCov()[5]);
1113 hcov.SetRotation(hcovel);
1114 // now rotate in local system
1115 hcov.Multiply(svMatrix);
1116 hcov.MultiplyLeft(&svMatrix->Inverse());
1117 // now hcov is LOCAL COVARIANCE MATRIX
1119 /// get original matrix of sens. vol.
1120 TGeoHMatrix *svOrigMatrix = m2[index]->GetSensitiveVolumeOrigGlobalMatrix(p.GetVolumeID());
1121 // modify global coordinates according with pre-aligment
1122 svOrigMatrix->LocalToMaster(pl,pg);
1123 // now rotate in local system
1124 hcov.Multiply(&svOrigMatrix->Inverse());
1125 hcov.MultiplyLeft(svOrigMatrix);
1126 // hcov is back in GLOBAL RF
1128 pcov[0]=hcov.GetRotationMatrix()[0];
1129 pcov[1]=hcov.GetRotationMatrix()[1];
1130 pcov[2]=hcov.GetRotationMatrix()[2];
1131 pcov[3]=hcov.GetRotationMatrix()[4];
1132 pcov[4]=hcov.GetRotationMatrix()[5];
1133 pcov[5]=hcov.GetRotationMatrix()[8];
1135 p.SetXYZ(pg[0],pg[1],pg[2],pcov);
1136 if (prn) printf("New global coordinates of measured point : X=%f Y=%f Z=%f \n",pg[0],pg[1],pg[2]);
1137 atps->AddPoint(npto,&p);
1138 if (prn) printf("Adding point[%d] = ( %f , %f , %f ) volid = %d\n",npto,atps->GetX()[npto],atps->GetY()[npto],atps->GetZ()[npto],atps->GetVolumeID()[npto] );
1139 if (prn) p.Print("");
1145 ////////////////////////////////////////////////////////////
1152 } // end loop on tracks
1154 pointsFile->Write();
1155 pointsFile->Close();