]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSAlignMille2Module.cxx
Changed scripts for new TrainSetup
[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
f1b15b8d 45\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
b83bddd1 207 this->TNamed::operator=(m);\r
6526a72c 208 //\r
209 fNSensVol=m.fNSensVol;\r
210 fIndex=m.fIndex;\r
211 fDetType = m.fDetType;\r
212 fVolumeID=m.fVolumeID;\r
213 fNParTot = m.fNParTot;\r
cef66441 214 fNParFree = m.fNParFree; \r
215 fNProcPoints = m.fNProcPoints; \r
6526a72c 216 delete[] fParVals; fParVals = 0;\r
217 delete[] fParErrs; fParErrs = 0;\r
218 delete[] fParCstr; fParCstr = 0;\r
219 //\r
220 if (fNParTot) {\r
221 fParVals = new Float_t[fNParTot];\r
222 fParErrs = new Float_t[fNParTot];\r
8102b2c9 223 fParCstr = new Float_t[fNParTot];\r
6526a72c 224 for (int i=m.GetNParTot();i--;) {\r
225 fParVals[i] = m.fParVals[i];\r
226 fParErrs[i] = m.fParErrs[i];\r
227 fParCstr[i] = m.fParCstr[i];\r
228 }\r
229 }\r
230 //\r
231 fParOffs.Set(fNParTot);\r
232 for (int i=0;i<fNParTot;i++) fParOffs[i] = m.fParOffs[i];\r
cef66441 233 for (int i=0;i<3;i++) fSigmaFactor[i] = m.fSigmaFactor[i];\r
6526a72c 234 if (fMatrix) delete fMatrix;\r
235 fMatrix=new TGeoHMatrix(*m.GetMatrix());\r
f437d003 236 if(fSensVolMatrix) delete fSensVolMatrix;\r
237 fSensVolMatrix = new TGeoHMatrix(*m.fSensVolMatrix);\r
238 if(fSensVolModifMatrix) delete fSensVolModifMatrix;\r
239 fSensVolModifMatrix = new TGeoHMatrix(*m.fSensVolModifMatrix);\r
6526a72c 240 fSensVolIndex = m.fSensVolIndex;\r
241 fSensVolVolumeID = m.fSensVolVolumeID;\r
242 fParent = m.fParent;\r
243 fChildren.Clear();\r
244 for (int i=0;i<m.GetNChildren();i++) fChildren.Add(m.GetChild(i));\r
245 return *this;\r
246}\r
247\r
248\r
249//-------------------------------------------------------------\r
250AliITSAlignMille2Module::~AliITSAlignMille2Module() { \r
251 /// Destructor \r
252 delete fMatrix; \r
253 delete fSensVolMatrix; \r
254 delete fSensVolModifMatrix; \r
255 delete[] fParVals;\r
256 delete[] fParErrs;\r
257 delete[] fParCstr;\r
258 fChildren.Clear();\r
259} \r
260\r
261//-------------------------------------------------------------\r
6be22b3f 262Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, const char* symname, \r
263 const TGeoHMatrix *m, Int_t nsv, const UShort_t *volidsv) \r
6526a72c 264{\r
265 // initialize a custom supermodule\r
266 // index, volid, symname and matrix must be given\r
267 // if (volidsv) add nsv sensitive volumes to the supermodules\r
268 // return 0 if success\r
269\r
270 if (index<2198) {\r
271 AliInfo("Index must be >= 2198");\r
272 return -1;\r
273 }\r
274 if (volid<14336) {\r
275 AliInfo("VolumeID must be >= 14336");\r
276 return -2;\r
277 }\r
278 \r
279 if (!symname) return -3;\r
280 for (Int_t i=0; i<2198; i++) {\r
281 if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {\r
282 AliInfo("Symname already used by a Sensitive Volume");\r
283 return -3;\r
284 }\r
285 }\r
286 \r
287 if (!m) return -4;\r
288\r
289 // can initialize needed stuffs\r
290 fIndex = index;\r
291 fVolumeID = volid;\r
292 SetName(symname);\r
293 //\r
294 (*fMatrix) = (*m);\r
295 //\r
296 fSensVolIndex.Set(nsv);\r
297 fSensVolVolumeID.Set(nsv);\r
298 // add sensitive volumes\r
299 for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);\r
300\r
301 return 0;\r
302}\r
303\r
304//-------------------------------------------------------------\r
305void AliITSAlignMille2Module::SetFreeDOF(Int_t dof,Double_t cstr)\r
306{\r
ef24eb3b 307 if (AliITSAlignMille2::IsZero(cstr)) fParCstr[dof] = 0; // fixed parameter\r
308 else if (cstr>0) fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained\r
309 else fParCstr[dof] = -cstr; // the parameter is free but constrained\r
6526a72c 310}\r
311\r
312//-------------------------------------------------------------\r
313Bool_t AliITSAlignMille2Module::IsSensor(UShort_t voluid) \r
314{\r
315 // Does this volid correspond to sensor ?\r
316 AliGeomManager::ELayerID layId = AliGeomManager::VolUIDToLayerSafe(voluid);\r
317 if (layId>0 && layId<7) {\r
318 Int_t mId = Int_t(voluid & 0x7ff);\r
319 if( mId>=0 && mId<AliGeomManager::LayerSize(layId)) return kTRUE;\r
320 }\r
321 return kFALSE;\r
322}\r
323\r
324//-------------------------------------------------------------\r
325Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {\r
326 /// index from volume ID\r
327 AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);\r
328 if (lay<1|| lay>6) return -1;\r
329 Int_t idx=Int_t(voluid)-2048*lay;\r
330 if (idx>=AliGeomManager::LayerSize(lay)) return -1;\r
331 for (Int_t ilay=1; ilay<lay; ilay++) \r
332 idx += AliGeomManager::LayerSize(ilay);\r
333 return idx;\r
334}\r
335\r
336//-------------------------------------------------------------\r
337void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)\r
338{\r
339 /// add a sensitive volume to this supermodule\r
340 if (GetIndexFromVolumeID(voluid)<0) return; // bad volid\r
341 //\r
342 // in principle, the correct size of fSensVol... arrays was set outside but check anyway\r
8fd71c0a 343 if (fSensVolVolumeID.GetSize()<fNSensVol+1) {\r
6526a72c 344 fSensVolVolumeID.Set(fNSensVol+1);\r
345 fSensVolIndex.Set(fNSensVol+1);\r
346 }\r
347 //\r
348 fSensVolVolumeID[fNSensVol] = Short_t(voluid);\r
349 fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);\r
350 fNSensVol++;\r
351}\r
352\r
353//-------------------------------------------------------------\r
354void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)\r
355{\r
356 // Suppress sensor at position "at"\r
357 // in fact we are swapping with the last valid one \r
358 int lastValid = --fNSensVol;\r
359 int tmpv = fSensVolIndex[at];\r
360 fSensVolIndex[at] = fSensVolIndex[lastValid];\r
361 tmpv = fSensVolVolumeID[at];\r
362 fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];\r
363 fSensVolVolumeID[lastValid] = tmpv;\r
364 //\r
365}\r
366\r
367//-------------------------------------------------------------\r
368Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const \r
369{\r
370 /// check if voluid is defined\r
371 if (!voluid) return kFALSE; // only positive voluid are accepted\r
372 for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;\r
373 return kFALSE;\r
374}\r
375\r
376//-------------------------------------------------------------\r
377Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const\r
378{\r
379 /// check if parent contains the sensors of this volume\r
380 if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;\r
381 return parent->IsIn( fSensVolVolumeID[0] );\r
382}\r
383\r
384//-------------------------------------------------------------\r
b80c197e 385TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, const Double_t *delta,Bool_t local)\r
6526a72c 386{\r
387 // modify the original TGeoHMatrix of the sensitive module 'voluid' according\r
388 // with a delta transform. applied to the supermodule matrix\r
389 // return NULL if error\r
390\r
391 if (!IsIn(voluid)) return NULL;\r
392 if (!gGeoManager) return NULL;\r
393\r
394 // prepare the TGeoHMatrix\r
395 Double_t tr[3],ang[3];\r
396 tr[0]=delta[0]; // in centimeter\r
397 tr[1]=delta[1]; \r
398 tr[2]=delta[2];\r
399 ang[0]=delta[3]; // psi (X) in deg\r
400 ang[1]=delta[4]; // theta (Y)\r
401 ang[2]=delta[5]; // phi (Z)\r
402 //\r
f1b15b8d 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
6526a72c 406 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
407 TGeoHMatrix hm;\r
f1b15b8d 408 tempAlignObj.GetMatrix(hm);\r
6526a72c 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
b80c197e 428AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const Double_t *deltalocal)\r
6526a72c 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
f1b15b8d 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
6526a72c 448 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r
449 //\r
f1b15b8d 450 return GetSensitiveVolumeMisalignment(voluid,&tempAlignObj);\r
6526a72c 451}\r
452\r
453//-------------------------------------------------------------\r
b80c197e 454AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, const AliAlignObjParams *a)\r
6526a72c 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
f1b15b8d 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
6526a72c 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
f1b15b8d 531 if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
532 tempAlignObj.SetVolUID(voluid);\r
533 tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
6526a72c 534 //\r
f1b15b8d 535 return &tempAlignObj;\r
6526a72c 536}\r
537\r
538// >> RS\r
539//-------------------------------------------------------------\r
b80c197e 540AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, const Double_t *deltalocal)\r
6526a72c 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
f1b15b8d 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
6526a72c 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
f1b15b8d 574 tempAlignObj.GetMatrix(dg);\r
6526a72c 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
f1b15b8d 600 tempAlignObj.SetVolUID(0);\r
601 tempAlignObj.SetSymName("");\r
602 tempAlignObj.SetTranslation(0,0,0);\r
603 tempAlignObj.SetRotation(0,0,0);\r
6526a72c 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
f1b15b8d 615 if (!tempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r
616 tempAlignObj.SetVolUID(voluid);\r
617 tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
6526a72c 618\r
619 \r
f1b15b8d 620 //tempAlignObj.Print("");\r
6526a72c 621\r
f1b15b8d 622 return &tempAlignObj;\r
6526a72c 623}\r
624//-------------------------------------------------------------\r
625\r
626//-------------------------------------------------------------\r
b80c197e 627AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, const Double_t *deltalocal)\r
6526a72c 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
f1b15b8d 645 static AliAlignObjParams tempAlignObj;\r
646 tempAlignObj.SetTranslation(0,0,0);\r
647 tempAlignObj.SetRotation(0,0,0);\r
6526a72c 648\r
f1b15b8d 649 tempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r
650 tempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r
6526a72c 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
f1b15b8d 661 tempAlignObj.GetMatrix(dg);\r
6526a72c 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
f1b15b8d 668 tempAlignObj.SetTranslation(0,0,0);\r
669 tempAlignObj.SetRotation(0,0,0);\r
6526a72c 670\r
f1b15b8d 671 tempAlignObj.SetVolUID(voluid);\r
672 tempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r
6526a72c 673\r
f1b15b8d 674 if (!tempAlignObj.SetMatrix(dg)) return NULL;\r
6526a72c 675 \r
f1b15b8d 676 //tempAlignObj.Print("");\r
6526a72c 677\r
f1b15b8d 678 return &tempAlignObj;\r
6526a72c 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
b80c197e 763 // print data\r
6526a72c 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
ef24eb3b 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
6526a72c 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
b80c197e 791 // it it alignable?\r
6526a72c 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
b80c197e 811 // assign the detector type\r
6526a72c 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
ef24eb3b 817 fNParTot = IsSDD() ? kMaxParTot:kMaxParGeom;\r
6526a72c 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
b80c197e 833 // count d.o.f.\r
6526a72c 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
f1b15b8d 844 AliAlignObjParams tempAlignObj;\r
845 tempAlignObj.SetMatrix(*fSensVolMatrix);\r
846 tempAlignObj.GetPars(t,r);\r
6526a72c 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
f1b15b8d 856 AliAlignObjParams tempAlignObj; \r
857 tempAlignObj.SetMatrix(*fSensVolMatrix);\r
858 tempAlignObj.GetPars(t,r);\r
6526a72c 859}\r
860\r
861//-------------------------------------------------------------\r
b80c197e 862void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,const Double_t* loct, const Double_t* locr,Double_t *t, Double_t *r)\r
6526a72c 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
f1b15b8d 867 AliAlignObjParams tempAlignObj;\r
868 tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
869 tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
6526a72c 870 //\r
f1b15b8d 871 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta\r
6526a72c 872 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
f1b15b8d 873 tempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
874 tempAlignObj.GetPars(t,r); // obtain global params\r
6526a72c 875}\r
876\r
877//-------------------------------------------------------------\r
b80c197e 878void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,const Double_t* loct,const Double_t* locr,Double_t *t, Double_t *r)\r
6526a72c 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
f1b15b8d 883 AliAlignObjParams tempAlignObj;\r
884 tempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
885 tempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
6526a72c 886 //\r
f1b15b8d 887 tempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta\r
6526a72c 888 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
889 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume\r
f1b15b8d 890 tempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
891 tempAlignObj.GetPars(t,r); // obtain params\r
6526a72c 892}\r
893\r
894//-------------------------------------------------------------\r
895void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)\r
896{\r
b80c197e 897 // set parameters\r
6526a72c 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
f1b15b8d 917 AliAlignObjParams tempAlignObj;\r
6526a72c 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
f1b15b8d 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
6526a72c 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
f1b15b8d 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
6526a72c 938 fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );\r
939 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );\r
f1b15b8d 940 tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // global delta matrix\r
941 tempAlignObj.GetPars(pars,pars+3);\r
6526a72c 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
f1b15b8d 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
6526a72c 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
f1b15b8d 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
6526a72c 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
f1b15b8d 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
6526a72c 985 fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );\r
986 fSensVolModifMatrix->Multiply( fSensVolMatrix );\r
f1b15b8d 987 tempAlignObj.SetMatrix( *fSensVolModifMatrix ); // local delta matrix\r
988 tempAlignObj.GetPars(pars,pars+3);\r
6526a72c 989 //\r
990}\r
991\r
6be22b3f 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
6526a72c 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
cfe39822 1189void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r) const\r
6526a72c 1190{\r
1191 // global parameters of the module\r
f1b15b8d 1192 AliAlignObjParams tempAlignObj;\r
1193 tempAlignObj.SetMatrix( *fMatrix );\r
1194 tempAlignObj.GetPars(t,r);\r
6526a72c 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
f1b15b8d 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
6526a72c 1205 *fSensVolMatrix = *fMatrix;\r
1206 fSensVolMatrix->Multiply(fSensVolModifMatrix);\r
f1b15b8d 1207 tempAlignObj.SetMatrix(*fSensVolMatrix);\r
1208 tempAlignObj.GetPars(t,r);\r
6526a72c 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
f1b15b8d 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
6526a72c 1219 fSensVolMatrix->Multiply( fMatrix );\r
1220 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
f1b15b8d 1221 tempAlignObj.SetMatrix(*fSensVolMatrix);\r
1222 tempAlignObj.GetPars(t,r);\r
6526a72c 1223}\r