]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/UPGRADE/testITSUv1/CreateITSUv1.C
ca08116745f1e8baa301947da4ead49d877d24a7
[u/mrichter/AliRoot.git] / ITS / UPGRADE / testITSUv1 / CreateITSUv1.C
1 #if !defined(__CINT__) || defined(__MAKECINT__)
2 #include <TSystem.h>
3 #include <TMath.h>
4 #endif
5
6 //---------------------------------------
7 double radii2Turbo(double rMin,double rMid,double rMax, double sensW)
8 {
9   // compute turbo angle from radii and sensor width
10   return TMath::ASin((rMax*rMax-rMin*rMin)/(2*rMid*sensW))*TMath::RadToDeg();
11 }
12
13 double radii2Phi(double rMin,double rMid,double rMax, double sensW)
14 {
15   // compute phi coverage
16   return 2*TMath::ACos((rMax+rMin)*
17                        (rMid*rMid+rMin*rMax-sensW*sensW/4.)/
18                        (4.*rMid*rMax*rMin));
19 }
20
21 void CreateITSUv1()
22 {
23   //
24   gSystem->Load("libITSUpgradeBase.so");
25   gSystem->Load("libITSUpgradeSim.so");
26
27
28   // build ITS upgrade detector
29   // sensitive area 13x15mm (X,Z) with 20x20 micron pitch, 2mm dead zone on readout side and 50 micron guardring
30   const double kSensThick = 18e-4;
31   const double kPitchX = 20e-4;
32   const double kPitchZ = 20e-4;
33   const int    kNRow   = 650; 
34   const int    kNCol   = 750;
35   const int    kNChips = 2;
36   const double kLrThick03 = 120e-4;   // -> effective thickness for ~0.3%X layers
37   const double kLrThick08 = 600e-4;   // -> effective thickness for ~0.8%X layers
38   //
39   const double kReadOutEdge = 0.2;   // width of the readout edge (passive bottom)
40   const double kGuardRing   = 50e-4; // width of passive area on left/right/top of the sensor
41   //
42   const int kNLr = 7;
43   const int kNLrInner = 3;
44   const int kBuildLevel = 3;
45   enum {kRmn,kRmd,kRmx,kNModPerStave,kPhi0,kNStave,kNPar};
46   // Radii are from last TDR (ALICE-TDR-017.pdf Tab. 1.1, rMid is mean value)
47   const double tdr5dat[kNLr][kNPar] = { 
48     {2.24, 2.34, 2.67,  9., 16.37, 12}, // for each inner layer: rMin,rMid,rMax,NMod/Stave,phi0, nStave
49     {3.01, 3.15, 3.46,  9., 12.03, 16},
50     {3.78, 3.93, 4.21,  9., 10.02, 20},
51     {-1,  19.6 ,   -1,  4.,  0.  , 24},  // for others: -, rMid, -, NMod/Stave, phi0, nStave // 24 was 49
52     {-1,  24.55, -1,    4.,  0.  , 30},  // 30 was 61
53     {-1,  34.39, -1,    7.,  0.  , 42},  // 42 was 88
54     {-1,  39.34, -1,    7.,  0.  , 48}   // 48 was 100
55   };
56   const int nChipsPerModule = 7; // For OB we have to specify how many chips
57
58   // create segmentations:
59   AliITSUSegmentationPix* seg0 = new AliITSUSegmentationPix(0,        // segID (0:9)
60                                                             kNChips,  // chips per module
61                                                             kNChips*kNCol,    // ncols (total for module)
62                                                             kNRow,    // nrows
63                                                             kPitchX,  // default row pitch in cm
64                                                             kPitchZ,  // default col pitch in cm
65                                                             kSensThick,  // sensor thickness in cm
66                                                             -1,     // no special left col between chips
67                                                             -1,     // no special right col between chips
68                                                             kGuardRing, // left
69                                                             kGuardRing, // right
70                                                             kGuardRing, // top
71                                                             kReadOutEdge  // bottom
72                                                             );    // see AliITSUSegmentationPix.h for extra options
73   seg0->Store(AliITSUGeomTGeo::GetITSsegmentationFileName());
74   //
75   AliITSUSegmentationPix* seg1 = new AliITSUSegmentationPix(1,        // segID (0:9)
76                                                             kNChips,  // chips per module
77                                                             kNChips*kNCol,    // ncols (total for module)
78                                                             2*kNRow,    // nrows for oute layers
79                                                             kPitchX,  // default row pitch in cm
80                                                             kPitchZ,  // default col pitch in cm
81                                                             kSensThick,  // sensor thickness in cm
82                                                             -1,     // no special left col between chips
83                                                             -1,     // no special right col between chips
84                                                             kGuardRing, // left
85                                                             kGuardRing, // right
86                                                             kReadOutEdge, // top   !!! readout from both sides
87                                                             kReadOutEdge  // bottom
88                                                             );    // see AliITSUSegmentationPix.h for extra options
89   seg1->Store(AliITSUGeomTGeo::GetITSsegmentationFileName());
90   //
91   seg0->Print();
92   seg1->Print();
93   //
94   const double kMinOvl = 0.005; // require active zones overlap
95   const double kTilt = -10.; // tilt in degrees for outer layers
96   double dzLr,rLr,phi0,turbo,thick;
97   AliITSUSegmentationPix* seg=0;
98   int nStaveLr,nModPerStaveLr,idLr;
99   //      virtual void   DefineLayerTurbo(const Int_t nlay, const Double_t r,  const Double_t zlen, const Int_t nladd,   const Int_t nmod, const Double_t width,
100   //                              const Double_t tilt,   const Double_t lthick = 0.,    const Double_t dthick = 0.,   const UInt_t detType=0);
101   AliITSUv1 *ITS  = new AliITSUv1("ITS Upgrade",7);
102   ITS->SetStaveModelIB(AliITSUv1::kIBModel22);
103   ITS->SetStaveModelOB(AliITSUv1::kOBModel1);
104   //
105   const int kNWrapVol = 3;
106   const double wrpRMin[kNWrapVol]  = { 2.1, 15.0, 32.0};
107   const double wrpRMax[kNWrapVol]  = { 7.0, 27.0+2.5, 43.0+1.5};
108   const double wrpZSpan[kNWrapVol] = {28.0, 96.0, 158.0};
109   ITS->SetNWrapVolumes(kNWrapVol); // define wrapper volumes for layers
110   for (int iw=0;iw<kNWrapVol;iw++) ITS->DefineWrapVolume(iw,wrpRMin[iw],wrpRMax[iw],wrpZSpan[iw]);
111   //
112   for (int idLr=0;idLr<kNLr;idLr++) {
113     rLr   = tdr5dat[idLr][kRmd];
114     phi0  = tdr5dat[idLr][kPhi0]; 
115     if (idLr<kNLrInner) {
116       seg = seg0;
117       turbo = -radii2Turbo(tdr5dat[idLr][kRmn],rLr,tdr5dat[idLr][kRmx],seg->Dx());      
118       thick = kLrThick03;
119     }
120     else {
121       seg   = seg1;
122       turbo = kTilt;
123       thick = kLrThick08;
124     }
125     nStaveLr = TMath::Nint(tdr5dat[idLr][kNStave]);
126     if (nStaveLr<0) nStaveLr = getNStaves(seg,kTilt,rLr,kMinOvl); // calculate automatically
127     nModPerStaveLr =  TMath::Nint(tdr5dat[idLr][kNModPerStave]);
128     int nChipsPerStaveLr = nModPerStaveLr;
129     if (idLr>=kNLrInner) {
130       nChipsPerStaveLr *= nChipsPerModule;
131       ITS->DefineLayer(idLr, phi0, rLr, nChipsPerStaveLr*seg->Dz(), nStaveLr, nModPerStaveLr, 
132                        thick, seg->Dy(), seg->GetChipTypeID(),kBuildLevel);
133       printf("Add Lr%d: R=%6.2f DZ:%6.2f Staves:%3d NMod/Stave:%3d\n",idLr,rLr,nChipsPerStaveLr*seg->Dz(),nStaveLr,nModPerStaveLr);
134     } else {
135       ITS->DefineLayerTurbo(idLr, phi0, rLr, nChipsPerStaveLr*seg->Dz(), nStaveLr, nModPerStaveLr, 
136                           seg->Dx(), turbo, thick, seg->Dy(), seg->GetChipTypeID());
137       printf("Add Lr%d: R=%6.2f DZ:%6.2f Turbo:%+6.2f Staves:%3d NMod/Stave:%3d\n",idLr,rLr,nChipsPerStaveLr*seg->Dz(),turbo,nStaveLr,nModPerStaveLr);
138     }
139     //
140   }
141   //  
142 }
143
144 Int_t getNStaves(AliITSUSegmentationPix* seg, double tilt, double r0, double minOvl)
145 {
146   double dphi = (90.-tilt)*TMath::DegToRad();
147   double cs = TMath::Cos(dphi);
148   double sn = TMath::Sin(dphi);  
149   double dx = seg->Dx();
150   double tL = -dx/2 + seg->GetGuardBot();
151   double tU =  dx/2 - seg->GetGuardTop();
152   //
153   double xL = r0 + cs*tL;
154   double yL =      sn*tL;
155   double xU = r0 + cs*tU;
156   double yU =      sn*tU;
157   double phiL = TMath::ATan2(yL,xL);
158   double phiU = TMath::ATan2(yU,xU);
159   double dphi = TMath::Abs(phiL-phiU);
160   if (dphi>TMath::Pi()) dphi = TMath::Abs(dphi-TMath::Pi()*2);
161   double span = dphi*r0;
162   //
163   double ov = -1;
164   int nStaveLr = 1 + r0*TMath::Pi()*2/span;
165   do { ov = 1.-r0*TMath::Pi()*2/nStaveLr/span; } while ( minOvl>=0 && ov<minOvl && nStaveLr++ );
166   printf("Reccommend %2d staves for R=%5.2f, ActiveOvl=%5.2f\% (%6.f micron)\n",nStaveLr,r0,ov*100,ov*span*1e4);
167   return nStaveLr;
168 }