]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSAlignMille2Module.cxx
bug fix in the vertex selection
[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
301 if (cstr>0) fParCstr[dof] = fgkDummyConstraint+1.; // the parameter is free and unconstrained\r
302 else if (cstr<0) fParCstr[dof] = -cstr; // the parameter is free but constrained\r
303 else fParCstr[dof] = 0; // fixed parameter\r
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
337 if (fSensVolVolumeID.GetSize()<fNSensVol) {\r
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
762 IsFreeDOF(kDOFTX) ? '+':'-',fParOffs[kDOFTX],IsFreeDOF(kDOFTY) ? '+':'-',fParOffs[kDOFTY],\r
763 IsFreeDOF(kDOFTZ) ? '+':'-',fParOffs[kDOFTZ],IsFreeDOF(kDOFPS) ? '+':'-',fParOffs[kDOFPS],\r
764 IsFreeDOF(kDOFTH) ? '+':'-',fParOffs[kDOFTH],IsFreeDOF(kDOFPH) ? '+':'-',fParOffs[kDOFPH]);\r
765 if (IsSDD()) printf("%cT0:%5d| %cDV:%5d|",IsFreeDOF(kDOFT0)?'+':'-',fParOffs[kDOFT0],\r
766 IsFreeDOF(kDOFDV)?'+':'-',fParOffs[kDOFDV]);\r
767 printf("\n");\r
768 fMatrix->Print();\r
769 printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);\r
770 for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));\r
771}\r
772\r
773//-------------------------------------------------------------\r
774Bool_t AliITSAlignMille2Module::IsAlignable() const\r
775{\r
776 TGeoManager* geoManager = AliGeomManager::GetGeometry();\r
777 if (!geoManager) {\r
778 AliInfo("Couldn't initialize geometry");\r
779 return kFALSE;\r
780 }\r
781 return geoManager->GetAlignableEntry(GetName())!=0;\r
782}\r
783\r
784//-------------------------------------------------------------\r
785void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const\r
786{\r
787 // return the local matrix for transformation to its parent\r
788 mat = *fMatrix;\r
789 if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );\r
790}\r
791\r
792//-------------------------------------------------------------\r
793void AliITSAlignMille2Module::AssignDetType()\r
794{\r
795 TString tp = GetName();\r
796 if (tp.Contains("SPD",TString::kIgnoreCase)) fDetType = kSPD;\r
797 else if (tp.Contains("SDD",TString::kIgnoreCase)) fDetType = kSDD;\r
798 else if (tp.Contains("SSD",TString::kIgnoreCase)) fDetType = kSSD;\r
799 else fDetType = -1;\r
800 fNParTot = IsSDD() ? 8:6;\r
801 fNParFree = 0;\r
802 fParVals = new Float_t[fNParTot];\r
803 fParErrs = new Float_t[fNParTot]; \r
804 fParCstr = new Float_t[fNParTot]; \r
805 if (fParOffs.GetSize()<fNParTot) fParOffs.Set(fNParTot);\r
806 for (int i=fNParTot;i--;) {\r
807 fParVals[i] = fParErrs[i] = 0.; \r
808 fParCstr[i] = 0.;\r
809 fParOffs[i] = -1;\r
810 }\r
811}\r
812\r
813//-------------------------------------------------------------\r
814void AliITSAlignMille2Module::EvaluateDOF()\r
815{\r
816 fNParFree = 0;\r
817 for (int i=fNParTot;i--;) if (IsFreeDOF(i)) fNParFree++;\r
818}\r
819\r
820//-------------------------------------------------------------\r
821void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t *t, Double_t *r)\r
822{\r
823 // return global parameters of the sensor volid\r
824 for (int i=3;i--;) t[i] = r[i] = 0.;\r
825 if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
826 fgTempAlignObj.SetMatrix(*fSensVolMatrix);\r
827 fgTempAlignObj.GetPars(t,r);\r
828}\r
829\r
830//-------------------------------------------------------------\r
831void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t *t, Double_t *r)\r
832{\r
833 // return parameters of the sensor volid in the current module\r
834 for (int i=3;i--;) t[i] = r[i] = 0.;\r
835 if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
836 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
837 fgTempAlignObj.SetMatrix(*fSensVolMatrix);\r
838 fgTempAlignObj.GetPars(t,r);\r
839}\r
840\r
841//-------------------------------------------------------------\r
842void AliITSAlignMille2Module::GetSensVolGlobalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)\r
843{\r
844 // return global parameters of the sensor volid modified by the localDelta params\r
845 for (int i=3;i--;) t[i] = r[i] = 0.;\r
846 if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
847 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
848 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
849 //\r
850 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta\r
851 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
852 fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
853 fgTempAlignObj.GetPars(t,r); // obtain global params\r
854}\r
855\r
856//-------------------------------------------------------------\r
857void AliITSAlignMille2Module::GetSensVolLocalParams(UShort_t volid,Double_t* loct,Double_t* locr,Double_t *t, Double_t *r)\r
858{\r
859 // return parameters of the sensor volid (modified by the localDelta params) in the current volume\r
860 for (int i=3;i--;) t[i] = r[i] = 0.;\r
861 if (SensVolMatrix(volid,fSensVolMatrix)) return; \r
862 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
863 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
864 //\r
865 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // obtain local delta\r
866 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix ); // obtain global delta\r
867 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() ); // obtain delta in current volume\r
868 fgTempAlignObj.SetMatrix(*fSensVolModifMatrix);\r
869 fgTempAlignObj.GetPars(t,r); // obtain params\r
870}\r
871\r
872//-------------------------------------------------------------\r
873void AliITSAlignMille2Module::SetParVals(Double_t *vl,Int_t npar)\r
874{\r
875 for (int i=TMath::Min(npar,(Int_t)fNParTot);i--;) fParVals[i] = vl[i];\r
876}\r
877\r
878//-------------------------------------------------------------\r
879void AliITSAlignMille2Module::GetGeomParamsGlo(Double_t *pars)\r
880{\r
881 // recompute parameters from local to global frame\r
882 //\r
883 // is there anything to do?\r
884 if (GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}\r
885 //\r
886 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)\r
887 // as for the current module. Since in the mp2 the modules are stored from parents to children,\r
888 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end\r
889 // of the modules array.\r
890 //\r
891 // DeltaGlobal = (ModifParents)*DeltaLocal*(ModifParents)^-1 \r
892 //\r
893 *fSensVolMatrix = *fMatrix; // current global matrix\r
894 AliITSAlignMille2Module* parent = GetParent();\r
895 while (parent) {\r
896 if (parent->GeomParamsGlobal()) {\r
897 AliError("Cannot convert params to Global when the parents are already Global\n");\r
898 for (int i=kMaxParGeom;i--;) pars[i] = 0;\r
899 return;\r
900 }\r
901 fSensVolMatrix->MultiplyLeft( &parent->GetMatrix()->Inverse() ); // Local Matrix\r
902 Float_t *parpar = parent->GetParVals();\r
903 fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);\r
904 fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);\r
905 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);\r
906 fSensVolMatrix->MultiplyLeft(fSensVolModifMatrix);\r
907 fSensVolMatrix->MultiplyLeft(parent->GetMatrix()); // global matrix after parents modifications\r
908 parent = parent->GetParent();\r
909 }\r
910 //\r
911 fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);\r
912 fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);\r
913 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // local delta matrix\r
914 fSensVolModifMatrix->Multiply( &fSensVolMatrix->Inverse() );\r
915 fSensVolModifMatrix->MultiplyLeft( fSensVolMatrix );\r
916 fgTempAlignObj.SetMatrix( *fSensVolModifMatrix ); // global delta matrix\r
917 fgTempAlignObj.GetPars(pars,pars+3);\r
918 //\r
919}\r
920\r
921//-------------------------------------------------------------\r
922void AliITSAlignMille2Module::GetGeomParamsLoc(Double_t *pars)\r
923{\r
924 // recompute parameters from global to local frame\r
925 //\r
926 // is there anything to do?\r
927 if (!GeomParamsGlobal()) {for (int i=kMaxParGeom;i--;) pars[i] = fParVals[i]; return;}\r
928 //\r
929 // IMPORTANT: It is assumed that the parents params are defined in a same way (local or global)\r
930 // as for the current module. Since in the mp2 the modules are stored from parents to children,\r
931 // it is safe to call this method in loop staring from the lowest level child, i.e. from the end\r
932 // of the modules array.\r
933 //\r
934 // DeltaLocal = (DeltaParents*GlobalMat)^-1*DeltaGlobal*(DeltaParents*GlobalMat)\r
935 //\r
936 AliITSAlignMille2Module* parent = GetParent();\r
937 fgTempAlignObj.SetTranslation(0.,0.,0.);\r
938 fgTempAlignObj.SetRotation(0.,0.,0.);\r
939 fgTempAlignObj.GetMatrix(*fSensVolMatrix); // get no-shift matrix\r
940 //\r
941 while (parent) { // accumulate the product of parents global modifications\r
942 if (!parent->GeomParamsGlobal()) {\r
943 AliError("Cannot convert params to Local when the parents are already Local\n");\r
944 for (int i=kMaxParGeom;i--;) pars[i] = 0;\r
945 return;\r
946 }\r
947 Float_t *parpar = parent->GetParVals();\r
948 fgTempAlignObj.SetTranslation(parpar[0],parpar[1],parpar[2]);\r
949 fgTempAlignObj.SetRotation(parpar[3],parpar[4],parpar[5]);\r
950 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix);\r
951 fSensVolMatrix->Multiply(fSensVolModifMatrix); \r
952 parent = parent->GetParent();\r
953 }\r
954 // global matrix after parents modifications\r
955 fSensVolMatrix->Multiply(fMatrix);\r
956 //\r
957 fgTempAlignObj.SetTranslation(fParVals[0],fParVals[1],fParVals[2]);\r
958 fgTempAlignObj.SetRotation(fParVals[3],fParVals[4],fParVals[5]);\r
959 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); // global delta matrix\r
960 fSensVolModifMatrix->MultiplyLeft( &fSensVolMatrix->Inverse() );\r
961 fSensVolModifMatrix->Multiply( fSensVolMatrix );\r
962 fgTempAlignObj.SetMatrix( *fSensVolModifMatrix ); // local delta matrix\r
963 fgTempAlignObj.GetPars(pars,pars+3);\r
964 //\r
965}\r
966\r
6be22b3f 967\r
968//-------------------------------------------------------------\r
969void AliITSAlignMille2Module::CalcDerivDPosDPar(Int_t sensVol,const Double_t* pl, Double_t *deriv)\r
970{\r
971 // calculate jacobian of the global position vs Parameters (dPos/dParam) \r
972 // for the point in the sensor sensVol\r
973 const double kDel = 0.01;\r
974 double pos0[3],pos1[3],pos2[3],pos3[3];\r
975 double delta[kMaxParGeom];\r
976 //\r
977 for (int ip=kMaxParGeom;ip--;) delta[ip] = 0;\r
978 //\r
979 for (int ip=kMaxParGeom;ip--;) {\r
980 //\r
981 delta[ip] -= kDel;\r
982 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos0); \r
983 delta[ip] += kDel/2;\r
984 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos1); \r
985 delta[ip] += kDel;\r
986 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos2); \r
987 delta[ip] += kDel/2;\r
988 GetSensitiveVolumeModifiedMatrix(sensVol,delta,!GeomParamsGlobal())->LocalToMaster(pl,pos3); \r
989 //\r
990 delta[ip] = 0;\r
991 double *curd = deriv + ip*3;\r
992 for (int i=3;i--;) curd[i] = (8.*(pos2[i]-pos1[i]) - (pos3[i]-pos0[i]))/6./kDel;\r
993 }\r
994 //\r
995}\r
996\r
6526a72c 997//-------------------------------------------------------------\r
998void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t idx,Double_t *deriv)\r
999{\r
1000 // calculate derivative of global params vs local param idx: deriv[j] = dParGlo[j]/dParLoc[idx]\r
1001 Double_t lpar[kMaxParGeom];\r
1002 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
1003 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1004 Double_t par1[kMaxParGeom]; // f(x-h)\r
1005 Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1006 Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1007 Double_t par4[kMaxParGeom]; // f(x+h)\r
1008 //\r
1009 const Double_t dpar = 1e-3;\r
1010 //\r
1011 // first values\r
1012 lpar[idx] -= dpar;\r
1013 GetGlobalParams(lpar,lpar+3, par1,par1+3);\r
1014 //\r
1015 // second values\r
1016 lpar[idx] += dpar/2;\r
1017 GetGlobalParams(lpar,lpar+3, par2,par2+3);\r
1018 //\r
1019 // third values\r
1020 lpar[idx] += dpar;\r
1021 GetGlobalParams(lpar,lpar+3, par3,par3+3);\r
1022 //\r
1023 // fourth values\r
1024 lpar[idx] += dpar/2;\r
1025 GetGlobalParams(lpar,lpar+3, par4,par4+3);\r
1026 //\r
1027 Double_t h2 = 1./(2.*dpar);\r
1028 for (int i=kMaxParGeom;i--;) {\r
1029 Double_t d0 = par4[i]-par1[i];\r
1030 Double_t d2 = 2.*(par3[i]-par2[i]);\r
1031 deriv[i] = h2*(4*d2 - d0)/3.;\r
1032 if (TMath::Abs(deriv[i]) < 1.0e-9) deriv[i] = 0.0;\r
1033 }\r
1034 //\r
1035}\r
1036\r
1037//-------------------------------------------------------------\r
1038void AliITSAlignMille2Module::CalcDerivLocGlo(Double_t *deriv)\r
1039{\r
1040 // calculate derivative of local params vs global params: deriv[i][j] = dParLoc[i]/dParGlo[j]\r
1041 Double_t gpar[kMaxParGeom];\r
1042 for (int i=kMaxParGeom;i--;) gpar[i] = 0.;\r
1043 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1044 Double_t par1[kMaxParGeom]; // f(x-h)\r
1045 Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1046 Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1047 Double_t par4[kMaxParGeom]; // f(x+h)\r
1048 //\r
1049 const Double_t dpar = 1e-3;\r
1050 //\r
1051 for (int ig=kMaxParGeom;ig--;) {\r
1052 // first values\r
1053 gpar[ig] -= dpar;\r
1054 GetLocalParams(gpar,gpar+3, par1,par1+3);\r
1055 //\r
1056 // second values\r
1057 gpar[ig] += dpar/2;\r
1058 GetLocalParams(gpar,gpar+3, par2,par2+3);\r
1059 //\r
1060 // third values\r
1061 gpar[ig] += dpar;\r
1062 GetLocalParams(gpar,gpar+3, par3,par3+3);\r
1063 //\r
1064 // fourth values\r
1065 gpar[ig] += dpar/2;\r
1066 GetLocalParams(gpar,gpar+3, par4,par4+3);\r
1067 //\r
1068 Double_t h2 = 1./(2.*dpar);\r
1069 for (int i=kMaxParGeom;i--;) {\r
1070 Double_t d0 = par4[i]-par1[i];\r
1071 Double_t d2 = 2.*(par3[i]-par2[i]);\r
1072 int idig = i*kMaxParGeom + ig;\r
1073 deriv[idig] = h2*(4*d2 - d0)/3.;\r
1074 if (TMath::Abs(deriv[idig]) < 1.0e-9) deriv[idig] = 0.0;\r
1075 }\r
1076 }\r
1077 //\r
1078}\r
1079\r
1080//________________________________________________________________________________________________________\r
1081void AliITSAlignMille2Module::CalcDerivGloLoc(Int_t sensVol,Int_t paridx,Double_t* derivative)\r
1082{\r
1083 /// calculate numerically the derivatives of global params vs local param paridx for sensor sensVol: dPglob/dPloc_paridx\r
1084 //\r
1085 Double_t lpar[kMaxParGeom];\r
1086 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
1087 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1088 Double_t par1[kMaxParGeom]; // f(x-h)\r
1089 Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1090 Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1091 Double_t par4[kMaxParGeom]; // f(x+h)\r
1092 //\r
1093 const Double_t dpar = 1e-3;\r
1094 //\r
1095 // first values\r
1096 lpar[paridx] -= dpar;\r
1097 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par1,par1+3);\r
1098 //\r
1099 // second values\r
1100 lpar[paridx] += dpar/2;\r
1101 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par2,par2+3);\r
1102 //\r
1103 // third values\r
1104 lpar[paridx] += dpar;\r
1105 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par3,par3+3);\r
1106 //\r
1107 // fourth values\r
1108 lpar[paridx] += dpar/2;\r
1109 GetSensVolGlobalParams(sensVol,lpar,lpar+3, par4,par4+3);\r
1110 //\r
1111 Double_t h2 = 1./(2.*dpar);\r
1112 for (int i=kMaxParGeom;i--;) {\r
1113 Double_t d0 = par4[i]-par1[i];\r
1114 Double_t d2 = 2.*(par3[i]-par2[i]);\r
1115 derivative[i] = h2*(4*d2 - d0)/3.;\r
1116 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;\r
1117 }\r
1118 //\r
1119}\r
1120\r
1121//________________________________________________________________________________________________________\r
1122void AliITSAlignMille2Module::CalcDerivCurLoc(Int_t sensVol,Int_t paridx,Double_t* derivative) \r
1123{\r
1124 /// calculate numerically the derivatives of sensor params in the current volume vs sensor local param paridx\r
1125 //\r
1126 Double_t lpar[kMaxParGeom];\r
1127 for (int i=kMaxParGeom;i--;) lpar[i] = 0.;\r
1128 // using f(x+h),f(x-h),f(x+h/2),f(x-h2)...\r
1129 Double_t par1[kMaxParGeom]; // f(x-h)\r
1130 Double_t par2[kMaxParGeom]; // f(x-h/2)\r
1131 Double_t par3[kMaxParGeom]; // f(x+h/2)\r
1132 Double_t par4[kMaxParGeom]; // f(x+h)\r
1133 //\r
1134 const Double_t dpar = 1e-3;\r
1135 //\r
1136 // first values\r
1137 lpar[paridx] -= dpar;\r
1138 GetSensVolLocalParams(sensVol,lpar,lpar+3, par1,par1+3);\r
1139 //\r
1140 // second values\r
1141 lpar[paridx] += dpar/2;\r
1142 GetSensVolLocalParams(sensVol,lpar,lpar+3, par2,par2+3);\r
1143 //\r
1144 // third values\r
1145 lpar[paridx] += dpar;\r
1146 GetSensVolLocalParams(sensVol,lpar,lpar+3, par3,par3+3);\r
1147 //\r
1148 // fourth values\r
1149 lpar[paridx] += dpar/2;\r
1150 GetSensVolLocalParams(sensVol,lpar,lpar+3, par4,par4+3);\r
1151 //\r
1152 Double_t h2 = 1./(2.*dpar);\r
1153 for (int i=kMaxParGeom;i--;) {\r
1154 Double_t d0 = par4[i]-par1[i];\r
1155 Double_t d2 = 2.*(par3[i]-par2[i]);\r
1156 derivative[i] = h2*(4*d2 - d0)/3.;\r
1157 if (TMath::Abs(derivative[i]) < 1.0e-9) derivative[i] = 0.0;\r
1158 }\r
1159 //\r
1160}\r
1161\r
1162\r
1163//-------------------------------------------------------------\r
1164void AliITSAlignMille2Module::GetGlobalParams(Double_t *t, Double_t *r)\r
1165{\r
1166 // global parameters of the module\r
1167 fgTempAlignObj.SetMatrix( *fMatrix );\r
1168 fgTempAlignObj.GetPars(t,r);\r
1169}\r
1170\r
1171//-------------------------------------------------------------\r
1172void AliITSAlignMille2Module::GetGlobalParams(const Double_t* loct, const Double_t* locr, Double_t *t, Double_t *r)\r
1173{\r
1174 // global parameters of the module after the modification by local loct,locr\r
1175 fgTempAlignObj.SetTranslation(loct[0],loct[1],loct[2]);\r
1176 fgTempAlignObj.SetRotation(locr[0],locr[1],locr[2]);\r
1177 fgTempAlignObj.GetMatrix(*fSensVolModifMatrix); \r
1178 *fSensVolMatrix = *fMatrix;\r
1179 fSensVolMatrix->Multiply(fSensVolModifMatrix);\r
1180 fgTempAlignObj.SetMatrix(*fSensVolMatrix);\r
1181 fgTempAlignObj.GetPars(t,r);\r
1182}\r
1183\r
1184//-------------------------------------------------------------\r
1185void AliITSAlignMille2Module::GetLocalParams(const Double_t* glot, const Double_t* glor, Double_t *t, Double_t *r)\r
1186{\r
1187 // obtain local delta parameters from global delta params\r
1188 fgTempAlignObj.SetTranslation(glot[0],glot[1],glot[2]);\r
1189 fgTempAlignObj.SetRotation(glor[0],glor[1],glor[2]);\r
1190 fgTempAlignObj.GetMatrix(*fSensVolMatrix); \r
1191 fSensVolMatrix->Multiply( fMatrix );\r
1192 fSensVolMatrix->MultiplyLeft( &fMatrix->Inverse() );\r
1193 fgTempAlignObj.SetMatrix(*fSensVolMatrix);\r
1194 fgTempAlignObj.GetPars(t,r);\r
1195}\r