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