1 /**************************************************************************
\r
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
\r
4 * Author: The ALICE Off-line Project. *
\r
5 * Contributors are mentioned in the code where appropriate. *
\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
17 //-----------------------------------------------------------------------------
\r
18 /// \class AliITSAlignMilleModule
\r
19 /// Alignment class for the ALICE ITS detector
\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
24 /// Custom supermodules must have VolumeID > 14335
\r
26 /// \author M. Lunardon
\r
27 //-----------------------------------------------------------------------------
\r
29 #include <TGeoManager.h>
\r
30 #include <TGeoMatrix.h>
\r
32 #include "AliITSAlignMilleModule.h"
\r
33 #include "AliITSgeomTGeo.h"
\r
34 #include "AliGeomManager.h"
\r
35 #include "AliAlignObjParams.h"
\r
36 #include "AliLog.h"
\r
39 ClassImp(AliITSAlignMilleModule)
\r
42 //-------------------------------------------------------------
\r
43 AliITSAlignMilleModule::AliITSAlignMilleModule() : TNamed(),
\r
48 fSensVolMatrix(NULL),
\r
49 fSensVolModifMatrix(NULL),
\r
52 /// void constructor
\r
53 fMatrix = new TGeoHMatrix;
\r
54 fSensVolMatrix = new TGeoHMatrix;
\r
55 fSensVolModifMatrix = new TGeoHMatrix;
\r
56 fTempAlignObj=new AliAlignObjParams;
\r
58 //-------------------------------------------------------------
\r
59 AliITSAlignMilleModule::AliITSAlignMilleModule(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv) : TNamed(),
\r
64 fSensVolMatrix(NULL),
\r
65 fSensVolModifMatrix(NULL),
\r
68 /// void constructor
\r
69 fMatrix = new TGeoHMatrix;
\r
70 fSensVolMatrix = new TGeoHMatrix;
\r
71 fSensVolModifMatrix = new TGeoHMatrix;
\r
72 fTempAlignObj=new AliAlignObjParams;
\r
73 if (Set(index,volid,symname,m,nsv,volidsv)) {
\r
74 AliInfo("Error in AliITSAlignMilleModule::Set() - initializing void supermodule...");
\r
77 //-------------------------------------------------------------
\r
78 AliITSAlignMilleModule::AliITSAlignMilleModule(UShort_t volid) : TNamed(),
\r
83 fSensVolMatrix(NULL),
\r
84 fSensVolModifMatrix(NULL),
\r
87 /// simple constructor building a supermodule from a single sensitive volume
\r
88 fMatrix = new TGeoHMatrix;
\r
89 fSensVolMatrix = new TGeoHMatrix;
\r
90 fSensVolModifMatrix = new TGeoHMatrix;
\r
91 // temporary align object, just use the rotation...
\r
92 fTempAlignObj=new AliAlignObjParams;
\r
94 fIndex = GetIndexFromVolumeID(volid);
\r
95 if (fIndex>=0 && gGeoManager) { // good sensitive module and geometry loaded
\r
96 SetName(AliGeomManager::SymName(volid));
\r
98 AddSensitiveVolume(volid);
\r
99 if (SensVolMatrix(volid, fMatrix))
\r
100 AliInfo("Matrix not defined");
\r
103 AliInfo("Wrong VolumeID or Geometry not loaded - initializing void supermodule...");
\r
106 //-------------------------------------------------------------
\r
107 AliITSAlignMilleModule::~AliITSAlignMilleModule() {
\r
110 delete fSensVolMatrix;
\r
111 delete fSensVolModifMatrix;
\r
112 delete fTempAlignObj;
\r
114 //-------------------------------------------------------------
\r
115 Int_t AliITSAlignMilleModule::Set(Int_t index, UShort_t volid, char* symname, TGeoHMatrix *m, Int_t nsv, UShort_t *volidsv)
\r
117 // initialize a custom supermodule
\r
118 // index, volid, symname and matrix must be given
\r
119 // if (volidsv) add nsv sensitive volumes to the supermodules
\r
120 // return 0 if success
\r
123 AliInfo("Index must be >= 2198");
\r
127 AliInfo("VolumeID must be >= 14336");
\r
131 if (!symname) return -3;
\r
132 for (Int_t i=0; i<2198; i++) {
\r
133 if (!strcmp(symname,AliITSgeomTGeo::GetSymName(i))) {
\r
134 AliInfo("Symname already used by a Sensitive Volume");
\r
141 // can initialize needed stuffs
\r
147 // add sensitive volumes
\r
148 for (Int_t i=0; i<nsv; i++) AddSensitiveVolume(volidsv[i]);
\r
152 //-------------------------------------------------------------
\r
153 Int_t AliITSAlignMilleModule::GetIndexFromVolumeID(UShort_t voluid) {
\r
154 /// index from volume ID
\r
155 AliGeomManager::ELayerID lay = AliGeomManager::VolUIDToLayer(voluid);
\r
156 if (lay<1|| lay>6) return -1;
\r
157 Int_t idx=Int_t(voluid)-2048*lay;
\r
158 if (idx>=AliGeomManager::LayerSize(lay)) return -1;
\r
159 for (Int_t ilay=1; ilay<lay; ilay++)
\r
160 idx += AliGeomManager::LayerSize(ilay);
\r
163 //-------------------------------------------------------------
\r
164 void AliITSAlignMilleModule::AddSensitiveVolume(UShort_t voluid)
\r
166 /// add a sensitive volume to this supermodule
\r
167 if (GetIndexFromVolumeID(voluid)<0) return; // bad volid
\r
168 fSensVolVolumeID[fNSensVol] = voluid;
\r
169 fSensVolIndex[fNSensVol] = GetIndexFromVolumeID(voluid);
\r
172 //-------------------------------------------------------------
\r
173 Bool_t AliITSAlignMilleModule::IsIn(UShort_t voluid) const
\r
175 /// check if voluid is defined
\r
176 if (!voluid) return kFALSE; // only positive voluid are accepted
\r
177 for (Int_t i=0; i<fNSensVol; i++) {
\r
178 if (fSensVolVolumeID[i]==voluid) return kTRUE;
\r
182 //-------------------------------------------------------------
\r
183 TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeModifiedMatrix(UShort_t voluid, Double_t *deltalocal)
\r
185 // modify the original TGeoHMatrix of the sensitive module 'voluid' according
\r
186 // with a delta transform. applied to the supermodule matrix
\r
187 // return NULL if error
\r
189 if (!IsIn(voluid)) return NULL;
\r
190 if (!gGeoManager) return NULL;
\r
192 // prepare the TGeoHMatrix
\r
193 Double_t tr[3],ang[3];
\r
194 tr[0]=deltalocal[0]; // in centimeter
\r
195 tr[1]=deltalocal[1];
\r
196 tr[2]=deltalocal[2];
\r
197 ang[0]=deltalocal[3]; // psi (X) in deg
\r
198 ang[1]=deltalocal[4]; // theta (Y)
\r
199 ang[2]=deltalocal[5]; // phi (Z)
\r
201 // reset align object (may not be needed...)
\r
202 fTempAlignObj->SetTranslation(0,0,0);
\r
203 fTempAlignObj->SetRotation(0,0,0);
\r
205 fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
\r
206 fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);
\r
207 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
209 fTempAlignObj->GetMatrix(hm);
\r
210 //printf("\n0: delta matrix\n");hm.Print();
\r
212 // 1) start setting fSensVolModif = fSensVol
\r
213 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
214 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
216 // 2) set fSensVolModif = SensVolRel
\r
217 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
218 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
220 // 3) multiply left by delta
\r
221 fSensVolModifMatrix->MultiplyLeft( &hm );
\r
222 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
224 // 4) multiply left by fMatrix
\r
225 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
226 //printf("\n4: modif=finale\n");fSensVolModifMatrix->Print();
\r
228 return fSensVolModifMatrix;
\r
230 //-------------------------------------------------------------
\r
231 AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, Double_t *deltalocal)
\r
233 // calculate misalignment of sens.vol. 'voluid' according with a displacement 'deltalocal'
\r
234 // of the mother volume. The misalignment is returned as AliAlignObjParams object
\r
236 if (!IsIn(voluid)) return NULL;
\r
237 if (!gGeoManager) return NULL;
\r
239 // prepare the TGeoHMatrix
\r
240 Double_t tr[3],ang[3];
\r
241 tr[0]=deltalocal[0]; // in centimeter
\r
242 tr[1]=deltalocal[1];
\r
243 tr[2]=deltalocal[2];
\r
244 ang[0]=deltalocal[3]; // psi (X) in deg
\r
245 ang[1]=deltalocal[4]; // theta (Y)
\r
246 ang[2]=deltalocal[5]; // phi (Z)
\r
248 // reset align object (may not be needed...)
\r
249 fTempAlignObj->SetTranslation(0,0,0);
\r
250 fTempAlignObj->SetRotation(0,0,0);
\r
252 fTempAlignObj->SetRotation(ang[0],ang[1],ang[2]);
\r
253 fTempAlignObj->SetTranslation(tr[0],tr[1],tr[2]);
\r
254 AliDebug(3,Form("Delta angles: psi=%f theta=%f phi=%f",ang[0],ang[1],ang[2]));
\r
256 return GetSensitiveVolumeMisalignment(voluid,fTempAlignObj);
\r
258 //-------------------------------------------------------------
\r
259 AliAlignObjParams *AliITSAlignMilleModule::GetSensitiveVolumeMisalignment(UShort_t voluid, AliAlignObjParams *a)
\r
261 // return the misalignment of the sens. vol. 'voluid' corresponding with
\r
262 // a misalignment 'a' in the mother volume
\r
263 // return NULL if error
\r
265 // Gsv = Gg * Gg-1 * Gsv -> Lsv,g = Gg-1 * Gsv
\r
266 // G'sv = Gg * Dg * Lsv,g === Gsv * Dsv
\r
267 // Gg * Dg * Gg-1 * Gsv = Gsv * Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
269 // => Dsv = (Gsv-1 * Gg * Dg * Gg-1 * Gsv)
\r
272 if (!IsIn(voluid)) return NULL;
\r
273 if (!gGeoManager) return NULL;
\r
277 // prepare the Delta matrix Dg
\r
282 // 1) start setting fSensVolModif = Gsv
\r
283 if (SensVolMatrix(voluid, fSensVolModifMatrix)) return NULL;
\r
284 //printf("\n1: modif=orig del sensvol\n");fSensVolModifMatrix->Print();
\r
286 // 2) set fSensVolModif = Gg-1 * Gsv
\r
287 fSensVolModifMatrix->MultiplyLeft( &fMatrix->Inverse() );
\r
288 //printf("\n2: modif=relative del sensvol\n");fSensVolModifMatrix->Print();
\r
290 // 3) set fSensVolModif = Dg * Gg-1 * Gsv
\r
291 fSensVolModifMatrix->MultiplyLeft( &dg );
\r
292 //printf("\n3: modif= delta*relative\n");fSensVolModifMatrix->Print();
\r
294 // 4) set fSensVolModif = Gg * Dg * Gg-1 * Gsv
\r
295 fSensVolModifMatrix->MultiplyLeft( fMatrix );
\r
296 //printf("\n4: modif=quasi,manca il Gsv-1...\n");fSensVolModifMatrix->Print();
\r
298 // 5) set fSensVolModif = Gsv-1 * Gg * Dg * Gg-1 * Gsv
\r
299 if (SensVolMatrix(voluid, &dg)) return NULL;
\r
300 fSensVolModifMatrix->MultiplyLeft( &dg.Inverse() );
\r
301 //printf("\n5: modif=finale\n");fSensVolModifMatrix->Print();
\r
303 // reset align object (may not be needed...)
\r
304 fTempAlignObj->SetTranslation(0,0,0);
\r
305 fTempAlignObj->SetRotation(0,0,0);
\r
307 if (!fTempAlignObj->SetMatrix(*fSensVolModifMatrix)) return NULL;
\r
308 fTempAlignObj->SetVolUID(voluid);
\r
309 fTempAlignObj->SetSymName(AliGeomManager::SymName(voluid));
\r
311 //fTempAlignObj->Print("");
\r
313 return fTempAlignObj;
\r
315 //-------------------------------------------------------------
\r
316 TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeMatrix(UShort_t voluid)
\r
318 // return TGeoHMatrix of the sens.vol. 'voluid' in the current geometry
\r
319 if (SensVolMatrix(voluid,fSensVolMatrix)) return NULL;
\r
320 return fSensVolMatrix;
\r
322 //-------------------------------------------------------------
\r
323 TGeoHMatrix *AliITSAlignMilleModule::GetSensitiveVolumeOrigGlobalMatrix(UShort_t voluid)
\r
325 // return original ideal position (from AliGeomManager::GetOrigGlobalMatrix())
\r
326 if (SensVolOrigGlobalMatrix(voluid,fSensVolMatrix)) return NULL;
\r
327 return fSensVolMatrix;
\r
329 //-------------------------------------------------------------
\r
330 Int_t AliITSAlignMilleModule::SensVolMatrix(UShort_t volid, TGeoHMatrix *m)
\r
332 // set matrix for sensitive modules (SPD corrected)
\r
333 // return 0 if success
\r
335 Int_t idx=GetIndexFromVolumeID(volid);
\r
336 if (idx<0) return -1;
\r
337 if (!AliITSgeomTGeo::GetRotation(idx,rot)) return -2;
\r
338 m->SetRotation(rot);
\r
339 Double_t oLoc[3]={0,0,0};
\r
340 Double_t oGlo[3]={0,0,0};
\r
341 if (!AliITSgeomTGeo::LocalToGlobal(idx,oLoc,oGlo)) return -3;
\r
342 m->SetTranslation(oGlo);
\r
345 //-------------------------------------------------------------
\r
346 Int_t AliITSAlignMilleModule::SensVolOrigGlobalMatrix(UShort_t volid, TGeoHMatrix *m)
\r
348 // set original global matrix for sensitive modules (SPD corrected)
\r
349 // return 0 if success
\r
350 Int_t idx=GetIndexFromVolumeID(volid);
\r
351 if (idx<0) return -1;
\r
353 if (!AliGeomManager::GetOrigGlobalMatrix(AliGeomManager::SymName(volid),mo));
\r
356 // SPD y-shift by 81 mu
\r
357 Double_t oLoc[3]={0.0,0.0081,0.0};
\r
358 Double_t oGlo[3]={0,0,0};
\r
359 m->LocalToMaster(oLoc,oGlo);
\r
360 m->SetTranslation(oGlo);
\r
363 //-------------------------------------------------------------
\r
364 UShort_t AliITSAlignMilleModule::GetVolumeIDFromSymname(const Char_t *symname) {
\r
365 /// volume ID from symname
\r
366 if (!symname) return 0;
\r
368 for (UShort_t voluid=2000; voluid<13300; voluid++) {
\r
370 AliGeomManager::ELayerID layerId = AliGeomManager::VolUIDToLayer(voluid,modId);
\r
371 if (layerId>0 && layerId<7 && modId>=0 && modId<AliGeomManager::LayerSize(layerId)) {
\r
372 if (!strcmp(symname,AliGeomManager::SymName(layerId,modId))) return voluid;
\r
379 UShort_t AliITSAlignMilleModule::GetVolumeIDFromIndex(Int_t index) {
\r
380 /// volume ID from index
\r
381 if (index<0 || index>2197) return 0;
\r
382 return GetVolumeIDFromSymname(AliITSgeomTGeo::GetSymName(index));
\r
384 //-------------------------------------------------------------
\r
385 void AliITSAlignMilleModule::Print(Option_t*) const
\r
388 printf("*** ITS SuperModule for AliITSAlignMille ***\n");
\r
389 printf("symname : %s\n",GetName());
\r
390 printf("volumeID : %d\n",fVolumeID);
\r
391 printf("index : %d\n",fIndex);
\r
393 printf("number of sensitive modules : %d\n",fNSensVol);
\r
394 for (Int_t i=0; i<fNSensVol; i++) printf(" voluid[%d] = %d\n",i,fSensVolVolumeID[i]);
\r
396 //_____________________________________________________________________________
\r
397 AliITSAlignMilleModule::AliITSAlignMilleModule(const AliITSAlignMilleModule &m) :
\r
399 fNSensVol(m.fNSensVol),
\r
401 fVolumeID(m.fVolumeID),
\r
402 fMatrix(new TGeoHMatrix(*m.GetMatrix())),
\r
403 fSensVolMatrix(new TGeoHMatrix),
\r
404 fSensVolModifMatrix(new TGeoHMatrix),
\r
405 fTempAlignObj(new AliAlignObjParams)
\r
407 // Copy constructor
\r
408 for (int i=0; i<fNSensVol; i++) {
\r
409 fSensVolIndex[i]=m.fSensVolIndex[i];
\r
410 fSensVolVolumeID[i]=m.fSensVolVolumeID[i];
\r
413 //_____________________________________________________________________________
\r
414 AliITSAlignMilleModule& AliITSAlignMilleModule::operator=(const AliITSAlignMilleModule &m)
\r
418 if(this==&m) return *this;
\r
419 ((TNamed *)this)->operator=(m);
\r
421 fNSensVol=m.fNSensVol;
\r
423 fVolumeID=m.fVolumeID;
\r
425 fMatrix=new TGeoHMatrix(*m.GetMatrix());
\r
426 for (int i=0; i<fNSensVol; i++) {
\r
427 fSensVolIndex[i]=m.fSensVolIndex[i];
\r
428 fSensVolVolumeID[i]=m.fSensVolVolumeID[i];
\r
433 //_____________________________________________________________________________
\r