]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - ITS/AliITSAlignMille2Module.cxx
deleting duplicate files
[u/mrichter/AliRoot.git] / ITS / AliITSAlignMille2Module.cxx
... / ...
CommitLineData
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
45\r
46const Float_t AliITSAlignMille2Module::fgkDummyConstraint = 1e-2;//1.E3;\r
47 \r
48//-------------------------------------------------------------\r
49AliITSAlignMille2Module::AliITSAlignMille2Module() : \r
50 TNamed(), \r
51 fNSensVol(0), \r
52 fIndex(-1), \r
53 fDetType(-1),\r
54 fVolumeID(0),\r
55 fNParTot(0),\r
56 fNParFree(0),\r
57 fParOffs(0),\r
58 fNProcPoints(0),\r
59 fParVals(0),\r
60 fParErrs(0),\r
61 fParCstr(0),\r
62 fSensVolIndex(0),\r
63 fSensVolVolumeID(0),\r
64 fMatrix(NULL),\r
65 fSensVolMatrix(NULL),\r
66 fSensVolModifMatrix(NULL),\r
67 fParent(NULL),\r
68 fChildren(0)\r
69{ \r
70 /// void constructor \r
71 fMatrix = new TGeoHMatrix; \r
72 fSensVolMatrix = new TGeoHMatrix; \r
73 fSensVolModifMatrix = new TGeoHMatrix; \r
74 fSensVolIndex.Set(1);\r
75 fSensVolVolumeID.Set(1);\r
76 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
77} \r
78\r
79//-------------------------------------------------------------\r
80AliITSAlignMille2Module::AliITSAlignMille2Module(Int_t index, UShort_t volid, const char* symname,\r
81 const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) : \r
82 TNamed(), \r
83 fNSensVol(0), \r
84 fIndex(-1), \r
85 fDetType(-1), \r
86 fVolumeID(0),\r
87 fNParTot(0),\r
88 fNParFree(0),\r
89 fParOffs(kMaxParGeom),\r
90 fNProcPoints(0),\r
91 fParVals(0),\r
92 fParErrs(0),\r
93 fParCstr(0),\r
94 fSensVolIndex(0),\r
95 fSensVolVolumeID(0), \r
96 fMatrix(NULL),\r
97 fSensVolMatrix(NULL),\r
98 fSensVolModifMatrix(NULL),\r
99 fParent(NULL),\r
100 fChildren(0)\r
101{ \r
102 /// void constructor \r
103 fMatrix = new TGeoHMatrix; \r
104 fSensVolMatrix = new TGeoHMatrix; \r
105 fSensVolModifMatrix = new TGeoHMatrix; \r
106 fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r
107 for (int i=kMaxParGeom;i--;) fParOffs[i] = -1;\r
108 if (Set(index,volid,symname,m,nsv,volidsv)) {\r
109 AliInfo("Error in AliITSAlignMille2Module::Set() - initializing void supermodule...");\r
110 }\r
111 AssignDetType();\r
112} \r
113\r
114//-------------------------------------------------------------\r
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 this->TNamed::operator=(m);\r
208 //\r
209 fNSensVol=m.fNSensVol;\r
210 fIndex=m.fIndex;\r
211 fDetType = m.fDetType;\r
212 fVolumeID=m.fVolumeID;\r
213 fNParTot = m.fNParTot;\r
214 fNParFree = m.fNParFree; \r
215 fNProcPoints = m.fNProcPoints; \r
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
223 fParCstr = new Float_t[fNParTot];\r
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
233 for (int i=0;i<3;i++) fSigmaFactor[i] = m.fSigmaFactor[i];\r
234 if (fMatrix) delete fMatrix;\r
235 fMatrix=new TGeoHMatrix(*m.GetMatrix());\r
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
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
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
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
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
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
343 if (fSensVolVolumeID.GetSize()<fNSensVol+1) {\r
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
385TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, const Double_t *delta,Bool_t local)\r
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 static AliAlignObjParams tempAlignObj;\r
404 tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
405 tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
406 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
407 TGeoHMatrix hm;\r
408 tempAlignObj.GetMatrix(hm);\r
409 //printf("\n0: delta matrix\n");hm.Print();\r
410\r
411 // 1) start setting fSensVolModif = fSensVol\r
412 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
413 //\r
414 if (local) {\r
415 // 2) set fSensVolModif = SensVolRel\r
416 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
417 // 3) multiply left by delta\r
418 fSensVolModifMatrix->MultiplyLeft( &hm );\r
419 // 4) multiply left by fMatrix\r
420 fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
421 }\r
422 else fSensVolModifMatrix->MultiplyLeft( &hm );\r
423 //\r
424 return fSensVolModifMatrix;\r
425}\r
426\r
427//-------------------------------------------------------------\r
428AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const Double_t *deltalocal)\r
429{\r
430 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
431 // of the mother volume. The misalignment is returned as AliAlignObjParams object\r
432\r
433 if (!IsIn(voluid)) return NULL;\r
434 if (!gGeoManager) return NULL;\r
435 \r
436 // prepare the TGeoHMatrix\r
437 Double_t tr[3],ang[3];\r
438 tr[0]=deltalocal[0]; // in centimeter\r
439 tr[1]=deltalocal[1]; \r
440 tr[2]=deltalocal[2];\r
441 ang[0]=deltalocal[3]; // psi (X) in deg\r
442 ang[1]=deltalocal[4]; // theta (Y)\r
443 ang[2]=deltalocal[5]; // phi (Z)\r
444 //\r
445 static AliAlignObjParams tempAlignObj;\r
446 tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
447 tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
448 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
449 //\r
450 return GetSensitiveVolumeMisalignment(voluid,&tempAlignObj);\r
451}\r
452\r
453//-------------------------------------------------------------\r
454AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const AliAlignObjParams *a)\r
455{\r
456 // return the misalignment of the sens. vol. 'voluid' corresponding with \r
457 // a misalignment 'a' in the mother volume\r
458 // return NULL if error\r
459\r
460 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r
461 // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv\r
462 // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
463 //\r
464 // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)\r
465 //\r
466\r
467 if (!IsIn(voluid)) return NULL;\r
468 if (!gGeoManager) return NULL;\r
469\r
470 //a->Print("");\r
471\r
472 // prepare the Delta matrix Dg\r
473 TGeoHMatrix dg;\r
474 a->GetMatrix(dg);\r
475 //dg.Print();\r
476\r
477 // 1) start setting fSensVolModif = Gsv\r
478 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
479 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
480\r
481 // 2) set fSensVolModif = Gg-1 * Gsv\r
482 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
483 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
484 \r
485 // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r
486 fSensVolModifMatrix->MultiplyLeft( &dg );\r
487 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
488 \r
489 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r
490 fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
491 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r
492\r
493 // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv\r
494 if (SensVolMatrix(voluid, &dg)) return NULL;\r
495 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r
496 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r
497 //\r
498 // >> RS\r
499 // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)\r
500 // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:\r
501 // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1\r
502 //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv\r
503 //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;\r
504 //if (SensVolMatrix(voluid, &dpre)) return NULL;\r
505 //dpre.MultiplyLeft( &dg.Inverse() );\r
506 //fSensVolModifMatrix->Multiply( &dpre.Inverse() );\r
507 //fSensVolModifMatrix->MultiplyLeft( &dpre );\r
508 // direi che NON FUNZIONA!!!! \r
509\r
510 // << RS\r
511\r
512 // reset align object (may not be needed...)\r
513 static AliAlignObjParams tempAlignObj;\r
514 tempAlignObj.SetVolUID(0);\r
515 tempAlignObj.SetSymName("");\r
516 tempAlignObj.SetTranslation(0,0,0);\r
517 tempAlignObj.SetRotation(0,0,0);\r
518 //\r
519 // >> RS\r
520#ifdef CORHW_\r
521 // correction for SPD y-shift\r
522 if (voluid>=2048 && voluid<4256) {\r
523 TGeoHMatrix deltay;\r
524 double dy[3]={0.,0.0081,0.};\r
525 deltay.SetTranslation(dy);\r
526 fSensVolModifMatrix->MultiplyLeft( &deltay );\r
527 fSensVolModifMatrix->Multiply( &deltay.Inverse() );\r
528 }\r
529#endif\r
530 // << RS\r
531 if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
532 tempAlignObj.SetVolUID(voluid);\r
533 tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
534 //\r
535 return &tempAlignObj;\r
536}\r
537\r
538// >> RS\r
539//-------------------------------------------------------------\r
540AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, const Double_t *deltalocal)\r
541{\r
542 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
543 // of the mother volume. The misalignment is returned as AliAlignObjParams object including\r
544 // the (evenctual) prealignment => no merging needed\r
545\r
546 if (!IsIn(voluid)) return NULL;\r
547 if (!gGeoManager) return NULL;\r
548 \r
549 // prepare the TGeoHMatrix\r
550 Double_t tr[3],ang[3];\r
551 tr[0]=deltalocal[0]; // in centimeter\r
552 tr[1]=deltalocal[1]; \r
553 tr[2]=deltalocal[2];\r
554 ang[0]=deltalocal[3]; // psi (X) in deg\r
555 ang[1]=deltalocal[4]; // theta (Y)\r
556 ang[2]=deltalocal[5]; // phi (Z)\r
557\r
558 // reset align object (may not be needed...)\r
559 static AliAlignObjParams tempAlignObj;\r
560 tempAlignObj.SetVolUID(0);\r
561 tempAlignObj.SetSymName("");\r
562 tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
563 tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
564 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
565\r
566 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r
567 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv \r
568 //\r
569 // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv) //\r
570 //\r
571\r
572 // prepare the Delta matrix Dg\r
573 TGeoHMatrix dg;\r
574 tempAlignObj.GetMatrix(dg);\r
575 //dg.Print();\r
576\r
577 // 1) start setting fSensVolModif = Gsv\r
578 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r
579 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r
580\r
581 // 2) set fSensVolModif = Gg-1 * Gsv\r
582 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
583 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r
584 \r
585 // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r
586 fSensVolModifMatrix->MultiplyLeft( &dg );\r
587 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r
588 \r
589 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r
590 fSensVolModifMatrix->MultiplyLeft( fMatrix );\r
591 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r
592\r
593 // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv\r
594 // qui usa l'orig anziche' la prealigned...\r
595 if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;\r
596 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r
597 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r
598\r
599 // reset align object (may not be needed...)\r
600 tempAlignObj.SetVolUID(0);\r
601 tempAlignObj.SetSymName("");\r
602 tempAlignObj.SetTranslation(0,0,0);\r
603 tempAlignObj.SetRotation(0,0,0);\r
604\r
605#ifdef CORHW_\r
606 // correction for SPD y-shift\r
607 if (voluid>=2048 && voluid<4256) {\r
608 TGeoHMatrix deltay;\r
609 double dy[3]={0.,0.0081,0.};\r
610 deltay.SetTranslation(dy);\r
611 fSensVolModifMatrix->MultiplyLeft( &deltay );\r
612 fSensVolModifMatrix->Multiply( &deltay.Inverse() );\r
613 }\r
614#endif\r
615 if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
616 tempAlignObj.SetVolUID(voluid);\r
617 tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
618\r
619 \r
620 //tempAlignObj.Print("");\r
621\r
622 return &tempAlignObj;\r
623}\r
624//-------------------------------------------------------------\r
625\r
626//-------------------------------------------------------------\r
627AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, const Double_t *deltalocal)\r
628{\r
629 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r
630 // of the mother volume. The misalignment is returned as AliAlignObjParams object\r
631\r
632 if (!IsIn(voluid)) return NULL;\r
633 if (!gGeoManager) return NULL;\r
634 \r
635 // prepare the TGeoHMatrix\r
636 Double_t tr[3],ang[3];\r
637 tr[0]=deltalocal[0]; // in centimeter\r
638 tr[1]=deltalocal[1]; \r
639 tr[2]=deltalocal[2];\r
640 ang[0]=deltalocal[3]; // psi (X) in deg\r
641 ang[1]=deltalocal[4]; // theta (Y)\r
642 ang[2]=deltalocal[5]; // phi (Z)\r
643\r
644 // reset align object (may not be needed...)\r
645 static AliAlignObjParams tempAlignObj;\r
646 tempAlignObj.SetTranslation(0,0,0);\r
647 tempAlignObj.SetRotation(0,0,0);\r
648\r
649 tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
650 tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
651 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
652\r
653 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r
654 // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv \r
655 //\r
656 // => DGsv = (Gg * Dg * Gg-1)\r
657 //\r
658\r
659 // prepare the Delta matrix Dg\r
660 TGeoHMatrix dg;\r
661 tempAlignObj.GetMatrix(dg);\r
662 //dg.Print();\r
663\r
664 dg.MultiplyLeft( fMatrix );\r
665 dg.Multiply( &fMatrix->Inverse() );\r
666\r
667 // reset align object (may not be needed...)\r
668 tempAlignObj.SetTranslation(0,0,0);\r
669 tempAlignObj.SetRotation(0,0,0);\r
670\r
671 tempAlignObj.SetVolUID(voluid);\r
672 tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
673\r
674 if (!tempAlignObj.SetMatrix(dg)) return NULL;\r
675 \r
676 //tempAlignObj.Print("");\r
677\r
678 return &tempAlignObj;\r
679}\r
680// << RS\r
681\r
682//-------------------------------------------------------------\r
683TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)\r
684{\r
685 // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry\r
686 if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;\r
687 return fSensVolMatrix;\r
688}\r
689\r
690//-------------------------------------------------------------\r
691TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)\r
692{\r
693 // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())\r
694 if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;\r
695 return fSensVolMatrix;\r
696}\r
697//-------------------------------------------------------------\r
698Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m) \r
699{\r
700 // set matrix for sensitive modules (SPD corrected)\r
701 // return 0 if success\r
702 Double_t rot[9];\r
703 Int_t idx=GetIndexFromVolumeID(volid);\r
704 if (idx<0) return -1;\r
705 if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;\r
706 m->SetRotation(rot);\r
707 Double_t oLoc[3]={0,0,0};\r
708 Double_t oGlo[3]={0,0,0};\r
709 if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;\r
710 m->SetTranslation(oGlo);\r
711 return 0;\r
712}\r
713\r
714//-------------------------------------------------------------\r
715Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m) \r
716{\r
717 // set original global matrix for sensitive modules (SPD corrected)\r
718 // return 0 if success\r
719 Int_t idx=GetIndexFromVolumeID(volid);\r
720 if (idx<0) return -1;\r
721 TGeoHMatrix mo;\r
722 if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo)) return -1;\r
723 (*m)=mo;\r
724 //\r
725#ifdef CORHW_\r
726 // SPD y-shift by 81 mu\r
727 if (volid<5000) { \r
728 Double_t oLoc[3]={0.0,0.0081,0.0};\r
729 Double_t oGlo[3]={0,0,0};\r
730 m->LocalToMaster(oLoc,oGlo);\r
731 m->SetTranslation(oGlo);\r
732 }\r
733#endif\r
734 return 0;\r
735}\r
736\r
737//-------------------------------------------------------------\r
738UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {\r
739 /// volume ID from symname\r
740 if (!symname) return 0;\r
741\r
742 for (UShort_t voluid=2000; voluid<13300; voluid++) {\r
743 Int_t modId;\r
744 AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);\r
745 if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {\r
746 if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;\r
747 }\r
748 }\r
749\r
750 return 0;\r
751}\r
752\r
753//-------------------------------------------------------------\r
754UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {\r
755 /// volume ID from index\r
756 if (index<0 || index>2197) return 0;\r
757 return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));\r
758}\r
759\r
760//-------------------------------------------------------------\r
761void AliITSAlignMille2Module::Print(Option_t*) const \r
762{\r
763 // print data\r
764 //\r
765 const char* typeName[] = {"SPD","SDD","SSD"};\r
766 printf("*** ITS SuperModule for AliITSAlignMille ***\n");\r
767 printf("symname : %s (type: %s)\n",GetName(),fDetType<0 ? "N/A":typeName[fDetType]);\r
768 printf("parent : %s | %d children\n",fParent ? fParent->GetName() : "N/A",GetNChildren());\r
769 printf("volumeID : %4d | index : %4d | Geom.Params are %s\n",fVolumeID,fIndex,\r
770 GeomParamsGlobal() ? "Global":"Local");\r
771 printf("Factors : X=%.2f Y=%.2f Z=%.2f\n"\r
772 "DOF: %cTx:%5d| %cTy:%5d| %cTz:%5d| %cPsi:%5d| %cTheta:%5d| %cPhi:%5d|",\r
773 fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],\r
774 IsFreeDOF(kDOFTX) ? '+':'-',GetParOffset(kDOFTX),IsFreeDOF(kDOFTY) ? '+':'-',GetParOffset(kDOFTY),\r
775 IsFreeDOF(kDOFTZ) ? '+':'-',GetParOffset(kDOFTZ),IsFreeDOF(kDOFPS) ? '+':'-',GetParOffset(kDOFPS),\r
776 IsFreeDOF(kDOFTH) ? '+':'-',GetParOffset(kDOFTH),IsFreeDOF(kDOFPH) ? '+':'-',GetParOffset(kDOFPH));\r
777 if (IsSDD()) {\r
778 printf("%cT0:%5d| %cDVl:%5d| %cDVr:%5d|",IsFreeDOF(kDOFT0)?'+':'-',GetParOffset(kDOFT0),\r
779 IsFreeDOF(kDOFDVL)?'+':'-',GetParOffset(kDOFDVL),IsFreeDOF(kDOFDVR)?'+':'-',GetParOffset(kDOFDVR));\r
780 if (IsVDriftLRSame()) printf("(dVL=dVR)");\r
781 }\r
782 printf("\n");\r
783 fMatrix->Print();\r
784 printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);\r
785 for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));\r
786}\r
787\r
788//-------------------------------------------------------------\r
789Bool_t AliITSAlignMille2Module::IsAlignable() const\r
790{\r
791 // it it alignable?\r
792 TGeoManager* geoManager = AliGeomManager::GetGeometry();\r
793 if (!geoManager) {\r
794 AliInfo("Couldn't initialize geometry");\r
795 return kFALSE;\r
796 }\r
797 return geoManager->GetAlignableEntry(GetName())!=0;\r
798}\r
799\r
800//-------------------------------------------------------------\r
801void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const\r
802{\r
803 // return the local matrix for transformation to its parent\r
804 mat = *fMatrix;\r
805 if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );\r
806}\r
807\r
808//-------------------------------------------------------------\r
809void AliITSAlignMille2Module::AssignDetType()\r
810{\r
811 // assign the detector type\r
812 TString tp = GetName();\r
813 if (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;\r
814 else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;\r
815 else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;\r
816 else fDetType = -1;\r
817 fNParTot = IsSDD() ? kMaxParTot:kMaxParGeom;\r
818 fNParFree = 0;\r
819 fParVals = new Float_t[fNParTot];\r
820 fParErrs = new Float_t[fNParTot]; \r
821 fParCstr = new Float_t[fNParTot]; \r
822 if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);\r
823 for (int i=fNParTot;i--;) {\r
824 fParVals[i] = fParErrs[i] = 0.; \r
825 fParCstr[i] = 0.;\r
826 fParOffs[i] = -1;\r
827 }\r
828}\r
829\r
830//-------------------------------------------------------------\r
831void AliITSAlignMille2Module::EvaluateDOF()\r
832{\r
833 // count d.o.f.\r
834 fNParFree = 0;\r
835 for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;\r
836}\r
837\r
838//-------------------------------------------------------------\r
839void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)\r
840{\r
841 // return global parameters of the sensor volid\r
842 for (int i=3;i--;) t[i] = r[i] = 0.;\r
843 if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
844 AliAlignObjParams tempAlignObj;\r
845 tempAlignObj.SetMatrix(*fSensVolMatrix);\r
846 tempAlignObj.GetPars(t,r);\r
847}\r
848\r
849//-------------------------------------------------------------\r
850void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)\r
851{\r
852 // return parameters of the sensor volid in the current module\r
853 for (int i=3;i--;) t[i] = r[i] = 0.;\r
854 if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
855 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
856 AliAlignObjParams tempAlignObj; \r
857 tempAlignObj.SetMatrix(*fSensVolMatrix);\r
858 tempAlignObj.GetPars(t,r);\r
859}\r
860\r
861//-------------------------------------------------------------\r
862void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,const Double_t* loct, const Double_t* locr,Double_t *t, Double_t *r)\r
863{\r
864 // return global parameters of the sensor volid modified by the localDelta params\r
865 for (int i=3;i--;) t[i] = r[i] = 0.;\r
866 if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
867 AliAlignObjParams tempAlignObj;\r
868 tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
869 tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
870 //\r
871 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta\r
872 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
873 tempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
874 tempAlignObj.GetPars(t,r); // obtain global params\r
875}\r
876\r
877//-------------------------------------------------------------\r
878void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,const Double_t* loct,const Double_t* locr,Double_t *t, Double_t *r)\r
879{\r
880 // return parameters of the sensor volid (modified by the localDelta params) in the current volume\r
881 for (int i=3;i--;) t[i] = r[i] = 0.;\r
882 if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
883 AliAlignObjParams tempAlignObj;\r
884 tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
885 tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
886 //\r
887 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta\r
888 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
889 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume\r
890 tempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
891 tempAlignObj.GetPars(t,r); // obtain params\r
892}\r
893\r
894//-------------------------------------------------------------\r
895void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)\r
896{\r
897 // set parameters\r
898 for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];\r
899}\r
900\r
901//-------------------------------------------------------------\r
902void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)\r
903{\r
904 // recompute parameters from local to global frame\r
905 //\r
906 // is there anything to do?\r
907 if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}\r
908 //\r
909 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)\r
910 // as for the current module. Since in the mp2 the modules are stored from parents to children,\r
911 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end\r
912 // of the modules array.\r
913 //\r
914 // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1 \r
915 //\r
916 *fSensVolMatrix = *fMatrix; // current global matrix\r
917 AliAlignObjParams tempAlignObj;\r
918 AliITSAlignMille2Module* parent = GetParent();\r
919 while (parent) {\r
920 if (parent->GeomParamsGlobal()) {\r
921 AliError("Cannot convert params to Global when the parents are already Global\n");\r
922 for (int i=kMaxParGeom;i--;) pars[i] = 0;\r
923 return;\r
924 }\r
925 fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix\r
926 Float_t *parpar = parent->GetParVals();\r
927 tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);\r
928 tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);\r
929 tempAlignObj.GetMatrix(*fSensVolModifMatrix);\r
930 fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);\r
931 fSensVolMatrix->MultiplyLeft(parent->GetMatrix()); // global matrix after parents modifications\r
932 parent = parent->GetParent();\r
933 }\r
934 //\r
935 tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);\r
936 tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);\r
937 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // local delta matrix\r
938 fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );\r
939 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );\r
940 tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // global delta matrix\r
941 tempAlignObj.GetPars(pars,pars+3);\r
942 //\r
943}\r
944\r
945//-------------------------------------------------------------\r
946void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)\r
947{\r
948 // recompute parameters from global to local frame\r
949 //\r
950 // is there anything to do?\r
951 if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}\r
952 //\r
953 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)\r
954 // as for the current module. Since in the mp2 the modules are stored from parents to children,\r
955 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end\r
956 // of the modules array.\r
957 //\r
958 // DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)\r
959 //\r
960 AliITSAlignMille2Module* parent = GetParent();\r
961 AliAlignObjParams tempAlignObj;\r
962 tempAlignObj.SetTranslation(0.,0.,0.);\r
963 tempAlignObj.SetRotation(0.,0.,0.);\r
964 tempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix\r
965 //\r
966 while (parent) { // accumulate the product of parents global modifications\r
967 if (!parent->GeomParamsGlobal()) {\r
968 AliError("Cannot convert params to Local when the parents are already Local\n");\r
969 for (int i=kMaxParGeom;i--;) pars[i] = 0;\r
970 return;\r
971 }\r
972 Float_t *parpar = parent->GetParVals();\r
973 tempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);\r
974 tempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);\r
975 tempAlignObj.GetMatrix(*fSensVolModifMatrix);\r
976 fSensVolMatrix->Multiply(fSensVolModifMatrix); \r
977 parent = parent->GetParent();\r
978 }\r
979 // global matrix after parents modifications\r
980 fSensVolMatrix->Multiply(fMatrix);\r
981 //\r
982 tempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);\r
983 tempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);\r
984 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // global delta matrix\r
985 fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );\r
986 fSensVolModifMatrix->Multiply( fSensVolMatrix );\r
987 tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // local delta matrix\r
988 tempAlignObj.GetPars(pars,pars+3);\r
989 //\r
990}\r
991\r
992\r
993//-------------------------------------------------------------\r
994void AliITSAlignMille2Module::CalcDerivDPosDPar(Int_t sensVol,const Double_t* pl, Double_t *deriv)\r
995{\r
996 // calculate jacobian of the global position vs Parameters (dPos/dParam) \r
997 // for the point in the sensor sensVol\r
998 const double kDel = 0.01;\r
999 double pos0[3],pos1[3],pos2[3],pos3[3];\r
1000 double delta[kMaxParGeom];\r
1001 //\r
1002 for (int ip=kMaxParGeom;ip--;) delta[ip] = 0;\r
1003 //\r
1004 for (int ip=kMaxParGeom;ip--;) {\r
1005 //\r
1006 delta[ip] -= kDel;\r
1007 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos0); \r
1008 delta[ip] += kDel/2;\r
1009 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos1); \r
1010 delta[ip] += kDel;\r
1011 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos2); \r
1012 delta[ip] += kDel/2;\r
1013 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos3); \r
1014 //\r
1015 delta[ip] = 0;\r
1016 double *curd = deriv + ip*3;\r
1017 for (int i=3;i--;) curd[i] = (8.*(pos2[i]-pos1[i]) - (pos3[i]-pos0[i]))/6./kDel;\r
1018 }\r
1019 //\r
1020}\r
1021\r
1022//-------------------------------------------------------------\r
1023void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)\r
1024{\r
1025 // calculate derivative of global params vs local param idx: deriv[j] = dParGlo[j]/dParLoc[idx]\r
1026 Double_t lpar[kMaxParGeom];\r
1027 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
1028 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1029 Double_t par1[kMaxParGeom]; // f(x-h)\r
1030 Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1031 Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1032 Double_t par4[kMaxParGeom]; // f(x+h)\r
1033 //\r
1034 const Double_t dpar = 1e-3;\r
1035 //\r
1036 // first values\r
1037 lpar[idx] -= dpar;\r
1038 GetGlobalParams(lpar,lpar+3, par1,par1+3);\r
1039 //\r
1040 // second values\r
1041 lpar[idx] += dpar/2;\r
1042 GetGlobalParams(lpar,lpar+3, par2,par2+3);\r
1043 //\r
1044 // third values\r
1045 lpar[idx] += dpar;\r
1046 GetGlobalParams(lpar,lpar+3, par3,par3+3);\r
1047 //\r
1048 // fourth values\r
1049 lpar[idx] += dpar/2;\r
1050 GetGlobalParams(lpar,lpar+3, par4,par4+3);\r
1051 //\r
1052 Double_t h2 = 1./(2.*dpar);\r
1053 for (int i=kMaxParGeom;i--;) {\r
1054 Double_t d0 = par4[i]-par1[i];\r
1055 Double_t d2 = 2.*(par3[i]-par2[i]);\r
1056 deriv[i] = h2*(4*d2 - d0)/3.;\r
1057 if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;\r
1058 }\r
1059 //\r
1060}\r
1061\r
1062//-------------------------------------------------------------\r
1063void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)\r
1064{\r
1065 // calculate derivative of local params vs global params: deriv[i][j] = dParLoc[i]/dParGlo[j]\r
1066 Double_t gpar[kMaxParGeom];\r
1067 for (int i=kMaxParGeom;i--;) gpar[i] = 0.;\r
1068 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1069 Double_t par1[kMaxParGeom]; // f(x-h)\r
1070 Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1071 Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1072 Double_t par4[kMaxParGeom]; // f(x+h)\r
1073 //\r
1074 const Double_t dpar = 1e-3;\r
1075 //\r
1076 for (int ig=kMaxParGeom;ig--;) {\r
1077 // first values\r
1078 gpar[ig] -= dpar;\r
1079 GetLocalParams(gpar,gpar+3, par1,par1+3);\r
1080 //\r
1081 // second values\r
1082 gpar[ig] += dpar/2;\r
1083 GetLocalParams(gpar,gpar+3, par2,par2+3);\r
1084 //\r
1085 // third values\r
1086 gpar[ig] += dpar;\r
1087 GetLocalParams(gpar,gpar+3, par3,par3+3);\r
1088 //\r
1089 // fourth values\r
1090 gpar[ig] += dpar/2;\r
1091 GetLocalParams(gpar,gpar+3, par4,par4+3);\r
1092 //\r
1093 Double_t h2 = 1./(2.*dpar);\r
1094 for (int i=kMaxParGeom;i--;) {\r
1095 Double_t d0 = par4[i]-par1[i];\r
1096 Double_t d2 = 2.*(par3[i]-par2[i]);\r
1097 int idig = i*kMaxParGeom + ig;\r
1098 deriv[idig] = h2*(4*d2 - d0)/3.;\r
1099 if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;\r
1100 }\r
1101 }\r
1102 //\r
1103}\r
1104\r
1105//________________________________________________________________________________________________________\r
1106void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)\r
1107{\r
1108 /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx\r
1109 //\r
1110 Double_t lpar[kMaxParGeom];\r
1111 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
1112 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1113 Double_t par1[kMaxParGeom]; // f(x-h)\r
1114 Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1115 Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1116 Double_t par4[kMaxParGeom]; // f(x+h)\r
1117 //\r
1118 const Double_t dpar = 1e-3;\r
1119 //\r
1120 // first values\r
1121 lpar[paridx] -= dpar;\r
1122 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);\r
1123 //\r
1124 // second values\r
1125 lpar[paridx] += dpar/2;\r
1126 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);\r
1127 //\r
1128 // third values\r
1129 lpar[paridx] += dpar;\r
1130 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);\r
1131 //\r
1132 // fourth values\r
1133 lpar[paridx] += dpar/2;\r
1134 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);\r
1135 //\r
1136 Double_t h2 = 1./(2.*dpar);\r
1137 for (int i=kMaxParGeom;i--;) {\r
1138 Double_t d0 = par4[i]-par1[i];\r
1139 Double_t d2 = 2.*(par3[i]-par2[i]);\r
1140 derivative[i] = h2*(4*d2 - d0)/3.;\r
1141 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;\r
1142 }\r
1143 //\r
1144}\r
1145\r
1146//________________________________________________________________________________________________________\r
1147void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative) \r
1148{\r
1149 /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx\r
1150 //\r
1151 Double_t lpar[kMaxParGeom];\r
1152 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
1153 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1154 Double_t par1[kMaxParGeom]; // f(x-h)\r
1155 Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1156 Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1157 Double_t par4[kMaxParGeom]; // f(x+h)\r
1158 //\r
1159 const Double_t dpar = 1e-3;\r
1160 //\r
1161 // first values\r
1162 lpar[paridx] -= dpar;\r
1163 GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);\r
1164 //\r
1165 // second values\r
1166 lpar[paridx] += dpar/2;\r
1167 GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);\r
1168 //\r
1169 // third values\r
1170 lpar[paridx] += dpar;\r
1171 GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);\r
1172 //\r
1173 // fourth values\r
1174 lpar[paridx] += dpar/2;\r
1175 GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);\r
1176 //\r
1177 Double_t h2 = 1./(2.*dpar);\r
1178 for (int i=kMaxParGeom;i--;) {\r
1179 Double_t d0 = par4[i]-par1[i];\r
1180 Double_t d2 = 2.*(par3[i]-par2[i]);\r
1181 derivative[i] = h2*(4*d2 - d0)/3.;\r
1182 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;\r
1183 }\r
1184 //\r
1185}\r
1186\r
1187\r
1188//-------------------------------------------------------------\r
1189void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r) const\r
1190{\r
1191 // global parameters of the module\r
1192 AliAlignObjParams tempAlignObj;\r
1193 tempAlignObj.SetMatrix( *fMatrix );\r
1194 tempAlignObj.GetPars(t,r);\r
1195}\r
1196\r
1197//-------------------------------------------------------------\r
1198void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)\r
1199{\r
1200 // global parameters of the module after the modification by local loct,locr\r
1201 AliAlignObjParams tempAlignObj;\r
1202 tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
1203 tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
1204 tempAlignObj.GetMatrix(*fSensVolModifMatrix); \r
1205 *fSensVolMatrix = *fMatrix;\r
1206 fSensVolMatrix->Multiply(fSensVolModifMatrix);\r
1207 tempAlignObj.SetMatrix(*fSensVolMatrix);\r
1208 tempAlignObj.GetPars(t,r);\r
1209}\r
1210\r
1211//-------------------------------------------------------------\r
1212void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)\r
1213{\r
1214 // obtain local delta parameters from global delta params\r
1215 AliAlignObjParams tempAlignObj;\r
1216 tempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);\r
1217 tempAlignObj.SetRotation(glor[0],glor[1],glor[2]);\r
1218 tempAlignObj.GetMatrix(*fSensVolMatrix); \r
1219 fSensVolMatrix->Multiply( fMatrix );\r
1220 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
1221 tempAlignObj.SetMatrix(*fSensVolMatrix);\r
1222 tempAlignObj.GetPars(t,r);\r
1223}\r