Update for Ds
[u/mrichter/AliRoot.git] / ITS / AliITSgeomTGeo.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 ///////////////////////////////////////////////////////////////////////////
17 //    AliITSgeomTGeo is a simple interface class to TGeoManager          //
18 //    It is used in the simulation and reconstruction in order to        //
19 //    query the TGeo ITS geometry                                        //
20 //                                                                       //
21 //    author - cvetan.cheshkov@cern.ch                                   //
22 //    15/02/2007                                                         //
23 ///////////////////////////////////////////////////////////////////////////
24
25 #include <TClass.h>
26 #include <TString.h>
27 #include <TGeoManager.h>
28 #include <TGeoPhysicalNode.h>
29
30 #include "AliITSgeomTGeo.h"
31 #include "AliLog.h"
32 #include "AliAlignObj.h"
33
34 ClassImp(AliITSgeomTGeo)
35
36 const Int_t AliITSgeomTGeo::fgkNModules = 2198;
37 const Int_t AliITSgeomTGeo::fgkNLadders[kNLayers] = {20,40,14,22,34,38};
38 const Int_t AliITSgeomTGeo::fgkNDetectors[kNLayers] = {4,4,6,8,22,25};
39
40 //______________________________________________________________________
41 Int_t AliITSgeomTGeo::GetModuleIndex(Int_t lay,Int_t lad,Int_t det)
42 {
43   // The method is taken from the old AliITSgeom class by Bjorn Nilsen
44   //
45   // This routine computes the module index number from the layer,
46   // ladder, and detector numbers. The number of ladders and detectors
47   // per layer is set statically
48   // see above for details.
49   // Inputs:
50   //    Int_t lay  The layer number. Starting from 1.
51   //    Int_t lad  The ladder number. Starting from 1.
52   //    Int_t det  The detector number. Starting from 1.
53   // Return:
54   //    the module index number, starting from zero.
55   //    -1 in case of error
56
57   if (lay < 1 || lay > kNLayers) {
58     AliErrorClass(Form("Invalid layer: %d (1 -> %d",lay,kNLayers));
59     return -1;
60   }
61
62   if (lad < 1 || lad > fgkNLadders[lay-1] ||
63       det < 1 || det > fgkNDetectors[lay-1]) {
64     AliErrorClass(Form("Invalid layer,ladder,detector combination: %d, %d, %d",lay,lad,det));
65     return -1;
66   }
67
68   Int_t index = fgkNDetectors[lay-1] * (lad-1) + (det-1);
69   for(Int_t iLayer=0;iLayer < (lay-1); iLayer++)
70     index += fgkNDetectors[iLayer]*fgkNLadders[iLayer];
71
72   return index;
73 }
74
75 //______________________________________________________________________
76 Bool_t AliITSgeomTGeo::GetLayer(Int_t index,Int_t &lay,Int_t &index2) 
77 {
78   // The method is taken from the old AliITSgeom class by Bjorn Nilsen
79   //
80   // This routine computes the layer number for a
81   // given the module index. The number of ladders and detectors
82   // per layer is defined statically,
83   // see above for details.
84   // Inputs:
85   //     Int_t index  The module index number, starting from zero.
86   // Outputs:
87   //     Int_t index2 The module index inside a layer, starting from zero.
88   //     Int_t lay    The layer number. Starting from 1.
89   // Return:
90   //     kTRUE in case of valid index
91   //     kFALSE in case of error
92
93   if (index < 0 || index >= fgkNModules) {
94     index2 = -1;
95     AliErrorClass(Form("Invalid module index: %d (0 -> %d)",index,fgkNModules));
96     return -1;
97   }
98
99   lay = 0;
100   index2 = 0;
101   do {
102     index2 += fgkNLadders[lay]*fgkNDetectors[lay];
103     lay++;
104   } while(index2 <= index);
105   index2 -= fgkNLadders[lay-1]*fgkNDetectors[lay-1];
106   index2 = index - index2;
107
108   return lay;
109 }
110
111 //______________________________________________________________________
112 Bool_t AliITSgeomTGeo::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det) 
113 {
114   // The method is taken from the old AliITSgeom class by Bjorn Nilsen
115   //
116   // This routine computes the layer, ladder and detector number 
117   // given the module index number. The number of ladders and detectors
118   // per layer is defined statically,
119   // see above for details.
120   // Inputs:
121   //     Int_t index  The module index number, starting from zero.
122   // Outputs:
123   //     Int_t lay    The layer number. Starting from 1.
124   //     Int_t lad    The ladder number. Starting from 1.
125   //     Int_t det    The detector number. Starting from 1.
126   // Return:
127   //     kTRUE in case of valid index
128   //     kFALSE in case of error
129
130   if (index < 0 || index >= fgkNModules) {
131     lay = lad = det = -1;
132     AliErrorClass(Form("Invalid module index: %d (0 -> %d)",index,fgkNModules));
133     return kFALSE;
134   }
135
136   lay  = lad = det = 0;
137   Int_t index2 = 0;
138   do {
139     index2 += fgkNLadders[lay]*fgkNDetectors[lay];
140     lay++;
141   } while(index2 <= index);
142   index2 -= fgkNLadders[lay-1]*fgkNDetectors[lay-1];
143
144   do {
145     index2 += fgkNDetectors[lay-1];
146     lad++;
147   } while(index2 <= index);
148   index2 -= fgkNDetectors[lay-1];
149
150   det = index-index2+1;
151
152   return kTRUE;
153 }
154
155 //______________________________________________________________________
156 const char* AliITSgeomTGeo::GetSymName(Int_t index) 
157 {
158   // Get the TGeoPNEntry symbolic name
159   // for a given module identified by 'index'
160
161   if (index < 0 || index >= fgkNModules) {
162     AliErrorClass(Form("Invalid ITS module index: %d (0 -> %d) !",index,fgkNModules));
163     return NULL;
164   }
165
166   Int_t lay, index2;
167   if (!GetLayer(index,lay,index2)) return NULL;
168
169   return AliGeomManager::SymName((AliGeomManager::ELayerID)((lay-1)+AliGeomManager::kSPD1),index2);
170 }
171
172 //______________________________________________________________________
173 TGeoHMatrix* AliITSgeomTGeo::GetMatrix(Int_t index) 
174 {
175   // Get the transformation matrix for a given module 'index'
176   // by quering the TGeoManager
177
178   TGeoPNEntry *pne = GetPNEntry(index);
179   if (!pne) return NULL;
180
181   TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
182   if (pnode) return pnode->GetMatrix();
183
184   const char* path = pne->GetTitle();
185   if (!gGeoManager->cd(path)) {
186     AliErrorClass(Form("Volume path %s not valid!",path));
187     return NULL;
188   }
189   return gGeoManager->GetCurrentMatrix();
190 }
191
192 //______________________________________________________________________
193 Bool_t AliITSgeomTGeo::GetTranslation(Int_t index, Double_t t[3]) 
194 {
195   // Get the translation vector for a given module 'index'
196   // by quering the TGeoManager
197
198   TGeoHMatrix *m = GetMatrix(index);
199   if (!m) return kFALSE;
200
201   Double_t *trans = m->GetTranslation();
202   for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
203
204   return kTRUE;
205 }
206
207 //______________________________________________________________________
208 Bool_t AliITSgeomTGeo::GetRotation(Int_t index, Double_t r[9]) 
209 {
210   // Get the rotation matrix for a given module 'index'
211   // by quering the TGeoManager
212
213   TGeoHMatrix *m = GetMatrix(index);
214   if (!m) return kFALSE;
215
216   Double_t *rot = m->GetRotationMatrix();
217   for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
218
219   return kTRUE;
220 }
221
222 //______________________________________________________________________
223 Bool_t AliITSgeomTGeo::GetOrigMatrix(Int_t index, TGeoHMatrix &m)
224 {
225   // Get the original (ideal geometry) TGeo matrix for
226   // a given module identified by 'index'.
227   // The method is slow, so it should be used
228   // with great care.
229
230   m.Clear();
231
232   const char *symname = GetSymName(index);
233   if (!symname) return kFALSE;
234
235   return AliGeomManager::GetOrigGlobalMatrix(symname,m);
236 }
237
238 //______________________________________________________________________
239 Bool_t AliITSgeomTGeo::GetOrigTranslation(Int_t index, Double_t t[3]) 
240 {
241   // Get the original translation vector (ideal geometry)
242   // for a given module 'index' by quering the TGeoManager
243
244   TGeoHMatrix m;
245   if (!GetOrigMatrix(index,m)) return kFALSE;
246
247   Double_t *trans = m.GetTranslation();
248   for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
249
250   return kTRUE;
251 }
252
253 //______________________________________________________________________
254 Bool_t AliITSgeomTGeo::GetOrigRotation(Int_t index, Double_t r[9]) 
255 {
256   // Get the original rotation matrix (ideal geometry)
257   // for a given module 'index' by quering the TGeoManager
258
259   TGeoHMatrix m;
260   if (!GetOrigMatrix(index,m)) return kFALSE;
261
262   Double_t *rot = m.GetRotationMatrix();
263   for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
264
265   return kTRUE;
266 }
267
268 //______________________________________________________________________
269 const TGeoHMatrix* AliITSgeomTGeo::GetTracking2LocalMatrix(Int_t index)
270 {
271   // Get the matrix which transforms from the tracking to local r.s.
272   // The method queries directly the TGeoPNEntry
273
274   TGeoPNEntry *pne = GetPNEntry(index);
275   if (!pne) return NULL;
276
277   const TGeoHMatrix *m = pne->GetMatrix();
278   if (!m)
279     AliErrorClass(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
280
281   return m;
282 }
283
284 //______________________________________________________________________
285 Bool_t AliITSgeomTGeo::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
286 {
287   // Get the matrix which transforms from the tracking r.s. to
288   // the global one.
289   // Returns kFALSE in case of error.
290
291   m.Clear();
292
293   TGeoHMatrix *m1 = GetMatrix(index);
294   if (!m1) return kFALSE;
295
296   const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
297   if (!m2) return kFALSE;
298
299   m = *m1;
300   m.Multiply(m2);
301
302   return kTRUE;
303 }
304
305 //______________________________________________________________________
306 TGeoPNEntry* AliITSgeomTGeo::GetPNEntry(Int_t index)
307 {
308   // Get a pointer to the TGeoPNEntry of a module
309   // identified by 'index'
310   // Returns NULL in case of invalid index,
311   // missing TGeoManager or invalid symbolic name
312
313   if (index < 0 || index >= fgkNModules) {
314     AliErrorClass(Form("Invalid ITS module index: %d (0 -> %d) !",index,fgkNModules));
315     return NULL;
316   }
317   
318   if (!gGeoManager || !gGeoManager->IsClosed()) {
319     AliErrorClass("Can't get the matrix! gGeoManager doesn't exist or it is still opened!");
320     return NULL;
321   }
322
323   TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(GetSymName(index));
324   if (!pne)
325     AliErrorClass(Form("The symbolic volume name %s does not correspond to a physical entry!",
326                        GetSymName(index)));
327
328   return pne;
329 }
330
331 //______________________________________________________________________
332 Bool_t AliITSgeomTGeo::LocalToGlobal(Int_t index,
333                                      const Double_t *loc, Double_t *glob)
334 {
335   // Make the conversion from the local sensitive reference system to the global
336   // reference system, for an arbitrary local position. The input is the pointer
337   // to the array of local coordinates, the result is sent to the glob pointer.
338   //
339   // Please don't use this method to get the global coordinates of clusters, use
340   // the direct method of AliCluster instead.
341
342   const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
343   if (!m2) return kFALSE;
344
345   // The shift (in local y only) between alignable and sensitive volume
346   // is extracted directly from the Tracking2Local matrix
347   Double_t locSens[] = {loc[0], loc[1]+m2->GetTranslation()[1], loc[2]};
348
349   TGeoHMatrix *ml = GetMatrix(index);
350   if (!ml) return kFALSE;
351   ml->LocalToMaster(locSens,glob);
352   return kTRUE;
353 }
354
355 //______________________________________________________________________
356 Bool_t AliITSgeomTGeo::GlobalToLocal(Int_t index,
357                                      const Double_t *glob, Double_t *loc)
358 {
359   // Make the conversion from the global reference system to the sensitive local
360   // reference system, for an arbitrary global position. The input is the pointer
361   // to the array of global coordinates, the result is sent to the loc pointer.
362
363   TGeoHMatrix *ml = GetMatrix(index);
364   if (!ml) return kFALSE;
365
366   const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
367   if (!m2) return kFALSE;
368   ml->MasterToLocal(glob,loc);
369   // The shift (in local y only) between alignable and sensitive volume
370   // is extracted directly from the Tracking2Local matrix
371   loc[1] -= m2->GetTranslation()[1];
372
373   return kTRUE;
374 }
375
376 //______________________________________________________________________
377 Bool_t AliITSgeomTGeo::LocalToGlobalVect(Int_t index,
378                                          const Double_t *loc, Double_t *glob)
379 {
380   // Make the conversion from the local sensitive reference system to the global
381   // reference system, for an arbitrary vector. The input is the pointer to the
382   // array of local coordinates, the result is sent to the glob pointer.
383
384   TGeoHMatrix *ml = GetMatrix(index);
385   if (!ml) return kFALSE;
386   ml->LocalToMasterVect(loc,glob);
387   return kTRUE;
388 }
389
390 //______________________________________________________________________
391 Bool_t AliITSgeomTGeo::GlobalToLocalVect(Int_t index,
392                                          const Double_t *glob, Double_t *loc)
393 {
394   // Make the conversion from the global reference system to the sensitive local
395   // reference system, for an arbitrary vector. The input is the pointer to the
396   // array of global coordinates, the result is sent to the loc pointer.
397
398   TGeoHMatrix *ml = GetMatrix(index);
399   if (!ml) return kFALSE;
400   ml->MasterToLocalVect(glob,loc);
401
402   return kTRUE;
403 }