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