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