]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSAlignMille2Module.cxx
Fix in assignment of label to SDD RecPoints (F. Prino)
[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 const Float_t AliITSAlignMille2Module::fgkDummyConstraint = 1.E3;\r
47     \r
48 //-------------------------------------------------------------\r
49 AliITSAlignMille2Module::AliITSAlignMille2Module() : \r
50   TNamed(), \r
51   fNSensVol(0), \r
52   fIndex(-1),  \r
53   fDetType(-1),\r
54   fVolumeID(0),\r
55   fNParTot(0),\r
56   fNParFree(0),\r
57   fParOffs(0),\r
58   fNProcPoints(0),\r
59   fParVals(0),\r
60   fParErrs(0),\r
61   fParCstr(0),\r
62   fSensVolIndex(0),\r
63   fSensVolVolumeID(0),\r
64   fMatrix(NULL),\r
65   fSensVolMatrix(NULL),\r
66   fSensVolModifMatrix(NULL),\r
67   fParent(NULL),\r
68   fChildren(0)\r
69\r
70   /// void constructor  \r
71   fMatrix = new TGeoHMatrix; \r
72   fSensVolMatrix = new TGeoHMatrix; \r
73   fSensVolModifMatrix = new TGeoHMatrix; \r
74   fSensVolIndex.Set(1);\r
75   fSensVolVolumeID.Set(1);\r
76   fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
77\r
78 \r
79 //-------------------------------------------------------------\r
80 AliITSAlignMille2Module::AliITSAlignMille2Module(Int_t index, UShort_t volid, const char* symname,\r
81                                                  const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) : \r
82   TNamed(), \r
83   fNSensVol(0), \r
84   fIndex(-1),  \r
85   fDetType(-1),  \r
86   fVolumeID(0),\r
87   fNParTot(0),\r
88   fNParFree(0),\r
89   fParOffs(kMaxParGeom),\r
90   fNProcPoints(0),\r
91   fParVals(0),\r
92   fParErrs(0),\r
93   fParCstr(0),\r
94   fSensVolIndex(0),\r
95   fSensVolVolumeID(0),  \r
96   fMatrix(NULL),\r
97   fSensVolMatrix(NULL),\r
98   fSensVolModifMatrix(NULL),\r
99   fParent(NULL),\r
100   fChildren(0)\r
101\r
102   /// void constructor  \r
103   fMatrix = new TGeoHMatrix; \r
104   fSensVolMatrix = new TGeoHMatrix; \r
105   fSensVolModifMatrix = new TGeoHMatrix; \r
106   fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
107   for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;\r
108   if (Set(index,volid,symname,m,nsv,volidsv)) {\r
109     AliInfo("Error in AliITSAlignMille2Module::Set() - initializing void supermodule...");\r
110   }\r
111   AssignDetType();\r
112\r
113 \r
114 //-------------------------------------------------------------\r
115 AliITSAlignMille2Module::AliITSAlignMille2Module(UShort_t volid) : \r
116   TNamed(), \r
117   fNSensVol(0), \r
118   fIndex(-1),    \r
119   fDetType(-1),\r
120   fVolumeID(0),\r
121   fNParTot(0),\r
122   fNParFree(0),\r
123   fParOffs(kMaxParGeom),\r
124   fNProcPoints(0),\r
125   fParVals(0),\r
126   fParErrs(0),\r
127   fParCstr(0),  \r
128   fSensVolIndex(0),\r
129   fSensVolVolumeID(0),\r
130   fMatrix(NULL),\r
131   fSensVolMatrix(NULL),\r
132   fSensVolModifMatrix(NULL),\r
133   fParent(NULL),\r
134   fChildren(0)\r
135\r
136   /// simple constructor building a supermodule from a single sensitive volume \r
137   fMatrix = new TGeoHMatrix; \r
138   fSensVolMatrix = new TGeoHMatrix; \r
139   fSensVolModifMatrix = new TGeoHMatrix;   \r
140   // temporary align object, just use the rotation...\r
141   fSensVolIndex.Set(1);\r
142   fSensVolVolumeID.Set(1);\r
143   fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
144   for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;\r
145   //\r
146   fIndex = GetIndexFromVolumeID(volid);  \r
147   if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded\r
148     SetName(AliGeomManager::SymName(volid));\r
149     fVolumeID = volid;\r
150     AddSensitiveVolume(volid);\r
151     SetSensorsProvided(kTRUE);\r
152     if (SensVolMatrix(volid, fMatrix))\r
153        AliInfo("Matrix not defined");\r
154   }\r
155   else {\r
156     AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");\r
157   }\r
158   AssignDetType();\r
159\r
160 \r
161 \r
162 //_____________________________________________________________________________\r
163 AliITSAlignMille2Module::AliITSAlignMille2Module(const AliITSAlignMille2Module &m) :\r
164   TNamed(m),\r
165   fNSensVol(m.fNSensVol),\r
166   fIndex(m.fIndex),  \r
167   fDetType(m.fDetType),\r
168   fVolumeID(m.fVolumeID),\r
169   fNParTot(m.fNParTot),\r
170   fNParFree(m.fNParFree),\r
171   fParOffs(m.fNParTot),\r
172   fNProcPoints(0),\r
173   fParVals(0),\r
174   fParErrs(0),\r
175   fParCstr(0),  \r
176   fSensVolIndex(m.fSensVolIndex),\r
177   fSensVolVolumeID(m.fSensVolVolumeID),\r
178   fMatrix(new TGeoHMatrix(*m.GetMatrix())),\r
179   fSensVolMatrix(new TGeoHMatrix),\r
180   fSensVolModifMatrix(new TGeoHMatrix),\r
181   fParent(m.fParent),\r
182   fChildren(0)\r
183 {\r
184   // Copy constructor\r
185   fSensVolIndex = m.fSensVolIndex;\r
186   fSensVolVolumeID = m.fSensVolVolumeID;\r
187   for (int i=m.fNParTot;i--;) fParOffs[i] = m.fParOffs[i];\r
188   for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];\r
189   if (fNParTot) {\r
190     fParVals = new Float_t[fNParTot];\r
191     fParErrs = new Float_t[fNParTot];\r
192     fParCstr = new Float_t[fNParTot];\r
193     for (int i=fNParTot;i--;) {\r
194       fParVals[i] = m.fParVals[i];\r
195       fParErrs[i] = m.fParErrs[i];\r
196       fParCstr[i] = m.fParCstr[i];\r
197     }\r
198   }\r
199 }\r
200 \r
201 //_____________________________________________________________________________\r
202 AliITSAlignMille2Module& AliITSAlignMille2Module::operator=(const AliITSAlignMille2Module &m)  \r
203 {\r
204   // operator =\r
205   //\r
206   if(this==&m) return *this;\r
207   ((TNamed *)this)->operator=(m);\r
208   //\r
209   fNSensVol=m.fNSensVol;\r
210   fIndex=m.fIndex;\r
211   fDetType = m.fDetType;\r
212   fVolumeID=m.fVolumeID;\r
213   fNParTot  = m.fNParTot;\r
214   fNParFree = m.fNParFree;\r
215   delete[] fParVals; fParVals = 0;\r
216   delete[] fParErrs; fParErrs = 0;\r
217   delete[] fParCstr; fParCstr = 0;\r
218   //\r
219   if (fNParTot) {\r
220     fParVals = new Float_t[fNParTot];\r
221     fParErrs = new Float_t[fNParTot];\r
222     for (int i=m.GetNParTot();i--;) {\r
223       fParVals[i] = m.fParVals[i];\r
224       fParErrs[i] = m.fParErrs[i];\r
225       fParCstr[i] = m.fParCstr[i];\r
226     }\r
227   }\r
228   //\r
229   fParOffs.Set(fNParTot);\r
230   for (int i=0;i<fNParTot;i++) fParOffs[i] = m.fParOffs[i];\r
231   for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];\r
232   if (fMatrix) delete fMatrix;\r
233   fMatrix=new TGeoHMatrix(*m.GetMatrix());\r
234   fSensVolIndex = m.fSensVolIndex;\r
235   fSensVolVolumeID = m.fSensVolVolumeID;\r
236   fParent = m.fParent;\r
237   fChildren.Clear();\r
238   for (int i=0;i<m.GetNChildren();i++) fChildren.Add(m.GetChild(i));\r
239   return *this;\r
240 }\r
241 \r
242 \r
243 //-------------------------------------------------------------\r
244 AliITSAlignMille2Module::~AliITSAlignMille2Module() { \r
245   /// Destructor \r
246   delete fMatrix; \r
247   delete fSensVolMatrix; \r
248   delete fSensVolModifMatrix; \r
249   delete[] fParVals;\r
250   delete[] fParErrs;\r
251   delete[] fParCstr;\r
252   fChildren.Clear();\r
253\r
254 \r
255 //-------------------------------------------------------------\r
256 Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, const char* symname, \r
257                                    const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) \r
258 {\r
259   // initialize a custom supermodule\r
260   // index, volid, symname and matrix must be given\r
261   // if (volidsv) add nsv sensitive volumes to the supermodules\r
262   // return 0 if success\r
263 \r
264   if (index<2198) {\r
265     AliInfo("Index must be >= 2198");\r
266     return -1;\r
267   }\r
268   if (volid<14336) {\r
269     AliInfo("VolumeID must be >= 14336");\r
270     return -2;\r
271   }\r
272   \r
273   if (!symname) return -3;\r
274   for (Int_t i=0; i<2198; i++) {\r
275     if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {\r
276       AliInfo("Symname already used by a Sensitive Volume");\r
277       return -3;\r
278     }\r
279   }\r
280   \r
281   if (!m) return -4;\r
282 \r
283   // can initialize needed stuffs\r
284   fIndex = index;\r
285   fVolumeID = volid;\r
286   SetName(symname);\r
287   //\r
288   (*fMatrix) = (*m);\r
289   //\r
290   fSensVolIndex.Set(nsv);\r
291   fSensVolVolumeID.Set(nsv);\r
292   // add sensitive volumes\r
293   for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);\r
294 \r
295   return 0;\r
296 }\r
297 \r
298 //-------------------------------------------------------------\r
299 void AliITSAlignMille2Module::SetFreeDOF(Int_t dof,Double_t cstr)\r
300 {\r
301   if (AliITSAlignMille2::IsZero(cstr)) fParCstr[dof] = 0;  // fixed parameter\r
302   else if (cstr>0)                     fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained\r
303   else                                 fParCstr[dof] = -cstr;                 // the parameter is free but constrained\r
304 }\r
305 \r
306 //-------------------------------------------------------------\r
307 Bool_t AliITSAlignMille2Module::IsSensor(UShort_t voluid) \r
308 {\r
309   // Does this volid correspond to sensor ?\r
310   AliGeomManager::ELayerID layId = AliGeomManager::VolUIDToLayerSafe(voluid);\r
311   if (layId>0 && layId<7) {\r
312     Int_t mId = Int_t(voluid & 0x7ff);\r
313     if( mId>=0 && mId<AliGeomManager::LayerSize(layId)) return kTRUE;\r
314   }\r
315   return kFALSE;\r
316 }\r
317 \r
318 //-------------------------------------------------------------\r
319 Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {\r
320   /// index from volume ID\r
321   AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);\r
322   if (lay<1|| lay>6) return -1;\r
323   Int_t idx=Int_t(voluid)-2048*lay;\r
324   if (idx>=AliGeomManager::LayerSize(lay)) return -1;\r
325   for (Int_t ilay=1; ilay<lay; ilay++) \r
326     idx += AliGeomManager::LayerSize(ilay);\r
327   return idx;\r
328 }\r
329 \r
330 //-------------------------------------------------------------\r
331 void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)\r
332 {\r
333   /// add a sensitive volume to this supermodule\r
334   if (GetIndexFromVolumeID(voluid)<0) return; // bad volid\r
335   //\r
336   // in principle, the correct size of fSensVol... arrays was set outside but check anyway\r
337   if (fSensVolVolumeID.GetSize()<fNSensVol+1) {\r
338     fSensVolVolumeID.Set(fNSensVol+1);\r
339     fSensVolIndex.Set(fNSensVol+1);\r
340   }\r
341   //\r
342   fSensVolVolumeID[fNSensVol] = Short_t(voluid);\r
343   fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);\r
344   fNSensVol++;\r
345 }\r
346 \r
347 //-------------------------------------------------------------\r
348 void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)\r
349 {\r
350   // Suppress sensor at position "at"\r
351   // in fact we are swapping with the last valid one \r
352   int lastValid = --fNSensVol;\r
353   int tmpv = fSensVolIndex[at];\r
354   fSensVolIndex[at] = fSensVolIndex[lastValid];\r
355   tmpv = fSensVolVolumeID[at];\r
356   fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];\r
357   fSensVolVolumeID[lastValid] = tmpv;\r
358   //\r
359 }\r
360 \r
361 //-------------------------------------------------------------\r
362 Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const \r
363 {\r
364   /// check if voluid is defined\r
365   if (!voluid) return kFALSE; // only positive voluid are accepted\r
366   for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;\r
367   return kFALSE;\r
368 }\r
369 \r
370 //-------------------------------------------------------------\r
371 Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const\r
372 {\r
373   /// check if parent contains the sensors of this volume\r
374   if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;\r
375   return parent->IsIn( fSensVolVolumeID[0] );\r
376 }\r
377 \r
378 //-------------------------------------------------------------\r
379 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *delta,Bool_t local)\r
380 {\r
381   // modify the original TGeoHMatrix of the sensitive module 'voluid' according\r
382   // with a delta transform. applied to the supermodule matrix\r
383   // return NULL if error\r
384 \r
385   if (!IsIn(voluid)) return NULL;\r
386   if (!gGeoManager)  return NULL;\r
387 \r
388   // prepare the TGeoHMatrix\r
389   Double_t tr[3],ang[3];\r
390   tr[0]=delta[0]; // in centimeter\r
391   tr[1]=delta[1]; \r
392   tr[2]=delta[2];\r
393   ang[0]=delta[3]; // psi   (X)  in deg\r
394   ang[1]=delta[4]; // theta (Y)\r
395   ang[2]=delta[5]; // phi   (Z)\r
396   //\r
397   fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
398   fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
399   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));\r
400   TGeoHMatrix hm;\r
401   fgTempAlignObj.GetMatrix(hm);\r
402   //printf("\n0: delta matrix\n");hm.Print();\r
403 \r
404   // 1) start setting fSensVolModif = fSensVol\r
405   if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
406   //\r
407   if (local) {\r
408     // 2) set fSensVolModif = SensVolRel\r
409     fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
410     // 3) multiply left by delta\r
411     fSensVolModifMatrix->MultiplyLeft( &hm );\r
412     // 4) multiply left by fMatrix\r
413     fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
414   }\r
415   else fSensVolModifMatrix->MultiplyLeft( &hm );\r
416   //\r
417   return fSensVolModifMatrix;\r
418 }\r
419 \r
420 //-------------------------------------------------------------\r
421 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)\r
422 {\r
423   // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
424   // of the mother volume. The misalignment is returned as AliAlignObjParams object\r
425 \r
426   if (!IsIn(voluid)) return NULL;\r
427   if (!gGeoManager) return NULL;\r
428   \r
429   // prepare the TGeoHMatrix\r
430   Double_t tr[3],ang[3];\r
431   tr[0]=deltalocal[0]; // in centimeter\r
432   tr[1]=deltalocal[1]; \r
433   tr[2]=deltalocal[2];\r
434   ang[0]=deltalocal[3]; // psi   (X)  in deg\r
435   ang[1]=deltalocal[4]; // theta (Y)\r
436   ang[2]=deltalocal[5]; // phi   (Z)\r
437   //\r
438   fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
439   fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
440   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));\r
441   //\r
442   return GetSensitiveVolumeMisalignment(voluid,&fgTempAlignObj);\r
443 }\r
444 \r
445 //-------------------------------------------------------------\r
446 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)\r
447 {\r
448   // return the misalignment of the sens. vol. 'voluid' corresponding with \r
449   // a misalignment 'a' in the mother volume\r
450   // return NULL if error\r
451 \r
452   // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv\r
453   // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv\r
454   // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
455   //\r
456   // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)\r
457   //\r
458 \r
459   if (!IsIn(voluid)) return NULL;\r
460   if (!gGeoManager) return NULL;\r
461 \r
462   //a->Print("");\r
463 \r
464   // prepare the Delta matrix Dg\r
465   TGeoHMatrix dg;\r
466   a->GetMatrix(dg);\r
467   //dg.Print();\r
468 \r
469   // 1) start setting fSensVolModif = Gsv\r
470   if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
471   //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
472 \r
473   // 2) set fSensVolModif = Gg-1 * Gsv\r
474   fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
475   //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
476  \r
477   // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r
478   fSensVolModifMatrix->MultiplyLeft( &dg );\r
479   //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
480   \r
481   // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r
482   fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
483   //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r
484 \r
485   // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
486   if (SensVolMatrix(voluid, &dg)) return NULL;\r
487   fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r
488   //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r
489   //\r
490   // >> RS\r
491  // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)\r
492   // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:\r
493   // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1\r
494   //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv\r
495   //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;\r
496   //if (SensVolMatrix(voluid, &dpre)) return NULL;\r
497   //dpre.MultiplyLeft( &dg.Inverse() );\r
498   //fSensVolModifMatrix->Multiply( &dpre.Inverse() );\r
499   //fSensVolModifMatrix->MultiplyLeft( &dpre );\r
500   // direi che NON FUNZIONA!!!!  \r
501 \r
502   // << RS\r
503 \r
504   // reset align object (may not be needed...)\r
505   fgTempAlignObj.SetVolUID(0);\r
506   fgTempAlignObj.SetSymName("");\r
507   fgTempAlignObj.SetTranslation(0,0,0);\r
508   fgTempAlignObj.SetRotation(0,0,0);\r
509   //\r
510   // >> RS\r
511 #ifdef CORHW_\r
512   // correction for SPD y-shift\r
513   if (voluid>=2048 && voluid<4256) {\r
514     TGeoHMatrix deltay;\r
515     double dy[3]={0.,0.0081,0.};\r
516     deltay.SetTranslation(dy);\r
517     fSensVolModifMatrix->MultiplyLeft( &deltay );\r
518     fSensVolModifMatrix->Multiply( &deltay.Inverse() );\r
519   }\r
520 #endif\r
521   // << RS\r
522   if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
523   fgTempAlignObj.SetVolUID(voluid);\r
524   fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
525   //\r
526   return &fgTempAlignObj;\r
527 }\r
528 \r
529 // >> RS\r
530 //-------------------------------------------------------------\r
531 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, Double_t *deltalocal)\r
532 {\r
533   // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
534   // of the mother volume. The misalignment is returned as AliAlignObjParams object including\r
535   // the (evenctual) prealignment => no merging needed\r
536 \r
537   if (!IsIn(voluid)) return NULL;\r
538   if (!gGeoManager) return NULL;\r
539   \r
540   // prepare the TGeoHMatrix\r
541   Double_t tr[3],ang[3];\r
542   tr[0]=deltalocal[0]; // in centimeter\r
543   tr[1]=deltalocal[1]; \r
544   tr[2]=deltalocal[2];\r
545   ang[0]=deltalocal[3]; // psi   (X)  in deg\r
546   ang[1]=deltalocal[4]; // theta (Y)\r
547   ang[2]=deltalocal[5]; // phi   (Z)\r
548 \r
549   // reset align object (may not be needed...)\r
550   fgTempAlignObj.SetVolUID(0);\r
551   fgTempAlignObj.SetSymName("");\r
552   fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
553   fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
554   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));\r
555 \r
556   // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv\r
557   // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv \r
558   //\r
559   // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv)  //\r
560   //\r
561 \r
562   // prepare the Delta matrix Dg\r
563   TGeoHMatrix dg;\r
564   fgTempAlignObj.GetMatrix(dg);\r
565   //dg.Print();\r
566 \r
567   // 1) start setting fSensVolModif = Gsv\r
568   if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
569   //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
570 \r
571   // 2) set fSensVolModif = Gg-1 * Gsv\r
572   fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
573   //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
574  \r
575   // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r
576   fSensVolModifMatrix->MultiplyLeft( &dg );\r
577   //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
578   \r
579   // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r
580   fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
581   //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r
582 \r
583   // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv\r
584   // qui usa l'orig anziche' la prealigned...\r
585   if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;\r
586   fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r
587   //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r
588 \r
589   // reset align object (may not be needed...)\r
590   fgTempAlignObj.SetVolUID(0);\r
591   fgTempAlignObj.SetSymName("");\r
592   fgTempAlignObj.SetTranslation(0,0,0);\r
593   fgTempAlignObj.SetRotation(0,0,0);\r
594 \r
595 #ifdef CORHW_\r
596   // correction for SPD y-shift\r
597   if (voluid>=2048 && voluid<4256) {\r
598     TGeoHMatrix deltay;\r
599     double dy[3]={0.,0.0081,0.};\r
600     deltay.SetTranslation(dy);\r
601     fSensVolModifMatrix->MultiplyLeft( &deltay );\r
602     fSensVolModifMatrix->Multiply( &deltay.Inverse() );\r
603   }\r
604 #endif\r
605   if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
606   fgTempAlignObj.SetVolUID(voluid);\r
607   fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
608 \r
609   \r
610   //fgTempAlignObj.Print("");\r
611 \r
612   return &fgTempAlignObj;\r
613 }\r
614 //-------------------------------------------------------------\r
615 \r
616 //-------------------------------------------------------------\r
617 AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, Double_t *deltalocal)\r
618 {\r
619   // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
620   // of the mother volume. The misalignment is returned as AliAlignObjParams object\r
621 \r
622   if (!IsIn(voluid)) return NULL;\r
623   if (!gGeoManager) return NULL;\r
624   \r
625   // prepare the TGeoHMatrix\r
626   Double_t tr[3],ang[3];\r
627   tr[0]=deltalocal[0]; // in centimeter\r
628   tr[1]=deltalocal[1]; \r
629   tr[2]=deltalocal[2];\r
630   ang[0]=deltalocal[3]; // psi   (X)  in deg\r
631   ang[1]=deltalocal[4]; // theta (Y)\r
632   ang[2]=deltalocal[5]; // phi   (Z)\r
633 \r
634   // reset align object (may not be needed...)\r
635   fgTempAlignObj.SetTranslation(0,0,0);\r
636   fgTempAlignObj.SetRotation(0,0,0);\r
637 \r
638   fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
639   fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
640   AliDebug(3,Form("Delta angles: psi=%f  theta=%f   phi=%f",ang[0],ang[1],ang[2]));\r
641 \r
642   // Gsv = Gg * Gg-1 * Gsv   -> Lsv,g = Gg-1 * Gsv\r
643   // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv \r
644   //\r
645   // => DGsv = (Gg * Dg * Gg-1)\r
646   //\r
647 \r
648   // prepare the Delta matrix Dg\r
649   TGeoHMatrix dg;\r
650   fgTempAlignObj.GetMatrix(dg);\r
651   //dg.Print();\r
652 \r
653   dg.MultiplyLeft( fMatrix );\r
654   dg.Multiply( &fMatrix->Inverse() );\r
655 \r
656   // reset align object (may not be needed...)\r
657   fgTempAlignObj.SetTranslation(0,0,0);\r
658   fgTempAlignObj.SetRotation(0,0,0);\r
659 \r
660   fgTempAlignObj.SetVolUID(voluid);\r
661   fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
662 \r
663   if (!fgTempAlignObj.SetMatrix(dg)) return NULL;\r
664   \r
665   //fgTempAlignObj.Print("");\r
666 \r
667   return &fgTempAlignObj;\r
668 }\r
669 // << RS\r
670 \r
671 //-------------------------------------------------------------\r
672 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)\r
673 {\r
674   // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry\r
675   if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;\r
676   return fSensVolMatrix;\r
677 }\r
678 \r
679 //-------------------------------------------------------------\r
680 TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)\r
681 {\r
682   // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())\r
683   if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;\r
684   return fSensVolMatrix;\r
685 }\r
686 //-------------------------------------------------------------\r
687 Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m) \r
688 {\r
689   // set matrix for sensitive modules (SPD corrected)\r
690   // return 0 if success\r
691   Double_t rot[9];\r
692   Int_t idx=GetIndexFromVolumeID(volid);\r
693   if (idx<0) return -1;\r
694   if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;\r
695   m->SetRotation(rot);\r
696   Double_t oLoc[3]={0,0,0};\r
697   Double_t oGlo[3]={0,0,0};\r
698   if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;\r
699   m->SetTranslation(oGlo);\r
700   return 0;\r
701 }\r
702 \r
703 //-------------------------------------------------------------\r
704 Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m) \r
705 {\r
706   // set original global matrix for sensitive modules (SPD corrected)\r
707   // return 0 if success\r
708   Int_t idx=GetIndexFromVolumeID(volid);\r
709   if (idx<0) return -1;\r
710   TGeoHMatrix mo;\r
711   if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;\r
712   (*m)=mo;\r
713   //\r
714 #ifdef CORHW_\r
715   // SPD y-shift by 81 mu\r
716   if (volid<5000) { \r
717     Double_t oLoc[3]={0.0,0.0081,0.0};\r
718     Double_t oGlo[3]={0,0,0};\r
719     m->LocalToMaster(oLoc,oGlo);\r
720     m->SetTranslation(oGlo);\r
721   }\r
722 #endif\r
723   return 0;\r
724 }\r
725 \r
726 //-------------------------------------------------------------\r
727 UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {\r
728   /// volume ID from symname\r
729   if (!symname) return 0;\r
730 \r
731   for (UShort_t voluid=2000; voluid<13300; voluid++) {\r
732     Int_t modId;\r
733     AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);\r
734     if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {\r
735       if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;\r
736     }\r
737   }\r
738 \r
739   return 0;\r
740 }\r
741 \r
742 //-------------------------------------------------------------\r
743 UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {\r
744   /// volume ID from index\r
745   if (index<0 || index>2197) return 0;\r
746   return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));\r
747 }\r
748 \r
749 //-------------------------------------------------------------\r
750 void AliITSAlignMille2Module::Print(Option_t*) const \r
751 {\r
752   //\r
753   const char* typeName[] = {"SPD","SDD","SSD"};\r
754   printf("*** ITS SuperModule for AliITSAlignMille ***\n");\r
755   printf("symname  : %s (type: %s)\n",GetName(),fDetType<0 ? "N/A":typeName[fDetType]);\r
756   printf("parent   : %s | %d children\n",fParent ? fParent->GetName() : "N/A",GetNChildren());\r
757   printf("volumeID : %4d  | index : %4d | Geom.Params are %s\n",fVolumeID,fIndex,\r
758          GeomParamsGlobal() ? "Global":"Local");\r
759   printf("Factors  : X=%.2f Y=%.2f Z=%.2f\n"\r
760          "DOF: %cTx:%5d| %cTy:%5d| %cTz:%5d| %cPsi:%5d| %cTheta:%5d| %cPhi:%5d|",\r
761          fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],\r
762          IsFreeDOF(kDOFTX) ? '+':'-',GetParOffset(kDOFTX),IsFreeDOF(kDOFTY) ? '+':'-',GetParOffset(kDOFTY),\r
763          IsFreeDOF(kDOFTZ) ? '+':'-',GetParOffset(kDOFTZ),IsFreeDOF(kDOFPS) ? '+':'-',GetParOffset(kDOFPS),\r
764          IsFreeDOF(kDOFTH) ? '+':'-',GetParOffset(kDOFTH),IsFreeDOF(kDOFPH) ? '+':'-',GetParOffset(kDOFPH));\r
765   if (IsSDD()) {\r
766     printf("%cT0:%5d| %cDVl:%5d| %cDVr:%5d|",IsFreeDOF(kDOFT0)?'+':'-',GetParOffset(kDOFT0),\r
767            IsFreeDOF(kDOFDVL)?'+':'-',GetParOffset(kDOFDVL),IsFreeDOF(kDOFDVR)?'+':'-',GetParOffset(kDOFDVR));\r
768     if (IsVDriftLRSame()) printf("(dVL=dVR)");\r
769   }\r
770   printf("\n");\r
771   fMatrix->Print();\r
772   printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);\r
773   for (Int_t i=0; i<fNSensVol; i++) printf("   voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));\r
774 }\r
775 \r
776 //-------------------------------------------------------------\r
777 Bool_t AliITSAlignMille2Module::IsAlignable() const\r
778 {\r
779   TGeoManager* geoManager = AliGeomManager::GetGeometry();\r
780   if (!geoManager) {\r
781     AliInfo("Couldn't initialize geometry");\r
782     return kFALSE;\r
783   }\r
784   return geoManager->GetAlignableEntry(GetName())!=0;\r
785 }\r
786 \r
787 //-------------------------------------------------------------\r
788 void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const\r
789 {\r
790   // return the local matrix for transformation to its parent\r
791   mat = *fMatrix;\r
792   if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );\r
793 }\r
794 \r
795 //-------------------------------------------------------------\r
796 void AliITSAlignMille2Module::AssignDetType()\r
797 {\r
798   TString tp = GetName();\r
799   if      (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;\r
800   else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;\r
801   else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;\r
802   else fDetType = -1;\r
803   fNParTot = IsSDD() ? kMaxParTot:kMaxParGeom;\r
804   fNParFree = 0;\r
805   fParVals = new Float_t[fNParTot];\r
806   fParErrs = new Float_t[fNParTot];  \r
807   fParCstr = new Float_t[fNParTot];  \r
808   if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);\r
809   for (int i=fNParTot;i--;) {\r
810     fParVals[i] = fParErrs[i] = 0.; \r
811     fParCstr[i] = 0.;\r
812     fParOffs[i] = -1;\r
813   }\r
814 }\r
815 \r
816 //-------------------------------------------------------------\r
817 void AliITSAlignMille2Module::EvaluateDOF()\r
818 {\r
819   fNParFree = 0;\r
820   for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;\r
821 }\r
822 \r
823 //-------------------------------------------------------------\r
824 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)\r
825 {\r
826   // return global parameters of the sensor volid\r
827   for (int i=3;i--;) t[i] = r[i] = 0.;\r
828   if (SensVolMatrix(volid,fSensVolMatrix)) return;  \r
829   fgTempAlignObj.SetMatrix(*fSensVolMatrix);\r
830   fgTempAlignObj.GetPars(t,r);\r
831 }\r
832 \r
833 //-------------------------------------------------------------\r
834 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)\r
835 {\r
836   // return parameters of the sensor volid in the current module\r
837   for (int i=3;i--;) t[i] = r[i] = 0.;\r
838   if (SensVolMatrix(volid,fSensVolMatrix)) return;  \r
839   fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
840   fgTempAlignObj.SetMatrix(*fSensVolMatrix);\r
841   fgTempAlignObj.GetPars(t,r);\r
842 }\r
843 \r
844 //-------------------------------------------------------------\r
845 void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)\r
846 {\r
847   // return global parameters of the sensor volid modified by the localDelta params\r
848   for (int i=3;i--;) t[i] = r[i] = 0.;\r
849   if (SensVolMatrix(volid,fSensVolMatrix)) return;  \r
850   fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
851   fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
852   //\r
853   fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);      // obtain local delta\r
854   fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
855   fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
856   fgTempAlignObj.GetPars(t,r);                         // obtain global params\r
857 }\r
858 \r
859 //-------------------------------------------------------------\r
860 void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)\r
861 {\r
862   // return parameters of the sensor volid (modified by the localDelta params) in the current volume\r
863   for (int i=3;i--;) t[i] = r[i] = 0.;\r
864   if (SensVolMatrix(volid,fSensVolMatrix)) return;  \r
865   fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
866   fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
867   //\r
868   fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);      // obtain local delta\r
869   fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
870   fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume\r
871   fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
872   fgTempAlignObj.GetPars(t,r);                         // obtain params\r
873 }\r
874 \r
875 //-------------------------------------------------------------\r
876 void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)\r
877 {\r
878   for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];\r
879 }\r
880 \r
881 //-------------------------------------------------------------\r
882 void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)\r
883 {\r
884   // recompute parameters from local to global frame\r
885   //\r
886   // is there anything to do?\r
887   if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}\r
888   //\r
889   // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)\r
890   // as for the current module. Since in the mp2 the modules are stored from parents to children,\r
891   // it is safe to call this method in loop staring from the lowest level child, i.e. from the end\r
892   // of the modules array.\r
893   //\r
894   // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1 \r
895   //\r
896   *fSensVolMatrix = *fMatrix;   // current global matrix\r
897   AliITSAlignMille2Module* parent = GetParent();\r
898   while (parent) {\r
899     if (parent->GeomParamsGlobal()) {\r
900       AliError("Cannot convert params to Global when the parents are already Global\n");\r
901       for (int i=kMaxParGeom;i--;) pars[i] = 0;\r
902       return;\r
903     }\r
904     fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix\r
905     Float_t *parpar = parent->GetParVals();\r
906     fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);\r
907     fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);\r
908     fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);\r
909     fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);\r
910     fSensVolMatrix->MultiplyLeft(parent->GetMatrix());  // global matrix after parents modifications\r
911     parent = parent->GetParent();\r
912   }\r
913   //\r
914   fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);\r
915   fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);\r
916   fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);  // local delta matrix\r
917   fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );\r
918   fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );\r
919   fgTempAlignObj.SetMatrix( *fSensVolModifMatrix );  // global delta matrix\r
920   fgTempAlignObj.GetPars(pars,pars+3);\r
921   //\r
922 }\r
923 \r
924 //-------------------------------------------------------------\r
925 void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)\r
926 {\r
927   // recompute parameters from global to local frame\r
928   //\r
929   // is there anything to do?\r
930   if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}\r
931   //\r
932   // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)\r
933   // as for the current module. Since in the mp2 the modules are stored from parents to children,\r
934   // it is safe to call this method in loop staring from the lowest level child, i.e. from the end\r
935   // of the modules array.\r
936   //\r
937   //  DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)\r
938   //\r
939   AliITSAlignMille2Module* parent = GetParent();\r
940   fgTempAlignObj.SetTranslation(0.,0.,0.);\r
941   fgTempAlignObj.SetRotation(0.,0.,0.);\r
942   fgTempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix\r
943   //\r
944   while (parent) { // accumulate the product of parents global modifications\r
945     if (!parent->GeomParamsGlobal()) {\r
946       AliError("Cannot convert params to Local when the parents are already Local\n");\r
947       for (int i=kMaxParGeom;i--;) pars[i] = 0;\r
948       return;\r
949     }\r
950     Float_t *parpar = parent->GetParVals();\r
951     fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);\r
952     fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);\r
953     fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);\r
954     fSensVolMatrix->Multiply(fSensVolModifMatrix); \r
955     parent = parent->GetParent();\r
956   }\r
957   // global matrix after parents modifications\r
958   fSensVolMatrix->Multiply(fMatrix);\r
959   //\r
960   fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);\r
961   fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);\r
962   fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);  // global delta matrix\r
963   fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );\r
964   fSensVolModifMatrix->Multiply( fSensVolMatrix );\r
965   fgTempAlignObj.SetMatrix( *fSensVolModifMatrix );  // local delta matrix\r
966   fgTempAlignObj.GetPars(pars,pars+3);\r
967   //\r
968 }\r
969 \r
970 \r
971 //-------------------------------------------------------------\r
972 void AliITSAlignMille2Module::CalcDerivDPosDPar(Int_t sensVol,const Double_t* pl, Double_t *deriv)\r
973 {\r
974   // calculate jacobian of the global position vs Parameters (dPos/dParam) \r
975   // for the point in the sensor sensVol\r
976   const double kDel = 0.01;\r
977   double pos0[3],pos1[3],pos2[3],pos3[3];\r
978   double delta[kMaxParGeom];\r
979   //\r
980   for (int ip=kMaxParGeom;ip--;) delta[ip] = 0;\r
981   //\r
982   for (int ip=kMaxParGeom;ip--;) {\r
983     //\r
984     delta[ip] -= kDel;\r
985     GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos0);    \r
986     delta[ip] += kDel/2;\r
987     GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos1);    \r
988     delta[ip] += kDel;\r
989     GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos2);    \r
990     delta[ip] += kDel/2;\r
991     GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos3);    \r
992     //\r
993     delta[ip] = 0;\r
994     double *curd = deriv + ip*3;\r
995     for (int i=3;i--;) curd[i] = (8.*(pos2[i]-pos1[i]) - (pos3[i]-pos0[i]))/6./kDel;\r
996   }\r
997   //\r
998 }\r
999 \r
1000 //-------------------------------------------------------------\r
1001 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)\r
1002 {\r
1003   // calculate derivative of global params vs local param idx:  deriv[j] = dParGlo[j]/dParLoc[idx]\r
1004   Double_t lpar[kMaxParGeom];\r
1005   for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
1006   //  using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1007   Double_t par1[kMaxParGeom]; // f(x-h)\r
1008   Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1009   Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1010   Double_t par4[kMaxParGeom]; // f(x+h)\r
1011   //\r
1012   const Double_t dpar = 1e-3;\r
1013   //\r
1014   // first values\r
1015   lpar[idx] -= dpar;\r
1016   GetGlobalParams(lpar,lpar+3, par1,par1+3);\r
1017   //\r
1018   // second values\r
1019   lpar[idx] += dpar/2;\r
1020   GetGlobalParams(lpar,lpar+3, par2,par2+3);\r
1021   //\r
1022   // third values\r
1023   lpar[idx] += dpar;\r
1024   GetGlobalParams(lpar,lpar+3, par3,par3+3);\r
1025   //\r
1026   // fourth values\r
1027   lpar[idx] += dpar/2;\r
1028   GetGlobalParams(lpar,lpar+3, par4,par4+3);\r
1029   //\r
1030   Double_t h2 = 1./(2.*dpar);\r
1031   for (int i=kMaxParGeom;i--;) {\r
1032     Double_t d0 = par4[i]-par1[i];\r
1033     Double_t d2 = 2.*(par3[i]-par2[i]);\r
1034     deriv[i] = h2*(4*d2 - d0)/3.;\r
1035     if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;\r
1036   }\r
1037   //\r
1038 }\r
1039 \r
1040 //-------------------------------------------------------------\r
1041 void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)\r
1042 {\r
1043   // calculate derivative of local params vs global params:  deriv[i][j] = dParLoc[i]/dParGlo[j]\r
1044   Double_t gpar[kMaxParGeom];\r
1045   for (int i=kMaxParGeom;i--;) gpar[i] = 0.;\r
1046   //  using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1047   Double_t par1[kMaxParGeom]; // f(x-h)\r
1048   Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1049   Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1050   Double_t par4[kMaxParGeom]; // f(x+h)\r
1051   //\r
1052   const Double_t dpar = 1e-3;\r
1053   //\r
1054   for (int ig=kMaxParGeom;ig--;) {\r
1055     // first values\r
1056     gpar[ig] -= dpar;\r
1057     GetLocalParams(gpar,gpar+3, par1,par1+3);\r
1058     //\r
1059     // second values\r
1060     gpar[ig] += dpar/2;\r
1061     GetLocalParams(gpar,gpar+3, par2,par2+3);\r
1062     //\r
1063     // third values\r
1064     gpar[ig] += dpar;\r
1065     GetLocalParams(gpar,gpar+3, par3,par3+3);\r
1066     //\r
1067     // fourth values\r
1068     gpar[ig] += dpar/2;\r
1069     GetLocalParams(gpar,gpar+3, par4,par4+3);\r
1070     //\r
1071     Double_t h2 = 1./(2.*dpar);\r
1072     for (int i=kMaxParGeom;i--;) {\r
1073       Double_t d0 = par4[i]-par1[i];\r
1074       Double_t d2 = 2.*(par3[i]-par2[i]);\r
1075       int idig = i*kMaxParGeom + ig;\r
1076       deriv[idig] = h2*(4*d2 - d0)/3.;\r
1077       if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;\r
1078     }\r
1079   }\r
1080   //\r
1081 }\r
1082 \r
1083 //________________________________________________________________________________________________________\r
1084 void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)\r
1085 {\r
1086   /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx\r
1087   //\r
1088   Double_t lpar[kMaxParGeom];\r
1089   for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
1090   //  using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1091   Double_t par1[kMaxParGeom]; // f(x-h)\r
1092   Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1093   Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1094   Double_t par4[kMaxParGeom]; // f(x+h)\r
1095   //\r
1096   const Double_t dpar = 1e-3;\r
1097   //\r
1098   // first values\r
1099   lpar[paridx] -= dpar;\r
1100   GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);\r
1101   //\r
1102   // second values\r
1103   lpar[paridx] += dpar/2;\r
1104   GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);\r
1105   //\r
1106   // third values\r
1107   lpar[paridx] += dpar;\r
1108   GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);\r
1109   //\r
1110   // fourth values\r
1111   lpar[paridx] += dpar/2;\r
1112   GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);\r
1113   //\r
1114   Double_t h2 = 1./(2.*dpar);\r
1115   for (int i=kMaxParGeom;i--;) {\r
1116     Double_t d0 = par4[i]-par1[i];\r
1117     Double_t d2 = 2.*(par3[i]-par2[i]);\r
1118     derivative[i] = h2*(4*d2 - d0)/3.;\r
1119     if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;\r
1120   }\r
1121   //\r
1122 }\r
1123 \r
1124 //________________________________________________________________________________________________________\r
1125 void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)  \r
1126 {\r
1127   /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx\r
1128   //\r
1129   Double_t lpar[kMaxParGeom];\r
1130   for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
1131   //  using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1132   Double_t par1[kMaxParGeom]; // f(x-h)\r
1133   Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1134   Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1135   Double_t par4[kMaxParGeom]; // f(x+h)\r
1136   //\r
1137   const Double_t dpar = 1e-3;\r
1138   //\r
1139   // first values\r
1140   lpar[paridx] -= dpar;\r
1141   GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);\r
1142   //\r
1143   // second values\r
1144   lpar[paridx] += dpar/2;\r
1145   GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);\r
1146   //\r
1147   // third values\r
1148   lpar[paridx] += dpar;\r
1149   GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);\r
1150   //\r
1151   // fourth values\r
1152   lpar[paridx] += dpar/2;\r
1153   GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);\r
1154   //\r
1155   Double_t h2 = 1./(2.*dpar);\r
1156   for (int i=kMaxParGeom;i--;) {\r
1157     Double_t d0 = par4[i]-par1[i];\r
1158     Double_t d2 = 2.*(par3[i]-par2[i]);\r
1159     derivative[i] = h2*(4*d2 - d0)/3.;\r
1160     if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;\r
1161   }\r
1162   //\r
1163 }\r
1164 \r
1165 \r
1166 //-------------------------------------------------------------\r
1167 void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r)\r
1168 {\r
1169   // global parameters of the module\r
1170   fgTempAlignObj.SetMatrix( *fMatrix );\r
1171   fgTempAlignObj.GetPars(t,r);\r
1172 }\r
1173 \r
1174 //-------------------------------------------------------------\r
1175 void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)\r
1176 {\r
1177   // global parameters of the module after the modification by local loct,locr\r
1178   fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
1179   fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
1180   fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);  \r
1181   *fSensVolMatrix = *fMatrix;\r
1182   fSensVolMatrix->Multiply(fSensVolModifMatrix);\r
1183   fgTempAlignObj.SetMatrix(*fSensVolMatrix);\r
1184   fgTempAlignObj.GetPars(t,r);\r
1185 }\r
1186 \r
1187 //-------------------------------------------------------------\r
1188 void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)\r
1189 {\r
1190   // obtain local delta parameters from global delta params\r
1191   fgTempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);\r
1192   fgTempAlignObj.SetRotation(glor[0],glor[1],glor[2]);\r
1193   fgTempAlignObj.GetMatrix(*fSensVolMatrix);  \r
1194   fSensVolMatrix->Multiply( fMatrix );\r
1195   fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
1196   fgTempAlignObj.SetMatrix(*fSensVolMatrix);\r
1197   fgTempAlignObj.GetPars(t,r);\r
1198 }\r