]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSSurveyToAlign.cxx
1) AliITSRecoParam -> flag for using the bad channels in the SSD CF
[u/mrichter/AliRoot.git] / ITS / AliITSSurveyToAlign.cxx
CommitLineData
02078bdf 1/**************************************************************************
2 * Copyright(c) 2008-2010, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
18//////////////////////////////////////////////////////////////////////////
19// Class to convert survey tables in alignment objects
20// for SSD and SDD
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//////////////////////////////////////////////////////////////////////////
25
26#include "Riostream.h"
02078bdf 27#include "TClonesArray.h"
28#include "TGeoManager.h"
02078bdf 29#include "TGeoPhysicalNode.h"
30#include "TMatrixD.h"
31#include "TMath.h"
32
33#include "AliITSSurveyToAlign.h"
02078bdf 34#include "AliSurveyPoint.h"
35#include "AliAlignObjParams.h"
36#include "AliGeomManager.h"
37
38#include "AliLog.h"
39
40#include "AliCDBManager.h"
02078bdf 41
42#include "AliITSgeomTGeo.h"
43
44ClassImp(AliITSSurveyToAlign)
45
46const Double_t AliITSSurveyToAlign::fgkLocR[6][3]={{ 3.24,0.21905,-2.4},
47 { 3.58,0.21905, 0. },
48 { 3.24,0.21905,+2.4},
49 {-3.24,0.21905,+2.4},
50 {-3.58,0.21905, 0. },
51 {-3.24,0.21905,-2.4}};
52
53const Double_t AliITSSurveyToAlign::fgkLocL[6][3]={{-3.24,0.21905, 2.4},
54 {-3.58,0.21905, 0. },
55 {-3.24,0.21905,-2.4},
56 { 3.24,0.21905,-2.4},
57 { 3.58,0.21905, 0. },
58 { 3.24,0.21905, 2.4}};
59
98380f3e 60const Double_t kRadToDeg = 180./TMath::Pi();
02078bdf 61
62//________________________________________________________________________
63AliITSSurveyToAlign::AliITSSurveyToAlign(Int_t run, Int_t repSDD, Int_t repVerSDD, Int_t repModSSD, Int_t repModVerSSD, Int_t repLaddSSD, Int_t repLaddVerSSD) :
02078bdf 64 AliSurveyToAlignObjs(),
65 fRun(run),
66 fSDDrepNumber(repSDD),
67 fSDDrepVersion(repVerSDD),
68 fSSDModuleRepNumber(repModSSD),
69 fSSDModuleRepVersion(repModVerSSD),
70 fSSDLadderRepNumber(repLaddSSD),
71 fSSDLadderRepVersion(repLaddVerSSD)
72 {
73 //
74 // default constructor
75 // Arguments are report numbers for survey data.
76 // The defaults point to reports from detector construction
77 //
78}
79
80//_________________________________________________________________________
81AliITSSurveyToAlign::AliITSSurveyToAlign(const AliITSSurveyToAlign &align) :
02078bdf 82 AliSurveyToAlignObjs(align),
83 fRun(align.fRun),
84 fSDDrepNumber(align.fSDDrepNumber),
85 fSDDrepVersion(align.fSDDrepVersion),
86 fSSDModuleRepNumber(align.fSSDModuleRepNumber),
87 fSSDModuleRepVersion(align.fSSDModuleRepVersion),
88 fSSDLadderRepNumber(align.fSSDLadderRepNumber),
89 fSSDLadderRepVersion(align.fSSDLadderRepVersion)
90{
91 //
92 // copy constructor
93 //
94}
95
96//__________________________________________________________________________
3f94bb0f 97AliITSSurveyToAlign & AliITSSurveyToAlign::operator =(const AliITSSurveyToAlign& /* align */) {
02078bdf 98 //
99 // assignment operator - dummy
100 //
101
102 return (*this);
103}
104
105//__________________________________________________________________________
106AliITSSurveyToAlign::~AliITSSurveyToAlign() {
107 //
108 // destructor
109 //
110}
111
112//______________________________________________________________________
113void AliITSSurveyToAlign::Run() {
114 //
115 // Runs the full chain
2afbf330 116 // User should call StoreAlignObjToFile or StoreAlignObjToCDB afterwards to
117 // store output (not included here to leave the choice between the two)
02078bdf 118 //
119
120 // Load ideal geometry from the OCDB
121 AliCDBManager *cdb = AliCDBManager::Instance();
122 cdb->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
123 cdb->SetRun(fRun);
124 AliGeomManager::LoadGeometry();
2afbf330 125
126 if(!CreateAlignObjs()) AliError("Construction of alignment objects from survey failed!");
127}
128
129//______________________________________________________________________
130Bool_t AliITSSurveyToAlign::CreateAlignObjs() {
131 // Fill the array of alignment objects with alignment objects
98380f3e 132 // from survey for all three subdetectors
2afbf330 133 //
134
135 //for SPD
136 CreateAlignObjDummySPD();
137
138 // for SDD
139 if(!LoadSurveyFromAlienFile("ITS", fSDDrepNumber, fSDDrepVersion)){
140 AliError("Loading of alignment objects from survey for SDD failed!");
141 return kFALSE;
142 }
02078bdf 143 CreateAlignObjSDD();
2afbf330 144
145 // for SSD ladders
146 if(!LoadSurveyFromAlienFile("ITS", fSSDLadderRepNumber, fSSDLadderRepVersion)){
147 AliError("Loading of alignment objects from survey for SSD ladders failed!");
148 return kFALSE;
149 }
02078bdf 150 CreateAlignObjSSDLadders();
2afbf330 151
152 // for SSD modules
153 if(!ApplyAlignObjSSDLadders()) return kFALSE; // needed to build correctly the objects for SSD modules
154 if(!LoadSurveyFromAlienFile("ITS", fSSDModuleRepNumber, fSSDModuleRepVersion)){
155 AliError("Loading of alignment objects from survey for SSD modules failed!");
156 return kFALSE;
157 }
158 CreateAlignObjSSDModules();
159
160 return kTRUE;
02078bdf 161}
162
2afbf330 163//______________________________________________________________________
164void AliITSSurveyToAlign::CreateAlignObjDummySPD(){
02078bdf 165 //
166 // Create alignObjs for SPD
167 // For the moment, uses 0,0,0,0,0,0
168 //
169 for(Int_t imod = 0; imod < 240; imod++) {
170 Int_t ilayer = (imod < 80) ? AliGeomManager::kSPD1 : AliGeomManager::kSPD2;
171 Int_t imodule = (imod < 80) ? imod : imod - 80;
172
173 Int_t uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
174 const Char_t *symname = AliGeomManager::SymName(uid);
175
176 new((*fAlignObjArray)[imod]) AliAlignObjParams(symname, uid, 0., 0., 0., 0., 0., 0., kTRUE);
177 }//module loop
178
179}
180
2afbf330 181//______________________________________________________________________
02078bdf 182void AliITSSurveyToAlign::CreateAlignObjSDD(){
183 //
184 // Create alignment objects for SDD
185 // Called by Run()
186 //
187 Int_t uid = 0;
188 const char* symname = 0;
189 AliSurveyPoint* pt = 0;
190
191 Int_t iModuleIndex=240;
192 Int_t iModule0=0;
193 Int_t iLadder0=0;
194 Int_t iLayer0=3;
195 Int_t nModules=0;
196
197 if (fSurveyPoints == 0 || fSurveyPoints->GetEntries() == 0) {
198 AliWarning("SDD survey data are not available, using zero values");
199 CreateAlignObjDummySDD();
200 return;
201 }
202
203 for(Int_t imod = 1; imod < fSurveyPoints->GetEntries(); imod++) {
204 pt = (AliSurveyPoint*) fSurveyPoints->At(imod);
205 if(!pt) continue;
206
207 Int_t iLayer, iLadder, iModule, iPoint;
208 ReadPointNameSDD(pt->GetName(),iLayer, iLadder, iModule, iPoint);
209
210 if(iModule==iModule0)
211 {
212 fSDDmeP[iPoint][0]=pt->GetX();
213 fSDDmeP[iPoint][1]=pt->GetY();
214 fSDDmeP[iPoint][2]=pt->GetZ();
215 fSDDmeP[iPoint][3]=pt->GetPrecisionX();
216 fSDDmeP[iPoint][4]=pt->GetPrecisionY();
217 fSDDmeP[iPoint][5]=pt->GetPrecisionZ();
218 fSDDisMe[iPoint]=kTRUE;
219
220 if(iLayer==3) uid = AliGeomManager::LayerToVolUID(iLayer0,iModuleIndex-240);
221 if(iLayer==4) uid = AliGeomManager::LayerToVolUID(iLayer0,iModuleIndex-324);
222 symname = AliGeomManager::SymName(uid);
223 GetIdPosSDD(uid,iLayer0, iModule0, iPoint);
224 nModules++;
225 }
226 // cout << "Points red module " << imod << endl;
227 if((iModule!=iModule0)||(imod==(fSurveyPoints->GetEntries()-1)))
228 {
229 ConvertToRSofModulesAndRotSDD(iLayer0, iModule0);
230
231 Double_t tet = 0.;
232 Double_t psi =0.;
233 Double_t phi = 0.;
234 Double_t x0 = 0.;
235 Double_t y0 =0.;
236 Double_t z0 = 0.;
237
238 if(nModules==2) CalcShiftSDD(x0,y0,z0);
239 if(nModules>2) CalcShiftRotSDD(tet, psi, phi, x0, y0, z0);
98380f3e 240 tet*=kRadToDeg;
241 psi*=kRadToDeg;
242 phi*=kRadToDeg;
02078bdf 243
244// printf("%s %d %f %f %f %f %f %f\n",symname, uid, x0/10., y0/10., z0/10., psi, tet, phi);
245// cout << "Allocate alignobjparams " << imod << endl;
246 new((*fAlignObjArray)[iModuleIndex]) AliAlignObjParams(symname, uid, x0/10., y0/10., z0/10., psi, tet, phi, kFALSE);
247
248 iModule0=iModule;
249 iLayer0=iLayer;
250 iLadder0=iLadder;
251 nModules=0;
252 iModuleIndex = AliITSgeomTGeo::GetModuleIndex(iLayer,iLadder+1,iModule+1);
253 for(Int_t i=0; i<6;i++) fSDDisMe[i]=kFALSE;
254 if(imod!=(fSurveyPoints->GetEntries()-1)) imod--;
255 }
256 }//module loop
257}
258
2afbf330 259//______________________________________________________________________
02078bdf 260void AliITSSurveyToAlign::CreateAlignObjDummySDD(){
261 //
262 // Create empty alignment objects
263 // Used when fSurveySDD == 0
264 //
265 for(Int_t imod = 0; imod < 260; imod++) {
266
267 Int_t ilayer = (imod < 84) ? AliGeomManager::kSDD1 : AliGeomManager::kSDD2;
268 Int_t imodule = (imod < 84) ? imod : imod - 84;
269
270 Int_t uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
271 const Char_t *symname = AliGeomManager::SymName(uid);
272
273 new((*fAlignObjArray)[imod+240]) AliAlignObjParams(symname, uid, 0., 0., 0., 0., 0., 0., kTRUE);
274 }//module loop
275}
276
2afbf330 277//______________________________________________________________________
02078bdf 278void AliITSSurveyToAlign::CreateAlignObjSSDModules(){
279 //
2afbf330 280 // Create alignment objects for SSD modules
281 // Objects for SSD ladders must be applied to geometry first
02078bdf 282 //
283 Double_t sx, sz;
284 const Float_t kMu2Cm = 1e-4;
285 const Float_t kSensLength = 7.464;
286 const Int_t kSSDMODULES = 1698;
287
288 if (fSurveyPoints == 0 || fSurveyPoints->GetEntries() == 0) {
289 AliWarning("SSD module survey data not available; using dummy values");
290 CreateAlignObjDummySSDModules();
291 return;
292 }
293
294 // First do module-by-module
295
296 for(Int_t imod = 500; imod < kSSDMODULES + 500; imod++) {
297 Int_t iLayer, iLadder, iLaddMod;
298 AliITSgeomTGeo::GetModuleId(imod,iLayer,iLadder,iLaddMod); // returns 1-based numbers
299
300 TString pname="ITS/SSD";
301 pname += iLayer-1;
302 pname += "/Ladder";
303 pname += iLadder-1;
304 pname += "/Sensor";
305 pname += iLaddMod-1;
306 AliSurveyPoint *pt1 = (AliSurveyPoint*) fSurveyPoints->FindObject(pname+"/Point0");
307 AliSurveyPoint *pt2 = (AliSurveyPoint*) fSurveyPoints->FindObject(pname+"/Point1");
308 if(!pt1 || !pt2) {
309 AliWarning(Form("No Survey points for iladd %d imod %d",iLadder,iLaddMod));
310 continue;
311 }
312
313 sx = 0.5*(pt1->GetX() + pt2->GetX()) * kMu2Cm;
314 sz = 0.5*(pt1->GetZ() + pt2->GetZ()) * kMu2Cm;
315
316 // Minus sign to change local coordinate convention
317 Float_t theta = -(pt2->GetZ() - pt1->GetZ())*kMu2Cm/kSensLength;
318
98380f3e 319 theta *= kRadToDeg;
02078bdf 320 Int_t iLayMod = imod - 500;
321 if (iLayer == 6)
322 iLayMod -= 748;
323 Int_t uid = AliGeomManager::LayerToVolUID(iLayer,iLayMod);
324
325 const Char_t *symname = AliGeomManager::SymName(uid);
326 if (pname.CompareTo(symname) != 0)
327 AliWarning(Form("Mapping mismatch survey point %s volume name %s",pname.Data(),symname));
328 /*
329 if (imod >= 676 && imod <= 697) {
330 cout << "ilayer " << iLayer << " imod " << imod
331 << " uid " << uid << " name " << symname
332 << " survey shift " << sx << " " << 0 << " " << sz << endl
333 << " theta " << theta << endl;
334 }
335 */
336 new((*fAlignObjArray)[imod]) AliAlignObjParams(symname, uid, sx, 0, sz, 0., theta, 0., kFALSE);
337 } //module loop
338}
339
2afbf330 340//______________________________________________________________________
341Bool_t AliITSSurveyToAlign::ApplyAlignObjSSDLadders(){
342 //
343 // Apply alignment objects for SSD ladders to geometry, needed to correctly
344 // build alignment objects for SSD modules
345 //
6e732991 346 Int_t applied=0;
347
2afbf330 348 for(Int_t jj=0; jj<fAlignObjArray->GetEntriesFast(); jj++)
349 {
350 AliAlignObjParams* ap = dynamic_cast<AliAlignObjParams*> (fAlignObjArray->UncheckedAt(jj));
351 if(ap)
352 {
353 TString sName(ap->GetSymName());
354 if(sName.Contains("SSD") && sName.Contains("Ladder"))
6e732991 355 {
356 if(!ap->ApplyToGeometry()) return kFALSE;
357 applied++;
358 }
2afbf330 359 }
360 }
6e732991 361 AliInfo(Form(" %d alignment objects for SSD ladders applied to geometry.",applied));
2afbf330 362
6e732991 363 return kTRUE;
2afbf330 364}
365
366//______________________________________________________________________
02078bdf 367void AliITSSurveyToAlign::CreateAlignObjSSDLadders(){
368 //
2afbf330 369 // Alignment objects from survey for SSD ladders (Torino data)
02078bdf 370 //
371 const Float_t kLaddLen5 = 90.27; // Layer 5: distance between mouting points
372 const Float_t kLaddLen6 = 102.0; // Layer 6: distance between mouting points
98380f3e 373 const Float_t zLag = 2.927; // Distance between V mounting point and Zloc = 0
02078bdf 374 // = half ladder length - nom z-position of ladder from gGeoManager
375 const Float_t kMu2Cm = 1e-4;
376
377 TString ssdName = "ITS/SSD";
378
98380f3e 379 TObjArray *ladderPoints = fSurveyPoints;
380 if (ladderPoints == 0 || ladderPoints->GetEntries() == 0) {
02078bdf 381 AliWarning("No SSD Ladder alignment points found. Skipping");
382 return;
383 }
98380f3e 384 if (ladderPoints->GetEntries()!= 2*(34+38)) {
385 AliWarning(Form("Unexpected number of survey points %d, should be 144",ladderPoints->GetEntries()));
02078bdf 386 }
387 Int_t iLadd = 0;
388 for (Int_t ilayer = 4; ilayer <= 5; ilayer ++) {
389 Int_t nLadder = 34; // layer 5
390 if (ilayer == 5)
391 nLadder = 38; // layer 6
392
393 for (Int_t iLadder = 0; iLadder < nLadder; iLadder++) {
394 TString ladName = ssdName;
395 ladName += ilayer;
396 ladName += "/Ladder";
397 ladName += iLadder;
398
98380f3e 399 AliSurveyPoint *vPoint = (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/V");
400 AliSurveyPoint *qPoint = (AliSurveyPoint*) ladderPoints->FindObject(ladName+"/Q");
401 if (vPoint == 0) {
02078bdf 402 AliWarning(Form("Cannot find V side point for ladder %s",ladName.Data()));
403 continue;
404 }
98380f3e 405 if (qPoint == 0) {
02078bdf 406 AliWarning(Form("Cannot find Q side point for ladder %s",ladName.Data()));
407 continue;
408 }
409
98380f3e 410 TString tmpStr;
411 tmpStr.Insert(0,vPoint->GetName(),3);
412 Int_t ladder = tmpStr.Atoi();
413 tmpStr="";
414 tmpStr.Insert(0,qPoint->GetName(),3);
415 if (tmpStr.Atoi() != ladder)
416 AliError(Form("Survey data file error. Expect pairs of V,Q points. Got ladders %d %d",ladder,tmpStr.Atoi()));
02078bdf 417
418 // Note: file gives meas-nom in local offline coordinates,
419 // ie. local z = - global z and local x = - global x (for ladder 508, i.e. top ladder)
98380f3e 420 Double_t dxLoc = vPoint->GetX() * kMu2Cm;
421 Double_t dyLoc = vPoint->GetY() * kMu2Cm;
422 Double_t dzLoc = vPoint->GetZ() * kMu2Cm;
02078bdf 423
424 // rot around z-axis
425 Double_t phi = 0; // Not measured
426 // rot around y-axis
427 Double_t theta = 0;
428 Double_t psi = 0;
429
430 // Note: local psi = -global psi, psi = atan(-(y(z1) - y(z0)) / (z1-z0))
431 // local theta = global theta = atan(dx/dz)
432 // V side is A side is large global z
433 // Q side is C side is large local z
434
435 if (ladder >= 600) {
98380f3e 436 theta = TMath::ATan((qPoint->GetX() - vPoint->GetX())*kMu2Cm/kLaddLen6);
437 psi = TMath::ATan((vPoint->GetY() - qPoint->GetY())*kMu2Cm/kLaddLen6);
02078bdf 438 }
439 else {
98380f3e 440 theta = TMath::ATan((qPoint->GetX() - vPoint->GetX())*kMu2Cm/kLaddLen5);
441 psi = TMath::ATan((vPoint->GetY() - qPoint->GetY())*kMu2Cm/kLaddLen5);
02078bdf 442 }
443
444 // Move along ladder to local Z = 0 point
98380f3e 445 dxLoc += zLag*theta;
446 dyLoc -= zLag*psi;
02078bdf 447
448 // Convert to degrees
98380f3e 449 theta *= kRadToDeg;
450 psi *= kRadToDeg;
451 AliDebug(1,Form("ladname %f %f %f %f %f %f ",dxLoc,dyLoc,dzLoc,psi,theta,phi));
02078bdf 452
98380f3e 453 new((*fAlignObjArray)[500+1698+iLadd]) AliAlignObjParams(ladName,0,dxLoc,dyLoc,dzLoc,psi,theta,phi,kFALSE);
02078bdf 454
455 iLadd++;
456 } // Ladder loop
457 } // Layer loop
458}
459
2afbf330 460//______________________________________________________________________
02078bdf 461void AliITSSurveyToAlign::CreateAlignObjDummySSDModules(){
462 //
463 // Create empty alignment objects
464 // Used when fSurveySSD == 0
465 //
466 for(Int_t imod = 0; imod < 1698; imod++) {
467 Int_t ilayer = (imod < 748) ? AliGeomManager::kSSD1 : AliGeomManager::kSSD2;
468 Int_t imodule = (imod < 748) ? imod : imod - 748;
469
470 Int_t uid = AliGeomManager::LayerToVolUID(ilayer,imodule);
471 const Char_t *symname = AliGeomManager::SymName(uid);
472
473 new((*fAlignObjArray)[500+imod]) AliAlignObjParams(symname, uid, 0., 0., 0., 0., 0., 0., kTRUE);
474 }//module loop
475}
476
477
2afbf330 478//______________________________________________________________________
02078bdf 479void AliITSSurveyToAlign::GetIdPosSDD(Int_t uid, Int_t layer, Int_t module, Int_t iPoint)
480{
481 //
482 // Utility function used by CreateAlignObjSDD
483 //
484 TGeoHMatrix gMod = *AliGeomManager::GetMatrix(uid); //global matrix of sensor
485 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID(uid);
486 // TString ladderPath = AliGeomManager::SymName(uid);
487 TString ladderPath(pne->GetTitle());
488 if(ladderPath.EndsWith("/")) ladderPath.Remove(TString::kTrailing,'/');
489 ladderPath.Remove(ladderPath.Last('/'));
490 ladderPath.Remove(ladderPath.Last('/'));
491 gGeoManager->cd(ladderPath.Data());
492 TGeoHMatrix gLad = *gGeoManager->GetCurrentMatrix(); // global matrix of ladder
493 TGeoHMatrix rel = gMod; // to equal relative matrix ladder to sensor.
494 TGeoHMatrix invgLad = gLad.Inverse();
495 rel.MultiplyLeft(&invgLad);
496 TGeoRotation* rr = new TGeoRotation("rr",90,90,0,0,90,180);
497 TGeoCombiTrans* ct = 0;
498 if(layer==3) ct= new TGeoCombiTrans(25.,0.,0.,rr);
499 if(layer==4) ct= new TGeoCombiTrans(25.+7.5,0.,0.,rr);
500
501 rel.MultiplyLeft(ct);
502
503 if((layer==3)&&(module<3)) rel.LocalToMaster(fgkLocR[iPoint],fSDDidP[iPoint]);
504 if((layer==3)&&(module>2)) rel.LocalToMaster(fgkLocL[iPoint],fSDDidP[iPoint]);
505 if((layer==4)&&(module<4)) rel.LocalToMaster(fgkLocR[iPoint],fSDDidP[iPoint]);
506 if((layer==4)&&(module>3)) rel.LocalToMaster(fgkLocL[iPoint],fSDDidP[iPoint]);
507
508 for(Int_t i=0; i<3; i++) fSDDidP[iPoint][i]*=10;
509
510}
511
2afbf330 512//______________________________________________________________________
98380f3e 513void AliITSSurveyToAlign::ReadPointNameSDD(const char str[], Int_t &iLayer, Int_t &iLader, Int_t &iModul, Int_t &iPoint) const
02078bdf 514{
515 //
516 // Utility function used by CreateAlignObjSDD
517 //
518 iLayer=-1;
519 iLader=-1;
520 iModul=-1;
521 iPoint=-1;
522
523 if(str[7]=='2') iLayer=3;
524 if(str[7]=='3') iLayer=4;
525
526 if(str[15]=='0') iLader=0;
527 if(str[15]=='1') iLader=1;
528 if(str[15]=='2') iLader=2;
529 if(str[15]=='3') iLader=3;
530 if(str[15]=='4') iLader=4;
531 if(str[15]=='5') iLader=5;
532 if(str[15]=='6') iLader=6;
533 if(str[15]=='7') iLader=7;
534 if(str[15]=='8') iLader=8;
535 if(str[15]=='9') iLader=9;
536
537 Int_t ord=0;
538 if(str[16]=='0') {iLader=10*iLader+0; ord=1;}
539 if(str[16]=='1') {iLader=10*iLader+1; ord=1;}
540 if(str[16]=='2') {iLader=10*iLader+2; ord=1;}
541 if(str[16]=='3') {iLader=10*iLader+3; ord=1;}
542 if(str[16]=='4') {iLader=10*iLader+4; ord=1;}
543 if(str[16]=='5') {iLader=10*iLader+5; ord=1;}
544 if(str[16]=='6') {iLader=10*iLader+6; ord=1;}
545 if(str[16]=='7') {iLader=10*iLader+7; ord=1;}
546 if(str[16]=='8') {iLader=10*iLader+8; ord=1;}
547 if(str[16]=='9') {iLader=10*iLader+9; ord=1;}
548
549 if(str[23+ord]=='0') iModul=0;
550 if(str[23+ord]=='1') iModul=1;
551 if(str[23+ord]=='2') iModul=2;
552 if(str[23+ord]=='3') iModul=3;
553 if(str[23+ord]=='4') iModul=4;
554 if(str[23+ord]=='5') iModul=5;
555 if(str[23+ord]=='6') iModul=6;
556 if(str[23+ord]=='7') iModul=7;
557 if(str[23+ord]=='8') iModul=8;
558 if(str[23+ord]=='9') iModul=9;
559
560 if((str[25+ord]=='R')&&(str[26+ord]=='D')) iPoint=0;
561 if((str[25+ord]=='R')&&(str[26+ord]=='C')) iPoint=1;
562 if((str[25+ord]=='R')&&(str[26+ord]=='U')) iPoint=2;
563 if((str[25+ord]=='L')&&(str[26+ord]=='U')) iPoint=3;
564 if((str[25+ord]=='L')&&(str[26+ord]=='C')) iPoint=4;
565 if((str[25+ord]=='L')&&(str[26+ord]=='D')) iPoint=5;
566 return;
567}
568
569
2afbf330 570//______________________________________________________________________
02078bdf 571void AliITSSurveyToAlign::ConvertToRSofModulesAndRotSDD(Int_t Layer, Int_t Module)
572{
573 //
574 // Utility function used by CreateAlignObjSDD
575 //
576
98380f3e 577 Double_t ymId;
578 Double_t zmId;
02078bdf 579
98380f3e 580 Double_t ymMe;
581 Double_t zmMe;
582 Double_t ymMeE;
583 Double_t zmMeE;
02078bdf 584
585 Double_t x0=fSDDidP[1][0];
586 Double_t z0=fSDDidP[1][2]-0.52;
587 for(Int_t i=0; i<6; i++)
588 {
589 fSDDidP[i][2]-=0.52;
590
591 if(!fSDDisMe[i]) continue;
592
593 fSDDidP[i][0]-=x0;
594 fSDDidP[i][2]-=z0;
595 fSDDmeP[i][0]-=x0;
596 fSDDmeP[i][2]-=z0;
597
98380f3e 598 ymId=fSDDidP[i][1];
599 zmId=fSDDidP[i][2];
02078bdf 600
601 fSDDidP[i][2]=fSDDidP[i][0];
98380f3e 602 fSDDidP[i][0]=ymId;
603 fSDDidP[i][1]=zmId;
02078bdf 604
98380f3e 605 ymMe=fSDDmeP[i][1];
606 zmMe=fSDDmeP[i][2];
02078bdf 607
98380f3e 608 ymMeE=fSDDmeP[i][4];
609 zmMeE=fSDDmeP[i][5];
02078bdf 610
611 fSDDmeP[i][2]=fSDDmeP[i][0];
98380f3e 612 fSDDmeP[i][0]=ymMe;
613 fSDDmeP[i][1]=zmMe;
02078bdf 614 fSDDmeP[i][5]=fSDDmeP[i][3];
98380f3e 615 fSDDmeP[i][3]=ymMeE;
616 fSDDmeP[i][4]=zmMeE;
02078bdf 617
618
619 if(((Layer==3)&&(Module>2))||((Layer==4)&&(Module>3)))
620 {
621 fSDDidP[i][0]*=(-1);
622 fSDDidP[i][2]*=(-1);
623 fSDDmeP[i][0]*=(-1);
624 fSDDmeP[i][2]*=(-1);
625 }
626 }
627}
628
629
2afbf330 630//______________________________________________________________________
98380f3e 631void AliITSSurveyToAlign::CalcShiftSDD(Double_t &x0,Double_t &y0,Double_t &z0) const
02078bdf 632{
98380f3e 633 // Calculates the 3 shifts for the present SDD module
634 // and sets the three reference arguments
635 //
636 Double_t xId, yId, zId;
637 Double_t xMe, yMe, zMe, sX2, sY2, sZ2;
02078bdf 638 Double_t aX=0., bX=0.;
639 Double_t aY=0., bY=0.;
640 Double_t aZ=0., bZ=0.;
641 for(Int_t iP1=0; iP1<6; iP1++)
642 {
643 if(!fSDDisMe[iP1]) continue;
98380f3e 644 xId=fSDDidP[iP1][0];
645 yId=fSDDidP[iP1][1];
646 zId=fSDDidP[iP1][2];
647 xMe=fSDDmeP[iP1][0];
648 yMe=fSDDmeP[iP1][1];
649 zMe=fSDDmeP[iP1][2];
02078bdf 650 sX2 =fSDDmeP[iP1][3]*fSDDmeP[iP1][3];
651 sY2 =fSDDmeP[iP1][4]*fSDDmeP[iP1][4];
652 sZ2 =fSDDmeP[iP1][5]*fSDDmeP[iP1][5];
653 aX+=(1./sX2);
98380f3e 654 bX+=((xMe-xId)/sX2);
02078bdf 655 aY+=(1./sY2);
98380f3e 656 bY+=((yMe-yId)/sY2);
02078bdf 657 aZ+=(1./sZ2);
98380f3e 658 bZ+=((zMe-zId)/sZ2);
02078bdf 659 }
660 Double_t x1 = bX/aX;
661 Double_t x2 = bY/aY;
662 Double_t x3 = bZ/aZ;
663 x0=x1;
664 y0=x2;
665 z0=x3;
666 return;
667}
668
669
2afbf330 670//______________________________________________________________________
02078bdf 671void AliITSSurveyToAlign::CalcShiftRotSDD(Double_t &tet,Double_t &psi,Double_t &phi,Double_t &x0,Double_t &y0,Double_t &z0)
672{
98380f3e 673 // Calculates the 3 shifts and 3 euler angles for the present SDD module
674 // and sets the six reference arguments
675 //
02078bdf 676 TMatrixD pC(6,6);
677
98380f3e 678 Double_t a[6][6];
679 for(Int_t ii=0; ii<6; ii++){
680 for(Int_t jj=0; jj<6; jj++){
681 a[ii][jj]=0.;
682 }
683 }
684
685 Double_t c[6];
686 for(Int_t ii=0; ii<6; ii++)
687 c[ii]=0.;
688
689 Double_t xId, yId, zId;
690 Double_t xMe, yMe, zMe, sX2, sY2, sZ2;
02078bdf 691
692 for(Int_t iP1=0; iP1<=6; iP1++)
693 {
694 if(!fSDDisMe[iP1]) continue;
695
98380f3e 696 //ideal x,y,z for fiducial mark iP1
697 xId= fSDDidP[iP1][0];
698 yId= fSDDidP[iP1][1];
699 zId= fSDDidP[iP1][2];
02078bdf 700
98380f3e 701 //measured x,y,z for fiducial mark iP1
702 xMe= fSDDmeP[iP1][0];
703 yMe= fSDDmeP[iP1][1];
704 zMe= fSDDmeP[iP1][2];
02078bdf 705
98380f3e 706 //squared precisions of measured x,y,z for fiducial mark iP1
02078bdf 707 sX2 = fSDDmeP[iP1][3]* fSDDmeP[iP1][3];
708 sY2 = fSDDmeP[iP1][4]* fSDDmeP[iP1][4];
709 sZ2 = fSDDmeP[iP1][5]* fSDDmeP[iP1][5];
710
98380f3e 711 a[0][0]+=(zId*zId/sX2+xId*xId/sZ2);
712 a[0][1]-=(zId*yId/sX2);
713 a[0][2]-=(xId*yId/sZ2);
714 a[0][3]-=(zId/sX2);
715 a[0][4] =0.;
716 a[0][5]+=(xId/sZ2);
717 c[0]+=(xId*(zMe-zId)/sZ2-zId*(xMe-xId)/sX2);
718
719 a[1][0]-=(yId*zId/sX2);
720 a[1][1]+=(xId*xId/sY2+yId*yId/sX2);
721 a[1][2]-=(xId*zId/sY2);
722 a[1][3]+=(yId/sX2);
723 a[1][4]-=(xId/sY2);
724 a[1][5] =0.;
725 c[1]+=(yId*(xMe-xId)/sX2-xId*(yMe-yId)/sY2);
726
727 a[2][0]-=(yId*xId/sZ2);
728 a[2][1]-=(xId*zId/sY2);
729 a[2][2]+=(zId*zId/sY2+yId*yId/sZ2);
730 a[2][3] =0.;
731 a[2][4]+=(zId/sY2);
732 a[2][5]-=(yId/sZ2);
733 c[2]+=(zId*(yMe-yId)/sY2-yId*(zMe-zId)/sZ2);
734
735 a[3][0]-=(zId/sX2);
736 a[3][1]+=(yId/sX2);
737 a[3][2] =0.;
738 a[3][3]+=(1./sX2);
739 a[3][4] =0.;
740 a[3][5] =0.;
741 c[3]+=((xMe-xId)/sX2);
742
743 a[4][0] =0.;
744 a[4][1]-=(xId/sY2);
745 a[4][2]+=(zId/sY2);
746 a[4][3] =0.;
747 a[4][4]+=(1./sY2);
748 a[4][5] =0.;
749 c[4]+=((yMe-yId)/sY2);
750
751 a[5][0]+=(xId/sZ2);
752 a[5][1] =0.;
753 a[5][2]-=(yId/sZ2);
754 a[5][3] =0.;
755 a[5][4] =0.;
756 a[5][5]+=(1./sZ2);
757 c[5]+=((zMe-zId)/sZ2);
02078bdf 758 }
759
760 ///////////////////////////////////////////////////////////////
761
98380f3e 762 pC.SetMatrixArray(&(a[0][0]));
763 TMatrixD p1(pC);
764 TMatrixD p2(pC);
765 TMatrixD p3(pC);
766 TMatrixD p4(pC);
767 TMatrixD p5(pC);
768 TMatrixD p6(pC);
769
770 for(Int_t raw=0; raw<6; raw++)
771 p1[raw][0]=c[raw];
772 for(Int_t raw=0; raw<6; raw++)
773 p2[raw][1]=c[raw];
774 for(Int_t raw=0; raw<6; raw++)
775 p3[raw][2]=c[raw];
776 for(Int_t raw=0; raw<6; raw++)
777 p4[raw][3]=c[raw];
778 for(Int_t raw=0; raw<6; raw++)
779 p5[raw][4]=c[raw];
780 for(Int_t raw=0; raw<6; raw++)
781 p6[raw][5]=c[raw];
02078bdf 782
783 // cout << "calculating determinants" << endl;
784 Double_t det0=pC.Determinant();
785 Double_t x1 = p1.Determinant()/det0;
786 Double_t x2 = p2.Determinant()/det0;
787 Double_t x3 = p3.Determinant()/det0;
788 Double_t x4 = p4.Determinant()/det0;
789 Double_t x5 = p5.Determinant()/det0;
790 Double_t x6 = p6.Determinant()/det0;
791 //cout << "calculating determinants done" << endl;
792 if (x1 == 0) {
793 AliInfo("p1 singular ");
794 p1.Print();
795 }
796 if (x2 == 0) {
797 AliInfo("p2 singular ");
798 p2.Print();
799 }
800 if (x3 == 0) {
801 AliInfo("p3 singular ");
802 p3.Print();
803 }
804 if (x4 == 0) {
805 AliInfo("p4 singular ");
806 p4.Print();
807 }
808 if (x5 == 0) {
809 AliInfo("p5 singular ");
810 p5.Print();
811 }
812 if (x6 == 0) {
813 AliInfo("p6 singular ");
814 p6.Print();
815 }
816
817
818 tet=x1;
819 psi=x2;
820 phi=x3;
821 x0=x4;
822 y0=x5;
823 z0=x6;
824 return;
825}