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