1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
19 ////////////////////////////////////////////////////////////////
20 // This class initializes the class AliITSgeom
21 // The initialization is done starting from
22 // a geometry coded by means of the ROOT geometrical modeler
23 // This initialization can be used both for simulation and reconstruction
24 ///////////////////////////////////////////////////////////////
28 #include <TStopwatch.h>
29 #include <TGeoManager.h>
30 #include <TGeoVolume.h>
31 #include <TGeoShape.h>
38 #include <TGeoSphere.h>
47 #include "AliITSgeomSPD.h"
48 #include "AliITSgeomSDD.h"
49 #include "AliITSgeomSSD.h"
50 #include "AliITSsegmentationSPD.h"
51 #include "AliITSsegmentationSDD.h"
52 #include "AliITSsegmentationSSD.h"
53 #include "AliITSgeom.h"
54 #include "AliITSInitGeometry.h"
56 ClassImp(AliITSInitGeometry)
58 const Bool_t AliITSInitGeometry::fgkOldSPDbarrel = kTRUE;
59 const Bool_t AliITSInitGeometry::fgkOldSDDbarrel = kFALSE;
60 const Bool_t AliITSInitGeometry::fgkOldSSDbarrel = kTRUE;
61 const Bool_t AliITSInitGeometry::fgkOldSDDcone = kTRUE;
62 const Bool_t AliITSInitGeometry::fgkOldSSDcone = kTRUE;
63 const Bool_t AliITSInitGeometry::fgkOldSPDshield = kTRUE;
64 const Bool_t AliITSInitGeometry::fgkOldSDDshield = kTRUE;
65 const Bool_t AliITSInitGeometry::fgkOldSSDshield = kTRUE;
66 const Bool_t AliITSInitGeometry::fgkOldServices = kTRUE;
67 const Bool_t AliITSInitGeometry::fgkOldSupports = kTRUE;
69 //______________________________________________________________________
70 AliITSInitGeometry::AliITSInitGeometry():
84 // A default inilized AliITSInitGeometry object
87 //______________________________________________________________________
88 AliITSInitGeometry::AliITSInitGeometry(AliITSVersion_t version,Int_t minorversion):
91 fMinorVersion(minorversion),
92 fMajorVersion(version),
102 // A default inilized AliITSInitGeometry object
103 if(version == kvPPRasymmFMD && (fMinorVersion==1|| fMinorVersion==2)){
104 fName="AliITSvPPRasymmFMD";
106 else if(version == kv11Hybrid){
107 fName="AliITSv11Hybrid";
110 AliFatal(Form("Undefined geometry: fMajorVersion=%d, fMinorVersion= %d",(Int_t)fMajorVersion,fMinorVersion));
114 if(fName.CompareTo("AliITSvPPRasymmFMD")==0)if(fMinorVersion==1||
120 if (fName.CompareTo("AliITSv11")==0) {
125 // if not defined geometry error
126 Error("AliITSInitGeometry(name,version)"," Name must be AliITSvPPRasymmFMD"
127 " and version must be 1 or 2 for now.");
133 //______________________________________________________________________
134 AliITSgeom* AliITSInitGeometry::CreateAliITSgeom(){
135 // Creates and Initilizes the geometry transformation class AliITSgeom
136 // to values appropreate to this specific geometry. Now that
137 // the segmentation is part of AliITSgeom, the detector
138 // segmentations are also defined here.
144 // A pointer to a new properly inilized AliITSgeom class. If
145 // pointer = 0 then failed to init.
147 AliITSgeom *geom = new AliITSgeom();
148 if(!InitAliITSgeom(geom)){ // Error initilization failed
154 //______________________________________________________________________
155 Bool_t AliITSInitGeometry::InitAliITSgeom(AliITSgeom *geom){
156 // Initilizes the geometry transformation class AliITSgeom
157 // to values appropreate to this specific geometry. Now that
158 // the segmentation is part of AliITSgeom, the detector
159 // segmentations are also defined here.
161 // AliITSgeom *geom A pointer to the AliITSgeom class
163 // AliITSgeom *geom This pointer recreated and properly inilized.
168 AliFatal("The geometry manager has not been initialized (e.g. TGeoManager::Import(\"geometry.root\")should be called in advance) - exit forced");
171 switch(fMajorVersion) {
173 case kvPPRasymmFMD: {
174 return InitAliITSgeomPPRasymmFMD(geom);
178 return InitAliITSgeomV11Hybrid(geom);
182 return InitAliITSgeomV11(geom);
186 AliFatal("Undefined geometry");
192 //______________________________________________________________________
193 Bool_t AliITSInitGeometry::InitAliITSgeomPPRasymmFMD(AliITSgeom *geom){
194 // Initilizes the geometry transformation class AliITSgeom
195 // to values appropreate to this specific geometry. Now that
196 // the segmentation is part of AliITSgeom, the detector
197 // segmentations are also defined here.
199 // AliITSgeom *geom A pointer to the AliITSgeom class
201 // AliITSgeom *geom This pointer recreated and properly inilized.
204 // const Double_t kcm2micron = 1.0E4;
205 const Int_t kItype=0; // Type of transormation defined 0=> Geant
206 const Int_t klayers = 6; // number of layers in the ITS
207 const Int_t kladders[klayers] = {20,40,14,22,34,38}; // Number of ladders
208 const Int_t kdetectors[klayers] = {4,4,6,8,22,25};// number of detector/lad
209 const AliITSDetector kIdet[6] = {kSPD,kSPD,kSDD,kSDD,kSSD,kSSD};
210 const TString kPathbase = "/ALIC_1/ITSV_1/ITSD_1/";
211 const TString kNames[2][klayers] = {
212 {"%sIT12_1/I12A_%d/I10A_%d/I103_%d/I101_1/ITS1_1", // lay=1
213 "%sIT12_1/I12A_%d/I20A_%d/I1D3_%d/I1D1_1/ITS2_1", // lay=2
214 "%sIT34_1/I004_%d/I302_%d/ITS3_%d/", // lay=3
215 "%sIT34_1/I005_%d/I402_%d/ITS4_%d/", // lay=4
216 "%sIT56_1/I565_%d/I562_%d/ITS5_%d/", // lay=5
217 "%sIT56_1/I569_%d/I566_%d/ITS6_%d/"},// lay=6
218 {"%sIT12_1/I12B_%d/I10B_%d/I107_%d/I101_1/ITS1_1", // lay=1
219 "%sIT12_1/I12B_%d/I20B_%d/I1D7_%d/I1D1_1/ITS2_1", // lay=2
220 "%sIT34_1/I004_%d/I302_%d/ITS3_%d", // lay=3
221 "%sIT34_1/I005_%d/I402_%d/ITS4_%d", // lay=4
222 "%sIT56_1/I565_%d/I562_%d/ITS5_%d", // lay=5
223 "%sIT56_1/I569_%d/I566_%d/ITS6_%d"}};// Lay=6
225 Int_t itsGeomTreeCopys[knlayers][3]= {{10, 2, 4},// lay=1
232 Int_t mod,nmods=0,lay,lad,det,cpn0,cpn1,cpn2;
233 Double_t tran[3]={0.0,0.0,0.0},rot[10]={9*0.0,1.0};
235 TString path,shapeName;
237 Bool_t initSeg[3]={kFALSE,kFALSE,kFALSE};
238 TStopwatch *time = 0x0;if(fTiming) time=new TStopwatch();
240 if(fTiming) time->Start();
241 for(mod=0;mod<klayers;mod++) nmods += kladders[mod]*kdetectors[mod];
242 geom->Init(kItype,klayers,kladders,kdetectors,nmods);
243 for(mod=0;mod<nmods;mod++){
244 DecodeDetectorLayers(mod,lay,lad,det); // Write
245 geom->CreateMatrix(mod,lay,lad,det,kIdet[lay-1],tran,rot);
246 RecodeDetector(mod,cpn0,cpn1,cpn2); // Write reusing lay,lad,det.
247 path.Form(kNames[fMinorVersion-1][lay-1].Data(),
248 kPathbase.Data(),cpn0,cpn1,cpn2);
249 geom->GetGeomMatrix(mod)->SetPath(path);
250 GetTransformation(path.Data(),materix);
251 geom->SetTrans(mod,materix.GetTranslation());
252 geom->SetRotMatrix(mod,materix.GetRotationMatrix());
253 if(initSeg[kIdet[lay-1]]) continue;
254 GetShape(path,shapeName,shapePar);
255 if(shapeName.CompareTo("BOX")){
256 Error("InitITSgeom","Geometry changed without proper code update"
257 "or error in reading geometry. Shape is not BOX.");
260 InitGeomShapePPRasymmFMD(kIdet[lay-1],initSeg,shapePar,geom);
270 //______________________________________________________________________
271 Bool_t AliITSInitGeometry::InitAliITSgeomV11Hybrid(AliITSgeom *geom){
272 // Initilizes the geometry transformation class AliITSgeom
273 // to values appropreate to this specific geometry. Now that
274 // the segmentation is part of AliITSgeom, the detector
275 // segmentations are also defined here.
277 // AliITSgeom *geom A pointer to the AliITSgeom class
279 // AliITSgeom *geom This pointer recreated and properly inilized.
283 const Int_t kItype = 0; // Type of transformation defined 0=> Geant
284 const Int_t klayers = 6; // number of layers in the ITS
285 const Int_t kladders[klayers] = {20,40,14,22,34,38}; // Number of ladders
286 const Int_t kdetectors[klayers] = {4,4,6,8,22,25};// number of detector/lad
287 const AliITSDetector kIdet[6] = {kSPD,kSPD,kSDD,kSDD,kSSD,kSSD};
288 const TString kPathbase = "/ALIC_1/ITSV_1/";
290 char *pathSDDsens1, *pathSDDsens2;
291 if (SDDIsTGeoNative()) {
292 pathSDDsens1 = "%sITSsddLayer3_1/ITSsddLadd_%d/ITSsddSensor3_%d/ITSsddWafer3_%d/ITSsddSensitivL3_1";
293 pathSDDsens2 = "%sITSsddLayer4_1/ITSsddLadd_%d/ITSsddSensor4_%d/ITSsddWafer4_%d/ITSsddSensitivL4_1";
295 pathSDDsens1 = "%sITSD_1/IT34_1/I004_%d/I302_%d/ITS3_%d";
296 pathSDDsens2 = "%sITSD_1/IT34_1/I005_%d/I402_%d/ITS4_%d";
299 const TString kNames[klayers] = {
300 "%sITSD_1/IT12_1/I12B_%d/I10B_%d/I107_%d/I101_1/ITS1_1", // lay=1
301 "%sITSD_1/IT12_1/I12B_%d/I20B_%d/I1D7_%d/I1D1_1/ITS2_1", // lay=2
302 pathSDDsens1, // lay=3
303 pathSDDsens2, // lay=4
304 "%sITSD_1/IT56_1/I565_%d/I562_%d/ITS5_%d", // lay=5
305 "%sITSD_1/IT56_1/I569_%d/I566_%d/ITS6_%d"};// Lay=6
307 Int_t mod,nmods=0, lay, lad, det, cpn0, cpn1, cpn2;
308 Double_t tran[3]={0.,0.,0.}, rot[10]={9*0.0,1.0};
310 TString path, shapeName;
312 Bool_t initSeg[3]={kFALSE, kFALSE, kFALSE};
313 TStopwatch *time = 0x0;
314 if(fTiming) time = new TStopwatch();
316 if(fTiming) time->Start();
317 for(mod=0;mod<klayers;mod++) nmods += kladders[mod]*kdetectors[mod];
318 geom->Init(kItype,klayers,kladders,kdetectors,nmods);
320 for(mod=0;mod<nmods;mod++) {
322 DecodeDetectorLayers(mod,lay,lad,det); // Write
323 geom->CreateMatrix(mod,lay,lad,det,kIdet[lay-1],tran,rot);
324 RecodeDetector(mod,cpn0,cpn1,cpn2); // Write reusing lay,lad,det.
326 if (SDDIsTGeoNative())
327 if (kIdet[lay-1]==kSDD) {
333 path.Form(kNames[lay-1].Data(),
334 kPathbase.Data(),cpn0,cpn1,cpn2);
335 geom->GetGeomMatrix(mod)->SetPath(path);
336 GetTransformation(path.Data(),matrix);
337 geom->SetTrans(mod,matrix.GetTranslation());
338 geom->SetRotMatrix(mod,matrix.GetRotationMatrix());
339 if(initSeg[kIdet[lay-1]]) continue;
340 GetShape(path,shapeName,shapePar);
341 if(shapeName.CompareTo("BOX")){
342 Error("InitITSgeom","Geometry changed without proper code update"
343 "or error in reading geometry. Shape is not BOX.");
346 InitGeomShapePPRasymmFMD(kIdet[lay-1],initSeg,shapePar,geom);
357 //______________________________________________________________________
358 Bool_t AliITSInitGeometry::InitAliITSgeomV11(AliITSgeom *geom){
359 // Initilizes the geometry transformation class AliITSgeom
360 // Now that the segmentation is part of AliITSgeom, the detector
361 // segmentations are also defined here.
364 // AliITSgeom *geom A pointer to the AliITSgeom class
366 // AliITSgeom *geom This pointer recreated and properly inilized.
370 const Int_t kItype=0; // Type of transormation defined 0=> Geant
371 const Int_t klayers = 6; // number of layers in the ITS
372 const Int_t kladders[klayers] = {20,40,14,22,34,38}; // Number of ladders
373 const Int_t kdetectors[klayers] = {4,4,6,8,22,25};// number of detector/lad
374 const AliITSDetector kIdet[6] = {kSPD,kSPD,kSDD,kSDD,kSSD,kSSD};
376 const TString kPathbase = "/ALIC_1/ITSV_1/";
377 const TString kNames[klayers] =
378 {"AliITSInitGeometry:spd missing", // lay=1
379 "AliITSInitGeometry:spd missing", // lay=2
380 "%sITSsddLayer3_1/ITSsddLadd_%d/ITSsddSensor_%d/ITSsddWafer_1/ITSsddSensitiv_1", // lay=3
381 "%sITSsddLayer4_1/ITSsddLadd_%d/ITSsddSensor_%d/ITSsddWafer_1/ITSsddSensitiv_1", // lay=4
382 "AliITSInitGeometry:ssd missing", // lay=5
383 "AliITSInitGeometry:ssd missing"};// lay=6
385 Int_t mod,nmods=0,lay,lad,det,cpn0,cpn1,cpn2;
386 Double_t tran[3]={0.0,0.0,0.0},rot[10]={9*0.0,1.0};
388 TString path,shapeName;
390 Bool_t initSeg[3]={kFALSE,kFALSE,kFALSE};
391 TStopwatch *time = 0x0;if(fTiming) time=new TStopwatch();
393 if(fTiming) time->Start();
394 for(mod=0;mod<klayers;mod++) nmods += kladders[mod]*kdetectors[mod];
396 geom->Init(kItype,klayers,kladders,kdetectors,nmods);
397 for(mod=0;mod<nmods;mod++) {
399 DecodeDetectorLayers(mod,lay,lad,det); // Write
400 geom->CreateMatrix(mod,lay,lad,det,kIdet[lay-1],tran,rot);
401 RecodeDetector(mod,cpn0,cpn1,cpn2); // Write reusing lay,lad,det.
402 path.Form(kNames[lay-1].Data(),
403 kPathbase.Data(),cpn0,cpn1,cpn2);
404 geom->GetGeomMatrix(mod)->SetPath(path);
405 if (GetTransformation(path.Data(),matrix)) {
406 geom->SetTrans(mod,matrix.GetTranslation());
407 geom->SetRotMatrix(mod,matrix.GetRotationMatrix());
410 if(initSeg[kIdet[lay-1]]) continue;
411 GetShape(path,shapeName,shapePar);
412 if(shapeName.CompareTo("BOX")){
413 Error("InitAliITSgeomV11","Geometry changed without proper code update"
414 "or error in reading geometry. Shape is not BOX.");
417 InitGeomShapePPRasymmFMD(kIdet[lay-1],initSeg,shapePar,geom);
429 //______________________________________________________________________
430 Bool_t AliITSInitGeometry::InitGeomShapePPRasymmFMD(AliITSDetector idet,
434 // Initilizes the geometry segmentation class AliITSgeomS?D, or
435 // AliITSsegmentationS?D depending on the vaule of fSegGeom,
436 // to values appropreate to this specific geometry. Now that
437 // the segmentation is part of AliITSgeom, the detector
438 // segmentations are also defined here.
440 // Int_t lay The layer number/name.
441 // AliITSgeom *geom A pointer to the AliITSgeom class
443 // AliITSgeom *geom This pointer recreated and properly inilized.
446 // const Double_t kcm2micron = 1.0E4;
447 const Double_t kmicron2cm = 1.0E-4;
451 shapeParF.Set(shapePar.GetSize());
452 for(i=0;i<shapePar.GetSize();i++) shapeParF[i]=shapePar[i];
455 initSeg[idet] = kTRUE;
456 AliITSgeomSPD *geomSPD = new AliITSgeomSPD425Short();
457 Float_t bx[256],bz[280];
458 for(i=000;i<256;i++) bx[i] = 50.0*kmicron2cm; // in x all are 50 microns.
459 for(i=000;i<160;i++) bz[i] = 425.0*kmicron2cm; // most are 425 microns
461 for(i=160;i<280;i++) bz[i] = 0.0*kmicron2cm; // Outside of detector.
462 bz[ 31] = bz[ 32] = 625.0*kmicron2cm; // first chip boundry
463 bz[ 63] = bz[ 64] = 625.0*kmicron2cm; // first chip boundry
464 bz[ 95] = bz[ 96] = 625.0*kmicron2cm; // first chip boundry
465 bz[127] = bz[128] = 625.0*kmicron2cm; // first chip boundry
466 bz[160] = 425.0*kmicron2cm;// Set so that there is no zero pixel size for fNz.
467 geomSPD->ReSetBins(shapeParF[1],256,bx,160,bz);
468 geom->ReSetShape(idet,geomSPD);
471 initSeg[idet] = kTRUE;
472 AliITSgeomSDD *geomSDD = new AliITSgeomSDD256(shapeParF.GetSize(),
473 shapeParF.GetArray());
474 geom->ReSetShape(idet,geomSDD);
477 initSeg[idet] = kTRUE;
478 AliITSgeomSSD *geomSSD = new AliITSgeomSSD275and75(
479 shapeParF.GetSize(),shapeParF.GetArray());
480 geom->ReSetShape(idet,geomSSD);
482 default:{// Others, Note no kSDDp or kSSDp in this geometry.
483 geom->ReSetShape(idet,0);
484 Info("InitGeomShapePPRasymmFMD",
485 "default Dx=%f Dy=%f Dz=%f default=%d",
486 shapePar[0],shapePar[1],shapePar[2],idet);
491 //______________________________________________________________________
492 Bool_t AliITSInitGeometry::InitSegmentationPPRasymmFMD(AliITSDetector idet,
496 // Initilizes the geometry segmentation class AliITSgeomS?D, or
497 // AliITSsegmentationS?D depending on the vaule of fSegGeom,
498 // to values appropreate to this specific geometry. Now that
499 // the segmentation is part of AliITSgeom, the detector
500 // segmentations are also defined here.
502 // Int_t lay The layer number/name.
503 // AliITSgeom *geom A pointer to the AliITSgeom class
505 // AliITSgeom *geom This pointer recreated and properly inilized.
508 const Double_t kcm2micron = 1.0E4;
513 initSeg[idet] = kTRUE;
514 AliITSsegmentationSPD *segSPD = new AliITSsegmentationSPD();
515 segSPD->SetDetSize(2.*shapePar[0]*kcm2micron, // X
516 2.*shapePar[2]*kcm2micron, // Z
517 2.*shapePar[1]*kcm2micron);// Y Microns
518 segSPD->SetNPads(256,160);// Number of Bins in x and z
519 Float_t bx[256],bz[280];
520 for(i=000;i<256;i++) bx[i] = 50.0; // in x all are 50 microns.
521 for(i=000;i<160;i++) bz[i] = 425.0; // most are 425 microns
523 for(i=160;i<280;i++) bz[i] = 0.0; // Outside of detector.
524 bz[ 31] = bz[ 32] = 625.0; // first chip boundry
525 bz[ 63] = bz[ 64] = 625.0; // first chip boundry
526 bz[ 95] = bz[ 96] = 625.0; // first chip boundry
527 bz[127] = bz[128] = 625.0; // first chip boundry
528 bz[160] = 425.0;// Set so that there is no zero pixel size for fNz.
529 segSPD->SetBinSize(bx,bz); // Based on AliITSgeomSPD for now.
530 geom->ReSetShape(idet,segSPD);
533 initSeg[idet] = kTRUE;
534 AliITSsegmentationSDD *segSDD = new AliITSsegmentationSDD();
535 segSDD->SetDetSize(shapePar[0]*kcm2micron, // X
536 2.*shapePar[2]*kcm2micron, // Z
537 2.*shapePar[1]*kcm2micron);// Y Microns
538 segSDD->SetNPads(256,256);// Anodes, Samples
539 geom->ReSetShape(idet,segSDD);
542 initSeg[idet] = kTRUE;
543 AliITSsegmentationSSD *segSSD = new AliITSsegmentationSSD();
544 segSSD->SetDetSize(2.*shapePar[0]*kcm2micron, // X
545 2.*shapePar[2]*kcm2micron, // Z
546 2.*shapePar[1]*kcm2micron);// Y Microns.
547 segSSD->SetPadSize(95.,0.); // strip x pitch in microns
548 segSSD->SetNPads(768,2); // number of strips on each side, sides.
549 segSSD->SetAngles(0.0075,0.0275); // strip angels rad P and N side.
550 segSSD->SetAnglesLay5(0.0075,0.0275);//strip angels rad P and N
551 segSSD->SetAnglesLay6(0.0275,0.0075);//strip angels rad P and N
552 geom->ReSetShape(idet,segSSD);
554 default:{// Others, Note no kSDDp or kSSDp in this geometry.
555 geom->ReSetShape(idet,0);
556 Info("InitSegmentationPPRasymmFMD",
557 "default segmentation Dx=%f Dy=%f Dz=%f default=%d",
558 shapePar[0],shapePar[1],shapePar[2],idet);
563 //______________________________________________________________________
564 Bool_t AliITSInitGeometry::GetTransformation(const TString &volumePath,
566 // Returns the Transformation matrix between the volume specified
567 // by the path volumePath and the Top or mater volume. The format
568 // of the path volumePath is as follows (assuming ALIC is the Top volume)
569 // "/ALIC_1/DDIP_1/S05I_2/S05H_1/S05G_3". Here ALIC is the top most
570 // or master volume which has only 1 instance of. Of all of the daughter
571 // volumes of ALICE, DDIP volume copy #1 is indicated. Similarly for
572 // the daughter volume of DDIP is S05I copy #2 and so on.
574 // TString& volumePath The volume path to the specific volume
575 // for which you want the matrix. Volume name
576 // hierarchy is separated by "/" while the
577 // copy number is appended using a "_".
579 // TGeoHMatrix &mat A matrix with its values set to those
580 // appropriate to the Local to Master transformation
582 // A logical value if kFALSE then an error occurred and no change to
585 // We have to preserve the modeler state
587 // Preserve the modeler state.
588 gGeoManager->PushPath();
589 if (!gGeoManager->cd(volumePath.Data())) {
590 gGeoManager->PopPath();
591 Error("GetTransformation","Error in cd-ing to ",volumePath.Data());
593 } // end if !gGeoManager
594 mat = *gGeoManager->GetCurrentMatrix();
595 // Retstore the modeler state.
596 gGeoManager->PopPath();
599 //______________________________________________________________________
600 Bool_t AliITSInitGeometry::GetShape(const TString &volumePath,
601 TString &shapeType,TArrayD &par){
602 // Returns the shape and its parameters for the volume specified
605 // TString& volumeName The volume name
607 // TString &shapeType Shape type
608 // TArrayD &par A TArrayD of parameters with all of the
609 // parameters of the specified shape.
611 // A logical indicating whether there was an error in getting this
614 gGeoManager->PushPath();
615 if (!gGeoManager->cd(volumePath.Data())) {
616 gGeoManager->PopPath();
619 TGeoVolume * vol = gGeoManager->GetCurrentVolume();
620 gGeoManager->PopPath();
621 if (!vol) return kFALSE;
622 TGeoShape *shape = vol->GetShape();
623 TClass *classType = shape->IsA();
624 if (classType==TGeoBBox::Class()) {
628 TGeoBBox *box = (TGeoBBox*)shape;
629 par.AddAt(box->GetDX(),0);
630 par.AddAt(box->GetDY(),1);
631 par.AddAt(box->GetDZ(),2);
634 if (classType==TGeoTrd1::Class()) {
638 TGeoTrd1 *trd1 = (TGeoTrd1*)shape;
639 par.AddAt(trd1->GetDx1(),0);
640 par.AddAt(trd1->GetDx2(),1);
641 par.AddAt(trd1->GetDy(), 2);
642 par.AddAt(trd1->GetDz(), 3);
645 if (classType==TGeoTrd2::Class()) {
649 TGeoTrd2 *trd2 = (TGeoTrd2*)shape;
650 par.AddAt(trd2->GetDx1(),0);
651 par.AddAt(trd2->GetDx2(),1);
652 par.AddAt(trd2->GetDy1(),2);
653 par.AddAt(trd2->GetDy2(),3);
654 par.AddAt(trd2->GetDz(), 4);
657 if (classType==TGeoTrap::Class()) {
661 TGeoTrap *trap = (TGeoTrap*)shape;
662 Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
663 par.AddAt(trap->GetDz(),0);
664 par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
665 par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
666 par.AddAt(trap->GetH1(),3);
667 par.AddAt(trap->GetBl1(),4);
668 par.AddAt(trap->GetTl1(),5);
669 par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
670 par.AddAt(trap->GetH2(),7);
671 par.AddAt(trap->GetBl2(),8);
672 par.AddAt(trap->GetTl2(),9);
673 par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
676 if (classType==TGeoTube::Class()) {
680 TGeoTube *tube = (TGeoTube*)shape;
681 par.AddAt(tube->GetRmin(),0);
682 par.AddAt(tube->GetRmax(),1);
683 par.AddAt(tube->GetDz(),2);
686 if (classType==TGeoTubeSeg::Class()) {
690 TGeoTubeSeg *tubs = (TGeoTubeSeg*)shape;
691 par.AddAt(tubs->GetRmin(),0);
692 par.AddAt(tubs->GetRmax(),1);
693 par.AddAt(tubs->GetDz(),2);
694 par.AddAt(tubs->GetPhi1(),3);
695 par.AddAt(tubs->GetPhi2(),4);
698 if (classType==TGeoCone::Class()) {
702 TGeoCone *cone = (TGeoCone*)shape;
703 par.AddAt(cone->GetDz(),0);
704 par.AddAt(cone->GetRmin1(),1);
705 par.AddAt(cone->GetRmax1(),2);
706 par.AddAt(cone->GetRmin2(),3);
707 par.AddAt(cone->GetRmax2(),4);
710 if (classType==TGeoConeSeg::Class()) {
714 TGeoConeSeg *cons = (TGeoConeSeg*)shape;
715 par.AddAt(cons->GetDz(),0);
716 par.AddAt(cons->GetRmin1(),1);
717 par.AddAt(cons->GetRmax1(),2);
718 par.AddAt(cons->GetRmin2(),3);
719 par.AddAt(cons->GetRmax2(),4);
720 par.AddAt(cons->GetPhi1(),5);
721 par.AddAt(cons->GetPhi2(),6);
724 if (classType==TGeoSphere::Class()) {
729 TGeoSphere *sphe = (TGeoSphere*)shape;
730 par.AddAt(sphe->GetRmin(),0);
731 par.AddAt(sphe->GetRmax(),1);
732 par.AddAt(sphe->GetTheta1(),2);
733 par.AddAt(sphe->GetTheta2(),3);
734 par.AddAt(sphe->GetPhi1(),4);
735 par.AddAt(sphe->GetPhi2(),5);
738 if (classType==TGeoPara::Class()) {
742 TGeoPara *para = (TGeoPara*)shape;
743 par.AddAt(para->GetX(),0);
744 par.AddAt(para->GetY(),1);
745 par.AddAt(para->GetZ(),2);
746 par.AddAt(para->GetTxy(),3);
747 par.AddAt(para->GetTxz(),4);
748 par.AddAt(para->GetTyz(),5);
751 if (classType==TGeoPgon::Class()) {
753 TGeoPgon *pgon = (TGeoPgon*)shape;
754 Int_t nz = pgon->GetNz();
755 const Double_t *rmin = pgon->GetRmin();
756 const Double_t *rmax = pgon->GetRmax();
757 const Double_t *z = pgon->GetZ();
760 par.AddAt(pgon->GetPhi1(),0);
761 par.AddAt(pgon->GetDphi(),1);
762 par.AddAt(pgon->GetNedges(),2);
763 par.AddAt(pgon->GetNz(),3);
764 for (Int_t i=0; i<nz; i++) {
765 par.AddAt(z[i], 4+3*i);
766 par.AddAt(rmin[i], 4+3*i+1);
767 par.AddAt(rmax[i], 4+3*i+2);
771 if (classType==TGeoPcon::Class()) {
773 TGeoPcon *pcon = (TGeoPcon*)shape;
774 Int_t nz = pcon->GetNz();
775 const Double_t *rmin = pcon->GetRmin();
776 const Double_t *rmax = pcon->GetRmax();
777 const Double_t *z = pcon->GetZ();
780 par.AddAt(pcon->GetPhi1(),0);
781 par.AddAt(pcon->GetDphi(),1);
782 par.AddAt(pcon->GetNz(),2);
783 for (Int_t i=0; i<nz; i++) {
784 par.AddAt(z[i], 3+3*i);
786 par.AddAt(rmin[i], 3+3*i+1);
787 par.AddAt(rmax[i], 3+3*i+2);
791 if (classType==TGeoEltu::Class()) {
795 TGeoEltu *eltu = (TGeoEltu*)shape;
796 par.AddAt(eltu->GetA(),0);
797 par.AddAt(eltu->GetB(),1);
798 par.AddAt(eltu->GetDz(),2);
801 if (classType==TGeoHype::Class()) {
805 TGeoHype *hype = (TGeoHype*)shape;
806 par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kTRUE)),0);
807 par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kFALSE)),1);
808 par.AddAt(hype->GetDZ(),2);
809 par.AddAt(hype->GetStIn(),3);
810 par.AddAt(hype->GetStOut(),4);
813 if (classType==TGeoGtra::Class()) {
817 TGeoGtra *trap = (TGeoGtra*)shape;
818 Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
819 par.AddAt(trap->GetDz(),0);
820 par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
821 par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
822 par.AddAt(trap->GetH1(),3);
823 par.AddAt(trap->GetBl1(),4);
824 par.AddAt(trap->GetTl1(),5);
825 par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
826 par.AddAt(trap->GetH2(),7);
827 par.AddAt(trap->GetBl2(),8);
828 par.AddAt(trap->GetTl2(),9);
829 par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
830 par.AddAt(trap->GetTwistAngle(),11);
833 if (classType==TGeoCtub::Class()) {
837 TGeoCtub *ctub = (TGeoCtub*)shape;
838 const Double_t *lx = ctub->GetNlow();
839 const Double_t *tx = ctub->GetNhigh();
840 par.AddAt(ctub->GetRmin(),0);
841 par.AddAt(ctub->GetRmax(),1);
842 par.AddAt(ctub->GetDz(),2);
843 par.AddAt(ctub->GetPhi1(),3);
844 par.AddAt(ctub->GetPhi2(),4);
853 Error("GetShape","Getting shape parameters for shape %s not implemented",
857 //______________________________________________________________________
858 void AliITSInitGeometry::DecodeDetector(Int_t &mod,Int_t layer,Int_t cpn0,
859 Int_t cpn1,Int_t cpn2) const {
860 // decode geometry into detector module number. There are two decoding
861 // Scheams. Old which does not follow the ALICE coordinate system
862 // requirements, and New which dose.
864 // Int_t layer The ITS layer
865 // Int_t cpn0 The lowest copy number
866 // Int_t cpn1 The middle copy number
867 // Int_t cpn2 the highest copy number
869 // Int_t &mod The module number assoicated with this set
873 const Int_t kDetPerLadderSPD[2]={2,4};
874 const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
875 const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
876 Int_t lay=-1,lad=-1,det=-1,i;
878 if(fDecode){ // New decoding scheam
883 if(cpn0==4&&cpn1==1) lad=1;
884 else if(cpn0==4&&cpn1==2) lad=20;
886 lad = 8-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
888 lad = 28-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
894 if(cpn0==4&&cpn1==1) lad=1;
896 lad = 14-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
898 lad = 54-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
903 if(cpn0<5) lad = 5-cpn0;
909 if(cpn0<7) lad = 7-cpn0;
915 if(cpn0<10) lad = 10-cpn0;
921 if(cpn0<9) lad = 9-cpn0;
927 for(i=0;i<layer-1;i++) mod += kLadPerLayer[i]*kDetPerLadder[i];
928 mod += kDetPerLadder[layer-1]*(lad-1)+det-1;// module start at zero.
931 // Old decoding scheam
935 lad = cpn1+kDetPerLadderSPD[layer-1]*(cpn0-1);
952 for(i=0;i<layer-1;i++) mod += kLadPerLayer[i]*kDetPerLadder[i];
953 mod += kDetPerLadder[layer-1]*(lad-1)+det-1;// module start at zero.
956 //______________________________________________________________________
957 void AliITSInitGeometry::RecodeDetector(Int_t mod,Int_t &cpn0,
958 Int_t &cpn1,Int_t &cpn2){
959 // decode geometry into detector module number. There are two decoding
960 // Scheams. Old which does not follow the ALICE coordinate system
961 // requirements, and New which dose.
963 // Int_t mod The module number assoicated with this set
966 // Int_t cpn0 The lowest copy number
967 // Int_t cpn1 The middle copy number
968 // Int_t cpn2 the highest copy number
971 const Int_t kITSgeoTreeCopys[6][3]= {{10, 2, 4},// lay=1
977 const Int_t kDetPerLadderSPD[2]={2,4};
978 // const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
979 // const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
982 cpn0 = cpn1 = cpn2 = 0;
983 DecodeDetectorLayers(mod,lay,lad,det);
984 if(fDecode){ // New decoding scheam
987 cpn2 = 5-det; // Detector 1-4
988 cpn1 = 1+(lad-1)%kDetPerLadderSPD[lay-1];
989 cpn0 = 5-(lad+kDetPerLadderSPD[lay-1])/kDetPerLadderSPD[lay-1];
990 if(mod>27) cpn0 = 15-(lad+kDetPerLadderSPD[lay-1])/
991 kDetPerLadderSPD[lay-1];
994 cpn2 = 5-det; // Detector 1-4
995 cpn1 = 4-(lad+2)%kDetPerLadderSPD[lay-1];
996 cpn0 = 1+(14-cpn1-lad)/kDetPerLadderSPD[lay-1];
997 if(mod>131) cpn0 = 1+(54-lad-cpn1)/kDetPerLadderSPD[lay-1];
1001 if(lad<5) cpn0 = 5-lad;
1007 if(lad<7) cpn0 = 7-lad;
1013 if(lad<10) cpn0 = 10-lad;
1019 if(lad<9) cpn0 = 9-lad;
1024 Error("RecodeDetector","New: mod=%d lay=%d not 1-6.");
1028 if(cpn0<1||cpn1<1||cpn2<1||
1029 cpn0>kITSgeoTreeCopys[lay-1][0]||
1030 cpn1>kITSgeoTreeCopys[lay-1][1]||
1031 cpn2>kITSgeoTreeCopys[lay-1][2])
1032 Error("RecodeDetector",
1033 "cpn0=%d cpn1=%d cpn2=%d mod=%d lay=%d lad=%d det=%d",
1034 cpn0,cpn1,cpn2,mod,lay,lad,det);
1040 cpn2 = det; // Detector 1-4
1041 cpn0 = (lad+kDetPerLadderSPD[lay-1]-1)/kDetPerLadderSPD[lay-1];
1042 cpn1 = (lad+kDetPerLadderSPD[lay-1]-1)%kDetPerLadderSPD[lay-1] + 1;
1044 case 3: case 4: case 5 : case 6:{
1050 Error("RecodeDetector","Old: mod=%d lay=%d not 1-6.");
1054 if(cpn0<1||cpn1<1||cpn2<1||
1055 cpn0>kITSgeoTreeCopys[lay-1][0]||
1056 cpn1>kITSgeoTreeCopys[lay-1][1]||
1057 cpn2>kITSgeoTreeCopys[lay-1][2])
1058 Error("RecodeDetector",
1059 "cpn0=%d cpn1=%d cpn2=%d mod=%d lay=%d lad=%d det=%d",
1060 cpn0,cpn1,cpn2,mod,lay,lad,det);
1063 //______________________________________________________________________
1064 void AliITSInitGeometry::DecodeDetectorLayers(Int_t mod,Int_t &lay,
1065 Int_t &lad,Int_t &det){
1066 // decode geometry into detector module number. There are two decoding
1067 // Scheams. Old which does not follow the ALICE coordinate system
1068 // requirements, and New which dose. Note, this use of layer ladder
1069 // and detector numbers are strictly for internal use of this
1070 // specific code. They do not represent the "standard" layer ladder
1071 // or detector numbering except in a very old and obsoleate sence.
1073 // Int_t mod The module number assoicated with this set
1076 // Int_t lay The layer number
1077 // Int_t lad The ladder number
1078 // Int_t det the dettector number
1081 // const Int_t kDetPerLadderSPD[2]={2,4};
1082 const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
1083 const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
1091 mod2 += kLadPerLayer[lay]*kDetPerLadder[lay];
1093 }while(mod2<=mod); // end while
1094 if(lay>6||lay<1) Error("DecodeDetectorLayers","0<lay=%d>6",lay);
1095 mod2 -= kLadPerLayer[lay-1]*kDetPerLadder[lay-1];
1098 mod2 += kDetPerLadder[lay-1];
1099 }while(mod2<=mod); // end while
1100 if(lad>kLadPerLayer[lay-1]||lad<1) Error("DecodeDetectorLayera",
1101 "lad=%d>kLadPerLayer[lay-1=%d]=%d mod=%d mod2=%d",lad,lay-1,
1102 kLadPerLayer[lay-1],mod,mod2);
1103 mod2 -= kDetPerLadder[lay-1];
1105 if(det>kDetPerLadder[lay-1]||det<1) Error("DecodeDetectorLayers",
1106 "det=%d>detPerLayer[lay-1=%d]=%d mod=%d mod2=%d lad=%d",det,
1107 lay-1,kDetPerLadder[lay-1],mod,mod2,lad);