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 <AliITSgeomSPD.h>
30 #include <AliITSgeomSDD.h>
31 #include <AliITSgeomSSD.h>
32 #include <AliITSsegmentationSPD.h>
33 #include <AliITSsegmentationSDD.h>
34 #include <AliITSsegmentationSSD.h>
35 #include <TGeoManager.h>
36 #include <TGeoVolume.h>
37 #include <TGeoShape.h>
44 #include <TGeoSphere.h>
51 #include "AliITSgeom.h"
52 #include "AliITSInitGeometry.h"
54 ClassImp(AliITSInitGeometry)
55 //______________________________________________________________________
56 AliITSInitGeometry::AliITSInitGeometry():
70 // A default inilized AliITSInitGeometry object
72 //______________________________________________________________________
73 AliITSInitGeometry::AliITSInitGeometry(const Char_t *name,Int_t minorversion):
76 fMinorVersion(minorversion),
87 // A default inilized AliITSInitGeometry object
89 if(fName.CompareTo("AliITSvPPRasymmFMD")==0)if(fMinorVersion==1||
94 // if not defined geometry error
95 Error("AliITSInitGeometry(name,version)"," Name must be AliITSvPPRasymmFMD"
96 " and version must be 1 or 2 for now.");
101 //______________________________________________________________________
102 AliITSgeom* AliITSInitGeometry::CreateAliITSgeom(){
103 // Creates and Initilizes the geometry transformation class AliITSgeom
104 // to values appropreate to this specific geometry. Now that
105 // the segmentation is part of AliITSgeom, the detector
106 // segmentations are also defined here.
112 // A pointer to a new properly inilized AliITSgeom class. If
113 // pointer = 0 then failed to init.
115 AliITSgeom *geom = new AliITSgeom();
116 if(!InitAliITSgeom(geom)){ // Error initilization failed
122 //______________________________________________________________________
123 Bool_t AliITSInitGeometry::InitAliITSgeom(AliITSgeom *geom){
124 // Initilizes the geometry transformation class AliITSgeom
125 // to values appropreate to this specific geometry. Now that
126 // the segmentation is part of AliITSgeom, the detector
127 // segmentations are also defined here.
129 // AliITSgeom *geom A pointer to the AliITSgeom class
131 // AliITSgeom *geom This pointer recreated and properly inilized.
135 switch(fMajorVersion){
136 case 10:{ // only case defined so far
137 return InitAliITSgeomPPRasymmFMD(geom);
140 Error("InitAliITSgeom","Undefine geomtery");
146 //______________________________________________________________________
147 Bool_t AliITSInitGeometry::InitAliITSgeomPPRasymmFMD(AliITSgeom *geom){
148 // Initilizes the geometry transformation class AliITSgeom
149 // to values appropreate to this specific geometry. Now that
150 // the segmentation is part of AliITSgeom, the detector
151 // segmentations are also defined here.
153 // AliITSgeom *geom A pointer to the AliITSgeom class
155 // AliITSgeom *geom This pointer recreated and properly inilized.
158 // const Double_t kcm2micron = 1.0E4;
159 const Int_t kItype=0; // Type of transormation defined 0=> Geant
160 const Int_t klayers = 6; // number of layers in the ITS
161 const Int_t kladders[klayers] = {20,40,14,22,34,38}; // Number of ladders
162 const Int_t kdetectors[klayers] = {4,4,6,8,22,25};// number of detector/lad
163 const AliITSDetector kIdet[6] = {kSPD,kSPD,kSDD,kSDD,kSSD,kSSD};
164 const TString kPathbase = "/ALIC_1/ITSV_1/ITSD_1/";
165 const TString kNames[2][klayers] = {
166 {"%sIT12_1/I12A_%d/I10A_%d/I103_%d/I101_1/ITS1_1", // lay=1
167 "%sIT12_1/I12A_%d/I20A_%d/I1D3_%d/I1D1_1/ITS2_1", // lay=2
168 "%sIT34_1/I004_%d/I302_%d/ITS3_%d/", // lay=3
169 "%sIT34_1/I005_%d/I402_%d/ITS4_%d/", // lay=4
170 "%sIT56_1/I565_%d/I562_%d/ITS5_%d/", // lay=5
171 "%sIT56_1/I569_%d/I566_%d/ITS6_%d/"},// lay=6
172 {"%sIT12_1/I12B_%d/I10B_%d/I107_%d/I101_1/ITS1_1", // lay=1
173 "%sIT12_1/I12B_%d/I20B_%d/I1D7_%d/I1D1_1/ITS2_1", // lay=2
174 "%sIT34_1/I004_%d/I302_%d/ITS3_%d", // lay=3
175 "%sIT34_1/I005_%d/I402_%d/ITS4_%d", // lay=4
176 "%sIT56_1/I565_%d/I562_%d/ITS5_%d", // lay=5
177 "%sIT56_1/I569_%d/I566_%d/ITS6_%d"}};// Lay=6
179 Int_t itsGeomTreeCopys[knlayers][3]= {{10, 2, 4},// lay=1
186 Int_t mod,nmods=0,lay,lad,det,cpn0,cpn1,cpn2;
187 Double_t tran[3]={0.0,0.0,0.0},rot[10]={9*0.0,1.0};
189 TString path,shapeName;
191 Bool_t initSeg[3]={kFALSE,kFALSE,kFALSE};
192 TStopwatch *time = 0x0;if(fTiming) time=new TStopwatch();
194 if(fTiming) time->Start();
195 for(mod=0;mod<klayers;mod++) nmods += kladders[mod]*kdetectors[mod];
196 geom->Init(kItype,klayers,kladders,kdetectors,nmods);
197 for(mod=0;mod<nmods;mod++){
198 DecodeDetectorLayers(mod,lay,lad,det); // Write
199 geom->CreateMatrix(mod,lay,lad,det,kIdet[lay-1],tran,rot);
200 RecodeDetector(mod,cpn0,cpn1,cpn2); // Write reusing lay,lad,det.
201 path.Form(kNames[fMinorVersion-1][lay-1].Data(),
202 kPathbase.Data(),cpn0,cpn1,cpn2);
203 geom->GetGeomMatrix(mod)->SetPath(path);
204 GetTransformation(path.Data(),materix);
205 geom->SetTrans(mod,materix.GetTranslation());
206 geom->SetRotMatrix(mod,materix.GetRotationMatrix());
207 if(initSeg[kIdet[lay-1]]) continue;
208 GetShape(path,shapeName,shapePar);
209 if(shapeName.CompareTo("BOX")){
210 Error("InitITSgeom","Geometry changed without proper code update"
211 "or error in reading geometry. Shape is not BOX.");
214 InitGeomShapePPRasymmFMD(kIdet[lay-1],initSeg,shapePar,geom);
223 //______________________________________________________________________
224 Bool_t AliITSInitGeometry::InitGeomShapePPRasymmFMD(AliITSDetector idet,
228 // Initilizes the geometry segmentation class AliITSgeomS?D, or
229 // AliITSsegmentationS?D depending on the vaule of fSegGeom,
230 // to values appropreate to this specific geometry. Now that
231 // the segmentation is part of AliITSgeom, the detector
232 // segmentations are also defined here.
234 // Int_t lay The layer number/name.
235 // AliITSgeom *geom A pointer to the AliITSgeom class
237 // AliITSgeom *geom This pointer recreated and properly inilized.
240 // const Double_t kcm2micron = 1.0E4;
241 const Double_t kmicron2cm = 1.0E-4;
245 shapeParF.Set(shapePar.GetSize());
246 for(i=0;i<shapePar.GetSize();i++) shapeParF[i]=shapePar[i];
249 initSeg[idet] = kTRUE;
250 AliITSgeomSPD *geomSPD = new AliITSgeomSPD425Short();
251 Float_t bx[256],bz[280];
252 for(i=000;i<256;i++) bx[i] = 50.0*kmicron2cm; // in x all are 50 microns.
253 for(i=000;i<160;i++) bz[i] = 425.0*kmicron2cm; // most are 425 microns
255 for(i=160;i<280;i++) bz[i] = 0.0*kmicron2cm; // Outside of detector.
256 bz[ 31] = bz[ 32] = 625.0*kmicron2cm; // first chip boundry
257 bz[ 63] = bz[ 64] = 625.0*kmicron2cm; // first chip boundry
258 bz[ 95] = bz[ 96] = 625.0*kmicron2cm; // first chip boundry
259 bz[127] = bz[128] = 625.0*kmicron2cm; // first chip boundry
260 bz[160] = 425.0*kmicron2cm;// Set so that there is no zero pixel size for fNz.
261 geomSPD->ReSetBins(shapeParF[1],256,bx,160,bz);
262 geom->ReSetShape(idet,geomSPD);
265 initSeg[idet] = kTRUE;
266 AliITSgeomSDD *geomSDD = new AliITSgeomSDD256(shapeParF.GetSize(),
267 shapeParF.GetArray());
268 geom->ReSetShape(idet,geomSDD);
271 initSeg[idet] = kTRUE;
272 AliITSgeomSSD *geomSSD = new AliITSgeomSSD275and75(
273 shapeParF.GetSize(),shapeParF.GetArray());
274 geom->ReSetShape(idet,geomSSD);
276 default:{// Others, Note no kSDDp or kSSDp in this geometry.
277 geom->ReSetShape(idet,0);
278 Info("InitGeomShapePPRasymmFMD",
279 "default Dx=%f Dy=%f Dz=%f default=%d",
280 shapePar[0],shapePar[1],shapePar[2],idet);
285 //______________________________________________________________________
286 Bool_t AliITSInitGeometry::InitSegmentationPPRasymmFMD(AliITSDetector idet,
290 // Initilizes the geometry segmentation class AliITSgeomS?D, or
291 // AliITSsegmentationS?D depending on the vaule of fSegGeom,
292 // to values appropreate to this specific geometry. Now that
293 // the segmentation is part of AliITSgeom, the detector
294 // segmentations are also defined here.
296 // Int_t lay The layer number/name.
297 // AliITSgeom *geom A pointer to the AliITSgeom class
299 // AliITSgeom *geom This pointer recreated and properly inilized.
302 const Double_t kcm2micron = 1.0E4;
307 initSeg[idet] = kTRUE;
308 AliITSsegmentationSPD *segSPD = new AliITSsegmentationSPD();
309 segSPD->SetDetSize(2.*shapePar[0]*kcm2micron, // X
310 2.*shapePar[2]*kcm2micron, // Z
311 2.*shapePar[1]*kcm2micron);// Y Microns
312 segSPD->SetNPads(256,160);// Number of Bins in x and z
313 Float_t bx[256],bz[280];
314 for(i=000;i<256;i++) bx[i] = 50.0; // in x all are 50 microns.
315 for(i=000;i<160;i++) bz[i] = 425.0; // most are 425 microns
317 for(i=160;i<280;i++) bz[i] = 0.0; // Outside of detector.
318 bz[ 31] = bz[ 32] = 625.0; // first chip boundry
319 bz[ 63] = bz[ 64] = 625.0; // first chip boundry
320 bz[ 95] = bz[ 96] = 625.0; // first chip boundry
321 bz[127] = bz[128] = 625.0; // first chip boundry
322 bz[160] = 425.0;// Set so that there is no zero pixel size for fNz.
323 segSPD->SetBinSize(bx,bz); // Based on AliITSgeomSPD for now.
324 geom->ReSetShape(idet,segSPD);
327 initSeg[idet] = kTRUE;
328 AliITSsegmentationSDD *segSDD = new AliITSsegmentationSDD();
329 segSDD->SetDetSize(shapePar[0]*kcm2micron, // X
330 2.*shapePar[2]*kcm2micron, // Z
331 2.*shapePar[1]*kcm2micron);// Y Microns
332 segSDD->SetNPads(256,256);// Anodes, Samples
333 geom->ReSetShape(idet,segSDD);
336 initSeg[idet] = kTRUE;
337 AliITSsegmentationSSD *segSSD = new AliITSsegmentationSSD();
338 segSSD->SetDetSize(2.*shapePar[0]*kcm2micron, // X
339 2.*shapePar[2]*kcm2micron, // Z
340 2.*shapePar[1]*kcm2micron);// Y Microns.
341 segSSD->SetPadSize(95.,0.); // strip x pitch in microns
342 segSSD->SetNPads(768,2); // number of strips on each side, sides.
343 segSSD->SetAngles(0.0075,0.0275); // strip angels rad P and N side.
344 segSSD->SetAnglesLay5(0.0075,0.0275);//strip angels rad P and N
345 segSSD->SetAnglesLay6(0.0275,0.0075);//strip angels rad P and N
346 geom->ReSetShape(idet,segSSD);
348 default:{// Others, Note no kSDDp or kSSDp in this geometry.
349 geom->ReSetShape(idet,0);
350 Info("InitSegmentationPPRasymmFMD",
351 "default segmentation Dx=%f Dy=%f Dz=%f default=%d",
352 shapePar[0],shapePar[1],shapePar[2],idet);
357 //______________________________________________________________________
358 Bool_t AliITSInitGeometry::GetTransformation(const TString &volumePath,
360 // Returns the Transformation matrix between the volume specified
361 // by the path volumePath and the Top or mater volume. The format
362 // of the path volumePath is as follows (assuming ALIC is the Top volume)
363 // "/ALIC_1/DDIP_1/S05I_2/S05H_1/S05G_3". Here ALIC is the top most
364 // or master volume which has only 1 instance of. Of all of the daughter
365 // volumes of ALICE, DDIP volume copy #1 is indicated. Similarly for
366 // the daughter volume of DDIP is S05I copy #2 and so on.
368 // TString& volumePath The volume path to the specific volume
369 // for which you want the matrix. Volume name
370 // hierarchy is separated by "/" while the
371 // copy number is appended using a "_".
373 // TGeoHMatrix &mat A matrix with its values set to those
374 // appropriate to the Local to Master transformation
376 // A logical value if kFALSE then an error occurred and no change to
379 // We have to preserve the modeler state
381 // Preserve the modeler state.
382 gGeoManager->PushPath();
383 if (!gGeoManager->cd(volumePath.Data())) {
384 gGeoManager->PopPath();
385 Error("GetTransformation","Error in cd-ing to ",volumePath.Data());
387 } // end if !gGeoManager
388 mat = *gGeoManager->GetCurrentMatrix();
389 // Retstore the modeler state.
390 gGeoManager->PopPath();
393 //______________________________________________________________________
394 Bool_t AliITSInitGeometry::GetShape(const TString &volumePath,
395 TString &shapeType,TArrayD &par){
396 // Returns the shape and its parameters for the volume specified
399 // TString& volumeName The volume name
401 // TString &shapeType Shape type
402 // TArrayD &par A TArrayD of parameters with all of the
403 // parameters of the specified shape.
405 // A logical indicating whether there was an error in getting this
408 gGeoManager->PushPath();
409 if (!gGeoManager->cd(volumePath.Data())) {
410 gGeoManager->PopPath();
413 TGeoVolume * vol = gGeoManager->GetCurrentVolume();
414 gGeoManager->PopPath();
415 if (!vol) return kFALSE;
416 TGeoShape *shape = vol->GetShape();
417 TClass *classType = shape->IsA();
418 if (classType==TGeoBBox::Class()) {
422 TGeoBBox *box = (TGeoBBox*)shape;
423 par.AddAt(box->GetDX(),0);
424 par.AddAt(box->GetDY(),1);
425 par.AddAt(box->GetDZ(),2);
428 if (classType==TGeoTrd1::Class()) {
432 TGeoTrd1 *trd1 = (TGeoTrd1*)shape;
433 par.AddAt(trd1->GetDx1(),0);
434 par.AddAt(trd1->GetDx2(),1);
435 par.AddAt(trd1->GetDy(), 2);
436 par.AddAt(trd1->GetDz(), 3);
439 if (classType==TGeoTrd2::Class()) {
443 TGeoTrd2 *trd2 = (TGeoTrd2*)shape;
444 par.AddAt(trd2->GetDx1(),0);
445 par.AddAt(trd2->GetDx2(),1);
446 par.AddAt(trd2->GetDy1(),2);
447 par.AddAt(trd2->GetDy2(),3);
448 par.AddAt(trd2->GetDz(), 4);
451 if (classType==TGeoTrap::Class()) {
455 TGeoTrap *trap = (TGeoTrap*)shape;
456 Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
457 par.AddAt(trap->GetDz(),0);
458 par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
459 par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
460 par.AddAt(trap->GetH1(),3);
461 par.AddAt(trap->GetBl1(),4);
462 par.AddAt(trap->GetTl1(),5);
463 par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
464 par.AddAt(trap->GetH2(),7);
465 par.AddAt(trap->GetBl2(),8);
466 par.AddAt(trap->GetTl2(),9);
467 par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
470 if (classType==TGeoTube::Class()) {
474 TGeoTube *tube = (TGeoTube*)shape;
475 par.AddAt(tube->GetRmin(),0);
476 par.AddAt(tube->GetRmax(),1);
477 par.AddAt(tube->GetDz(),2);
480 if (classType==TGeoTubeSeg::Class()) {
484 TGeoTubeSeg *tubs = (TGeoTubeSeg*)shape;
485 par.AddAt(tubs->GetRmin(),0);
486 par.AddAt(tubs->GetRmax(),1);
487 par.AddAt(tubs->GetDz(),2);
488 par.AddAt(tubs->GetPhi1(),3);
489 par.AddAt(tubs->GetPhi2(),4);
492 if (classType==TGeoCone::Class()) {
496 TGeoCone *cone = (TGeoCone*)shape;
497 par.AddAt(cone->GetDz(),0);
498 par.AddAt(cone->GetRmin1(),1);
499 par.AddAt(cone->GetRmax1(),2);
500 par.AddAt(cone->GetRmin2(),3);
501 par.AddAt(cone->GetRmax2(),4);
504 if (classType==TGeoConeSeg::Class()) {
508 TGeoConeSeg *cons = (TGeoConeSeg*)shape;
509 par.AddAt(cons->GetDz(),0);
510 par.AddAt(cons->GetRmin1(),1);
511 par.AddAt(cons->GetRmax1(),2);
512 par.AddAt(cons->GetRmin2(),3);
513 par.AddAt(cons->GetRmax2(),4);
514 par.AddAt(cons->GetPhi1(),5);
515 par.AddAt(cons->GetPhi2(),6);
518 if (classType==TGeoSphere::Class()) {
523 TGeoSphere *sphe = (TGeoSphere*)shape;
524 par.AddAt(sphe->GetRmin(),0);
525 par.AddAt(sphe->GetRmax(),1);
526 par.AddAt(sphe->GetTheta1(),2);
527 par.AddAt(sphe->GetTheta2(),3);
528 par.AddAt(sphe->GetPhi1(),4);
529 par.AddAt(sphe->GetPhi2(),5);
532 if (classType==TGeoPara::Class()) {
536 TGeoPara *para = (TGeoPara*)shape;
537 par.AddAt(para->GetX(),0);
538 par.AddAt(para->GetY(),1);
539 par.AddAt(para->GetZ(),2);
540 par.AddAt(para->GetTxy(),3);
541 par.AddAt(para->GetTxz(),4);
542 par.AddAt(para->GetTyz(),5);
545 if (classType==TGeoPgon::Class()) {
547 TGeoPgon *pgon = (TGeoPgon*)shape;
548 Int_t nz = pgon->GetNz();
549 const Double_t *rmin = pgon->GetRmin();
550 const Double_t *rmax = pgon->GetRmax();
551 const Double_t *z = pgon->GetZ();
554 par.AddAt(pgon->GetPhi1(),0);
555 par.AddAt(pgon->GetDphi(),1);
556 par.AddAt(pgon->GetNedges(),2);
557 par.AddAt(pgon->GetNz(),3);
558 for (Int_t i=0; i<nz; i++) {
559 par.AddAt(z[i], 4+3*i);
560 par.AddAt(rmin[i], 4+3*i+1);
561 par.AddAt(rmax[i], 4+3*i+2);
565 if (classType==TGeoPcon::Class()) {
567 TGeoPcon *pcon = (TGeoPcon*)shape;
568 Int_t nz = pcon->GetNz();
569 const Double_t *rmin = pcon->GetRmin();
570 const Double_t *rmax = pcon->GetRmax();
571 const Double_t *z = pcon->GetZ();
574 par.AddAt(pcon->GetPhi1(),0);
575 par.AddAt(pcon->GetDphi(),1);
576 par.AddAt(pcon->GetNz(),2);
577 for (Int_t i=0; i<nz; i++) {
578 par.AddAt(z[i], 3+3*i);
580 par.AddAt(rmin[i], 3+3*i+1);
581 par.AddAt(rmax[i], 3+3*i+2);
585 if (classType==TGeoEltu::Class()) {
589 TGeoEltu *eltu = (TGeoEltu*)shape;
590 par.AddAt(eltu->GetA(),0);
591 par.AddAt(eltu->GetB(),1);
592 par.AddAt(eltu->GetDz(),2);
595 if (classType==TGeoHype::Class()) {
599 TGeoHype *hype = (TGeoHype*)shape;
600 par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kTRUE)),0);
601 par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kFALSE)),1);
602 par.AddAt(hype->GetDZ(),2);
603 par.AddAt(hype->GetStIn(),3);
604 par.AddAt(hype->GetStOut(),4);
607 if (classType==TGeoGtra::Class()) {
611 TGeoGtra *trap = (TGeoGtra*)shape;
612 Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
613 par.AddAt(trap->GetDz(),0);
614 par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
615 par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
616 par.AddAt(trap->GetH1(),3);
617 par.AddAt(trap->GetBl1(),4);
618 par.AddAt(trap->GetTl1(),5);
619 par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
620 par.AddAt(trap->GetH2(),7);
621 par.AddAt(trap->GetBl2(),8);
622 par.AddAt(trap->GetTl2(),9);
623 par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
624 par.AddAt(trap->GetTwistAngle(),11);
627 if (classType==TGeoCtub::Class()) {
631 TGeoCtub *ctub = (TGeoCtub*)shape;
632 const Double_t *lx = ctub->GetNlow();
633 const Double_t *tx = ctub->GetNhigh();
634 par.AddAt(ctub->GetRmin(),0);
635 par.AddAt(ctub->GetRmax(),1);
636 par.AddAt(ctub->GetDz(),2);
637 par.AddAt(ctub->GetPhi1(),3);
638 par.AddAt(ctub->GetPhi2(),4);
647 Error("GetShape","Getting shape parameters for shape %s not implemented",
651 //______________________________________________________________________
652 void AliITSInitGeometry::DecodeDetector(Int_t &mod,Int_t layer,Int_t cpn0,
653 Int_t cpn1,Int_t cpn2) const {
654 // decode geometry into detector module number. There are two decoding
655 // Scheams. Old which does not follow the ALICE coordinate system
656 // requirements, and New which dose.
658 // Int_t layer The ITS layer
659 // Int_t cpn0 The lowest copy number
660 // Int_t cpn1 The middle copy number
661 // Int_t cpn2 the highest copy number
663 // Int_t &mod The module number assoicated with this set
667 const Int_t kDetPerLadderSPD[2]={2,4};
668 const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
669 const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
670 Int_t lay=-1,lad=-1,det=-1,i;
672 if(fDecode){ // New decoding scheam
677 if(cpn0==4&&cpn1==1) lad=1;
678 else if(cpn0==4&&cpn1==2) lad=20;
680 lad = 8-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
682 lad = 28-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
688 if(cpn0==4&&cpn1==1) lad=1;
690 lad = 14-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
692 lad = 54-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
697 if(cpn0<5) lad = 5-cpn0;
703 if(cpn0<7) lad = 7-cpn0;
709 if(cpn0<10) lad = 10-cpn0;
715 if(cpn0<9) lad = 9-cpn0;
721 for(i=0;i<layer-1;i++) mod += kLadPerLayer[i]*kDetPerLadder[i];
722 mod += kDetPerLadder[layer-1]*(lad-1)+det-1;// module start at zero.
725 // Old decoding scheam
729 lad = cpn1+kDetPerLadderSPD[layer-1]*(cpn0-1);
746 for(i=0;i<layer-1;i++) mod += kLadPerLayer[i]*kDetPerLadder[i];
747 mod += kDetPerLadder[layer-1]*(lad-1)+det-1;// module start at zero.
750 //______________________________________________________________________
751 void AliITSInitGeometry::RecodeDetector(Int_t mod,Int_t &cpn0,
752 Int_t &cpn1,Int_t &cpn2){
753 // decode geometry into detector module number. There are two decoding
754 // Scheams. Old which does not follow the ALICE coordinate system
755 // requirements, and New which dose.
757 // Int_t mod The module number assoicated with this set
760 // Int_t cpn0 The lowest copy number
761 // Int_t cpn1 The middle copy number
762 // Int_t cpn2 the highest copy number
765 const Int_t kITSgeoTreeCopys[6][3]= {{10, 2, 4},// lay=1
771 const Int_t kDetPerLadderSPD[2]={2,4};
772 // const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
773 // const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
776 cpn0 = cpn1 = cpn2 = 0;
777 DecodeDetectorLayers(mod,lay,lad,det);
778 if(fDecode){ // New decoding scheam
781 cpn2 = 5-det; // Detector 1-4
782 cpn1 = 1+(lad-1)%kDetPerLadderSPD[lay-1];
783 cpn0 = 5-(lad+kDetPerLadderSPD[lay-1])/kDetPerLadderSPD[lay-1];
784 if(mod>27) cpn0 = 15-(lad+kDetPerLadderSPD[lay-1])/
785 kDetPerLadderSPD[lay-1];
788 cpn2 = 5-det; // Detector 1-4
789 cpn1 = 4-(lad+2)%kDetPerLadderSPD[lay-1];
790 cpn0 = 1+(14-cpn1-lad)/kDetPerLadderSPD[lay-1];
791 if(mod>131) cpn0 = 1+(54-lad-cpn1)/kDetPerLadderSPD[lay-1];
795 if(lad<5) cpn0 = 5-lad;
801 if(lad<7) cpn0 = 7-lad;
807 if(lad<10) cpn0 = 10-lad;
813 if(lad<9) cpn0 = 9-lad;
818 Error("RecodeDetector","New: mod=%d lay=%d not 1-6.");
822 if(cpn0<1||cpn1<1||cpn2<1||
823 cpn0>kITSgeoTreeCopys[lay-1][0]||
824 cpn1>kITSgeoTreeCopys[lay-1][1]||
825 cpn2>kITSgeoTreeCopys[lay-1][2])
826 Error("RecodeDetector",
827 "cpn0=%d cpn1=%d cpn2=%d mod=%d lay=%d lad=%d det=%d",
828 cpn0,cpn1,cpn2,mod,lay,lad,det);
834 cpn2 = det; // Detector 1-4
835 cpn0 = (lad+kDetPerLadderSPD[lay-1]-1)/kDetPerLadderSPD[lay-1];
836 cpn1 = (lad+kDetPerLadderSPD[lay-1]-1)%kDetPerLadderSPD[lay-1] + 1;
838 case 3: case 4: case 5 : case 6:{
844 Error("RecodeDetector","Old: mod=%d lay=%d not 1-6.");
848 if(cpn0<1||cpn1<1||cpn2<1||
849 cpn0>kITSgeoTreeCopys[lay-1][0]||
850 cpn1>kITSgeoTreeCopys[lay-1][1]||
851 cpn2>kITSgeoTreeCopys[lay-1][2])
852 Error("RecodeDetector",
853 "cpn0=%d cpn1=%d cpn2=%d mod=%d lay=%d lad=%d det=%d",
854 cpn0,cpn1,cpn2,mod,lay,lad,det);
857 //______________________________________________________________________
858 void AliITSInitGeometry::DecodeDetectorLayers(Int_t mod,Int_t &lay,
859 Int_t &lad,Int_t &det){
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. Note, this use of layer ladder
863 // and detector numbers are strictly for internal use of this
864 // specific code. They do not represent the "standard" layer ladder
865 // or detector numbering except in a very old and obsoleate sence.
867 // Int_t mod The module number assoicated with this set
870 // Int_t lay The layer number
871 // Int_t lad The ladder number
872 // Int_t det the dettector number
875 // const Int_t kDetPerLadderSPD[2]={2,4};
876 const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
877 const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
885 mod2 += kLadPerLayer[lay]*kDetPerLadder[lay];
887 }while(mod2<=mod); // end while
888 if(lay>6||lay<1) Error("DecodeDetectorLayers","0<lay=%d>6",lay);
889 mod2 -= kLadPerLayer[lay-1]*kDetPerLadder[lay-1];
892 mod2 += kDetPerLadder[lay-1];
893 }while(mod2<=mod); // end while
894 if(lad>kLadPerLayer[lay-1]||lad<1) Error("DecodeDetectorLayera",
895 "lad=%d>kLadPerLayer[lay-1=%d]=%d mod=%d mod2=%d",lad,lay-1,
896 kLadPerLayer[lay-1],mod,mod2);
897 mod2 -= kDetPerLadder[lay-1];
899 if(det>kDetPerLadder[lay-1]||det<1) Error("DecodeDetectorLayers",
900 "det=%d>detPerLayer[lay-1=%d]=%d mod=%d mod2=%d lad=%d",det,
901 lay-1,kDetPerLadder[lay-1],mod,mod2,lad);