]>
Commit | Line | Data |
---|---|---|
7b85e477 | 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 | |
40 | ClassImp(AliITSAlignMille2Module) \r | |
41 | /// \endcond \r | |
42 | \r | |
43 | #define CORHW_\r | |
44 | \r | |
45 | AliAlignObjParams AliITSAlignMille2Module::fgTempAlignObj;\r | |
46 | \r | |
47 | //-------------------------------------------------------------\r | |
48 | AliITSAlignMille2Module::AliITSAlignMille2Module() : \r | |
49 | TNamed(), \r | |
50 | fNSensVol(0), \r | |
51 | fIndex(-1), \r | |
52 | fVolumeID(0),\r | |
53 | fNProcPoints(0),\r | |
54 | fSensVolIndex(0),\r | |
55 | fSensVolVolumeID(0),\r | |
56 | fMatrix(NULL),\r | |
57 | fSensVolMatrix(NULL),\r | |
58 | fSensVolModifMatrix(NULL),\r | |
59 | fParent(NULL)\r | |
60 | { \r | |
61 | /// void constructor \r | |
62 | fMatrix = new TGeoHMatrix; \r | |
63 | fSensVolMatrix = new TGeoHMatrix; \r | |
64 | fSensVolModifMatrix = new TGeoHMatrix; \r | |
65 | fSensVolIndex.Set(1);\r | |
66 | fSensVolVolumeID.Set(1);\r | |
67 | fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r | |
68 | } \r | |
69 | \r | |
70 | //-------------------------------------------------------------\r | |
71 | AliITSAlignMille2Module::AliITSAlignMille2Module(Int_t index,UShort_t volid,char* symname,TGeoHMatrix *m,Int_t nsv,UShort_t *volidsv) : \r | |
72 | TNamed(), \r | |
73 | fNSensVol(0), \r | |
74 | fIndex(-1), \r | |
75 | fVolumeID(0),\r | |
76 | fNProcPoints(0),\r | |
77 | fSensVolIndex(0),\r | |
78 | fSensVolVolumeID(0), \r | |
79 | fMatrix(NULL),\r | |
80 | fSensVolMatrix(NULL),\r | |
81 | fSensVolModifMatrix(NULL),\r | |
82 | fParent(NULL)\r | |
83 | { \r | |
84 | /// void constructor \r | |
85 | fMatrix = new TGeoHMatrix; \r | |
86 | fSensVolMatrix = new TGeoHMatrix; \r | |
87 | fSensVolModifMatrix = new TGeoHMatrix; \r | |
88 | fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r | |
89 | if (Set(index,volid,symname,m,nsv,volidsv)) {\r | |
90 | AliInfo("Error in AliITSAlignMille2Module::Set() - initializing void supermodule...");\r | |
91 | }\r | |
92 | } \r | |
93 | \r | |
94 | //-------------------------------------------------------------\r | |
95 | AliITSAlignMille2Module::AliITSAlignMille2Module(UShort_t volid) : \r | |
96 | TNamed(), \r | |
97 | fNSensVol(0), \r | |
98 | fIndex(-1), \r | |
99 | fVolumeID(0),\r | |
100 | fNProcPoints(0),\r | |
101 | fSensVolIndex(0),\r | |
102 | fSensVolVolumeID(0),\r | |
103 | fMatrix(NULL),\r | |
104 | fSensVolMatrix(NULL),\r | |
105 | fSensVolModifMatrix(NULL),\r | |
106 | fParent(NULL)\r | |
107 | { \r | |
108 | /// simple constructor building a supermodule from a single sensitive volume \r | |
109 | fMatrix = new TGeoHMatrix; \r | |
110 | fSensVolMatrix = new TGeoHMatrix; \r | |
111 | fSensVolModifMatrix = new TGeoHMatrix; \r | |
112 | // temporary align object, just use the rotation...\r | |
113 | fSensVolIndex.Set(1);\r | |
114 | fSensVolVolumeID.Set(1);\r | |
115 | fSigmaFactor[0]=fSigmaFactor[1]=fSigmaFactor[2]=1.0;\r | |
116 | //\r | |
117 | fIndex = GetIndexFromVolumeID(volid); \r | |
118 | if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded\r | |
119 | SetName(AliGeomManager::SymName(volid));\r | |
120 | fVolumeID = volid;\r | |
121 | AddSensitiveVolume(volid);\r | |
122 | if (SensVolMatrix(volid, fMatrix))\r | |
123 | AliInfo("Matrix not defined");\r | |
124 | }\r | |
125 | else {\r | |
126 | AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");\r | |
127 | }\r | |
128 | } \r | |
129 | \r | |
130 | \r | |
131 | //_____________________________________________________________________________\r | |
132 | AliITSAlignMille2Module::AliITSAlignMille2Module(const AliITSAlignMille2Module &m) :\r | |
133 | TNamed(m),\r | |
134 | fNSensVol(m.fNSensVol),\r | |
135 | fIndex(m.fIndex),\r | |
136 | fVolumeID(m.fVolumeID),\r | |
137 | fNProcPoints(0),\r | |
138 | fSensVolIndex(m.fSensVolIndex),\r | |
139 | fSensVolVolumeID(m.fSensVolVolumeID),\r | |
140 | fMatrix(new TGeoHMatrix(*m.GetMatrix())),\r | |
141 | fSensVolMatrix(new TGeoHMatrix),\r | |
142 | fSensVolModifMatrix(new TGeoHMatrix),\r | |
143 | fParent(m.fParent)\r | |
144 | {\r | |
145 | // Copy constructor\r | |
146 | fSensVolIndex = m.fSensVolIndex;\r | |
147 | fSensVolVolumeID = m.fSensVolVolumeID;\r | |
148 | for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];\r | |
149 | }\r | |
150 | \r | |
151 | //_____________________________________________________________________________\r | |
152 | AliITSAlignMille2Module& AliITSAlignMille2Module::operator=(const AliITSAlignMille2Module &m) \r | |
153 | {\r | |
154 | // operator =\r | |
155 | //\r | |
156 | if(this==&m) return *this;\r | |
157 | ((TNamed *)this)->operator=(m);\r | |
158 | //\r | |
159 | fNSensVol=m.fNSensVol;\r | |
160 | fIndex=m.fIndex;\r | |
161 | fVolumeID=m.fVolumeID;\r | |
162 | for (int i=3;i--;) fSigmaFactor[i] = m.fSigmaFactor[i];\r | |
163 | if (fMatrix) delete fMatrix;\r | |
164 | fMatrix=new TGeoHMatrix(*m.GetMatrix());\r | |
165 | fSensVolIndex = m.fSensVolIndex;\r | |
166 | fSensVolVolumeID = m.fSensVolVolumeID;\r | |
167 | fParent = m.fParent;\r | |
168 | return *this;\r | |
169 | }\r | |
170 | \r | |
171 | \r | |
172 | //-------------------------------------------------------------\r | |
173 | AliITSAlignMille2Module::~AliITSAlignMille2Module() { \r | |
174 | /// Destructor \r | |
175 | delete fMatrix; \r | |
176 | delete fSensVolMatrix; \r | |
177 | delete fSensVolModifMatrix; \r | |
178 | } \r | |
179 | \r | |
180 | //-------------------------------------------------------------\r | |
181 | Int_t AliITSAlignMille2Module::Set(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv) \r | |
182 | {\r | |
183 | // initialize a custom supermodule\r | |
184 | // index, volid, symname and matrix must be given\r | |
185 | // if (volidsv) add nsv sensitive volumes to the supermodules\r | |
186 | // return 0 if success\r | |
187 | \r | |
188 | if (index<2198) {\r | |
189 | AliInfo("Index must be >= 2198");\r | |
190 | return -1;\r | |
191 | }\r | |
192 | if (volid<14336) {\r | |
193 | AliInfo("VolumeID must be >= 14336");\r | |
194 | return -2;\r | |
195 | }\r | |
196 | \r | |
197 | if (!symname) return -3;\r | |
198 | for (Int_t i=0; i<2198; i++) {\r | |
199 | if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {\r | |
200 | AliInfo("Symname already used by a Sensitive Volume");\r | |
201 | return -3;\r | |
202 | }\r | |
203 | }\r | |
204 | \r | |
205 | if (!m) return -4;\r | |
206 | \r | |
207 | // can initialize needed stuffs\r | |
208 | fIndex = index;\r | |
209 | fVolumeID = volid;\r | |
210 | SetName(symname);\r | |
211 | //\r | |
212 | (*fMatrix) = (*m);\r | |
213 | //\r | |
214 | fSensVolIndex.Set(nsv);\r | |
215 | fSensVolVolumeID.Set(nsv);\r | |
216 | // add sensitive volumes\r | |
217 | for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);\r | |
218 | \r | |
219 | return 0;\r | |
220 | }\r | |
221 | \r | |
222 | //-------------------------------------------------------------\r | |
223 | Int_t AliITSAlignMille2Module::GetIndexFromVolumeID(UShort_t voluid) {\r | |
224 | /// index from volume ID\r | |
225 | AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);\r | |
226 | if (lay<1|| lay>6) return -1;\r | |
227 | Int_t idx=Int_t(voluid)-2048*lay;\r | |
228 | if (idx>=AliGeomManager::LayerSize(lay)) return -1;\r | |
229 | for (Int_t ilay=1; ilay<lay; ilay++) \r | |
230 | idx += AliGeomManager::LayerSize(ilay);\r | |
231 | return idx;\r | |
232 | }\r | |
233 | \r | |
234 | //-------------------------------------------------------------\r | |
235 | void AliITSAlignMille2Module::AddSensitiveVolume(UShort_t voluid)\r | |
236 | {\r | |
237 | /// add a sensitive volume to this supermodule\r | |
238 | if (GetIndexFromVolumeID(voluid)<0) return; // bad volid\r | |
239 | //\r | |
240 | // in principle, the correct size of fSensVol... arrays was set outside but check anyway\r | |
241 | if (fSensVolVolumeID.GetSize()<fNSensVol) {\r | |
242 | fSensVolVolumeID.Set(fNSensVol+1);\r | |
243 | fSensVolIndex.Set(fNSensVol+1);\r | |
244 | }\r | |
245 | //\r | |
246 | fSensVolVolumeID[fNSensVol] = Short_t(voluid);\r | |
247 | fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);\r | |
248 | fNSensVol++;\r | |
249 | }\r | |
250 | \r | |
251 | //-------------------------------------------------------------\r | |
252 | void AliITSAlignMille2Module::DelSensitiveVolume(Int_t at)\r | |
253 | {\r | |
254 | // Suppress sensor at position "at"\r | |
255 | // in fact we are swapping with the last valid one \r | |
256 | int lastValid = --fNSensVol;\r | |
257 | int tmpv = fSensVolIndex[at];\r | |
258 | fSensVolIndex[at] = fSensVolIndex[lastValid];\r | |
259 | tmpv = fSensVolVolumeID[at];\r | |
260 | fSensVolVolumeID[at] = fSensVolVolumeID[lastValid];\r | |
261 | fSensVolVolumeID[lastValid] = tmpv;\r | |
262 | //\r | |
263 | }\r | |
264 | \r | |
265 | //-------------------------------------------------------------\r | |
266 | Bool_t AliITSAlignMille2Module::IsIn(UShort_t voluid) const \r | |
267 | {\r | |
268 | /// check if voluid is defined\r | |
269 | if (!voluid) return kFALSE; // only positive voluid are accepted\r | |
270 | for (Int_t i=0; i<fNSensVol; i++) if (UShort_t(fSensVolVolumeID[i])==voluid) return kTRUE;\r | |
271 | return kFALSE;\r | |
272 | }\r | |
273 | \r | |
274 | //-------------------------------------------------------------\r | |
275 | Bool_t AliITSAlignMille2Module::BelongsTo(AliITSAlignMille2Module* parent) const\r | |
276 | {\r | |
277 | /// check if parent contains the sensors of this volume\r | |
278 | if (fNSensVol<1 || fNSensVol>=parent->GetNSensitiveVolumes()) return kFALSE;\r | |
279 | return parent->IsIn( fSensVolVolumeID[0] );\r | |
280 | }\r | |
281 | \r | |
282 | //-------------------------------------------------------------\r | |
283 | TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *delta,Bool_t local)\r | |
284 | {\r | |
285 | // modify the original TGeoHMatrix of the sensitive module 'voluid' according\r | |
286 | // with a delta transform. applied to the supermodule matrix\r | |
287 | // return NULL if error\r | |
288 | \r | |
289 | if (!IsIn(voluid)) return NULL;\r | |
290 | if (!gGeoManager) return NULL;\r | |
291 | \r | |
292 | // prepare the TGeoHMatrix\r | |
293 | Double_t tr[3],ang[3];\r | |
294 | tr[0]=delta[0]; // in centimeter\r | |
295 | tr[1]=delta[1]; \r | |
296 | tr[2]=delta[2];\r | |
297 | ang[0]=delta[3]; // psi (X) in deg\r | |
298 | ang[1]=delta[4]; // theta (Y)\r | |
299 | ang[2]=delta[5]; // phi (Z)\r | |
300 | //\r | |
301 | fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r | |
302 | fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r | |
303 | AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r | |
304 | TGeoHMatrix hm;\r | |
305 | fgTempAlignObj.GetMatrix(hm);\r | |
306 | //printf("\n0: delta matrix\n");hm.Print();\r | |
307 | \r | |
308 | // 1) start setting fSensVolModif = fSensVol\r | |
309 | if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r | |
310 | //\r | |
311 | if (local) {\r | |
312 | // 2) set fSensVolModif = SensVolRel\r | |
313 | fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r | |
314 | // 3) multiply left by delta\r | |
315 | fSensVolModifMatrix->MultiplyLeft( &hm );\r | |
316 | // 4) multiply left by fMatrix\r | |
317 | fSensVolModifMatrix->MultiplyLeft( fMatrix );\r | |
318 | }\r | |
319 | else fSensVolModifMatrix->MultiplyLeft( &hm );\r | |
320 | //\r | |
321 | return fSensVolModifMatrix;\r | |
322 | }\r | |
323 | \r | |
324 | //-------------------------------------------------------------\r | |
325 | AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)\r | |
326 | {\r | |
327 | // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r | |
328 | // of the mother volume. The misalignment is returned as AliAlignObjParams object\r | |
329 | \r | |
330 | if (!IsIn(voluid)) return NULL;\r | |
331 | if (!gGeoManager) return NULL;\r | |
332 | \r | |
333 | // prepare the TGeoHMatrix\r | |
334 | Double_t tr[3],ang[3];\r | |
335 | tr[0]=deltalocal[0]; // in centimeter\r | |
336 | tr[1]=deltalocal[1]; \r | |
337 | tr[2]=deltalocal[2];\r | |
338 | ang[0]=deltalocal[3]; // psi (X) in deg\r | |
339 | ang[1]=deltalocal[4]; // theta (Y)\r | |
340 | ang[2]=deltalocal[5]; // phi (Z)\r | |
341 | //\r | |
342 | fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r | |
343 | fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r | |
344 | AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r | |
345 | //\r | |
346 | return GetSensitiveVolumeMisalignment(voluid,&fgTempAlignObj);\r | |
347 | }\r | |
348 | \r | |
349 | //-------------------------------------------------------------\r | |
350 | AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)\r | |
351 | {\r | |
352 | // return the misalignment of the sens. vol. 'voluid' corresponding with \r | |
353 | // a misalignment 'a' in the mother volume\r | |
354 | // return NULL if error\r | |
355 | \r | |
356 | // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r | |
357 | // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv\r | |
358 | // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv\r | |
359 | //\r | |
360 | // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)\r | |
361 | //\r | |
362 | \r | |
363 | if (!IsIn(voluid)) return NULL;\r | |
364 | if (!gGeoManager) return NULL;\r | |
365 | \r | |
366 | //a->Print("");\r | |
367 | \r | |
368 | // prepare the Delta matrix Dg\r | |
369 | TGeoHMatrix dg;\r | |
370 | a->GetMatrix(dg);\r | |
371 | //dg.Print();\r | |
372 | \r | |
373 | // 1) start setting fSensVolModif = Gsv\r | |
374 | if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r | |
375 | //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r | |
376 | \r | |
377 | // 2) set fSensVolModif = Gg-1 * Gsv\r | |
378 | fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r | |
379 | //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r | |
380 | \r | |
381 | // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r | |
382 | fSensVolModifMatrix->MultiplyLeft( &dg );\r | |
383 | //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r | |
384 | \r | |
385 | // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r | |
386 | fSensVolModifMatrix->MultiplyLeft( fMatrix );\r | |
387 | //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r | |
388 | \r | |
389 | // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv\r | |
390 | if (SensVolMatrix(voluid, &dg)) return NULL;\r | |
391 | fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r | |
392 | //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r | |
393 | //\r | |
394 | // >> RS\r | |
395 | // 6) mo' fSensVolModif dovrebbe essere la Dsv(loc) t.c. G'sv = Gsv*Dsv(loc)\r | |
396 | // per trasformarla in Dsv(loc rispetto al Gsv0, non modificato) dovrebbe essere:\r | |
397 | // Dsv(loc) -> Dpre * Dsv(loc) * Dpre-1\r | |
398 | //TGeoHMatrix dpre; // dpre = Gsv0-1*Gsv\r | |
399 | //if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;\r | |
400 | //if (SensVolMatrix(voluid, &dpre)) return NULL;\r | |
401 | //dpre.MultiplyLeft( &dg.Inverse() );\r | |
402 | //fSensVolModifMatrix->Multiply( &dpre.Inverse() );\r | |
403 | //fSensVolModifMatrix->MultiplyLeft( &dpre );\r | |
404 | // direi che NON FUNZIONA!!!! \r | |
405 | \r | |
406 | // << RS\r | |
407 | \r | |
408 | // reset align object (may not be needed...)\r | |
409 | fgTempAlignObj.SetVolUID(0);\r | |
410 | fgTempAlignObj.SetSymName("");\r | |
411 | fgTempAlignObj.SetTranslation(0,0,0);\r | |
412 | fgTempAlignObj.SetRotation(0,0,0);\r | |
413 | //\r | |
414 | // >> RS\r | |
415 | #ifdef CORHW_\r | |
416 | // correction for SPD y-shift\r | |
417 | if (voluid>=2048 && voluid<4256) {\r | |
418 | TGeoHMatrix deltay;\r | |
419 | double dy[3]={0.,0.0081,0.};\r | |
420 | deltay.SetTranslation(dy);\r | |
421 | fSensVolModifMatrix->MultiplyLeft( &deltay );\r | |
422 | fSensVolModifMatrix->Multiply( &deltay.Inverse() );\r | |
423 | }\r | |
424 | #endif\r | |
425 | // << RS\r | |
426 | if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r | |
427 | fgTempAlignObj.SetVolUID(voluid);\r | |
428 | fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r | |
429 | //\r | |
430 | return &fgTempAlignObj;\r | |
431 | }\r | |
432 | \r | |
433 | // >> RS\r | |
434 | //-------------------------------------------------------------\r | |
435 | AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeTotalMisalignment(UShort_t voluid, Double_t *deltalocal)\r | |
436 | {\r | |
437 | // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r | |
438 | // of the mother volume. The misalignment is returned as AliAlignObjParams object including\r | |
439 | // the (evenctual) prealignment => no merging needed\r | |
440 | \r | |
441 | if (!IsIn(voluid)) return NULL;\r | |
442 | if (!gGeoManager) return NULL;\r | |
443 | \r | |
444 | // prepare the TGeoHMatrix\r | |
445 | Double_t tr[3],ang[3];\r | |
446 | tr[0]=deltalocal[0]; // in centimeter\r | |
447 | tr[1]=deltalocal[1]; \r | |
448 | tr[2]=deltalocal[2];\r | |
449 | ang[0]=deltalocal[3]; // psi (X) in deg\r | |
450 | ang[1]=deltalocal[4]; // theta (Y)\r | |
451 | ang[2]=deltalocal[5]; // phi (Z)\r | |
452 | \r | |
453 | // reset align object (may not be needed...)\r | |
454 | fgTempAlignObj.SetVolUID(0);\r | |
455 | fgTempAlignObj.SetSymName("");\r | |
456 | fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r | |
457 | fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r | |
458 | AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r | |
459 | \r | |
460 | // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r | |
461 | // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv \r | |
462 | //\r | |
463 | // => Dsv = (G0sv-1 * Gg * Dg * Gg-1 * GMsv) //\r | |
464 | //\r | |
465 | \r | |
466 | // prepare the Delta matrix Dg\r | |
467 | TGeoHMatrix dg;\r | |
468 | fgTempAlignObj.GetMatrix(dg);\r | |
469 | //dg.Print();\r | |
470 | \r | |
471 | // 1) start setting fSensVolModif = Gsv\r | |
472 | if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;\r | |
473 | //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();\r | |
474 | \r | |
475 | // 2) set fSensVolModif = Gg-1 * Gsv\r | |
476 | fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );\r | |
477 | //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();\r | |
478 | \r | |
479 | // 3) set fSensVolModif = Dg * Gg-1 * Gsv\r | |
480 | fSensVolModifMatrix->MultiplyLeft( &dg );\r | |
481 | //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();\r | |
482 | \r | |
483 | // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv\r | |
484 | fSensVolModifMatrix->MultiplyLeft( fMatrix );\r | |
485 | //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();\r | |
486 | \r | |
487 | // 5) set fSensVolModif = G0sv-1 * Gg * Dg * Gg-1 * Gsv\r | |
488 | // qui usa l'orig anziche' la prealigned...\r | |
489 | if (SensVolOrigGlobalMatrix(voluid, &dg)) return NULL;\r | |
490 | fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );\r | |
491 | //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();\r | |
492 | \r | |
493 | // reset align object (may not be needed...)\r | |
494 | fgTempAlignObj.SetVolUID(0);\r | |
495 | fgTempAlignObj.SetSymName("");\r | |
496 | fgTempAlignObj.SetTranslation(0,0,0);\r | |
497 | fgTempAlignObj.SetRotation(0,0,0);\r | |
498 | \r | |
499 | #ifdef CORHW_\r | |
500 | // correction for SPD y-shift\r | |
501 | if (voluid>=2048 && voluid<4256) {\r | |
502 | TGeoHMatrix deltay;\r | |
503 | double dy[3]={0.,0.0081,0.};\r | |
504 | deltay.SetTranslation(dy);\r | |
505 | fSensVolModifMatrix->MultiplyLeft( &deltay );\r | |
506 | fSensVolModifMatrix->Multiply( &deltay.Inverse() );\r | |
507 | }\r | |
508 | #endif\r | |
509 | if (!fgTempAlignObj.SetMatrix(*fSensVolModifMatrix)) return NULL;\r | |
510 | fgTempAlignObj.SetVolUID(voluid);\r | |
511 | fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r | |
512 | \r | |
513 | \r | |
514 | //fgTempAlignObj.Print("");\r | |
515 | \r | |
516 | return &fgTempAlignObj;\r | |
517 | }\r | |
518 | //-------------------------------------------------------------\r | |
519 | \r | |
520 | //-------------------------------------------------------------\r | |
521 | AliAlignObjParams *AliITSAlignMille2Module::GetSensitiveVolumeGlobalMisalignment(UShort_t voluid, Double_t *deltalocal)\r | |
522 | {\r | |
523 | // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'\r | |
524 | // of the mother volume. The misalignment is returned as AliAlignObjParams object\r | |
525 | \r | |
526 | if (!IsIn(voluid)) return NULL;\r | |
527 | if (!gGeoManager) return NULL;\r | |
528 | \r | |
529 | // prepare the TGeoHMatrix\r | |
530 | Double_t tr[3],ang[3];\r | |
531 | tr[0]=deltalocal[0]; // in centimeter\r | |
532 | tr[1]=deltalocal[1]; \r | |
533 | tr[2]=deltalocal[2];\r | |
534 | ang[0]=deltalocal[3]; // psi (X) in deg\r | |
535 | ang[1]=deltalocal[4]; // theta (Y)\r | |
536 | ang[2]=deltalocal[5]; // phi (Z)\r | |
537 | \r | |
538 | // reset align object (may not be needed...)\r | |
539 | fgTempAlignObj.SetTranslation(0,0,0);\r | |
540 | fgTempAlignObj.SetRotation(0,0,0);\r | |
541 | \r | |
542 | fgTempAlignObj.SetRotation(ang[0],ang[1],ang[2]);\r | |
543 | fgTempAlignObj.SetTranslation(tr[0],tr[1],tr[2]);\r | |
544 | AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));\r | |
545 | \r | |
546 | // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv\r | |
547 | // G'sv = Gg * Dg * Lsv,g === DGsv * Gsv \r | |
548 | //\r | |
549 | // => DGsv = (Gg * Dg * Gg-1)\r | |
550 | //\r | |
551 | \r | |
552 | // prepare the Delta matrix Dg\r | |
553 | TGeoHMatrix dg;\r | |
554 | fgTempAlignObj.GetMatrix(dg);\r | |
555 | //dg.Print();\r | |
556 | \r | |
557 | dg.MultiplyLeft( fMatrix );\r | |
558 | dg.Multiply( &fMatrix->Inverse() );\r | |
559 | \r | |
560 | // reset align object (may not be needed...)\r | |
561 | fgTempAlignObj.SetTranslation(0,0,0);\r | |
562 | fgTempAlignObj.SetRotation(0,0,0);\r | |
563 | \r | |
564 | fgTempAlignObj.SetVolUID(voluid);\r | |
565 | fgTempAlignObj.SetSymName(AliGeomManager::SymName(voluid));\r | |
566 | \r | |
567 | if (!fgTempAlignObj.SetMatrix(dg)) return NULL;\r | |
568 | \r | |
569 | //fgTempAlignObj.Print("");\r | |
570 | \r | |
571 | return &fgTempAlignObj;\r | |
572 | }\r | |
573 | // << RS\r | |
574 | \r | |
575 | //-------------------------------------------------------------\r | |
576 | TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeMatrix(UShort_t voluid)\r | |
577 | {\r | |
578 | // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry\r | |
579 | if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;\r | |
580 | return fSensVolMatrix;\r | |
581 | }\r | |
582 | \r | |
583 | //-------------------------------------------------------------\r | |
584 | TGeoHMatrix *AliITSAlignMille2Module::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)\r | |
585 | {\r | |
586 | // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())\r | |
587 | if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;\r | |
588 | return fSensVolMatrix;\r | |
589 | }\r | |
590 | //-------------------------------------------------------------\r | |
591 | Int_t AliITSAlignMille2Module::SensVolMatrix(UShort_t volid, TGeoHMatrix *m) \r | |
592 | {\r | |
593 | // set matrix for sensitive modules (SPD corrected)\r | |
594 | // return 0 if success\r | |
595 | Double_t rot[9];\r | |
596 | Int_t idx=GetIndexFromVolumeID(volid);\r | |
597 | if (idx<0) return -1;\r | |
598 | if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;\r | |
599 | m->SetRotation(rot);\r | |
600 | Double_t oLoc[3]={0,0,0};\r | |
601 | Double_t oGlo[3]={0,0,0};\r | |
602 | if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;\r | |
603 | m->SetTranslation(oGlo);\r | |
604 | return 0;\r | |
605 | }\r | |
606 | \r | |
607 | //-------------------------------------------------------------\r | |
608 | Int_t AliITSAlignMille2Module::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m) \r | |
609 | {\r | |
610 | // set original global matrix for sensitive modules (SPD corrected)\r | |
611 | // return 0 if success\r | |
612 | Int_t idx=GetIndexFromVolumeID(volid);\r | |
613 | if (idx<0) return -1;\r | |
614 | TGeoHMatrix mo;\r | |
615 | if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo));\r | |
616 | (*m)=mo;\r | |
617 | \r | |
618 | #ifdef CORHW_\r | |
619 | // SPD y-shift by 81 mu\r | |
620 | if (volid<5000) { \r | |
621 | Double_t oLoc[3]={0.0,0.0081,0.0};\r | |
622 | Double_t oGlo[3]={0,0,0};\r | |
623 | m->LocalToMaster(oLoc,oGlo);\r | |
624 | m->SetTranslation(oGlo);\r | |
625 | }\r | |
626 | #endif\r | |
627 | return 0;\r | |
628 | }\r | |
629 | \r | |
630 | //-------------------------------------------------------------\r | |
631 | UShort_t AliITSAlignMille2Module::GetVolumeIDFromSymname(const Char_t *symname) {\r | |
632 | /// volume ID from symname\r | |
633 | if (!symname) return 0;\r | |
634 | \r | |
635 | for (UShort_t voluid=2000; voluid<13300; voluid++) {\r | |
636 | Int_t modId;\r | |
637 | AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);\r | |
638 | if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {\r | |
639 | if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;\r | |
640 | }\r | |
641 | }\r | |
642 | \r | |
643 | return 0;\r | |
644 | }\r | |
645 | \r | |
646 | //-------------------------------------------------------------\r | |
647 | UShort_t AliITSAlignMille2Module::GetVolumeIDFromIndex(Int_t index) {\r | |
648 | /// volume ID from index\r | |
649 | if (index<0 || index>2197) return 0;\r | |
650 | return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));\r | |
651 | }\r | |
652 | \r | |
653 | //-------------------------------------------------------------\r | |
654 | void AliITSAlignMille2Module::Print(Option_t*) const \r | |
655 | {\r | |
656 | ///\r | |
657 | printf("*** ITS SuperModule for AliITSAlignMille ***\n");\r | |
658 | printf("symname : %s\n",GetName());\r | |
659 | printf("parent : %s\n",fParent ? fParent->GetName() : "N/A");\r | |
660 | printf("volumeID : %4d | index : %4d\n",fVolumeID,fIndex);\r | |
661 | printf("Factors : X=%.2f Y=%.2f Z=%.2f | DOF: Tx:%d Ty:%d Tz:%d Phi:%d Theta:%d Psi:%d\n",\r | |
662 | fSigmaFactor[0],fSigmaFactor[1],fSigmaFactor[2],\r | |
663 | IsFreeDOF(AliITSAlignMille2::kDOFTX),IsFreeDOF(AliITSAlignMille2::kDOFTY),\r | |
664 | IsFreeDOF(AliITSAlignMille2::kDOFTZ),IsFreeDOF(AliITSAlignMille2::kDOFPH),\r | |
665 | IsFreeDOF(AliITSAlignMille2::kDOFTH),IsFreeDOF(AliITSAlignMille2::kDOFPS));\r | |
666 | fMatrix->Print();\r | |
667 | printf("%4d Sensitive volumes | %6d Processed Points\n",fNSensVol,fNProcPoints);\r | |
668 | for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,UShort_t(fSensVolVolumeID[i]));\r | |
669 | }\r | |
670 | \r | |
671 | //-------------------------------------------------------------\r | |
672 | Bool_t AliITSAlignMille2Module::IsAlignable() const\r | |
673 | {\r | |
674 | TGeoManager* geoManager = AliGeomManager::GetGeometry();\r | |
675 | if (!geoManager) {\r | |
676 | AliInfo("Couldn't initialize geometry");\r | |
677 | return kFALSE;\r | |
678 | }\r | |
679 | return geoManager->GetAlignableEntry(GetName())!=0;\r | |
680 | }\r | |
681 | \r | |
682 | //-------------------------------------------------------------\r | |
683 | void AliITSAlignMille2Module::GetLocalMatrix(TGeoHMatrix &mat) const\r | |
684 | {\r | |
685 | // return the local matrix for transformation to its parent\r | |
686 | mat = *fMatrix;\r | |
687 | if (fParent) mat.MultiplyLeft( &fParent->GetMatrix()->Inverse() );\r | |
688 | }\r |