1 /**************************************************************************
2 * Copyright(c) 2008-2010, 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 **************************************************************************/
18 //////////////////////////////////////////////////////////////////////////
19 // Class to convert survey tables in alignment objects
21 // origin: Marco Van Leeuwen (m.vanleeuwen1@uu.nl)
22 // Panos.Christakoglou (Panos.Christakoglou@cern.ch)
23 // Martin Poghosyan (Martin.Poghosyan@to.infn.it)
24 //////////////////////////////////////////////////////////////////////////
26 #include "TGeoManager.h"
27 #include "TGeoPhysicalNode.h"
31 #include "AliITSSurveyToAlign.h"
32 #include "AliSurveyPoint.h"
33 #include "AliAlignObjParams.h"
34 #include "AliGeomManager.h"
38 #include "AliCDBManager.h"
40 #include "AliITSgeomTGeo.h"
43 //#include "dataSDDladder.h"
44 ClassImp(AliITSSurveyToAlign)
46 const Double_t AliITSSurveyToAlign::fgkLocR[6][3]={{ 3.24,0.21905,-2.4},
51 {-3.24,0.21905,-2.4}};
53 const Double_t AliITSSurveyToAlign::fgkLocL[6][3]={{-3.24,0.21905, 2.4},
58 { 3.24,0.21905, 2.4}};
60 const Double_t kRadToDeg = 180./TMath::Pi();
62 //________________________________________________________________________
63 AliITSSurveyToAlign::AliITSSurveyToAlign(Int_t run, Int_t repModSDD, Int_t repModVerSDD, Int_t repLadSDD, Int_t repLadVerSDD, Int_t repModSSD, Int_t repModVerSSD, Int_t repLaddSSD, Int_t repLaddVerSSD) :
64 AliSurveyToAlignObjs(),
66 fSDDModuleRepNumber(repModSDD),
67 fSDDModuleRepVersion(repModVerSDD),
68 fSDDLadderRepNumber(repLadSDD),
69 fSDDLadderRepVersion(repLadVerSDD),
70 fSSDModuleRepNumber(repModSSD),
71 fSSDModuleRepVersion(repModVerSSD),
72 fSSDLadderRepNumber(repLaddSSD),
73 fSSDLadderRepVersion(repLaddVerSSD)
75 // Standard constructor
76 for(Int_t i=0; i<260; i++)
79 fsymnameSDDm[i]=TString("");
88 fsymnameSDDl[i]=TString("");
99 // default constructor
100 // Arguments are report numbers for survey data.
101 // The defaults point to reports from detector construction
105 //_________________________________________________________________________
106 AliITSSurveyToAlign::AliITSSurveyToAlign(const AliITSSurveyToAlign &align) :
107 AliSurveyToAlignObjs(align),
109 fSDDModuleRepNumber(align.fSDDModuleRepNumber),
110 fSDDModuleRepVersion(align.fSDDModuleRepVersion),
111 fSDDLadderRepNumber(align.fSDDLadderRepNumber),
112 fSDDLadderRepVersion(align.fSDDLadderRepVersion),
113 fSSDModuleRepNumber(align.fSSDModuleRepNumber),
114 fSSDModuleRepVersion(align.fSSDModuleRepVersion),
115 fSSDLadderRepNumber(align.fSSDLadderRepNumber),
116 fSSDLadderRepVersion(align.fSSDLadderRepVersion)
121 for(Int_t i=0; i<260; i++)
123 fuidSDDm[i]= align.fuidSDDm[i];
124 fsymnameSDDm[i]=TString(align.fsymnameSDDm[i]);
125 fxSDDm[i]=align.fxSDDm[i];
126 fySDDm[i]=align.fySDDm[i];
127 fzSDDm[i]=align.fzSDDm[i];
128 fpsiSDDm[i]=align.fpsiSDDm[i];
129 ftetSDDm[i]=align.ftetSDDm[i];
130 fphiSDDm[i]=align.fphiSDDm[i];
132 fuidSDDl[i]=align.fuidSDDl[i];
133 fsymnameSDDl[i]=TString(align.fsymnameSDDl[i]);
134 fxSDDl[i]=align.fxSDDl[i];
135 fySDDl[i]=align.fySDDl[i];
136 fzSDDl[i]=align.fzSDDl[i];
137 fpsiSDDl[i]=align.fpsiSDDl[i];
138 ftetSDDl[i]=align.ftetSDDl[i];
139 fphiSDDl[i]=align.fphiSDDl[i];
144 //__________________________________________________________________________
145 AliITSSurveyToAlign & AliITSSurveyToAlign::operator =(const AliITSSurveyToAlign& align) {
147 // assignment operator
149 this->~AliITSSurveyToAlign();
150 new(this) AliITSSurveyToAlign(align);
154 //__________________________________________________________________________
155 AliITSSurveyToAlign::~AliITSSurveyToAlign() {
161 //______________________________________________________________________
162 void AliITSSurveyToAlign::Run() {
164 // Runs the full chain
165 // User should call StoreAlignObjToFile or StoreAlignObjToCDB afterwards to
166 // store output (not included here to leave the choice between the two)
169 // Load ideal geometry from the OCDB
170 AliCDBManager *cdb = AliCDBManager::Instance();
171 cdb->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
173 AliGeomManager::LoadGeometry();
175 if(!CreateAlignObjs()) AliError("Construction of alignment objects from survey failed!");
178 //______________________________________________________________________
179 Bool_t AliITSSurveyToAlign::CreateAlignObjs() {
180 // Fill the array of alignment objects with alignment objects
181 // from survey for all three subdetectors
185 CreateAlignObjDummySPD();
187 ///////////////////////////
189 if(!LoadSurveyFromAlienFile("ITS", fSDDModuleRepNumber, fSDDModuleRepVersion)){
190 AliError("Loading of alignment objects from survey for SDD modules failed!");
193 CreateAlignObjSDDModules();
195 if(!LoadSurveyFromAlienFile("ITS", fSDDLadderRepNumber, fSDDLadderRepVersion)){
196 AliError("Loading of alignment objects from survey for SDD ladder failed!");
199 CreateAlignObjSDDLadders();
200 if(!ApplyAlignObjSDD()) return kFALSE;
204 if(!LoadSurveyFromAlienFile("ITS", fSSDLadderRepNumber, fSSDLadderRepVersion)){
205 AliError("Loading of alignment objects from survey for SSD ladders failed!");
208 CreateAlignObjSSDLadders();
211 if(!ApplyAlignObjSSDLadders()) return kFALSE; // needed to build correctly the objects for SSD modules
212 if(!LoadSurveyFromAlienFile("ITS", fSSDModuleRepNumber, fSSDModuleRepVersion)){
213 AliError("Loading of alignment objects from survey for SSD modules failed!");
216 CreateAlignObjSSDModules();
221 //______________________________________________________________________
222 void AliITSSurveyToAlign::CreateAlignObjDummySPD(){
224 // Create alignObjs for SPD
225 // For the moment, uses 0,0,0,0,0,0
227 for(Int_t imod = 0; imod < 240; imod++) {
228 Int_t ilayer = (imod < 80) ? AliGeomManager::kSPD1 : AliGeomManager::kSPD2;
229 Int_t imodule = (imod < 80) ? imod : imod - 80;
231 Int_t uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
232 const Char_t *symname = AliGeomManager::SymName(uid);
234 new((*fAlignObjArray)[imod]) AliAlignObjParams(symname, uid, 0., 0., 0., 0., 0., 0., kTRUE);
238 Bool_t AliITSSurveyToAlign::ApplyAlignObjSDD()
240 // Apply alignment for SDD
243 for(Int_t iLadd=0; iLadd<36; iLadd++)
245 new((*fAlignObjArray)[240+iLadd]) AliAlignObjParams(fsymnameSDDl[iLadd].Data(), fuidSDDl[iLadd],
246 fxSDDl[iLadd] , fySDDl[iLadd] , fzSDDl[iLadd] ,
247 fpsiSDDl[iLadd], ftetSDDl[iLadd], fphiSDDl[iLadd], kFALSE);
248 // new((*fAlignObjArray)[240+iLadd]) AliAlignObjParams(fsymnameSDDl[iLadd].Data(), fuidSDDl[iLadd],
249 // fxSDDl[iLadd] , fySDDl[iLadd] , fzSDDl[iLadd] ,
252 AliAlignObjParams* ap = dynamic_cast<AliAlignObjParams*> (fAlignObjArray->UncheckedAt(240+iLadd));
253 // printf("%s %f %f %f\n",fxSDDl[iLadd], fsymnameSDDl[iLadd].Data(), fySDDl[iLadd] , fzSDDl[iLadd]);
254 //printf("%d %f\n", iLadd, fzSDDl[iLadd]);
256 if(ap != 0 && fsymnameSDDl[iLadd].Contains("SDD") && fsymnameSDDl[iLadd].Contains("Ladder"))
258 // printf("%d %s %d\n",240+iLadd, fsymnameSDDl[iLadd].Data(),fuidSDDl[iLadd] );
260 if(!ap->ApplyToGeometry()) return kFALSE;
265 AliError("SDD Ladder array is not initialized correctly");
270 for(Int_t iMod=0; iMod<260; iMod++)
272 // printf("%d s=%s x= %f y= %f z= %f\n",240+36+iMod, fsymnameSDDm[iMod].Data(),fxSDDm[iMod], fySDDm[iMod], fzSDDm[iMod] );
274 new((*fAlignObjArray)[240+36+iMod]) AliAlignObjParams(fsymnameSDDm[iMod].Data(), fuidSDDm[iMod],
275 fxSDDm[iMod] , fySDDm[iMod] , fzSDDm[iMod],
276 fpsiSDDm[iMod], ftetSDDm[iMod], fphiSDDm[iMod], kFALSE);
279 if(!fsymnameSDDm[iMod].Contains("SDD") || !fsymnameSDDm[iMod].Contains("Sensor"))
281 AliError("SDD Module array is not initialized correctly\n");
287 AliInfo(Form(" %d alignment objects for SDD ladders applied to geometry.",applied));
291 //______________________________________________________________________
292 void AliITSSurveyToAlign::CreateAlignObjSDDModules(){
294 // Create alignment objects for SDD
298 const char* symname = 0;
299 AliSurveyPoint* pt = 0;
301 Int_t iModuleIndex=240;
307 if (fSurveyPoints == 0 || fSurveyPoints->GetEntries() == 0) {
308 AliWarning("SDD survey data are not available, using zero values");
309 CreateAlignObjDummySDDModules();
313 for(Int_t imod = 1; imod < fSurveyPoints->GetEntries(); imod++) {
314 pt = (AliSurveyPoint*) fSurveyPoints->At(imod);
317 Int_t iLayer, iLadder, iModule, iPoint;
318 ReadPointNameSDD(pt->GetName(),iLayer, iLadder, iModule, iPoint);
320 Double_t x =pt->GetX();
321 Double_t y =pt->GetY();
322 Double_t z =pt->GetZ();
323 Double_t xE=pt->GetPrecisionX();
324 Double_t yE=pt->GetPrecisionY();
325 Double_t zE=pt->GetPrecisionZ();
327 if(iLayer==3 && iLadder==2)
329 if(iPoint<3) iPoint+=3;
330 else if(iPoint>2) iPoint-=3;
331 iModule=TMath::Abs(iModule - 5);
337 iModuleIndex = AliITSgeomTGeo::GetModuleIndex(iLayer0,iLadder0+1,iModule0+1);
338 Int_t iModuleIndex1 = AliITSgeomTGeo::GetModuleIndex(iLayer,iLadder+1,iModule+1);
340 if(iModuleIndex==iModuleIndex1)
342 fSDDmeP[iPoint][0]=x;
343 fSDDmeP[iPoint][1]=y;
344 fSDDmeP[iPoint][2]=z;
345 fSDDmeP[iPoint][3]=xE;
346 fSDDmeP[iPoint][4]=yE;
347 fSDDmeP[iPoint][5]=zE;
348 fSDDisMe[iPoint]=kTRUE;
350 if(iLayer==3) uid = AliGeomManager::LayerToVolUID(iLayer0,iModuleIndex-240);
351 if(iLayer==4) uid = AliGeomManager::LayerToVolUID(iLayer0,iModuleIndex-324);
352 symname = AliGeomManager::SymName(uid);
353 GetIdPosSDD(uid,iLayer0, iModule0, iPoint);
357 // printf("%s\n",pt->GetName());
358 // printf("Me: %7.4f %7.4f %7.4f\n", fSDDmeP[iPoint][0], fSDDmeP[iPoint][1], fSDDmeP[iPoint][2]);
359 // printf("Id: %7.4f %7.4f %7.4f\n", fSDDidP[iPoint][0], fSDDidP[iPoint][1], fSDDidP[iPoint][2]);
362 // cout << "Points red module " << imod << endl;
363 if((iModuleIndex!=iModuleIndex1)||(imod==(fSurveyPoints->GetEntries()-1)))
365 ConvertToRSofModulesAndRotSDD(iLayer0, iModule0);
374 if(nModules==2) CalcShiftSDD(x0,y0,z0);
375 if(nModules>2) CalcShiftRotSDD(tet, psi, phi, x0, y0, z0);
376 // printf("%s %d %f %f %f %f %f %f\n",symname, uid, x0/10., y0/10., z0/10., psi, tet, phi);
380 // cout << "Allocate alignobjparams " << imod << endl;
381 // new((*fAlignObjArray)[iModuleIndex]) AliAlignObjParams(symname, uid, x0/10., y0/10., z0/10., psi, tet, phi, kFALSE);
382 // printf("INDEX: Module: %d\n",iModuleIndex);
385 fsymnameSDDm[iModuleIndex-240]=TString(symname);
386 fuidSDDm[iModuleIndex-240]=uid;
387 fxSDDm[iModuleIndex-240]=x0/10.;
388 fySDDm[iModuleIndex-240]=y0/10.;
389 fzSDDm[iModuleIndex-240]=z0/10.;
390 fpsiSDDm[iModuleIndex-240]=psi;
391 ftetSDDm[iModuleIndex-240]=tet;
392 fphiSDDm[iModuleIndex-240]=phi;
393 // new((*fAlignObjArray)[36+iModuleIndex]) AliAlignObjParams(fsymnameSDDm[iModuleIndex-240].Data(), fuidSDDm[iModuleIndex-240],
394 // fxSDDm[iModuleIndex-240], fySDDm[iModuleIndex-240], fzSDDm[iModuleIndex-240],
395 // fpsiSDDm[iModuleIndex-240], ftetSDDm[iModuleIndex-240], fphiSDDm[iModuleIndex-240], kFALSE);
400 // iModuleIndex = AliITSgeomTGeo::GetModuleIndex(iLayer,iLadder+1,iModule+1);
401 for(Int_t i=0; i<6;i++) fSDDisMe[i]=kFALSE;
402 if(imod!=(fSurveyPoints->GetEntries()-1)) imod--;
408 //______________________________________________________________________
409 void AliITSSurveyToAlign::CreateAlignObjDummySDDModules(){
411 // Create empty alignment objects
412 // Used when fSurveySDD == 0
414 for(Int_t imod = 0; imod < 260; imod++) {
416 Int_t ilayer = (imod < 84) ? AliGeomManager::kSDD1 : AliGeomManager::kSDD2;
417 Int_t imodule = (imod < 84) ? imod : imod - 84;
419 Int_t uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
420 const Char_t *symname = AliGeomManager::SymName(uid);
422 fsymnameSDDm[imod]=TString(symname);
431 // new((*fAlignObjArray)[imod+36+240]) AliAlignObjParams(symname, uid, 0., 0., 0., 0., 0., 0., kTRUE);
435 //______________________________________________________________________
436 void AliITSSurveyToAlign::CreateAlignObjSSDModules(){
438 // Create alignment objects for SSD modules
439 // Objects for SSD ladders must be applied to geometry first
442 const Float_t kMu2Cm = 1e-4;
443 const Float_t kSensLength = 7.464;
444 const Int_t kSSDMODULES = 1698;
446 if (fSurveyPoints == 0 || fSurveyPoints->GetEntries() == 0) {
447 AliWarning("SSD module survey data not available; using dummy values");
448 CreateAlignObjDummySSDModules();
452 // First do module-by-module
454 for(Int_t imod = 500; imod < kSSDMODULES + 500; imod++) {
455 Int_t iLayer, iLadder, iLaddMod;
456 AliITSgeomTGeo::GetModuleId(imod,iLayer,iLadder,iLaddMod); // returns 1-based numbers
458 TString pname="ITS/SSD";
464 AliSurveyPoint *pt1 = (AliSurveyPoint*) fSurveyPoints->FindObject(pname+"/Point0");
465 AliSurveyPoint *pt2 = (AliSurveyPoint*) fSurveyPoints->FindObject(pname+"/Point1");
467 AliWarning(Form("No Survey points for iladd %d imod %d",iLadder,iLaddMod));
471 sx = 0.5*(pt1->GetX() + pt2->GetX()) * kMu2Cm;
472 sz = 0.5*(pt1->GetZ() + pt2->GetZ()) * kMu2Cm;
474 // Minus sign to change local coordinate convention
475 Float_t theta = -(pt2->GetZ() - pt1->GetZ())*kMu2Cm/kSensLength;
478 Int_t iLayMod = imod - 500;
481 Int_t uid = AliGeomManager::LayerToVolUID(iLayer,iLayMod);
483 const Char_t *symname = AliGeomManager::SymName(uid);
484 if (pname.CompareTo(symname) != 0)
485 AliWarning(Form("Mapping mismatch survey point %s volume name %s",pname.Data(),symname));
487 if (imod >= 676 && imod <= 697) {
488 cout << "ilayer " << iLayer << " imod " << imod
489 << " uid " << uid << " name " << symname
490 << " survey shift " << sx << " " << 0 << " " << sz << endl
491 << " theta " << theta << endl;
494 new((*fAlignObjArray)[imod+36]) AliAlignObjParams(symname, uid, sx, 0, sz, 0., theta, 0., kFALSE);
498 //______________________________________________________________________
499 Bool_t AliITSSurveyToAlign::ApplyAlignObjSSDLadders(){
501 // Apply alignment objects for SSD ladders to geometry, needed to correctly
502 // build alignment objects for SSD modules
506 for(Int_t jj=0; jj<fAlignObjArray->GetEntriesFast(); jj++)
508 AliAlignObjParams* ap = dynamic_cast<AliAlignObjParams*> (fAlignObjArray->UncheckedAt(jj));
511 TString sName(ap->GetSymName());
512 if(sName.Contains("SSD") && sName.Contains("Ladder"))
514 if(!ap->ApplyToGeometry()) return kFALSE;
519 AliInfo(Form(" %d alignment objects for SSD ladders applied to geometry.",applied));
523 //______________________________________________________________________
525 Bool_t AliITSSurveyToAlign::ApplyAlignObjSDDLadders(){
527 // Apply alignment objects for SDD ladders to geometry, needed to correctly
528 // build alignment objects for SDD modules
532 for(Int_t jj=0; jj<fAlignObjArray->GetEntriesFast(); jj++)
534 AliAlignObjParams* ap = dynamic_cast<AliAlignObjParams*> (fAlignObjArray->UncheckedAt(jj));
537 TString sName(ap->GetSymName());
538 // printf("%s\n",sName.Data());
539 if(sName.Contains("SDD") && sName.Contains("Ladder"))
541 if(!ap->ApplyToGeometry()) return kFALSE;
546 AliInfo(Form(" %d alignment objects for SDD ladders applied to geometry.",applied));
551 //______________________________________________________________________
552 void AliITSSurveyToAlign::CreateAlignObjDummySDDLadders()
555 // Create empty alignment objects
556 TString sddName = "ITS/SDD";
559 for (Int_t ilayer = 0; ilayer < 2; ilayer ++)
561 Int_t nLadder = 14; // layer SDD1
562 if (ilayer == 1) nLadder = 22; // layer SDD2
563 for (Int_t iLadder = 0; iLadder < nLadder; iLadder++) {
564 TString ladName = sddName;
565 ladName += (ilayer+2);
566 ladName += "/Ladder";
568 fsymnameSDDl[iLadd]=TString(ladName);
584 void AliITSSurveyToAlign::CreateAlignObjSDDLadders(){
586 // Alignment objects from survey for SDD ladders
588 const Float_t kLaddLenz[2] ={500, 650}; // Layer 2,3: distance between mouting points along z (mm)
589 const Float_t kLaddLenx = 28 ; // Layer 2,3: distance between mouting points along x (mm)
591 TString sddName = "ITS/SDD";
593 TObjArray *ladderPoints = fSurveyPoints;
594 if (ladderPoints == 0 || ladderPoints->GetEntries() == 0) {
595 AliWarning("No SDD Ladder alignment points found. Skipping");
598 if (ladderPoints->GetEntries()!= 72) {
599 AliWarning(Form("Unexpected number of survey points %d, should be 72",ladderPoints->GetEntries()));
604 TAlien::Connect("alien://");
605 gSystem->Load("libXMLParser.so");
608 AliCDBManager *cdb = AliCDBManager::Instance();
609 cdb->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
611 AliGeomManager::LoadGeometry();
612 AliITSSurveyToAlign *a = new AliITSSurveyToAlign();
614 a->CreateAlignObjSDDLadders()
615 a->ApplyAlignObjSDDLadders();
617 a->LoadSurveyFromAlienFile("ITS", 845069, 1);
618 a->CreateAlignObjSDD();
620 a->CreateAlignObjs();
625 for (Int_t ilayer = 0; ilayer < 2; ilayer ++)
627 Int_t nLadder = 14; // layer SDD1
628 if (ilayer == 1) nLadder = 22; // layer SDD2
630 for (Int_t iLadder = 0; iLadder < nLadder; iLadder++) {
631 TString ladName = sddName;
632 ladName += (ilayer+2);
633 ladName += "/Ladder";
637 /////////////////////////////////////////////////////////////////////////////
638 AliSurveyPoint *p24 = (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/RB24");
639 AliSurveyPoint *p26 = (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/RB26");
641 AliWarning(Form("Cannot find RB24 side point for ladder %s",ladName.Data()));
645 AliWarning(Form("Cannot find RB26 side point for ladder %s",ladName.Data()));
650 tmpStr.Insert(0,p24->GetName(),3);
651 Int_t ladder = tmpStr.Atoi();
653 tmpStr.Insert(0,p26->GetName(),3);
654 if (tmpStr.Atoi() != ladder)
655 AliError(Form("Survey data file error. Expect pairs of RB24, RB26 points. Got ladders %d %d",ladder,tmpStr.Atoi()));
658 Double_t x24, y24, z24;
659 Double_t x26, y26, z26;
668 // for top ladders: RS(local) = RS(global) + Y_shift
670 Double_t phi = 0; // Not measured
677 psi=TMath::ATan((y26-y24)/(kLaddLenz[ilayer]+z24-z26));
678 Double_t tgtet0 = kLaddLenx/kLaddLenz[ilayer];
679 Double_t tgtet1 = (x24-x26+kLaddLenx)/(kLaddLenz[ilayer]+z24-z26);
680 theta=TMath::ATan((tgtet1-tgtet0)/(1+tgtet1*tgtet0));
682 Double_t x0=x24-theta*kLaddLenz[ilayer]/2;
683 Double_t y0=y24+psi*kLaddLenz[ilayer]/2;
684 Double_t z0=z24+theta*kLaddLenx/2;
689 // local delta transformation by passing 3 shifts (in centimeters) and 3 angles (expressed in degrees)
690 // new((*fAlignObjArray)[500+1698+144+iLadd]) AliAlignObjParams(ladName,0,drLoc[0],drLoc[1],drLoc[2],psi,theta,phi,kFALSE);
691 fsymnameSDDl[iLadd]=TString(ladName);
693 fxSDDl[iLadd]=x0/10.;
694 fySDDl[iLadd]=y0/10.;
695 fzSDDl[iLadd]=z0/10.;
697 ftetSDDl[iLadd]=theta;
699 // new((*fAlignObjArray)[240+iLadd]) AliAlignObjParams(fsymnameSDDl[iLadd].Data(), fuidSDDl[iLadd],
700 // fxSDDl[iLadd] , fySDDl[iLadd] , fzSDDl[iLadd] ,
701 // fpsiSDDl[iLadd], ftetSDDl[iLadd], fphiSDDl[iLadd], kFALSE);
702 // printf("INDEX: Ladder: %d\n",iLadd);
707 ////////////////////////////////////////////////////////////////////////////////////////
711 //______________________________________________________________________
712 void AliITSSurveyToAlign::CreateAlignObjSSDLadders(){
714 // Alignment objects from survey for SSD ladders (Torino data)
716 const Float_t kLaddLen5 = 90.27; // Layer 5: distance between mouting points
717 const Float_t kLaddLen6 = 102.0; // Layer 6: distance between mouting points
718 const Float_t zLag = 2.927; // Distance between V mounting point and Zloc = 0
719 // = half ladder length - nom z-position of ladder from gGeoManager
720 const Float_t kMu2Cm = 1e-4;
722 TString ssdName = "ITS/SSD";
724 TObjArray *ladderPoints = fSurveyPoints;
725 if (ladderPoints == 0 || ladderPoints->GetEntries() == 0) {
726 AliWarning("No SSD Ladder alignment points found. Skipping");
729 if (ladderPoints->GetEntries()!= 2*(34+38)) {
730 AliWarning(Form("Unexpected number of survey points %d, should be 144",ladderPoints->GetEntries()));
733 for (Int_t ilayer = 4; ilayer <= 5; ilayer ++) {
734 Int_t nLadder = 34; // layer 5
736 nLadder = 38; // layer 6
738 for (Int_t iLadder = 0; iLadder < nLadder; iLadder++) {
739 TString ladName = ssdName;
741 ladName += "/Ladder";
744 AliSurveyPoint *vPoint = (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/V");
745 AliSurveyPoint *qPoint = (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/Q");
747 AliWarning(Form("Cannot find V side point for ladder %s",ladName.Data()));
751 AliWarning(Form("Cannot find Q side point for ladder %s",ladName.Data()));
756 tmpStr.Insert(0,vPoint->GetName(),3);
757 Int_t ladder = tmpStr.Atoi();
759 tmpStr.Insert(0,qPoint->GetName(),3);
760 if (tmpStr.Atoi() != ladder)
761 AliError(Form("Survey data file error. Expect pairs of V,Q points. Got ladders %d %d",ladder,tmpStr.Atoi()));
763 // Note: file gives meas-nom in local offline coordinates,
764 // ie. local z = - global z and local x = - global x (for ladder 508, i.e. top ladder)
765 Double_t dxLoc = vPoint->GetX() * kMu2Cm;
766 Double_t dyLoc = vPoint->GetY() * kMu2Cm;
767 Double_t dzLoc = vPoint->GetZ() * kMu2Cm;
770 Double_t phi = 0; // Not measured
775 // Note: local psi = -global psi, psi = atan(-(y(z1) - y(z0)) / (z1-z0))
776 // local theta = global theta = atan(dx/dz)
777 // V side is A side is large global z
778 // Q side is C side is large local z
782 theta = TMath::ATan((qPoint->GetX() - vPoint->GetX())*kMu2Cm/kLaddLen6);
783 psi = TMath::ATan((vPoint->GetY() - qPoint->GetY())*kMu2Cm/kLaddLen6);
786 theta = TMath::ATan((qPoint->GetX() - vPoint->GetX())*kMu2Cm/kLaddLen5);
787 psi = TMath::ATan((vPoint->GetY() - qPoint->GetY())*kMu2Cm/kLaddLen5);
790 // Move along ladder to local Z = 0 point
794 // Convert to degrees
797 AliDebug(1,Form("ladname %f %f %f %f %f %f ",dxLoc,dyLoc,dzLoc,psi,theta,phi));
799 new((*fAlignObjArray)[500+36+1698+iLadd]) AliAlignObjParams(ladName,0,dxLoc,dyLoc,dzLoc,psi,theta,phi,kFALSE);
805 ////////////////////////////////////////////////////////////////////////////////////////
807 //______________________________________________________________________
808 void AliITSSurveyToAlign::CreateAlignObjDummySSDModules(){
810 // Create empty alignment objects
811 // Used when fSurveySSD == 0
813 for(Int_t imod = 0; imod < 1698; imod++) {
814 Int_t ilayer = (imod < 748) ? AliGeomManager::kSSD1 : AliGeomManager::kSSD2;
815 Int_t imodule = (imod < 748) ? imod : imod - 748;
817 Int_t uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
818 const Char_t *symname = AliGeomManager::SymName(uid);
820 new((*fAlignObjArray)[500+36+imod]) AliAlignObjParams(symname, uid, 0., 0., 0., 0., 0., 0., kTRUE);
825 //______________________________________________________________________
826 void AliITSSurveyToAlign::GetIdPosSDD(Int_t uid, Int_t layer, Int_t module, Int_t iPoint)
829 // Utility function used by CreateAlignObjSDD
831 TGeoHMatrix gMod = *AliGeomManager::GetMatrix(uid); //global matrix of sensor
832 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID(uid);
833 // TString ladderPath = AliGeomManager::SymName(uid);
834 TString ladderPath(pne->GetTitle());
835 if(ladderPath.EndsWith("/")) ladderPath.Remove(TString::kTrailing,'/');
836 ladderPath.Remove(ladderPath.Last('/'));
837 // ladderPath.Remove(ladderPath.Last('/'));
838 gGeoManager->cd(ladderPath.Data());
839 TGeoHMatrix gLad = *gGeoManager->GetCurrentMatrix(); // global matrix of ladder
842 TGeoHMatrix rel = gMod; // to equal relative matrix ladder to sensor.
843 TGeoHMatrix invgLad = gLad.Inverse();
844 rel.MultiplyLeft(&invgLad);
845 TGeoRotation* rr = new TGeoRotation("rr",90,90,0,0,90,180);
846 TGeoCombiTrans* ct = 0;
847 if(layer==3) ct= new TGeoCombiTrans(25.,0.,0.,rr);
848 if(layer==4) ct= new TGeoCombiTrans(25.+7.5,0.,0.,rr);
850 rel.MultiplyLeft(ct);
852 if((layer==3)&&(module<3)) rel.LocalToMaster(fgkLocR[iPoint],fSDDidP[iPoint]);
853 if((layer==3)&&(module>2)) rel.LocalToMaster(fgkLocL[iPoint],fSDDidP[iPoint]);
854 if((layer==4)&&(module<4)) rel.LocalToMaster(fgkLocR[iPoint],fSDDidP[iPoint]);
855 if((layer==4)&&(module>3)) rel.LocalToMaster(fgkLocL[iPoint],fSDDidP[iPoint]);
857 for(Int_t i=0; i<3; i++) fSDDidP[iPoint][i]*=10;
858 fSDDidP[iPoint][2]-=0.5205;
860 // if(ladderPath.Data(),"/ALIC_1/ITSV_1/ITSsddLayer3_1/ITSsddLadd_3");
861 // if(ladderPath.Contains("ITSsddLayer3_1") && (ladderPath.Contains("ITSsddLadd_3")|| ladderPath.Contains("ITSsddLadd_10")))
863 ///ALIC_1/ITSV_1/ITSsddLayer4_1/ITSsddLadd_5
864 ///ALIC_1/ITSV_1/ITSsddLayer4_1/ITSsddLadd_16
866 // printf("%s : Module# %d Point# %d\n",ladderPath.Data(), module, iPoint);
868 if((layer==3)&&(module<3)) rel.LocalToMaster(fgkLocR[1],fSDDidP[1]);
869 if((layer==3)&&(module>2)) rel.LocalToMaster(fgkLocL[1],fSDDidP[1]);
870 if((layer==4)&&(module<4)) rel.LocalToMaster(fgkLocR[1],fSDDidP[1]);
871 if((layer==4)&&(module>3)) rel.LocalToMaster(fgkLocL[1],fSDDidP[1]);
872 for(Int_t i=0; i<3; i++) fSDDidP[1][i]*=10;
873 fSDDidP[1][2]-=0.5205;
875 // rel.LocalToMaster(fgkLocR[1],fSDDidP[1]);
876 // printf("ID {%f, %f, %f}\n", fSDDidP[iPoint][0],fSDDidP[iPoint][1],fSDDidP[iPoint][2]);
877 // printf("Me {%f, %f, %f}\n", fSDDmeP[iPoint][0],fSDDmeP[iPoint][1],fSDDmeP[iPoint][2]);
881 //______________________________________________________________________
882 void AliITSSurveyToAlign::ReadPointNameSDD(const char str[], Int_t &iLayer, Int_t &iLader, Int_t &iModul, Int_t &iPoint) const
885 // Utility function used by CreateAlignObjSDD
892 if(str[7]=='2') iLayer=3;
893 if(str[7]=='3') iLayer=4;
895 if(str[15]=='0') iLader=0;
896 if(str[15]=='1') iLader=1;
897 if(str[15]=='2') iLader=2;
898 if(str[15]=='3') iLader=3;
899 if(str[15]=='4') iLader=4;
900 if(str[15]=='5') iLader=5;
901 if(str[15]=='6') iLader=6;
902 if(str[15]=='7') iLader=7;
903 if(str[15]=='8') iLader=8;
904 if(str[15]=='9') iLader=9;
907 if(str[16]=='0') {iLader=10*iLader+0; ord=1;}
908 if(str[16]=='1') {iLader=10*iLader+1; ord=1;}
909 if(str[16]=='2') {iLader=10*iLader+2; ord=1;}
910 if(str[16]=='3') {iLader=10*iLader+3; ord=1;}
911 if(str[16]=='4') {iLader=10*iLader+4; ord=1;}
912 if(str[16]=='5') {iLader=10*iLader+5; ord=1;}
913 if(str[16]=='6') {iLader=10*iLader+6; ord=1;}
914 if(str[16]=='7') {iLader=10*iLader+7; ord=1;}
915 if(str[16]=='8') {iLader=10*iLader+8; ord=1;}
916 if(str[16]=='9') {iLader=10*iLader+9; ord=1;}
921 if(str[23+ord]=='0') module=0;
922 if(str[23+ord]=='1') module=1;
923 if(str[23+ord]=='2') module=2;
924 if(str[23+ord]=='3') module=3;
925 if(str[23+ord]=='4') module=4;
926 if(str[23+ord]=='5') module=5;
927 if(str[23+ord]=='6') module=6;
928 if(str[23+ord]=='7') module=7;
929 if(str[23+ord]=='8') module=8;
930 if(str[23+ord]=='9') module=9;
934 if(module==0) iModul= 5;
935 if(module==1) iModul= 4;
936 if(module==2) iModul= 3;
937 if(module==3) iModul= 2;
938 if(module==4) iModul= 1;
939 if(module==5) iModul= 0;
945 if(module==0) iModul= 7;
946 if(module==1) iModul= 6;
947 if(module==2) iModul= 5;
948 if(module==3) iModul= 4;
949 if(module==4) iModul= 3;
950 if(module==5) iModul= 2;
951 if(module==6) iModul= 1;
952 if(module==7) iModul= 0;
955 if(module<0) {printf("ERROR MOULE\n"); iModul=0;}
958 if(str[23+ord]=='0') iModul=0;
959 if(str[23+ord]=='1') iModul=1;
960 if(str[23+ord]=='2') iModul=2;
961 if(str[23+ord]=='3') iModul=3;
962 if(str[23+ord]=='4') iModul=4;
963 if(str[23+ord]=='5') iModul=5;
964 if(str[23+ord]=='6') iModul=6;
965 if(str[23+ord]=='7') iModul=7;
966 if(str[23+ord]=='8') iModul=8;
967 if(str[23+ord]=='9') iModul=9;
970 if((str[25+ord]=='R')&&(str[26+ord]=='D')) iPoint=0;
971 if((str[25+ord]=='R')&&(str[26+ord]=='C')) iPoint=1;
972 if((str[25+ord]=='R')&&(str[26+ord]=='U')) iPoint=2;
973 if((str[25+ord]=='L')&&(str[26+ord]=='U')) iPoint=3;
974 if((str[25+ord]=='L')&&(str[26+ord]=='C')) iPoint=4;
975 if((str[25+ord]=='L')&&(str[26+ord]=='D')) iPoint=5;
981 //______________________________________________________________________
982 void AliITSSurveyToAlign::ConvertToRSofModulesAndRotSDD(Int_t Layer, Int_t Module)
985 // Utility function used by CreateAlignObjSDD
996 Double_t x0=fSDDidP[1][0];
997 Double_t z0=fSDDidP[1][2];//-0.5205;
998 // Double_t z0=fSDDidP[1][2]-0.5;
999 // printf("x0= %f z0= %f \n",x0,z0);
1000 for(Int_t i=0; i<6; i++)
1002 // fSDDidP[i][2]-=0.5205;
1003 // fSDDidP[i][2]-=0.5;
1005 if(!fSDDisMe[i]) continue;
1007 // printf("Me1_0: %d: %f %f %f\n",i, fSDDmeP[i][0], fSDDmeP[i][1], fSDDmeP[i][2]);
1008 // printf("Id1_0: %d: %f %f %f\n",i, fSDDidP[i][0], fSDDidP[i][1], fSDDidP[i][2]);
1018 fSDDidP[i][2]=fSDDidP[i][0];
1025 ymMeE=fSDDmeP[i][4];
1026 zmMeE=fSDDmeP[i][5];
1028 fSDDmeP[i][2]=fSDDmeP[i][0];
1031 fSDDmeP[i][5]=fSDDmeP[i][3];
1032 fSDDmeP[i][3]=ymMeE;
1033 fSDDmeP[i][4]=zmMeE;
1036 if(((Layer==3)&&(Module>2))||((Layer==4)&&(Module>3)))
1038 fSDDidP[i][0]*=(-1);
1039 fSDDidP[i][2]*=(-1);
1040 fSDDmeP[i][0]*=(-1);
1041 fSDDmeP[i][2]*=(-1);
1043 // printf("Me1_1: %d: %f %f %f\n",i, fSDDmeP[i][0], fSDDmeP[i][1], fSDDmeP[i][2] );
1044 // printf("Id1_1: %d: %f %f %f\n",i, fSDDidP[i][0], fSDDidP[i][1], fSDDidP[i][2]);
1050 //______________________________________________________________________
1051 void AliITSSurveyToAlign::CalcShiftSDD(Double_t &x0,Double_t &y0,Double_t &z0) const
1053 // Calculates the 3 shifts for the present SDD module
1054 // and sets the three reference arguments
1056 Double_t xId, yId, zId;
1057 Double_t xMe, yMe, zMe, sX2, sY2, sZ2;
1058 Double_t aX=0., bX=0.;
1059 Double_t aY=0., bY=0.;
1060 Double_t aZ=0., bZ=0.;
1061 for(Int_t iP1=0; iP1<6; iP1++)
1063 if(!fSDDisMe[iP1]) continue;
1064 xId=fSDDidP[iP1][0];
1065 yId=fSDDidP[iP1][1];
1066 zId=fSDDidP[iP1][2];
1067 xMe=fSDDmeP[iP1][0];
1068 yMe=fSDDmeP[iP1][1];
1069 zMe=fSDDmeP[iP1][2];
1070 sX2 =fSDDmeP[iP1][3]*fSDDmeP[iP1][3];
1071 sY2 =fSDDmeP[iP1][4]*fSDDmeP[iP1][4];
1072 sZ2 =fSDDmeP[iP1][5]*fSDDmeP[iP1][5];
1074 bX+=((xMe-xId)/sX2);
1076 bY+=((yMe-yId)/sY2);
1078 bZ+=((zMe-zId)/sZ2);
1080 Double_t x1 = bX/aX;
1081 Double_t x2 = bY/aY;
1082 Double_t x3 = bZ/aZ;
1088 for(Int_t iP1=0; iP1<6; iP1++)
1090 if(!fSDDisMe[iP1]) continue;
1091 printf("%d Me: %6.3f %6.3f %6.3f\n",iP1, fSDDmeP[iP1][0], fSDDmeP[iP1][1], fSDDmeP[iP1][2]);
1092 printf("%d Id: %6.3f %6.3f %6.3f\n",iP1, fSDDidP[iP1][0], fSDDidP[iP1][1], fSDDidP[iP1][2]);
1100 //______________________________________________________________________
1101 void AliITSSurveyToAlign::CalcShiftRotSDD(Double_t &tet,Double_t &psi,Double_t &phi,Double_t &x0,Double_t &y0,Double_t &z0)
1103 // Calculates the 3 shifts and 3 euler angles for the present SDD module
1104 // and sets the six reference arguments
1109 for(Int_t ii=0; ii<6; ii++){
1110 for(Int_t jj=0; jj<6; jj++){
1116 for(Int_t ii=0; ii<6; ii++)
1119 Double_t xId, yId, zId;
1120 Double_t xMe, yMe, zMe, sX2, sY2, sZ2;
1124 for(Int_t iP1=0; iP1<6; iP1++)
1126 if(!fSDDisMe[iP1]) continue;
1128 //ideal x,y,z for fiducial mark iP1
1129 xId= fSDDidP[iP1][0];
1130 yId= fSDDidP[iP1][1];
1131 zId= fSDDidP[iP1][2];
1133 //measured x,y,z for fiducial mark iP1
1134 xMe= fSDDmeP[iP1][0];
1135 yMe= fSDDmeP[iP1][1];
1136 zMe= fSDDmeP[iP1][2];
1138 // printf("Me1: %d: %f %f %f\n",iP1, xMe, yMe, zMe );
1139 // printf("MeE: %d: %f %f %f\n",iP1, fSDDmeP[iP1][3], fSDDmeP[iP1][4], fSDDmeP[iP1][5] );
1140 // printf("Id1: %d: %f %f %f\n",iP1, xId, yId, zId );
1141 // printf("Res: %d: %f %f %f\n",iP1, xMe-xId, yMe-yId, zMe-zId );
1143 //squared precisions of measured x,y,z for fiducial mark iP1
1144 sX2 = fSDDmeP[iP1][3]* fSDDmeP[iP1][3];
1145 sY2 = fSDDmeP[iP1][4]* fSDDmeP[iP1][4];
1146 sZ2 = fSDDmeP[iP1][5]* fSDDmeP[iP1][5];
1148 a[0][0]+=(zId*zId/sX2+xId*xId/sZ2);
1149 // printf("%f\n",a[0][0]);
1150 a[0][1]-=(zId*yId/sX2);
1151 a[0][2]-=(xId*yId/sZ2);
1155 c[0]+=(xId*(zMe-zId)/sZ2-zId*(xMe-xId)/sX2);
1157 a[1][0]-=(yId*zId/sX2);
1158 a[1][1]+=(xId*xId/sY2+yId*yId/sX2);
1159 a[1][2]-=(xId*zId/sY2);
1163 c[1]+=(yId*(xMe-xId)/sX2-xId*(yMe-yId)/sY2);
1165 a[2][0]-=(yId*xId/sZ2);
1166 a[2][1]-=(xId*zId/sY2);
1167 a[2][2]+=(zId*zId/sY2+yId*yId/sZ2);
1171 c[2]+=(zId*(yMe-yId)/sY2-yId*(zMe-zId)/sZ2);
1179 c[3]+=((xMe-xId)/sX2);
1187 c[4]+=((yMe-yId)/sY2);
1195 c[5]+=((zMe-zId)/sZ2);
1198 ///////////////////////////////////////////////////////////////
1200 pC.SetMatrixArray(&(a[0][0]));
1208 for(Int_t raw=0; raw<6; raw++)
1210 for(Int_t raw=0; raw<6; raw++)
1212 for(Int_t raw=0; raw<6; raw++)
1214 for(Int_t raw=0; raw<6; raw++)
1216 for(Int_t raw=0; raw<6; raw++)
1218 for(Int_t raw=0; raw<6; raw++)
1221 // cout << "calculating determinants" << endl;
1222 Double_t det0=pC.Determinant();
1223 Double_t x1 = p1.Determinant()/det0;
1224 Double_t x2 = p2.Determinant()/det0;
1225 Double_t x3 = p3.Determinant()/det0;
1226 Double_t x4 = p4.Determinant()/det0;
1227 Double_t x5 = p5.Determinant()/det0;
1228 Double_t x6 = p6.Determinant()/det0;
1229 //cout << "calculating determinants done" << endl;
1230 if (TMath::Abs(x1) < 1.e-10) {
1231 AliInfo("p1 singular ");
1234 if (TMath::Abs(x2) < 1.e-10) {
1235 AliInfo("p2 singular ");
1238 if (TMath::Abs(x3) < 1.e-10) {
1239 AliInfo("p3 singular ");
1242 if (TMath::Abs(x4) < 1.e-10) {
1243 AliInfo("p4 singular ");
1246 if (TMath::Abs(x5) < 1.e-10) {
1247 AliInfo("p5 singular ");
1250 if (TMath::Abs(x6) < 1.e-10) {
1251 AliInfo("p6 singular ");
1263 // for(Int_t i=0; i<6; i++)
1264 // printf("%f %f %f %f %f %f\n",a[i][0], a[i][1], a[i][2], a[i][3], a[i][4], a[i][5]);
1275 // printf("fit: %f %f %f %f %f %f\n",x0, y0, z0, tet, psi, phi);