]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSAlignMille2Module.cxx
bug fixed
[u/mrichter/AliRoot.git] / ITS / AliITSAlignMille2Module.cxx
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
40 ClassImp(AliITSAlignMille2Module) \r
41 /// \endcond \r
42 \r
43 #define CORHW_\r
44 \r
45 AliAlignObjParams AliITSAlignMille2Module::fgTempAlignObj;\r
46     \r
47 //-------------------------------------------------------------\r
48 AliITSAlignMille2Module::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
71 AliITSAlignMille2Module::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
95 AliITSAlignMille2Module::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
132 AliITSAlignMille2Module::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
152 AliITSAlignMille2Module& 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
173 AliITSAlignMille2Module::~AliITSAlignMille2Module() { \r
174   /// Destructor \r
175   delete fMatrix; \r
176   delete fSensVolMatrix; \r
177   delete fSensVolModifMatrix; \r
178\r
179 \r
180 //-------------------------------------------------------------\r
181 Int_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
223 Int_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
235 void 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
252 void 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
266 Bool_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
275 Bool_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
283 TGeoHMatrix *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
325 AliAlignObjParams *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
350 AliAlignObjParams *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
435 AliAlignObjParams *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
521 AliAlignObjParams *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
576 TGeoHMatrix *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
584 TGeoHMatrix *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
591 Int_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
608 Int_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
631 UShort_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
647 UShort_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
654 void 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
672 Bool_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
683 void 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