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