]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/UPGRADE/AliITSgeomTGeoUpg.cxx
move for proof
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSgeomTGeoUpg.cxx
CommitLineData
ce886e8e 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// AliITSgeomTGeoUpg 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///////////////////////////////////////////////////////////////////////////
26
27#include <TClass.h>
28#include <TString.h>
29#include <TGeoManager.h>
30#include <TGeoPhysicalNode.h>
31#include <TDatime.h>
32
33#include "AliITSgeomTGeoUpg.h"
34#include "AliLog.h"
35#include "AliAlignObj.h"
36
37ClassImp(AliITSgeomTGeoUpg)
38
39
40const char* AliITSgeomTGeoUpg::fgkITSVolName = "ITSV";
41const char* AliITSgeomTGeoUpg::fgkITSLrName = "ITSupgLayer";
42const char* AliITSgeomTGeoUpg::fgkITSLadName = "ITSupgLadder";
43const char* AliITSgeomTGeoUpg::fgkITSModName = "ITSupgModule";
44
45const Int_t AliITSgeomTGeoUpg::fgkNModulesOld = 2198;
46const Int_t AliITSgeomTGeoUpg::fgkNLaddersOld[AliITSgeomTGeoUpg::kNLayersOld] = {20,40,14,22,34,38};
47const Int_t AliITSgeomTGeoUpg::fgkNDetectorsOld[AliITSgeomTGeoUpg::kNLayersOld] = {4,4,6,8,22,25};
48
49Int_t AliITSgeomTGeoUpg::fgVersion = 0;
50Int_t AliITSgeomTGeoUpg::fgNLayers = 0;
51Int_t AliITSgeomTGeoUpg::fgNModules = 0;
52Int_t* AliITSgeomTGeoUpg::fgNLadders = 0;
53Int_t* AliITSgeomTGeoUpg::fgNDetectors = 0;
54
55
56//______________________________________________________________________
57Int_t AliITSgeomTGeoUpg::GetModuleIndex(Int_t lay,Int_t lad,Int_t det)
58{
59 // The method is taken from the old AliITSgeom class by Bjorn Nilsen
60 //
61 // This routine computes the module index number from the layer,
62 // ladder, and detector numbers. The number of ladders and detectors
63 // per layer is set statically
64 // see above for details.
65 // Inputs:
66 // Int_t lay The layer number. Starting from 1.
67 // Int_t lad The ladder number. Starting from 1.
68 // Int_t det The detector number. Starting from 1.
69 // Return:
70 // the module index number, starting from zero.
71 // -1 in case of error
72 CheckInit();
73 //
74 if (lay < 1 || lay > fgNLayers) {
75 AliErrorClass(Form("Invalid layer: %d (1 -> %d",lay,fgNLayers));
76 return -1;
77 }
78
79 if (lad < 1 || lad > fgNLadders[lay-1] ||
80 det < 1 || det > fgNDetectors[lay-1]) {
81 AliErrorClass(Form("Invalid layer,ladder,detector combination: %d, %d, %d",lay,lad,det));
82 return -1;
83 }
84
85 Int_t index = fgNDetectors[lay-1] * (lad-1) + (det-1);
86 for(Int_t iLayer=0;iLayer < (lay-1); iLayer++)
87 index += fgNDetectors[iLayer]*fgNLadders[iLayer];
88
89 return index;
90}
91
92//______________________________________________________________________
93Bool_t AliITSgeomTGeoUpg::GetLayer(Int_t index,Int_t &lay,Int_t &index2)
94{
95 // The method is taken from the old AliITSgeom class by Bjorn Nilsen
96 //
97 // This routine computes the layer number for a
98 // given the module index. The number of ladders and detectors
99 // per layer is defined statically,
100 // see above for details.
101 // Inputs:
102 // Int_t index The module index number, starting from zero.
103 // Outputs:
104 // Int_t index2 The module index inside a layer, starting from zero.
105 // Int_t lay The layer number. Starting from 1.
106 // Return:
107 // kTRUE in case of valid index
108 // kFALSE in case of error
109 CheckInit();
110 //
111 if (index < 0 || index >= fgNModules) {
112 index2 = -1;
113 AliErrorClass(Form("Invalid module index: %d (0 -> %d)",index,fgNModules));
114 return -1;
115 }
116
117 lay = 0;
118 index2 = 0;
119 do {
120 index2 += fgNLadders[lay]*fgNDetectors[lay];
121 lay++;
122 } while(index2 <= index);
123 index2 -= fgNLadders[lay-1]*fgNDetectors[lay-1];
124 index2 = index - index2;
125
126 return lay;
127}
128
129//______________________________________________________________________
130Bool_t AliITSgeomTGeoUpg::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det)
131{
132 // The method is taken from the old AliITSgeom class by Bjorn Nilsen
133 //
134 // This routine computes the layer, ladder and detector number
135 // given the module index number. The number of ladders and detectors
136 // per layer is defined statically,
137 // see above for details.
138 // Inputs:
139 // Int_t index The module index number, starting from zero.
140 // Outputs:
141 // Int_t lay The layer number. Starting from 1.
142 // Int_t lad The ladder number. Starting from 1.
143 // Int_t det The detector number. Starting from 1.
144 // Return:
145 // kTRUE in case of valid index
146 // kFALSE in case of error
147 CheckInit();
148 //
149 if (index < 0 || index >= fgNModules) {
150 lay = lad = det = -1;
151 AliErrorClass(Form("Invalid module index: %d (0 -> %d)",index,fgNModules));
152 return kFALSE;
153 }
154
155 lay = lad = det = 0;
156 Int_t index2 = 0;
157 do {
158 index2 += fgNLadders[lay]*fgNDetectors[lay];
159 lay++;
160 } while(index2 <= index);
161 index2 -= fgNLadders[lay-1]*fgNDetectors[lay-1];
162
163 do {
164 index2 += fgNDetectors[lay-1];
165 lad++;
166 } while(index2 <= index);
167 index2 -= fgNDetectors[lay-1];
168
169 det = index-index2+1;
170
171 return kTRUE;
172}
173
174//______________________________________________________________________
175const char* AliITSgeomTGeoUpg::GetSymName(Int_t index)
176{
177 // Get the TGeoPNEntry symbolic name
178 // for a given module identified by 'index'
179 CheckInit();
180 //
181 if (index < 0 || index >= fgNModules) {
182 AliErrorClass(Form("Invalid ITS module index: %d (0 -> %d) !",index,fgNModules));
183 return NULL;
184 }
185
186 Int_t lay, index2;
187 if (!GetLayer(index,lay,index2)) return NULL;
188 if (fgVersion == kITSVOld) return AliGeomManager::SymName((AliGeomManager::ELayerID)((lay-1)+AliGeomManager::kSPD1),index2);
189 else {
190 // RS: this is not optimal, but we cannod access directly AliGeomManager, since the latter has hardwired layers
191 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( AliGeomManager::LayerToVolUID(lay,index2) );
192 if (!pne) {
193 AliErrorClass(Form("Failed to find alignable entry with index %d: (Lr%d Mod:%d) !",index,lay,index2));
194 return NULL;
195 }
196 return pne->GetName();
197 }
198}
199
200//______________________________________________________________________
201TGeoHMatrix* AliITSgeomTGeoUpg::GetMatrix(Int_t index)
202{
203 // Get the transformation matrix for a given module 'index'
204 // by quering the TGeoManager
205 CheckInit();
206 //
207 TGeoPNEntry *pne = GetPNEntry(index);
208 if (!pne) return NULL;
209
210 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
211 if (pnode) return pnode->GetMatrix();
212
213 const char* path = pne->GetTitle();
214 if (!gGeoManager->cd(path)) {
215 AliErrorClass(Form("Volume path %s not valid!",path));
216 return NULL;
217 }
218 return gGeoManager->GetCurrentMatrix();
219}
220
221//______________________________________________________________________
222Bool_t AliITSgeomTGeoUpg::GetTranslation(Int_t index, Double_t t[3])
223{
224 // Get the translation vector for a given module 'index'
225 // by quering the TGeoManager
226 CheckInit();
227 //
228 TGeoHMatrix *m = GetMatrix(index);
229 if (!m) return kFALSE;
230
231 Double_t *trans = m->GetTranslation();
232 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
233
234 return kTRUE;
235}
236
237//______________________________________________________________________
238Bool_t AliITSgeomTGeoUpg::GetRotation(Int_t index, Double_t r[9])
239{
240 // Get the rotation matrix for a given module 'index'
241 // by quering the TGeoManager
242 CheckInit();
243 //
244 TGeoHMatrix *m = GetMatrix(index);
245 if (!m) return kFALSE;
246
247 Double_t *rot = m->GetRotationMatrix();
248 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
249
250 return kTRUE;
251}
252
253//______________________________________________________________________
254Bool_t AliITSgeomTGeoUpg::GetOrigMatrix(Int_t index, TGeoHMatrix &m)
255{
256 // Get the original (ideal geometry) TGeo matrix for
257 // a given module identified by 'index'.
258 // The method is slow, so it should be used
259 // with great care.
260 CheckInit();
261 //
262 m.Clear();
263
264 const char *symname = GetSymName(index);
265 if (!symname) return kFALSE;
266
267 return AliGeomManager::GetOrigGlobalMatrix(symname,m);
268}
269
270//______________________________________________________________________
271Bool_t AliITSgeomTGeoUpg::GetOrigTranslation(Int_t index, Double_t t[3])
272{
273 // Get the original translation vector (ideal geometry)
274 // for a given module 'index' by quering the TGeoManager
275 CheckInit();
276 //
277 TGeoHMatrix m;
278 if (!GetOrigMatrix(index,m)) return kFALSE;
279
280 Double_t *trans = m.GetTranslation();
281 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
282
283 return kTRUE;
284}
285
286//______________________________________________________________________
287Bool_t AliITSgeomTGeoUpg::GetOrigRotation(Int_t index, Double_t r[9])
288{
289 // Get the original rotation matrix (ideal geometry)
290 // for a given module 'index' by quering the TGeoManager
291 CheckInit();
292 //
293 TGeoHMatrix m;
294 if (!GetOrigMatrix(index,m)) return kFALSE;
295
296 Double_t *rot = m.GetRotationMatrix();
297 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
298
299 return kTRUE;
300}
301
302//______________________________________________________________________
303const TGeoHMatrix* AliITSgeomTGeoUpg::GetTracking2LocalMatrix(Int_t index)
304{
305 // Get the matrix which transforms from the tracking to local r.s.
306 // The method queries directly the TGeoPNEntry
307 CheckInit();
308 //
309 TGeoPNEntry *pne = GetPNEntry(index);
310 if (!pne) return NULL;
311
312 const TGeoHMatrix *m = pne->GetMatrix();
313 if (!m)
314 AliErrorClass(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
315
316 return m;
317}
318
319//______________________________________________________________________
320Bool_t AliITSgeomTGeoUpg::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
321{
322 // Get the matrix which transforms from the tracking r.s. to
323 // the global one.
324 // Returns kFALSE in case of error.
325 CheckInit();
326 //
327 m.Clear();
328
329 TGeoHMatrix *m1 = GetMatrix(index);
330 if (!m1) return kFALSE;
331
332 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
333 if (!m2) return kFALSE;
334
335 m = *m1;
336 m.Multiply(m2);
337
338 return kTRUE;
339}
340
341//______________________________________________________________________
342TGeoPNEntry* AliITSgeomTGeoUpg::GetPNEntry(Int_t index)
343{
344 // Get a pointer to the TGeoPNEntry of a module
345 // identified by 'index'
346 // Returns NULL in case of invalid index,
347 // missing TGeoManager or invalid symbolic name
348 CheckInit();
349 //
350 if (index < 0 || index >= fgNModules) {
351 AliErrorClass(Form("Invalid ITS module index: %d (0 -> %d) !",index,fgNModules));
352 return NULL;
353 }
354
355 if (!gGeoManager || !gGeoManager->IsClosed()) {
356 AliErrorClass("Can't get the matrix! gGeoManager doesn't exist or it is still opened!");
357 return NULL;
358 }
359
360 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(GetSymName(index));
361 if (!pne)
362 AliErrorClass(Form("The symbolic volume name %s does not correspond to a physical entry!",
363 GetSymName(index)));
364
365 return pne;
366}
367
368//______________________________________________________________________
369Bool_t AliITSgeomTGeoUpg::LocalToGlobal(Int_t index,
370 const Double_t *loc, Double_t *glob)
371{
372 // Make the conversion from the local sensitive reference system to the global
373 // reference system, for an arbitrary local position. The input is the pointer
374 // to the array of local coordinates, the result is sent to the glob pointer.
375 //
376 // Please don't use this method to get the global coordinates of clusters, use
377 // the direct method of AliCluster instead.
378 CheckInit();
379 //
380 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
381 if (!m2) return kFALSE;
382
383 // The shift (in local y only) between alignable and sensitive volume
384 // is extracted directly from the Tracking2Local matrix
385 Double_t locSens[] = {loc[0], loc[1]+m2->GetTranslation()[1], loc[2]};
386
387 TGeoHMatrix *ml = GetMatrix(index);
388 if (!ml) return kFALSE;
389 ml->LocalToMaster(locSens,glob);
390 return kTRUE;
391}
392
393//______________________________________________________________________
394Bool_t AliITSgeomTGeoUpg::GlobalToLocal(Int_t index,
395 const Double_t *glob, Double_t *loc)
396{
397 // Make the conversion from the global reference system to the sensitive local
398 // reference system, for an arbitrary global position. The input is the pointer
399 // to the array of global coordinates, the result is sent to the loc pointer.
400 CheckInit();
401 //
402 TGeoHMatrix *ml = GetMatrix(index);
403 if (!ml) return kFALSE;
404
405 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
406 if (!m2) return kFALSE;
407 ml->MasterToLocal(glob,loc);
408 // The shift (in local y only) between alignable and sensitive volume
409 // is extracted directly from the Tracking2Local matrix
410 loc[1] -= m2->GetTranslation()[1];
411
412 return kTRUE;
413}
414
415//______________________________________________________________________
416Bool_t AliITSgeomTGeoUpg::LocalToGlobalVect(Int_t index,
417 const Double_t *loc, Double_t *glob)
418{
419 // Make the conversion from the local sensitive reference system to the global
420 // reference system, for an arbitrary vector. The input is the pointer to the
421 // array of local coordinates, the result is sent to the glob pointer.
422 CheckInit();
423 //
424 TGeoHMatrix *ml = GetMatrix(index);
425 if (!ml) return kFALSE;
426 ml->LocalToMasterVect(loc,glob);
427 return kTRUE;
428}
429
430//______________________________________________________________________
431Bool_t AliITSgeomTGeoUpg::GlobalToLocalVect(Int_t index,
432 const Double_t *glob, Double_t *loc)
433{
434 // Make the conversion from the global reference system to the sensitive local
435 // reference system, for an arbitrary vector. The input is the pointer to the
436 // array of global coordinates, the result is sent to the loc pointer.
437 CheckInit();
438 //
439 TGeoHMatrix *ml = GetMatrix(index);
440 if (!ml) return kFALSE;
441 ml->MasterToLocalVect(glob,loc);
442
443 return kTRUE;
444}
445
446//______________________________________________________________________
447void AliITSgeomTGeoUpg::BuildITS()
448{
449 // build ITS info from TGeo
450 if (fgVersion!=kITSVNA) return; // already initialized
451 //
452 if (!gGeoManager) AliFatalClass("Geometry is not loaded");
453 //
454 // get ITS version
455 TGeoVolume *itsV = gGeoManager->GetVolume(fgkITSVolName);
456 if (!gGeoManager) AliFatalClass(Form("ITS volume %s is not in the geometry",fgkITSVolName));
457 //
458 Int_t minor = 0;
459 TDatime datetime;
460 const Char_t *title = itsV->GetTitle();
461 if(!ReadVersionString(title,fgVersion,minor,datetime))
462 AliFatalClass(Form("Can't read title %s to extract version",title));
463 //
464 if (fgVersion==kITSVNA) AliFatalClass(Form("Failed to detrmine ITS version from title %s",title));
465 //
466 (fgVersion==kITSVOld) ? BuildITSOld() : BuildITSUpg();
467 //
468}
469
470//______________________________________________________________________
471void AliITSgeomTGeoUpg::BuildITSOld()
472{
473 // assign old ITS
474 fgNLayers = kNLayersOld;
475 fgNModules = fgkNModulesOld;
476 fgNLadders = (Int_t*)fgkNLaddersOld;
477 fgNDetectors = (Int_t*)fgkNDetectorsOld;
478}
479
480//______________________________________________________________________
481void AliITSgeomTGeoUpg::BuildITSUpg()
482{
483 // exract upg ITS parameters from TGeo
484 fgNLayers = ExtractNumberOfLayers();
485 if (!fgNLayers) return;
486 //
487 fgNLadders = new Int_t[fgNLayers];
488 fgNDetectors = new Int_t[fgNLayers];
489 fgNModules = 0;
490 for (int i=0;i<fgNLayers;i++) {
91fc36e5 491 fgNLadders[i] = ExtractNumberOfLadders(i+1);
492 fgNDetectors[i] = ExtractNumberOfDetectors(i+1);
ce886e8e 493 fgNModules += fgNLadders[i]*fgNDetectors[i];
494 }
495 //
496}
497
498//______________________________________________________________________
499Bool_t AliITSgeomTGeoUpg::ReadVersionString(const Char_t *str,
500 Int_t &maj,Int_t &min,
501 TDatime &dt)
502{
503 // fills the string str with the major and minor version number
504 // Inputs:
505 // Char_t *str The character string to holding the major and minor
506 // version numbers in
507 // Outputs:
508 // Int_t maj The major number
509 // Int_t min The minor number
510 // TDatime dt The date and time of the cvs commit
511 // Return:
512 // kTRUE if no errors
2695e019 513 enum {kv11=11,kv110=110,kvUpgrade=20}; // RS: to make consistent global numbering scheme
ce886e8e 514
515 Bool_t ok;
516 Char_t cvsRevision[10],cvsDate[11],cvsTime[9];
517 Int_t i,m,n=strlen(str),year,month,day,hours,minuts,seconds;
518 memset(cvsRevision,0,10*sizeof(Char_t));
519 memset(cvsDate,0,11*sizeof(Char_t));
520 memset(cvsTime,0,9*sizeof(Char_t));
521
522 if(n<35) return kFALSE; // not enough space for numbers
523 m = sscanf(str,"Major Version= %d Minor Version= %d Revision: %9s "
524 "Date: %10s %8s",&i,&min,cvsRevision,cvsDate,cvsTime);
525 ok = m==5;
526 if(!ok) return !ok;
527 m = sscanf(cvsDate,"%d/%d/%d",&year,&month,&day);
528 ok = m==3;
529 if(!ok) return !ok;
530 m = sscanf(cvsTime,"%d:%d:%d",&hours,&minuts,&seconds);
531 ok = m==3;
532 if(!ok) return !ok;
533 dt.Set(year,month,day,hours,minuts,seconds);
534 //
535 switch (i){
2695e019 536 case kv110:
ce886e8e 537 case kv11:{
538 maj = kITSVOld;
539 } break;
540 case kvUpgrade:{
541 maj = kITSVUpg;
542 } break;
543 default:{
544 maj = kITSVNA;
545 } break;
546 } // end switch
547 return ok;
548}
549
550//______________________________________________________________________
551Int_t AliITSgeomTGeoUpg::ExtractNumberOfLayers()
552{
553 // Determines the number of layers in the Upgrade Geometry
554 //
555 // Inputs:
556 // none
557 // Outputs:
558 // none
559 // Return:
560 // the number of layers in the current geometry
561 // -1 if not Upgrade Geometry
562 // MS
563 //
564 Int_t numberOfLayers = 0;
565 //
566 TGeoVolume *itsV = gGeoManager->GetVolume(fgkITSVolName);
567 if (!itsV) AliFatalClass(Form("ITS volume %s is not in the geometry",fgkITSVolName));
568 //
569 // Loop on all ITSV nodes, count Layer volumes by checking names
570 Int_t nNodes = itsV->GetNodes()->GetEntries();
571 for (Int_t j=0; j<nNodes; j++) if (strstr(itsV->GetNodes()->At(j)->GetName(),fgkITSLrName)) numberOfLayers++;
572 //
573 return numberOfLayers;
574}
575
576//______________________________________________________________________
577Int_t AliITSgeomTGeoUpg::ExtractNumberOfLadders(const Int_t lay)
578{
579 // Determines the number of layers in the Upgrade Geometry
580 //
581 // Inputs:
91fc36e5 582 // lay: layer number, starting from 1
ce886e8e 583 // Outputs:
584 // none
585 // Return:
586 // the number of ladders in layer lay
587 // -1 if not Upgrade Geometry
588 // MS
589 Int_t numberOfLadders = 0;
590 char laynam[30];
591 snprintf(laynam, 30, "%s%d",fgkITSLrName,lay);
592 TGeoVolume* volLr = gGeoManager->GetVolume(laynam);
593 if (!volLr) AliFatalClass(Form("can't find %s volume",laynam));
594 //
595 // Loop on all layer nodes, count Ladder volumes by checking names
596 Int_t nNodes = volLr->GetNodes()->GetEntries();
597 for (Int_t j=0; j<nNodes; j++) if (strstr(volLr->GetNodes()->At(j)->GetName(),fgkITSLadName)) numberOfLadders++;
598 //
599 return numberOfLadders;
600 //
601}
602
603//______________________________________________________________________
604Int_t AliITSgeomTGeoUpg::ExtractNumberOfDetectors(const Int_t lay)
605{
606 // Determines the number of detectors per ladder in the Upgrade Geometry
607 //
608 // Inputs:
91fc36e5 609 // lay: layer number from 1
ce886e8e 610 // Outputs:
611 // none
612 // Return:
613 // the number of modules per ladder in layer lay
614 // -1 if not Upgrade Geometry
615 // MS
616 Int_t numberOfModules = 0;
617 char laddnam[30];
618 snprintf(laddnam, 30, "%s%d", fgkITSLadName,lay);
619 TGeoVolume* volLd = gGeoManager->GetVolume(laddnam);
620 if (!volLd) AliFatalClass(Form("can't find %s volume",laddnam));
621 //
622 // Loop on all ladder nodes, count Module volumes by checking names
623 Int_t nNodes = volLd->GetNodes()->GetEntries();
624 for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),"ITSupgModule")) numberOfModules++;
625 //
626 return numberOfModules;
627 //
628}