]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/UPGRADE/AliITSUGeomTGeo.cxx
Coverity fix
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSUGeomTGeo.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 //    AliITSUGeomTGeo 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 //    adapted to ITSupg 18/07/2012 - ruben.shahoyan@cern.ch              //
24 //                                                                       //
25 //    ATTENTION: In opposite to ols AliITSgeomTGeo, all indices start    //
26 //    from 0, not from 1!!!                                              //
27 //                                                                       //
28 ///////////////////////////////////////////////////////////////////////////
29
30 #include <TClass.h>
31 #include <TString.h>
32 #include <TGeoManager.h>
33 #include <TGeoPhysicalNode.h>
34 #include <TDatime.h>
35 #include <TMath.h>
36 #include <TSystem.h>
37
38 #include "AliITSUGeomTGeo.h"
39 #include "AliLog.h"
40 #include "AliAlignObj.h"
41 #include "AliITSsegmentation.h"
42 #include "AliITSUSegmentationPix.h"
43 using namespace TMath;
44
45 ClassImp(AliITSUGeomTGeo)
46
47 UInt_t AliITSUGeomTGeo::fgUIDShift = 16;                // bit shift to go from mod.id to modUUID for TGeo
48 TString AliITSUGeomTGeo::fgITSVolName = "ITSV";
49 TString AliITSUGeomTGeo::fgITSLrName  = "ITSULayer";
50 TString AliITSUGeomTGeo::fgITSStaveName = "ITSUStave";
51 TString AliITSUGeomTGeo::fgITSSubStaveName = "ITSUSubStave";
52 TString AliITSUGeomTGeo::fgITSModuleName = "ITSUModuleName"; 
53 TString AliITSUGeomTGeo::fgITSChipName = "ITSUChip";
54 TString AliITSUGeomTGeo::fgITSSensName = "ITSUSensor";
55 TString AliITSUGeomTGeo::fgITSWrapVolName = "ITSUWrapVol";
56 TString AliITSUGeomTGeo::fgITSChipTypeName[AliITSUGeomTGeo::kNChipTypes] = {"Pix"};
57 //
58 TString AliITSUGeomTGeo::fgITSsegmFileName = "itsSegmentations.root";
59
60 //______________________________________________________________________
61 AliITSUGeomTGeo::AliITSUGeomTGeo(Bool_t build, Bool_t loadSegm)
62   :fVersion(kITSVNA)
63   ,fNLayers(0)
64   ,fNChips(0)
65   ,fNStaves(0)
66   ,fNSubStaves(0)
67   ,fNModules(0)
68   ,fNChipsPerModule(0)
69   ,fNChipsPerSubStave(0)
70   ,fNChipsPerStave(0)
71   ,fNChipsPerLayer(0)
72   ,fLrChipType(0)
73   ,fLastChipIndex(0)
74   ,fMatSens(0)
75   ,fMatT2L(0)
76   ,fSegm(0)
77 {
78   // default c-tor
79   for (int i=AliITSUAux::kMaxLayers;i--;) fLr2Wrapper[i] = -1;
80   if (build) BuildITS(loadSegm);
81 }
82
83 //______________________________________________________________________
84 AliITSUGeomTGeo::AliITSUGeomTGeo(const AliITSUGeomTGeo &src)
85   :TObject(src)
86   ,fVersion(src.fVersion)
87   ,fNLayers(src.fNLayers)
88   ,fNChips(src.fNChips)
89   ,fNStaves(0)
90   ,fNSubStaves(0)
91   ,fNModules(0)
92   ,fNChipsPerModule(0)
93   ,fNChipsPerSubStave(0)
94   ,fNChipsPerStave(0)
95   ,fNChipsPerLayer(0)
96   ,fLrChipType(0)
97   ,fLastChipIndex(0)
98   ,fMatSens(0)
99   ,fMatT2L(0)
100   ,fSegm(0)
101 {
102   // copy c-tor
103   if (fNLayers) {
104     fNStaves   = new Int_t[fNLayers];
105     fNSubStaves= new Int_t[fNLayers];
106     fNChipsPerModule = new Int_t[fNLayers];
107     fLrChipType  = new Int_t[fNLayers];
108     fLastChipIndex   = new Int_t[fNLayers];
109     fNChipsPerSubStave = new Int_t[fNLayers];
110     fNChipsPerStave = new Int_t[fNLayers];
111     fNChipsPerLayer = new Int_t[fNLayers];
112     //
113     for (int i=fNLayers;i--;) {
114       fNStaves[i] = src.fNStaves[i];
115       fNSubStaves[i] = src.fNSubStaves[i];
116       fNModules[i] = src.fNModules[i];
117       fNChipsPerModule[i] = src.fNChipsPerModule[i];
118       fNChipsPerSubStave[i] = src.fNChipsPerSubStave[i];
119       fNChipsPerStave[i] = src.fNChipsPerStave[i];
120       fNChipsPerLayer[i] = src.fNChipsPerLayer[i];
121       fLrChipType[i]  = src.fLrChipType[i];
122       fLastChipIndex[i] = src.fLastChipIndex[i];
123     }
124     if (src.fMatSens) {
125       fMatSens = new TObjArray(fNChips);
126       fMatSens->SetOwner(kTRUE);
127       for (int i=0;i<fNChips;i++) {
128         const TGeoHMatrix* mat = (TGeoHMatrix*)src.fMatSens->At(i);
129         fMatSens->AddAt(new TGeoHMatrix(*mat),i);
130       }
131     }
132     if (src.fMatT2L) {
133       fMatT2L = new TObjArray(fNChips);
134       fMatT2L->SetOwner(kTRUE);
135       for (int i=0;i<fNChips;i++) {
136         const TGeoHMatrix* mat =(TGeoHMatrix*) src.fMatT2L->At(i);
137         fMatT2L->AddAt(new TGeoHMatrix(*mat),i);
138       }
139     }
140     if (src.fSegm) {
141       int sz = src.fSegm->GetEntriesFast();
142       fSegm = new TObjArray(sz);
143       fSegm->SetOwner(kTRUE);
144       for (int i=0;i<sz;i++) {
145         AliITSsegmentation* sg = (AliITSsegmentation*)src.fSegm->UncheckedAt(i);
146         if (!sg) continue;
147         fSegm->AddAt(sg->Clone(),i);
148       }
149     }
150   }
151   for (int i=AliITSUAux::kMaxLayers;i--;) fLr2Wrapper[i] = src.fLr2Wrapper[i];
152 }
153
154 //______________________________________________________________________
155 AliITSUGeomTGeo::~AliITSUGeomTGeo()
156 {
157   //d-tor
158   delete[] fNStaves;
159   delete[] fNSubStaves;
160   delete[] fNModules;
161   delete[] fLrChipType;
162   delete[] fNChipsPerModule;
163   delete[] fNChipsPerSubStave;
164   delete[] fNChipsPerStave;
165   delete[] fNChipsPerLayer;
166   delete[] fLastChipIndex;
167   delete fMatT2L;
168   delete fMatSens;
169   delete fSegm;
170 }
171
172
173 //______________________________________________________________________
174 AliITSUGeomTGeo& AliITSUGeomTGeo::operator=(const AliITSUGeomTGeo &src)
175 {
176   // cp op.
177   if (this!=&src) {
178     delete[] fNStaves;
179     delete[] fNSubStaves;
180     delete[] fNModules;
181     delete[] fLrChipType;
182     delete[] fNChipsPerModule;
183     delete[] fNChipsPerSubStave;
184     delete[] fNChipsPerStave;
185     delete[] fNChipsPerLayer;
186     delete[] fLastChipIndex;
187     fNStaves = fNSubStaves = fNModules = fLrChipType = fNChipsPerModule = fLastChipIndex = 0;
188     fVersion = src.fVersion;
189     fNLayers = src.fNLayers;
190     fNChips = src.fNChips;
191     if (src.fMatSens) {
192       delete fMatSens; 
193       fMatSens = new TObjArray(fNChips);
194       fMatSens->SetOwner(kTRUE);
195       for (int i=0;i<fNChips;i++) {
196         const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatSens->At(i);
197         fMatSens->AddAt(new TGeoHMatrix(*mat),i);
198       }
199     }
200     if (src.fMatT2L) {
201       delete fMatT2L; 
202       fMatT2L = new TObjArray(fNChips);
203       fMatT2L->SetOwner(kTRUE);
204       for (int i=0;i<fNChips;i++) {
205         const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatT2L->At(i);
206         fMatT2L->AddAt(new TGeoHMatrix(*mat),i);
207       }
208     }
209     if (src.fSegm) {
210       int sz = src.fSegm->GetEntriesFast();
211       fSegm = new TObjArray(sz);
212       fSegm->SetOwner(kTRUE);
213       for (int i=0;i<sz;i++) {
214         AliITSsegmentation* sg = (AliITSsegmentation*)src.fSegm->UncheckedAt(i);
215         if (!sg) continue;
216         fSegm->AddAt(sg->Clone(),i);
217       }
218     }
219     //
220     if (fNLayers) {
221       fNStaves   = new Int_t[fNLayers];
222       fNSubStaves   = new Int_t[fNLayers];
223       fNModules     = new Int_t[fNLayers];
224       fNChipsPerModule = new Int_t[fNLayers];
225       fNChipsPerSubStave = new Int_t[fNLayers];
226       fNChipsPerStave = new Int_t[fNLayers];
227       fNChipsPerLayer = new Int_t[fNLayers];
228       fLrChipType  = new Int_t[fNLayers];
229       fLastChipIndex   = new Int_t[fNLayers];
230       for (int i=fNLayers;i--;) {
231         fNStaves[i] = src.fNStaves[i];
232         fNSubStaves[i] = src.fNSubStaves[i];
233         fNModules[i]   = src.fNModules[i];
234         fNChipsPerModule[i] = src.fNChipsPerModule[i];
235         fNChipsPerSubStave[i] = src.fNChipsPerSubStave[i];
236         fNChipsPerStave[i] = src.fNChipsPerStave[i];
237         fNChipsPerLayer[i] = src.fNChipsPerLayer[i];
238         fLrChipType[i]  = src.fLrChipType[i];
239         fLastChipIndex[i] = src.fLastChipIndex[i];
240       }
241     }    
242   }
243   return *this;
244 }
245
246 //______________________________________________________________________
247 Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta,Int_t chipInStave) const
248 {
249   // This routine computes the chip index number from the layer,
250   // stave, and chip number in stave. 
251   // Inputs:
252   //    Int_t lay  The layer number. Starting from 0.
253   //    Int_t sta  The stave number. Starting from 0
254   //    Int_t chipInStave  The chip number in the stave. Starting from 0
255   //
256   return GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInStave;
257 }
258
259 //______________________________________________________________________
260 Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t chipInSStave) const
261 {
262   // This routine computes the chip index number from the layer,
263   // stave, substave and chip number in substave. 
264   // Inputs:
265   //    Int_t lay  The layer number. Starting from 0.
266   //    Int_t sta  The stave number. Starting from 0
267   //    Int_t substa  The substave number. Starting from 0
268   //    Int_t chipInSStave  The chip number in the sub stave. Starting from 0
269   //
270   int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInSStave;
271   if (fNSubStaves[lay] && substa>0) n += fNChipsPerSubStave[lay]*substa;
272   return n;
273 }
274
275 //______________________________________________________________________
276 Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t md, Int_t chipInMod) const
277 {
278   // This routine computes the chip index number from the layer,
279   // stave, substave module and chip number in module. 
280   // Inputs:
281   //    Int_t lay  The layer number. Starting from 0.
282   //    Int_t sta  The stave number. Starting from 0
283   //    Int_t substa  The substave number. Starting from 0
284   //    Int_t module  The module number ...
285   //    Int_t chipInSStave  The chip number in the module. Starting from 0
286   //
287   int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInMod;
288   if (fNSubStaves[lay] && substa>0) n += fNChipsPerSubStave[lay]*substa;
289   if (fNModules[lay] && md>0)       n += fNChipsPerModule[lay]*md;
290   return n;
291 }
292
293 //______________________________________________________________________
294 Bool_t AliITSUGeomTGeo::GetLayer(Int_t index,Int_t &lay,Int_t &indexInLr)  const
295 {
296   // This routine computes the layer number a
297   // given the chip index. The 
298   // Inputs:
299   //     Int_t index  The chip index number, starting from zero.
300   // Outputs:
301   //     Int_t indexInLr The chip index inside a layer, starting from zero.
302   //     Int_t lay    The layer number. Starting from 0.
303   //
304   lay = GetLayer(index);
305   indexInLr = index - GetFirstChipIndex(lay);
306   return kTRUE;
307   //
308 }
309
310 //______________________________________________________________________
311 Int_t AliITSUGeomTGeo::GetLayer(Int_t index) const
312 {
313   // Get chip layer, from 0
314   //
315   int lay = 0;
316   while(index>fLastChipIndex[lay]) lay++;
317   return lay;
318 }
319
320 //______________________________________________________________________
321 Int_t AliITSUGeomTGeo::GetStave(Int_t index) const
322 {
323   // Get chip stave, from 0
324   //
325   int lay = 0;
326   while(index>fLastChipIndex[lay]) lay++;
327   index -= GetFirstChipIndex(lay);
328   return index/fNChipsPerStave[lay];
329 }
330
331 //______________________________________________________________________
332 Int_t AliITSUGeomTGeo::GetSubStave(Int_t index) const
333 {
334   // Get chip substave id in stave, from 0
335   //
336   int lay = 0;
337   while(index>fLastChipIndex[lay]) lay++;
338   if (fNSubStaves[lay]<0) return -1;
339   index -= GetFirstChipIndex(lay);
340   index %= fNChipsPerStave[lay];
341   return index/fNChipsPerSubStave[lay];
342 }
343
344 //______________________________________________________________________
345 Int_t AliITSUGeomTGeo::GetModule(Int_t index) const
346 {
347   // Get chip module id in substave, from 0
348   //
349   int lay = 0;
350   while(index>fLastChipIndex[lay]) lay++;
351   if (fNModules[lay]<0) return 0;
352   index -= GetFirstChipIndex(lay);
353   index %= fNChipsPerStave[lay];
354   if (fNSubStaves[lay]) index %= fNChipsPerSubStave[lay];
355   return index/fNChipsPerModule[lay];
356 }
357
358 //______________________________________________________________________
359 Int_t AliITSUGeomTGeo::GetChipIdInLayer(Int_t index) const
360 {
361   // Get chip number within layer, from 0
362   //
363   int lay = 0;
364   while(index>fLastChipIndex[lay]) lay++;
365   index -= GetFirstChipIndex(lay);
366   return index;
367 }
368
369 //______________________________________________________________________
370 Int_t AliITSUGeomTGeo::GetChipIdInStave(Int_t index) const
371 {
372   // Get chip number within stave, from 0
373   //
374   int lay = 0;
375   while(index>fLastChipIndex[lay]) lay++;
376   index -= GetFirstChipIndex(lay);
377   return index%fNChipsPerStave[lay];
378 }
379
380 //______________________________________________________________________
381 Int_t AliITSUGeomTGeo::GetChipIdInSubStave(Int_t index) const
382 {
383   // Get chip number within stave, from 0
384   //
385   int lay = 0;
386   while(index>fLastChipIndex[lay]) lay++;
387   index -= GetFirstChipIndex(lay);
388   return index%fNChipsPerSubStave[lay];
389 }
390
391 //______________________________________________________________________
392 Int_t AliITSUGeomTGeo::GetChipIdInModule(Int_t index) const
393 {
394   // Get chip number within module, from 0
395   //
396   int lay = 0;
397   while(index>fLastChipIndex[lay]) lay++;
398   index -= GetFirstChipIndex(lay);
399   return index%fNChipsPerModule[lay];
400 }
401
402 //______________________________________________________________________
403 Bool_t AliITSUGeomTGeo::GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &ssta, Int_t &mod, Int_t &chip)  const
404 {
405   //
406   // This routine computes the layer, stave, substave, module and chip number 
407   // given the chip index number. 
408   // Inputs:
409   //     Int_t index  The chip index number, starting from zero.
410   // Outputs:
411   //     Int_t lay    The layer number. Starting from 0
412   //     Int_t sta    The stave number. Starting from 0
413   //     Int_t ssta   The substave number. Starting from 0
414   //     Int_t mod    The module number. Starting from 0
415   //     Int_t chip   The detector number. Starting from 0
416   //
417   lay  = GetLayer(index);
418   index -= GetFirstChipIndex(lay);
419   sta  = index/fNChipsPerStave[lay];
420   index %= fNChipsPerStave[lay];
421   ssta = fNSubStaves[lay]>0 ? index/fNChipsPerSubStave[lay] : -1;
422   index %= fNChipsPerSubStave[lay];
423   mod  = fNModules[lay]>0 ? index/fNChipsPerModule[lay] : -1;
424   chip = index%fNChipsPerModule[lay];
425   //
426   return kTRUE;
427 }
428
429 //______________________________________________________________________
430 const char* AliITSUGeomTGeo::GetSymName(Int_t index)  const
431 {
432   // Get the TGeoPNEntry symbolic name
433   // for a given chip identified by 'index'
434   //
435   Int_t lay, index2;
436   if (!GetLayer(index,lay,index2)) return NULL;
437   // return AliGeomManager::SymName((AliGeomManager::ELayerID)((lay-1)+AliGeomManager::kSPD1),index2);
438   // RS: this is not optimal, but we cannod access directly AliGeomManager, since the latter has hardwired layers 
439   //  TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( AliGeomManager::LayerToVolUID(lay+1,index2) );
440   TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) );
441   if (!pne) {
442     AliError(Form("Failed to find alignable entry with index %d: (Lr%d Chip:%d) !",index,lay,index2));
443     return NULL;
444   }
445   return pne->GetName();
446 }
447
448 //______________________________________________________________________
449 const char* AliITSUGeomTGeo::ComposeSymNameITS()
450 {
451   // sym name of the layer
452   return "ITS";
453 }
454
455 //______________________________________________________________________
456 const char* AliITSUGeomTGeo::ComposeSymNameLayer(Int_t lr)
457 {
458   // sym name of the layer
459   return Form("%s/%s%d",ComposeSymNameITS(),GetITSLayerPattern(),lr);
460 }
461
462 //______________________________________________________________________
463 const char* AliITSUGeomTGeo::ComposeSymNameStave(Int_t lr, Int_t stave)
464 {
465   // sym name of the stave at given layer
466   return Form("%s/%s%d",ComposeSymNameLayer(lr),GetITSStavePattern(),stave);
467 }
468
469 //______________________________________________________________________
470 const char* AliITSUGeomTGeo::ComposeSymNameSubStave(Int_t lr, Int_t stave, Int_t substave)
471 {
472   // sym name of the stave at given layer
473   return substave>=0 ? 
474     Form("%s/%s%d",ComposeSymNameStave(lr,stave),GetITSSubStavePattern(),substave) :
475     ComposeSymNameStave(lr,stave);
476 }
477
478 //______________________________________________________________________
479 const char* AliITSUGeomTGeo::ComposeSymNameModule(Int_t lr, Int_t stave, Int_t substave, Int_t mod)
480 {
481   // sym name of the substave at given layer/stave
482   return mod>=0 ? 
483     Form("%s/%s%d",ComposeSymNameSubStave(lr,stave,substave),GetITSModulePattern(),mod) :
484     ComposeSymNameSubStave(lr,stave,substave);    
485 }
486
487 //______________________________________________________________________
488 const char* AliITSUGeomTGeo::ComposeSymNameChip(Int_t lr, Int_t sta, Int_t substave, Int_t mod, Int_t chip)
489 {
490   // sym name of the chip in the given layer/stave/substave/module
491   return Form("%s/%s%d",ComposeSymNameModule(lr,sta,substave,mod),GetITSChipPattern(),chip);
492 }
493
494 //______________________________________________________________________
495 TGeoHMatrix* AliITSUGeomTGeo::GetMatrix(Int_t index)  const
496 {
497   // Get the transformation matrix for a given chip 'index'
498   // by quering the TGeoManager
499   static TGeoHMatrix matTmp;
500   TGeoPNEntry *pne = GetPNEntry(index);
501   if (!pne) return NULL;
502
503   TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
504   if (pnode) return pnode->GetMatrix();
505
506   const char* path = pne->GetTitle();
507   gGeoManager->PushPath(); // Preserve the modeler state.
508   if (!gGeoManager->cd(path)) {
509     gGeoManager->PopPath();
510     AliError(Form("Volume path %s not valid!",path));
511     return NULL;
512   }
513   matTmp = *gGeoManager->GetCurrentMatrix();
514   gGeoManager->PopPath();
515   return &matTmp;
516 }
517
518 //______________________________________________________________________
519 Bool_t AliITSUGeomTGeo::GetTranslation(Int_t index, Double_t t[3])  const
520 {
521   // Get the translation vector for a given chip 'index'
522   // by quering the TGeoManager
523   TGeoHMatrix *m = GetMatrix(index);
524   if (!m) return kFALSE;
525
526   Double_t *trans = m->GetTranslation();
527   for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
528
529   return kTRUE;
530 }
531
532 //______________________________________________________________________
533 Bool_t AliITSUGeomTGeo::GetRotation(Int_t index, Double_t r[9])  const
534 {
535   // Get the rotation matrix for a given chip 'index'
536   // by quering the TGeoManager
537   TGeoHMatrix *m = GetMatrix(index);
538   if (!m) return kFALSE;
539
540   Double_t *rot = m->GetRotationMatrix();
541   for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
542
543   return kTRUE;
544 }
545
546 //______________________________________________________________________
547 Bool_t AliITSUGeomTGeo::GetOrigMatrix(Int_t index, TGeoHMatrix &m) const
548 {
549   // Get the original (ideal geometry) TGeo matrix for
550   // a given chip identified by 'index'.
551   // The method is slow, so it should be used
552   // with great care.
553   m.Clear();
554
555   const char *symname = GetSymName(index);
556   if (!symname) return kFALSE;
557
558   return AliGeomManager::GetOrigGlobalMatrix(symname,m);
559 }
560
561 //______________________________________________________________________
562 Bool_t AliITSUGeomTGeo::GetOrigTranslation(Int_t index, Double_t t[3])  const
563 {
564   // Get the original translation vector (ideal geometry)
565   // for a given chip 'index' by quering the TGeoManager
566   TGeoHMatrix m;
567   if (!GetOrigMatrix(index,m)) return kFALSE;
568
569   Double_t *trans = m.GetTranslation();
570   for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
571
572   return kTRUE;
573 }
574
575 //______________________________________________________________________
576 Bool_t AliITSUGeomTGeo::GetOrigRotation(Int_t index, Double_t r[9])  const
577 {
578   // Get the original rotation matrix (ideal geometry)
579   // for a given chip 'index' by quering the TGeoManager
580   TGeoHMatrix m;
581   if (!GetOrigMatrix(index,m)) return kFALSE;
582
583   Double_t *rot = m.GetRotationMatrix();
584   for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
585
586   return kTRUE;
587 }
588
589 //______________________________________________________________________
590 TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixT2L(Int_t index) const
591 {
592   // Get the matrix which transforms from the tracking to local r.s.
593   // The method queries directly the TGeoPNEntry
594   TGeoPNEntry *pne = GetPNEntry(index);
595   if (!pne) return NULL;
596
597   TGeoHMatrix *m = (TGeoHMatrix*) pne->GetMatrix();
598   if (!m) AliError(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
599
600   return m;
601 }
602
603 //______________________________________________________________________
604 Bool_t AliITSUGeomTGeo::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
605 {
606   // Get the matrix which transforms from the tracking r.s. to
607   // the global one.
608   // Returns kFALSE in case of error.
609   m.Clear();
610
611   TGeoHMatrix *m1 = GetMatrix(index);
612   if (!m1) return kFALSE;
613
614   const TGeoHMatrix *m2 = GetMatrixT2L(index);
615   if (!m2) return kFALSE;
616
617   m = *m1;
618   m.Multiply(m2);
619
620   return kTRUE;
621 }
622
623 //______________________________________________________________________
624 TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixSens(Int_t index) const
625 {
626   // Get the transformation matrix of the SENSOR (not ncessary the same as the chip) 
627   // for a given chip 'index' by quering the TGeoManager
628   Int_t lay,stav,sstav,mod,chipInMod;
629   GetChipId(index,lay,stav,sstav,mod,chipInMod);
630   int wrID = fLr2Wrapper[lay];
631   TString path = Form("/ALIC_1/%s_2/",AliITSUGeomTGeo::GetITSVolPattern());
632   if (wrID>=0) path += Form("%s%d_1/",GetITSWrapVolPattern(),wrID);
633   path += Form("%s%d_1/%s%d_%d/",AliITSUGeomTGeo::GetITSLayerPattern(),lay,AliITSUGeomTGeo::GetITSStavePattern(),lay,stav);
634   if (fNSubStaves[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSSubStavePattern(),lay,sstav);
635   if (fNModules[lay]>0)   path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSModulePattern(),lay,mod);
636   path += Form("%s%d_%d/%s%d_1",AliITSUGeomTGeo::GetITSChipPattern(),lay,chipInMod,AliITSUGeomTGeo::GetITSSensorPattern(),lay);
637   static TGeoHMatrix matTmp;
638   gGeoManager->PushPath();
639   if (!gGeoManager->cd(path.Data())) {
640     gGeoManager->PopPath();
641     AliError(Form("Error in cd-ing to %s",path.Data()));
642     return 0;
643   } // end if !gGeoManager
644   matTmp = *gGeoManager->GetCurrentMatrix(); // matrix may change after cd
645   //RSS
646   //  printf("%d/%d/%d %s\n",lay,stav,detInSta,path.Data());
647   //  mat->Print();
648   // Retstore the modeler state.
649   gGeoManager->PopPath();
650   return &matTmp;
651 }
652
653
654 //______________________________________________________________________
655 TGeoPNEntry* AliITSUGeomTGeo::GetPNEntry(Int_t index) const
656 {
657   // Get a pointer to the TGeoPNEntry of a chip
658   // identified by 'index'
659   // Returns NULL in case of invalid index,
660   // missing TGeoManager or invalid symbolic name
661   //
662   if (index >= fNChips) {
663     AliError(Form("Invalid ITS chip index: %d (0 -> %d) !",index,fNChips));
664     return NULL;
665   }
666   
667   if (!gGeoManager || !gGeoManager->IsClosed()) {
668     AliError("Can't get the matrix! gGeoManager doesn't exist or it is still opened!");
669     return NULL;
670   }
671   TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) );
672   //  TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(GetSymName(index));
673   if (!pne) AliError(Form("The index %d does not correspond to a physical entry!",index));
674   //
675   return pne;
676 }
677
678 //______________________________________________________________________
679 void AliITSUGeomTGeo::BuildITS(Bool_t loadSegm)
680 {
681   // exract upg ITS parameters from TGeo
682   if (fVersion!=kITSVNA) {AliWarning("Already built"); return; // already initialized}
683     if (!gGeoManager) AliFatal("Geometry is not loaded");
684   }
685   fNLayers    = ExtractNumberOfLayers();
686   if (!fNLayers) return;
687   //
688   fNStaves         = new Int_t[fNLayers];
689   fNSubStaves      = new Int_t[fNLayers];
690   fNModules        = new Int_t[fNLayers];
691   fNChipsPerModule = new Int_t[fNLayers];
692   fNChipsPerSubStave = new Int_t[fNLayers];
693   fNChipsPerStave  = new Int_t[fNLayers];
694   fNChipsPerLayer  = new Int_t[fNLayers];
695   fLrChipType      = new Int_t[fNLayers];
696   fLastChipIndex   = new Int_t[fNLayers];
697   fNChips = 0;
698   for (int i=0;i<fNLayers;i++) {
699     fLrChipType[i]      = ExtractLayerChipType(i);
700     fNStaves[i]         = ExtractNumberOfStaves(i);
701     fNSubStaves[i]      = ExtractNumberOfSubStaves(i);
702     fNModules[i]        = ExtractNumberOfModules(i);
703     fNChipsPerModule[i] = ExtractNChipsPerModule(i);
704     fNChipsPerSubStave[i] = fNChipsPerModule[i]*Max(1,fNModules[i]);
705     fNChipsPerStave[i]    = fNChipsPerSubStave[i]*Max(1,fNSubStaves[i]);
706     fNChipsPerLayer[i]    = fNChipsPerStave[i]*fNStaves[i];
707     fNChips              += fNChipsPerLayer[i];
708     fLastChipIndex[i]     = fNChips-1;
709   }
710   //
711   FetchMatrices();
712   fVersion = kITSVUpg;
713   //
714   if (loadSegm) {  // fetch segmentations
715     fSegm = new TObjArray();
716     AliITSUSegmentationPix::LoadSegmentations(fSegm,GetITSsegmentationFileName());
717   }
718   //
719 }
720
721 //______________________________________________________________________
722 Int_t AliITSUGeomTGeo::ExtractNumberOfLayers()
723 {
724   // Determines the number of layers in the Upgrade Geometry
725   //
726   Int_t numberOfLayers = 0;
727   //
728   TGeoVolume *itsV = gGeoManager->GetVolume(GetITSVolPattern());
729   if (!itsV) AliFatal(Form("ITS volume %s is not in the geometry",GetITSVolPattern()));
730   SetUIDShift(itsV->GetUniqueID());
731   //
732   // Loop on all ITSV nodes, count Layer volumes by checking names
733   // Build on the fly layer - wrapper correspondence
734   TObjArray* nodes = itsV->GetNodes();
735   Int_t nNodes = nodes->GetEntriesFast();
736   //
737   int nWrp = 0;
738   for (Int_t j=0; j<nNodes; j++) {
739     TGeoNode* nd = (TGeoNode*)nodes->At(j);
740     const char* name = nd->GetName();
741     if      (strstr(name,GetITSLayerPattern())) numberOfLayers++;
742     else if (strstr(name,GetITSWrapVolPattern())) { // this is a wrapper volume, may cointain layers
743       TObjArray* nodesW = nd->GetNodes();
744       int nNodesW = nodesW->GetEntriesFast();
745       for (Int_t jw=0; jw<nNodesW; jw++) {
746         TGeoNode* ndW = (TGeoNode*)nodesW->At(jw);
747         if (strstr(ndW->GetName(),GetITSLayerPattern())) fLr2Wrapper[numberOfLayers++] = nWrp;
748       }
749       nWrp++;
750     }
751   }
752   //  
753   return numberOfLayers;
754 }
755
756 //______________________________________________________________________
757 Int_t AliITSUGeomTGeo::ExtractNumberOfStaves(Int_t lay) const
758 {
759   // Determines the number of layers in the Upgrade Geometry
760   //
761   // Inputs:
762   //   lay: layer number, starting from 0
763   //
764   // MS
765   Int_t numberOfStaves = 0;
766   char laynam[30];
767   snprintf(laynam, 30, "%s%d",GetITSLayerPattern(),lay);
768   TGeoVolume* volLr = gGeoManager->GetVolume(laynam);
769   if (!volLr) AliFatal(Form("can't find %s volume",laynam));
770   //
771   // Loop on all layer nodes, count Stave volumes by checking names
772   Int_t nNodes = volLr->GetNodes()->GetEntries();
773   for (Int_t j=0; j<nNodes; j++) {
774     //    AliInfo(Form("L%d %d of %d %s %s -> %d",lay,j,nNodes,volLr->GetNodes()->At(j)->GetName(),GetITSStavePattern(),numberOfStaves));
775     if (strstr(volLr->GetNodes()->At(j)->GetName(),GetITSStavePattern())) numberOfStaves++;
776   }
777   //
778   return numberOfStaves;
779   //
780 }
781
782 //______________________________________________________________________
783 Int_t AliITSUGeomTGeo::ExtractNumberOfSubStaves(Int_t lay) const
784 {
785   // Determines the number of substaves in the stave of the layer
786   //
787   // Inputs:
788   //   lay: layer number, starting from 0
789   //
790   // MS
791   if (fgITSSubStaveName.IsNull()) return 0; // for the setup w/o substave defined the stave and the substave is the same thing
792   Int_t nSS = 0;
793   char stavnam[30];
794   snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
795   TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
796   if (!volLd) AliFatal(Form("can't find %s volume",stavnam));
797   //
798   // Loop on all stave nodes, count Chip volumes by checking names
799   Int_t nNodes = volLd->GetNodes()->GetEntries();
800   for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSSubStavePattern())) nSS++;
801   //
802   return nSS;
803   //
804 }
805
806 //______________________________________________________________________
807 Int_t AliITSUGeomTGeo::ExtractNumberOfModules(Int_t lay) const
808 {
809   // Determines the number of modules in substave in the stave of the layer
810   //
811   // Inputs:
812   //   lay: layer number, starting from 0
813   //
814   // for the setup w/o modules defined the module and the stave or the substave is the same thing
815   if (fgITSModuleName.IsNull()) return 0;
816   char stavnam[30];
817   TGeoVolume* volLd = 0;
818   if (!fgITSSubStaveName.IsNull()) {
819     snprintf(stavnam, 30, "%s%d", GetITSSubStavePattern(),lay); 
820     volLd = gGeoManager->GetVolume(stavnam);
821   }
822   if (!volLd) { // no substaves, check staves
823     snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay); 
824     volLd = gGeoManager->GetVolume(stavnam);
825   }
826   if (!volLd) return 0;
827   Int_t nMod = 0;
828   //
829   // Loop on all substave nodes, count module volumes by checking names
830   Int_t nNodes = volLd->GetNodes()->GetEntries();
831   for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSModulePattern())) nMod++;
832   //
833   return nMod;
834   //
835 }
836
837 //______________________________________________________________________
838 Int_t AliITSUGeomTGeo::ExtractNChipsPerModule(Int_t lay)  const
839 {
840   // Determines the number of chips per module on the (sub)stave in the Upgrade Geometry
841   //
842   // Inputs:
843   //   lay: layer number from 0
844   // MS
845   Int_t numberOfChips = 0;
846   char stavnam[30];
847   TGeoVolume* volLd = 0;
848   if (!fgITSModuleName.IsNull()) {
849     snprintf(stavnam, 30, "%s%d", GetITSModulePattern(),lay); 
850     volLd = gGeoManager->GetVolume(stavnam);
851   }
852   if (!volLd) { // no modules on this layer, check substaves
853     if (!fgITSSubStaveName.IsNull()) {
854       snprintf(stavnam, 30, "%s%d", GetITSSubStavePattern(),lay); 
855       volLd = gGeoManager->GetVolume(stavnam);
856     }
857   }
858   if (!volLd) { // no substaves on this layer, check staves
859     snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
860     volLd = gGeoManager->GetVolume(stavnam);
861   }
862   if (!volLd) AliFatal(Form("can't find volume containing chips on layer %d",lay));
863   //
864   // Loop on all stave nodes, count Chip volumes by checking names
865   Int_t nNodes = volLd->GetNodes()->GetEntries();
866   for (Int_t j=0; j<nNodes; j++) {
867     //    AliInfo(Form("L%d %d of %d %s %s -> %d",lay,j,nNodes,volLd->GetNodes()->At(j)->GetName(),GetITSChipPattern(),numberOfChips));
868     if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSChipPattern())) numberOfChips++;
869   }
870   //
871   return numberOfChips;
872   //
873 }
874
875 //______________________________________________________________________
876 Int_t AliITSUGeomTGeo::ExtractLayerChipType(Int_t lay)  const
877 {
878   // Determines the layer detector type the Upgrade Geometry
879   //
880   // Inputs:
881   //   lay: layer number from 0
882   // Outputs:
883   //   none
884   // Return:
885   //   detector type id for the layer
886   // MS
887   char stavnam[30];
888   snprintf(stavnam, 30, "%s%d", GetITSLayerPattern(),lay);
889   TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
890   if (!volLd) {AliFatal(Form("can't find %s volume",stavnam)); return -1;}
891   //
892   return volLd->GetUniqueID();
893   //
894 }
895
896 //______________________________________________________________________
897 UInt_t AliITSUGeomTGeo::ComposeChipTypeID(UInt_t segmId)
898 {
899   if (segmId>=kMaxSegmPerChipType) AliFatalClass(Form("Id=%d is >= max.allowed %d",segmId,kMaxSegmPerChipType));
900   return segmId + kChipTypePix*kMaxSegmPerChipType;
901 }
902
903 //______________________________________________________________________
904 void AliITSUGeomTGeo::Print(Option_t *) const
905 {
906   // print
907   printf("Geometry version %d, NLayers:%d NChips:%d\n",fVersion,fNLayers,fNChips);
908   if (fVersion==kITSVNA) return;
909   for (int i=0;i<fNLayers;i++) {
910     printf("Lr%2d\tNStav:%2d\tNChips:%2d\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChipType:%3d\tChip#:%4d:%4d\tWrapVol:%d\n",
911            i,fNStaves[i],fNChipsPerModule[i],fNModules[i],fNSubStaves[i],fNStaves[i],
912            fLrChipType[i],GetFirstChipIndex(i),GetLastChipIndex(i),fLr2Wrapper[i]);
913   }
914 }
915
916 //______________________________________________________________________
917 void AliITSUGeomTGeo::FetchMatrices()
918 {
919   // store pointer on often used matrices for faster access
920   if (!gGeoManager) AliFatal("Geometry is not loaded");
921   fMatSens = new TObjArray(fNChips);
922   fMatSens->SetOwner(kTRUE);
923   for (int i=0;i<fNChips;i++) fMatSens->AddAt(new TGeoHMatrix(*ExtractMatrixSens(i)),i);
924   CreateT2LMatrices();
925 }
926
927 //______________________________________________________________________
928 void AliITSUGeomTGeo::CreateT2LMatrices()
929 {
930   // create tracking to local (Sensor!) matrices
931   fMatT2L  = new TObjArray(fNChips);  
932   fMatT2L->SetOwner(kTRUE);
933   TGeoHMatrix matLtoT;
934   double loc[3]={0,0,0},glo[3];
935   const double *rotm;
936   for (int isn=0;isn<fNChips;isn++) {
937     const TGeoHMatrix* matSens = GetMatrixSens(isn);
938     if (!matSens) {AliFatal(Form("Failed to get matrix for sensor %d",isn)); return;}
939     matSens->LocalToMaster(loc,glo);
940     rotm = matSens->GetRotationMatrix();
941     Double_t al = -ATan2(rotm[1],rotm[0]);
942     double sn=Sin(al), cs=Cos(al), r=glo[0]*sn-glo[1]*cs, x=r*sn, y=-r*cs; // sensor plane PCA to origin
943     TGeoHMatrix* t2l = new TGeoHMatrix();
944     t2l->RotateZ(ATan2(y,x)*RadToDeg()); // rotate in direction of normal to the sensor plane
945     t2l->SetDx(x);
946     t2l->SetDy(y);
947     t2l->MultiplyLeft(&matSens->Inverse());
948     fMatT2L->AddAt(t2l,isn);
949     /*
950     const double *gtrans = matSens->GetTranslation();
951     memcpy(&rotMatrix[0], matSens->GetRotationMatrix(), 9*sizeof(Double_t));
952     Double_t al = -ATan2(rotMatrix[1],rotMatrix[0]);
953     Double_t rSens = Sqrt(gtrans[0]*gtrans[0] + gtrans[1]*gtrans[1]);
954     Double_t tanAl = ATan2(gtrans[1],gtrans[0]) - Pi()/2; //angle of tangent
955     Double_t alTr = tanAl - al;
956     //
957     // The X axis of tracking frame must always look outward
958     loc[1] = rSens/2;
959     matSens->LocalToMaster(loc,glo);
960     double rPos = Sqrt(glo[0]*glo[0] + glo[1]*glo[1]);
961     Bool_t rotOutward = rPos>rSens ? kFALSE : kTRUE;
962     //
963     // Transformation matrix
964     matLtoT.Clear();
965     matLtoT.SetDx(-rSens*Sin(alTr)); // translation
966     matLtoT.SetDy(0.);
967     matLtoT.SetDz(gtrans[2]);
968     // Rotation matrix
969     rotMatrix[0]= 0;  rotMatrix[1]= 1;  rotMatrix[2]= 0; // + rotation
970     rotMatrix[3]=-1;  rotMatrix[4]= 0;  rotMatrix[5]= 0;
971     rotMatrix[6]= 0;  rotMatrix[7]= 0;  rotMatrix[8]= 1;
972     //
973     TGeoRotation rot;
974     rot.SetMatrix(rotMatrix);
975     matLtoT.MultiplyLeft(&rot);
976     if (rotOutward) matLtoT.RotateZ(180.);
977     // Inverse transformation Matrix
978     fMatT2L->AddAt(new TGeoHMatrix(matLtoT.Inverse()),isn);
979     */
980   }
981   //
982 }
983