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