]>
Commit | Line | Data |
---|---|---|
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 | ||
44 | ClassImp(AliITSSurveyToAlign) | |
45 | ||
46 | const 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 | ||
53 | const 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 | 60 | const Double_t kRadToDeg = 180./TMath::Pi(); |
02078bdf | 61 | |
62 | //________________________________________________________________________ | |
63 | AliITSSurveyToAlign::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 | //_________________________________________________________________________ | |
81 | AliITSSurveyToAlign::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 | 97 | AliITSSurveyToAlign & AliITSSurveyToAlign::operator =(const AliITSSurveyToAlign& /* align */) { |
02078bdf | 98 | // |
99 | // assignment operator - dummy | |
100 | // | |
101 | ||
102 | return (*this); | |
103 | } | |
104 | ||
105 | //__________________________________________________________________________ | |
106 | AliITSSurveyToAlign::~AliITSSurveyToAlign() { | |
107 | // | |
108 | // destructor | |
109 | // | |
110 | } | |
111 | ||
112 | //______________________________________________________________________ | |
113 | void 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 | //______________________________________________________________________ | |
130 | Bool_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 | //______________________________________________________________________ |
164 | void 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 | 182 | void 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 | 260 | void 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 | 278 | void 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 | //______________________________________________________________________ |
341 | Bool_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 | 367 | void 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 | 461 | void 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 | 479 | void 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 | 513 | void 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 | 571 | void 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 | 631 | void 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 | 671 | void 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 | } |