]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSAlignMille2Module.cxx
Update of GMS subprocessor to take into account incremental computation of alignement...
[u/mrichter/AliRoot.git] / ITS / AliITSAlignMille2Module.cxx
CommitLineData
7b85e477 1/************************************************************************** \r
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. * \r
3 * * \r
4 * Author: The ALICE Off-line Project. * \r
5 * Contributors are mentioned in the code where appropriate. * \r
6 * * \r
7 * Permission to use, copy, modify and distribute this software and its * \r
8 * documentation strictly for non-commercial purposes is hereby granted * \r
9 * without fee, provided that the above copyright notice appears in all * \r
10 * copies and that both the copyright notice and this permission notice * \r
11 * appear in the supporting documentation. The authors make no claims * \r
12 * about the suitability of this software for any purpose. It is * \r
13 * provided "as is" without express or implied warranty. * \r
14 **************************************************************************/ \r
15 \r
16/* $Id$ */ \r
17//----------------------------------------------------------------------------- \r
18/// \class AliITSAlignMille2Module\r
19/// Alignment class for the ALICE ITS detector \r
20/// \r
21/// This class is used by AliITSAlignMille to build custom supermodules \r
22/// made of ITS sensitive modules. These supermodules are then aligned\r
23/// \r
24/// Custom supermodules must have VolumeID > 14335\r
25///\r
26/// \author M. Lunardon \r
27//----------------------------------------------------------------------------- \r
28 \r
29#include <TGeoManager.h> \r
30#include <TGeoMatrix.h> \r
31 \r
32#include "AliITSAlignMille2Module.h" \r
33#include "AliITSgeomTGeo.h" \r
34#include "AliGeomManager.h" \r
35#include "AliAlignObjParams.h" \r
36#include "AliLog.h" \r
37#include "AliITSAlignMille2.h"\r
38 \r
39/// \cond CLASSIMP \r
40ClassImp(AliITSAlignMille2Module) \r
41/// \endcond \r
42\r
43#define CORHW_\r
44\r
45AliAlignObjParams AliITSAlignMille2Module::fgTempAlignObj;\r
46 \r
47//-------------------------------------------------------------\r
48AliITSAlignMille2Module::AliITSAlignMille2Module() : \r
49 TNamed(), \r
50 fNSensVol(0), \r
51 fIndex(-1), \r
52 fVolumeID(0),\r
53 fNProcPoints(0),\r
54 fSensVolIndex(0),\r
55 fSensVolVolumeID(0),\r
56 fMatrix(NULL),\r
57 fSensVolMatrix(NULL),\r
58 fSensVolModifMatrix(NULL),\r
59 fParent(NULL)\r
60{ \r
61 /// void constructor \r
62 fMatrix = new TGeoHMatrix; \r
63 fSensVolMatrix = new TGeoHMatrix; \r
64 fSensVolModifMatrix = new TGeoHMatrix; \r
65 fSensVolIndex.Set(1);\r
66 fSensVolVolumeID.Set(1);\r
67 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
68} \r
69\r
70//-------------------------------------------------------------\r
71AliITSAlignMille2Module::AliITSAlignMille2Module(Int_t index,UShort_t volid,char* symname,TGeoHMatrix *m,Int_t nsv,UShort_t *volidsv) : \r
72 TNamed(), \r
73 fNSensVol(0), \r
74 fIndex(-1), \r
75 fVolumeID(0),\r
76 fNProcPoints(0),\r
77 fSensVolIndex(0),\r
78 fSensVolVolumeID(0), \r
79 fMatrix(NULL),\r
80 fSensVolMatrix(NULL),\r
81 fSensVolModifMatrix(NULL),\r
82 fParent(NULL)\r
83{ \r
84 /// void constructor \r
85 fMatrix = new TGeoHMatrix; \r
86 fSensVolMatrix = new TGeoHMatrix; \r
87 fSensVolModifMatrix = new TGeoHMatrix; \r
88 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
89 if (Set(index,volid,symname,m,nsv,volidsv)) {\r
90 AliInfo("Error in AliITSAlignMille2Module::Set() - initializing void supermodule...");\r
91 }\r
92} \r
93\r
94//-------------------------------------------------------------\r
95AliITSAlignMille2Module::AliITSAlignMille2Module(UShort_t volid) : \r
96 TNamed(), \r
97 fNSensVol(0), \r
98 fIndex(-1), \r
99 fVolumeID(0),\r
100 fNProcPoints(0),\r
101 fSensVolIndex(0),\r
102 fSensVolVolumeID(0),\r
103 fMatrix(NULL),\r
104 fSensVolMatrix(NULL),\r
105 fSensVolModifMatrix(NULL),\r
106 fParent(NULL)\r
107{ \r
108 /// simple constructor building a supermodule from a single sensitive volume \r
109 fMatrix = new TGeoHMatrix; \r
110 fSensVolMatrix = new TGeoHMatrix; \r
111 fSensVolModifMatrix = new TGeoHMatrix; \r
112 // temporary align object, just use the rotation...\r
113 fSensVolIndex.Set(1);\r
114 fSensVolVolumeID.Set(1);\r
115 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
116 //\r
117 fIndex = GetIndexFromVolumeID(volid); \r
118 if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded\r
119 SetName(AliGeomManager::SymName(volid));\r
120 fVolumeID = volid;\r
121 AddSensitiveVolume(volid);\r
122 if (SensVolMatrix(volid, fMatrix))\r
123 AliInfo("Matrix not defined");\r
124 }\r
125 else {\r
126 AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");\r
127 }\r
128} \r
129\r
130\r
131//_____________________________________________________________________________\r
132AliITSAlignMille2Module::AliITSAlignMille2Module(const AliITSAlignMille2Module &m) :\r
133 TNamed(m),\r
134 fNSensVol(m.fNSensVol),\r
135 fIndex(m.fIndex),\r
136 fVolumeID(m.fVolumeID),\r
137 fNProcPoints(0),\r
138 fSensVolIndex(m.fSensVolIndex),\r
139 fSensVolVolumeID(m.fSensVolVolumeID),\r
140 fMatrix(new TGeoHMatrix(*m.GetMatrix())),\r
141 fSensVolMatrix(new TGeoHMatrix),\r
142 fSensVolModifMatrix(new TGeoHMatrix),\r
143 fParent(m.fParent)\r
144{\r
145 // Copy constructor\r
146 fSensVolIndex = m.fSensVolIndex;\r
147 fSensVolVolumeID = m.fSensVolVolumeID;\r
148 for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];\r
149}\r
150\r
151//_____________________________________________________________________________\r
152AliITSAlignMille2Module& AliITSAlignMille2Module::operator=(const AliITSAlignMille2Module &m) \r
153{\r
154 // operator =\r
155 //\r
156 if(this==&m) return *this;\r
157 ((TNamed *)this)->operator=(m);\r
158 //\r
159 fNSensVol=m.fNSensVol;\r
160 fIndex=m.fIndex;\r
161 fVolumeID=m.fVolumeID;\r
162 for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];\r
163 if (fMatrix) delete fMatrix;\r
164 fMatrix=new TGeoHMatrix(*m.GetMatrix());\r
165 fSensVolIndex = m.fSensVolIndex;\r
166 fSensVolVolumeID = m.fSensVolVolumeID;\r
167 fParent = m.fParent;\r
168 return *this;\r
169}\r
170\r
171\r
172//-------------------------------------------------------------\r
173AliITSAlignMille2Module::~AliITSAlignMille2Module() { \r
174 /// Destructor \r
175 delete fMatrix; \r
176 delete fSensVolMatrix; \r
177 delete fSensVolModifMatrix; \r
178} \r
179\r
180//-------------------------------------------------------------\r
181Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv) \r
182{\r
183 // initialize a custom supermodule\r
184 // index, volid, symname and matrix must be given\r
185 // if (volidsv) add nsv sensitive volumes to the supermodules\r
186 // return 0 if success\r
187\r
188 if (index<2198) {\r
189 AliInfo("Index must be >= 2198");\r
190 return -1;\r
191 }\r
192 if (volid<14336) {\r
193 AliInfo("VolumeID must be >= 14336");\r
194 return -2;\r
195 }\r
196 \r
197 if (!symname) return -3;\r
198 for (Int_t i=0; i<2198; i++) {\r
199 if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {\r
200 AliInfo("Symname already used by a Sensitive Volume");\r
201 return -3;\r
202 }\r
203 }\r
204 \r
205 if (!m) return -4;\r
206\r
207 // can initialize needed stuffs\r
208 fIndex = index;\r
209 fVolumeID = volid;\r
210 SetName(symname);\r
211 //\r
212 (*fMatrix) = (*m);\r
213 //\r
214 fSensVolIndex.Set(nsv);\r
215 fSensVolVolumeID.Set(nsv);\r
216 // add sensitive volumes\r
217 for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);\r
218\r
219 return 0;\r
220}\r
221\r
222//-------------------------------------------------------------\r
223Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {\r
224 /// index from volume ID\r
225 AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);\r
226 if (lay<1|| lay>6) return -1;\r
227 Int_t idx=Int_t(voluid)-2048*lay;\r
228 if (idx>=AliGeomManager::LayerSize(lay)) return -1;\r
229 for (Int_t ilay=1; ilay<lay; ilay++) \r
230 idx += AliGeomManager::LayerSize(ilay);\r
231 return idx;\r
232}\r
233\r
234//-------------------------------------------------------------\r
235void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)\r
236{\r
237 /// add a sensitive volume to this supermodule\r
238 if (GetIndexFromVolumeID(voluid)<0) return; // bad volid\r
239 //\r
240 // in principle, the correct size of fSensVol... arrays was set outside but check anyway\r
241 if (fSensVolVolumeID.GetSize()<fNSensVol) {\r
242 fSensVolVolumeID.Set(fNSensVol+1);\r
243 fSensVolIndex.Set(fNSensVol+1);\r
244 }\r
245 //\r
246 fSensVolVolumeID[fNSensVol] = Short_t(voluid);\r
247 fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);\r
248 fNSensVol++;\r
249}\r
250\r
251//-------------------------------------------------------------\r
252void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)\r
253{\r
254 // Suppress sensor at position "at"\r
255 // in fact we are swapping with the last valid one \r
256 int lastValid = --fNSensVol;\r
257 int tmpv = fSensVolIndex[at];\r
258 fSensVolIndex[at] = fSensVolIndex[lastValid];\r
259 tmpv = fSensVolVolumeID[at];\r
260 fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];\r
261 fSensVolVolumeID[lastValid] = tmpv;\r
262 //\r
263}\r
264\r
265//-------------------------------------------------------------\r
266Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const \r
267{\r
268 /// check if voluid is defined\r
269 if (!voluid) return kFALSE; // only positive voluid are accepted\r
270 for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;\r
271 return kFALSE;\r
272}\r
273\r
274//-------------------------------------------------------------\r
275Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const\r
276{\r
277 /// check if parent contains the sensors of this volume\r
278 if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;\r
279 return parent->IsIn( fSensVolVolumeID[0] );\r
280}\r
281\r
282//-------------------------------------------------------------\r
283TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *delta,Bool_t local)\r
284{\r
285 // modify the original TGeoHMatrix of the sensitive module 'voluid' according\r
286 // with a delta transform. applied to the supermodule matrix\r
287 // return NULL if error\r
288\r
289 if (!IsIn(voluid)) return NULL;\r
290 if (!gGeoManager) return NULL;\r
291\r
292 // prepare the TGeoHMatrix\r
293 Double_t tr[3],ang[3];\r
294 tr[0]=delta[0]; // in centimeter\r
295 tr[1]=delta[1]; \r
296 tr[2]=delta[2];\r
297 ang[0]=delta[3]; // psi (X) in deg\r
298 ang[1]=delta[4]; // theta (Y)\r
299 ang[2]=delta[5]; // phi (Z)\r
300 //\r
301 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
302 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
303 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
304 TGeoHMatrix hm;\r
305 fgTempAlignObj.GetMatrix(hm);\r
306 //printf("\n0: delta matrix\n");hm.Print();\r
307\r
308 // 1) start setting fSensVolModif = fSensVol\r
309 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
310 //\r
311 if (local) {\r
312 // 2) set fSensVolModif = SensVolRel\r
313 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
314 // 3) multiply left by delta\r
315 fSensVolModifMatrix->MultiplyLeft( &hm );\r
316 // 4) multiply left by fMatrix\r
317 fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
318 }\r
319 else fSensVolModifMatrix->MultiplyLeft( &hm );\r
320 //\r
321 return fSensVolModifMatrix;\r
322}\r
323\r
324//-------------------------------------------------------------\r
325AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)\r
326{\r
327 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
328 // of the mother volume. The misalignment is returned as AliAlignObjParams object\r
329\r
330 if (!IsIn(voluid)) return NULL;\r
331 if (!gGeoManager) return NULL;\r
332 \r
333 // prepare the TGeoHMatrix\r
334 Double_t tr[3],ang[3];\r
335 tr[0]=deltalocal[0]; // in centimeter\r
336 tr[1]=deltalocal[1]; \r
337 tr[2]=deltalocal[2];\r
338 ang[0]=deltalocal[3]; // psi (X) in deg\r
339 ang[1]=deltalocal[4]; // theta (Y)\r
340 ang[2]=deltalocal[5]; // phi (Z)\r
341 //\r
342 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
343 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
344 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
345 //\r
346 return GetSensitiveVolumeMisalignment(voluid,&fgTempAlignObj);\r
347}\r
348\r
349//-------------------------------------------------------------\r
350AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)\r
351{\r
352 // return the misalignment of the sens. vol. 'voluid' corresponding with \r
353 // a misalignment 'a' in the mother volume\r
354 // return NULL if error\r
355\r
356 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r
357 // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv\r
358 // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
359 //\r
360 // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)\r
361 //\r
362\r
363 if (!IsIn(voluid)) return NULL;\r
364 if (!gGeoManager) return NULL;\r
365\r
366 //a->Print("");\r
367\r
368 // prepare the Delta matrix Dg\r
369 TGeoHMatrix dg;\r
370 a->GetMatrix(dg);\r
371 //dg.Print();\r
372\r
373 // 1) start setting fSensVolModif = Gsv\r
374 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
375 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
376\r
377 // 2) set fSensVolModif = Gg-1 * Gsv\r
378 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
379 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
380 \r
381 // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r
382 fSensVolModifMatrix->MultiplyLeft( &dg );\r
383 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
384 \r
385 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r
386 fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
387 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r
388\r
389 // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
390 if (SensVolMatrix(voluid, &dg)) return NULL;\r
391 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r
392 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r
393 //\r
394 // >> RS\r
395 // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)\r
396 // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:\r
397 // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1\r
398 //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv\r
399 //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;\r
400 //if (SensVolMatrix(voluid, &dpre)) return NULL;\r
401 //dpre.MultiplyLeft( &dg.Inverse() );\r
402 //fSensVolModifMatrix->Multiply( &dpre.Inverse() );\r
403 //fSensVolModifMatrix->MultiplyLeft( &dpre );\r
404 // direi che NON FUNZIONA!!!! \r
405\r
406 // << RS\r
407\r
408 // reset align object (may not be needed...)\r
409 fgTempAlignObj.SetVolUID(0);\r
410 fgTempAlignObj.SetSymName("");\r
411 fgTempAlignObj.SetTranslation(0,0,0);\r
412 fgTempAlignObj.SetRotation(0,0,0);\r
413 //\r
414 // >> RS\r
415#ifdef CORHW_\r
416 // correction for SPD y-shift\r
417 if (voluid>=2048 && voluid<4256) {\r
418 TGeoHMatrix deltay;\r
419 double dy[3]={0.,0.0081,0.};\r
420 deltay.SetTranslation(dy);\r
421 fSensVolModifMatrix->MultiplyLeft( &deltay );\r
422 fSensVolModifMatrix->Multiply( &deltay.Inverse() );\r
423 }\r
424#endif\r
425 // << RS\r
426 if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
427 fgTempAlignObj.SetVolUID(voluid);\r
428 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
429 //\r
430 return &fgTempAlignObj;\r
431}\r
432\r
433// >> RS\r
434//-------------------------------------------------------------\r
435AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, Double_t *deltalocal)\r
436{\r
437 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
438 // of the mother volume. The misalignment is returned as AliAlignObjParams object including\r
439 // the (evenctual) prealignment => no merging needed\r
440\r
441 if (!IsIn(voluid)) return NULL;\r
442 if (!gGeoManager) return NULL;\r
443 \r
444 // prepare the TGeoHMatrix\r
445 Double_t tr[3],ang[3];\r
446 tr[0]=deltalocal[0]; // in centimeter\r
447 tr[1]=deltalocal[1]; \r
448 tr[2]=deltalocal[2];\r
449 ang[0]=deltalocal[3]; // psi (X) in deg\r
450 ang[1]=deltalocal[4]; // theta (Y)\r
451 ang[2]=deltalocal[5]; // phi (Z)\r
452\r
453 // reset align object (may not be needed...)\r
454 fgTempAlignObj.SetVolUID(0);\r
455 fgTempAlignObj.SetSymName("");\r
456 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
457 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
458 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
459\r
460 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r
461 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv \r
462 //\r
463 // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv) //\r
464 //\r
465\r
466 // prepare the Delta matrix Dg\r
467 TGeoHMatrix dg;\r
468 fgTempAlignObj.GetMatrix(dg);\r
469 //dg.Print();\r
470\r
471 // 1) start setting fSensVolModif = Gsv\r
472 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
473 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
474\r
475 // 2) set fSensVolModif = Gg-1 * Gsv\r
476 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
477 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
478 \r
479 // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r
480 fSensVolModifMatrix->MultiplyLeft( &dg );\r
481 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
482 \r
483 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r
484 fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
485 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r
486\r
487 // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv\r
488 // qui usa l'orig anziche' la prealigned...\r
489 if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;\r
490 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r
491 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r
492\r
493 // reset align object (may not be needed...)\r
494 fgTempAlignObj.SetVolUID(0);\r
495 fgTempAlignObj.SetSymName("");\r
496 fgTempAlignObj.SetTranslation(0,0,0);\r
497 fgTempAlignObj.SetRotation(0,0,0);\r
498\r
499#ifdef CORHW_\r
500 // correction for SPD y-shift\r
501 if (voluid>=2048 && voluid<4256) {\r
502 TGeoHMatrix deltay;\r
503 double dy[3]={0.,0.0081,0.};\r
504 deltay.SetTranslation(dy);\r
505 fSensVolModifMatrix->MultiplyLeft( &deltay );\r
506 fSensVolModifMatrix->Multiply( &deltay.Inverse() );\r
507 }\r
508#endif\r
509 if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
510 fgTempAlignObj.SetVolUID(voluid);\r
511 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
512\r
513 \r
514 //fgTempAlignObj.Print("");\r
515\r
516 return &fgTempAlignObj;\r
517}\r
518//-------------------------------------------------------------\r
519\r
520//-------------------------------------------------------------\r
521AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, Double_t *deltalocal)\r
522{\r
523 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
524 // of the mother volume. The misalignment is returned as AliAlignObjParams object\r
525\r
526 if (!IsIn(voluid)) return NULL;\r
527 if (!gGeoManager) return NULL;\r
528 \r
529 // prepare the TGeoHMatrix\r
530 Double_t tr[3],ang[3];\r
531 tr[0]=deltalocal[0]; // in centimeter\r
532 tr[1]=deltalocal[1]; \r
533 tr[2]=deltalocal[2];\r
534 ang[0]=deltalocal[3]; // psi (X) in deg\r
535 ang[1]=deltalocal[4]; // theta (Y)\r
536 ang[2]=deltalocal[5]; // phi (Z)\r
537\r
538 // reset align object (may not be needed...)\r
539 fgTempAlignObj.SetTranslation(0,0,0);\r
540 fgTempAlignObj.SetRotation(0,0,0);\r
541\r
542 fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
543 fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
544 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
545\r
546 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r
547 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv \r
548 //\r
549 // => DGsv = (Gg * Dg * Gg-1)\r
550 //\r
551\r
552 // prepare the Delta matrix Dg\r
553 TGeoHMatrix dg;\r
554 fgTempAlignObj.GetMatrix(dg);\r
555 //dg.Print();\r
556\r
557 dg.MultiplyLeft( fMatrix );\r
558 dg.Multiply( &fMatrix->Inverse() );\r
559\r
560 // reset align object (may not be needed...)\r
561 fgTempAlignObj.SetTranslation(0,0,0);\r
562 fgTempAlignObj.SetRotation(0,0,0);\r
563\r
564 fgTempAlignObj.SetVolUID(voluid);\r
565 fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
566\r
567 if (!fgTempAlignObj.SetMatrix(dg)) return NULL;\r
568 \r
569 //fgTempAlignObj.Print("");\r
570\r
571 return &fgTempAlignObj;\r
572}\r
573// << RS\r
574\r
575//-------------------------------------------------------------\r
576TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)\r
577{\r
578 // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry\r
579 if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;\r
580 return fSensVolMatrix;\r
581}\r
582\r
583//-------------------------------------------------------------\r
584TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)\r
585{\r
586 // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())\r
587 if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;\r
588 return fSensVolMatrix;\r
589}\r
590//-------------------------------------------------------------\r
591Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m) \r
592{\r
593 // set matrix for sensitive modules (SPD corrected)\r
594 // return 0 if success\r
595 Double_t rot[9];\r
596 Int_t idx=GetIndexFromVolumeID(volid);\r
597 if (idx<0) return -1;\r
598 if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;\r
599 m->SetRotation(rot);\r
600 Double_t oLoc[3]={0,0,0};\r
601 Double_t oGlo[3]={0,0,0};\r
602 if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;\r
603 m->SetTranslation(oGlo);\r
604 return 0;\r
605}\r
606\r
607//-------------------------------------------------------------\r
608Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m) \r
609{\r
610 // set original global matrix for sensitive modules (SPD corrected)\r
611 // return 0 if success\r
612 Int_t idx=GetIndexFromVolumeID(volid);\r
613 if (idx<0) return -1;\r
614 TGeoHMatrix mo;\r
615 if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo));\r
616 (*m)=mo;\r
617\r
618#ifdef CORHW_\r
619 // SPD y-shift by 81 mu\r
620 if (volid<5000) { \r
621 Double_t oLoc[3]={0.0,0.0081,0.0};\r
622 Double_t oGlo[3]={0,0,0};\r
623 m->LocalToMaster(oLoc,oGlo);\r
624 m->SetTranslation(oGlo);\r
625 }\r
626#endif\r
627 return 0;\r
628}\r
629\r
630//-------------------------------------------------------------\r
631UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {\r
632 /// volume ID from symname\r
633 if (!symname) return 0;\r
634\r
635 for (UShort_t voluid=2000; voluid<13300; voluid++) {\r
636 Int_t modId;\r
637 AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);\r
638 if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {\r
639 if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;\r
640 }\r
641 }\r
642\r
643 return 0;\r
644}\r
645\r
646//-------------------------------------------------------------\r
647UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {\r
648 /// volume ID from index\r
649 if (index<0 || index>2197) return 0;\r
650 return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));\r
651}\r
652\r
653//-------------------------------------------------------------\r
654void AliITSAlignMille2Module::Print(Option_t*) const \r
655{\r
656 ///\r
657 printf("*** ITS SuperModule for AliITSAlignMille ***\n");\r
658 printf("symname : %s\n",GetName());\r
659 printf("parent : %s\n",fParent ? fParent->GetName() : "N/A");\r
660 printf("volumeID : %4d | index : %4d\n",fVolumeID,fIndex);\r
661 printf("Factors : X=%.2f Y=%.2f Z=%.2f | DOF: Tx:%d Ty:%d Tz:%d Phi:%d Theta:%d Psi:%d\n",\r
662 fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],\r
663 IsFreeDOF(AliITSAlignMille2::kDOFTX),IsFreeDOF(AliITSAlignMille2::kDOFTY),\r
664 IsFreeDOF(AliITSAlignMille2::kDOFTZ),IsFreeDOF(AliITSAlignMille2::kDOFPH),\r
665 IsFreeDOF(AliITSAlignMille2::kDOFTH),IsFreeDOF(AliITSAlignMille2::kDOFPS));\r
666 fMatrix->Print();\r
667 printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);\r
668 for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));\r
669}\r
670\r
671//-------------------------------------------------------------\r
672Bool_t AliITSAlignMille2Module::IsAlignable() const\r
673{\r
674 TGeoManager* geoManager = AliGeomManager::GetGeometry();\r
675 if (!geoManager) {\r
676 AliInfo("Couldn't initialize geometry");\r
677 return kFALSE;\r
678 }\r
679 return geoManager->GetAlignableEntry(GetName())!=0;\r
680}\r
681\r
682//-------------------------------------------------------------\r
683void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const\r
684{\r
685 // return the local matrix for transformation to its parent\r
686 mat = *fMatrix;\r
687 if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );\r
688}\r