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