]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/UPGRADE/AliITSUv1.cxx
New geometry from Mario
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSUv1.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, 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 /* $Id: AliITSUv1.cxx */
18
19
20 //========================================================================
21 //
22 //        Geometry for the Upgrade of the Inner Tracking System
23 //
24 // Mario Sitta (sitta@to.infn.it)
25 // Chinorat Kobdaj (kobdaj@g.sut.ac.th)
26 //
27 //========================================================================
28
29
30
31 // $Log: AliITSUv1.cxx,v $
32
33 #include <TClonesArray.h>
34 #include <TGeoGlobalMagField.h>
35 #include <TGeoManager.h>
36 #include <TGeoMatrix.h>
37 #include <TGeoPhysicalNode.h>
38 #include <TGeoVolume.h>
39 #include <TGeoTube.h>
40 #include <TGeoXtru.h>
41 #include <TLorentzVector.h>
42 #include <TString.h>
43 #include <TVirtualMC.h>
44
45 #include "AliITSU.h"
46 #include "AliITSUHit.h"
47 #include "AliLog.h"
48 #include "AliMC.h"
49 #include "AliMagF.h"
50 #include "AliRun.h"
51 #include "AliTrackReference.h"
52 #include "AliITSv11Geometry.h"
53 #include "AliITSUv1Layer.h"
54 #include "AliITSUv1.h"
55 #include "AliITSUGeomTGeo.h"
56 #include "AliGeomManager.h"
57 using namespace TMath;
58
59
60 ClassImp(AliITSUv1)
61
62 //______________________________________________________________________
63 AliITSUv1::AliITSUv1()
64 :  fNWrapVol(0)
65   ,fWrapRMin(0)
66   ,fWrapRMax(0)
67   ,fWrapZSpan(0)
68   ,fLayTurbo(0)
69   ,fLayPhi0(0)
70   ,fLayRadii(0)
71   ,fLayZLength(0)
72   ,fLaddPerLay(0)
73   ,fModPerLadd(0)
74   ,fLadThick(0)
75   ,fLadWidth(0)
76   ,fLadTilt(0)
77   ,fDetThick(0)
78   ,fDetTypeID(0)
79   ,fBuildLevel(0)
80   ,fUpGeom(0)
81   ,fStaveModelIB(kIBModel0)
82   ,fStaveModelOB(kOBModel0)
83 {
84   //    Standard default constructor
85   // Inputs:
86   //   none.
87   // Outputs:
88   //   none.
89   // Return:
90   //   none.
91 }
92
93 //______________________________________________________________________
94 AliITSUv1::AliITSUv1(const char *title,const Int_t nlay)
95   :AliITSU(title,nlay)
96   ,fNWrapVol(0)
97   ,fWrapRMin(0)
98   ,fWrapRMax(0)
99   ,fWrapZSpan(0)
100   ,fLayTurbo(0)
101   ,fLayPhi0(0)
102   ,fLayRadii(0)
103   ,fLayZLength(0)
104   ,fLaddPerLay(0)
105   ,fModPerLadd(0)
106   ,fLadThick(0)
107   ,fLadWidth(0)
108   ,fLadTilt(0)
109   ,fDetThick(0)
110   ,fDetTypeID(0)
111   ,fBuildLevel(0)
112   ,fUpGeom(0)
113   ,fStaveModelIB(kIBModel0)
114   ,fStaveModelOB(kOBModel0)
115 {
116   //    Standard constructor for the Upgrade geometry.
117   // Inputs:
118   //   const char * name   Ignored, set to "ITS"
119   //   const char * title  Arbitrary title
120   //   const Int_t nlay    Number of layers
121   //
122   fLayerName = new TString[fNLayers];
123   //
124   for (Int_t j=0; j<fNLayers; j++)
125     fLayerName[j].Form("%s%d",AliITSUGeomTGeo::GetITSSensorPattern(),j); // See AliITSUv1Layer
126   //
127   fLayTurbo   = new Bool_t[fNLayers];
128   fLayPhi0    = new Double_t[fNLayers];
129   fLayRadii   = new Double_t[fNLayers];
130   fLayZLength = new Double_t[fNLayers];
131   fLaddPerLay = new Int_t[fNLayers];
132   fModPerLadd = new Int_t[fNLayers];
133   fLadThick   = new Double_t[fNLayers];
134   fLadWidth   = new Double_t[fNLayers];
135   fLadTilt    = new Double_t[fNLayers];
136   fDetThick   = new Double_t[fNLayers];
137   fDetTypeID  = new UInt_t[fNLayers];
138   fBuildLevel = new Int_t[fNLayers];
139
140
141   fUpGeom = new AliITSUv1Layer*[fNLayers];
142   
143   if (fNLayers > 0) { // if not, we'll Fatal-ize in CreateGeometry
144     for (Int_t j=0; j<fNLayers; j++) {
145       fLayPhi0[j] = 0;
146       fLayRadii[j] = 0.;
147       fLayZLength[j] = 0.;
148       fLaddPerLay[j] = 0;
149       fModPerLadd[j] = 0;
150       fLadWidth[j] = 0.;
151       fDetThick[j] = 0.;
152       fDetTypeID[j] = 0;
153       fBuildLevel[j] = 0;
154       fUpGeom[j] = 0;     
155     }
156   }
157 }
158
159 //______________________________________________________________________
160 AliITSUv1::~AliITSUv1() {
161   //    Standard destructor
162   // Inputs:
163   //   none.
164   // Outputs:
165   //   none.
166   // Return:
167   //   none.
168   delete [] fLayTurbo;
169   delete [] fLayPhi0;
170   delete [] fLayRadii;
171   delete [] fLayZLength;
172   delete [] fLaddPerLay;
173   delete [] fModPerLadd;
174   delete [] fLadThick;
175   delete [] fLadWidth;
176   delete [] fLadTilt;
177   delete [] fDetThick;
178   delete [] fDetTypeID;
179   delete [] fBuildLevel;
180   delete [] fUpGeom;
181   delete [] fWrapRMin;
182   delete [] fWrapRMax;
183   delete [] fWrapZSpan;
184 }
185
186 //______________________________________________________________________
187 void AliITSUv1::AddAlignableVolumes() const{
188   // Creates entries for alignable volumes associating the symbolic volume
189   // name with the corresponding volume path.
190   // 
191   // Records in the alignable entries the transformation matrices converting
192   // TGeo local coordinates (in the RS of alignable volumes) to the tracking
193   // system
194   // For this, this function has to run before the misalignment because we
195   // are using the ideal positions in the AliITSgeom object.
196   // Inputs:
197   //   none.
198   // Outputs:
199   //   none.
200   // Return:
201   //   none.
202
203   AliInfo("Add ITS alignable volumes");
204
205   if (!gGeoManager) { AliFatal("TGeoManager doesn't exist !"); return;  }
206   TString pth;
207   //
208   pth = Form("ALIC_1/%s_2",AliITSUGeomTGeo::GetITSVolPattern());
209   // RS: to be checked with MS
210   if( !gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameITS(),pth.Data()) )
211     AliFatal(Form("Unable to set alignable entry ! %s :: %s","ITS",pth.Data()));    
212   //
213   int modNum = 0;
214   //
215   for (int lr=0; lr<fNLayers; lr++) {
216     //
217     pth = Form("ALIC_1/%s_2/%s%d_1",AliITSUGeomTGeo::GetITSVolPattern(),AliITSUGeomTGeo::GetITSLayerPattern(),lr);
218     //printf("SetAlignable: %s %s\n",snm.Data(),pth.Data());
219     gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameLayer(lr),pth.Data());
220     //
221     for (int ld=0; ld<fLaddPerLay[lr]; ld++) {
222       //
223       TString pthL = Form("%s/%s%d_%d",pth.Data(),AliITSUGeomTGeo::GetITSLadderPattern(),lr,ld);
224       //printf("SetAlignable: %s %s\n",snmL.Data(),pthL.Data());
225       gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameLadder(lr,ld),pthL.Data());
226       //
227       for (int md=0; md<fModPerLadd[lr]; md++) {
228         //
229         TString pthM = Form("%s/%s%d_%d",pthL.Data(),AliITSUGeomTGeo::GetITSModulePattern(),lr,md);
230         //
231         // RS: Attention, this is a hack: AliGeomManager cannot accomodate all ITSU modules w/o
232         // conflicts with TPC. For this reason we define the UID of the module to be simply its ID
233         //      int modUID = AliGeomManager::LayerToVolUID(lr+1,modNum++); // here modNum would be module within the layer
234         int modUID = AliITSUGeomTGeo::ModuleVolUID( modNum++ );
235         // 
236         gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameModule(lr,ld,md),pthM.Data(),modUID);
237         //
238       }
239     }
240   }
241   //
242 }
243
244 //______________________________________________________________________
245 void AliITSUv1::SetNWrapVolumes(Int_t n)
246 {
247   // book arrays for wrapper volumes
248   if (fNWrapVol) AliFatal(Form("%d wrapper volumes already defined",fNWrapVol));
249   if (n<1) return;
250   fNWrapVol = n;
251   fWrapRMin = new Double_t[fNWrapVol];
252   fWrapRMax = new Double_t[fNWrapVol];
253   fWrapZSpan= new Double_t[fNWrapVol];
254   for (int i=fNWrapVol;i--;) fWrapRMin[i]=fWrapRMax[i]=fWrapZSpan[i]=-1;
255   //
256 }
257
258 //______________________________________________________________________
259 void AliITSUv1::DefineWrapVolume(Int_t id, Double_t rmin,Double_t rmax, Double_t zspan)
260 {
261   // set parameters of id-th wrapper volume
262   if (id>=fNWrapVol||id<0) AliFatal(Form("id=%d of wrapper volume is not in 0-%d range",id,fNWrapVol-1));
263   fWrapRMin[id] = rmin;
264   fWrapRMax[id] = rmax;
265   fWrapZSpan[id] = zspan;
266 }
267
268 //______________________________________________________________________
269 void AliITSUv1::CreateGeometry() {
270
271   // Create the geometry and insert it in the mother volume ITSV
272   TGeoManager *geoManager = gGeoManager;
273
274   TGeoVolume *vALIC = geoManager->GetVolume("ALIC");
275
276   new TGeoVolumeAssembly(AliITSUGeomTGeo::GetITSVolPattern());
277   TGeoVolume *vITSV = geoManager->GetVolume(AliITSUGeomTGeo::GetITSVolPattern());
278   vITSV->SetUniqueID(AliITSUGeomTGeo::GetUIDShift()); // store modID -> midUUID bitshift
279   vALIC->AddNode(vITSV, 2, 0);  // Copy number is 2 to cheat AliGeoManager::CheckSymNamesLUT
280   //
281   const Int_t kLength=100;
282   Char_t vstrng[kLength] = "xxxRS"; //?
283   vITSV->SetTitle(vstrng);
284   //
285   // Check that we have all needed parameters
286   if (fNLayers <= 0) AliFatal(Form("Wrong number of layers (%d)",fNLayers));
287   //
288   for (Int_t j=0; j<fNLayers; j++) {
289     if (fLayRadii[j] <= 0)                 AliFatal(Form("Wrong layer radius for layer %d (%f)",j,fLayRadii[j]));
290     if (fLayZLength[j] <= 0)               AliFatal(Form("Wrong layer length for layer %d (%f)",j,fLayZLength[j]));
291     if (fLaddPerLay[j] <= 0)               AliFatal(Form("Wrong number of ladders for layer %d (%d)",j,fLaddPerLay[j]));
292     if (fModPerLadd[j] <= 0)               AliFatal(Form("Wrong number of modules for layer %d (%d)",j,fModPerLadd[j]));
293     if (fLadThick[j] < 0)                  AliFatal(Form("Wrong ladder thickness for layer %d (%f)",j,fLadThick[j]));
294     if (fLayTurbo[j] && fLadWidth[j] <= 0) AliFatal(Form("Wrong ladder width for layer %d (%f)",j,fLadWidth[j]));
295     if (fDetThick[j] < 0)                  AliFatal(Form("Wrong module thickness for layer %d (%f)",j,fDetThick[j]));
296     //
297     if (j > 0) {
298       if (fLayRadii[j]<=fLayRadii[j-1])    AliFatal(Form("Layer %d radius (%f) is smaller than layer %d radius (%f)",
299                                                          j,fLayRadii[j],j-1,fLayRadii[j-1]));
300     } // if (j > 0)
301
302     if (fLadThick[j] == 0) AliInfo(Form("Ladder thickness for layer %d not set, using default",j));
303     if (fDetThick[j] == 0) AliInfo(Form("Module thickness for layer %d not set, using default",j));
304
305   } // for (Int_t j=0; j<fNLayers; j++)
306
307   // Create the wrapper volumes
308   TGeoVolume **wrapVols = 0;
309   if (fNWrapVol) {
310     wrapVols = new TGeoVolume*[fNWrapVol];
311     for (int id=0;id<fNWrapVol;id++) {
312       wrapVols[id] = CreateWrapperVolume(id);
313       vITSV->AddNode(wrapVols[id], 1, 0);
314     }
315   }
316   //
317   // Now create the actual geometry
318   for (Int_t j=0; j<fNLayers; j++) {
319     TGeoVolume* dest = vITSV;
320     //
321     if (fLayTurbo[j]) {
322       fUpGeom[j] = new AliITSUv1Layer(j,kTRUE,kFALSE);
323       fUpGeom[j]->SetLadderWidth(fLadWidth[j]);
324       fUpGeom[j]->SetLadderTilt(fLadTilt[j]);
325     }
326     else fUpGeom[j] = new AliITSUv1Layer(j,kFALSE);
327     //
328     fUpGeom[j]->SetPhi0(fLayPhi0[j]);
329     fUpGeom[j]->SetRadius(fLayRadii[j]);
330     fUpGeom[j]->SetZLength(fLayZLength[j]);
331     fUpGeom[j]->SetNLadders(fLaddPerLay[j]);
332     fUpGeom[j]->SetNModules(fModPerLadd[j]);
333     fUpGeom[j]->SetDetType(fDetTypeID[j]);
334     fUpGeom[j]->SetBuildLevel(fBuildLevel[j]);
335     if (j < 3)
336       fUpGeom[j]->SetStaveModel(fStaveModelIB);
337     else
338       fUpGeom[j]->SetStaveModel(fStaveModelOB);
339     AliDebug(1,Form("fBuildLevel: %d\n",fBuildLevel[j]));
340     //
341     if (fLadThick[j] != 0) fUpGeom[j]->SetLadderThick(fLadThick[j]);
342     if (fDetThick[j] != 0) fUpGeom[j]->SetSensorThick(fDetThick[j]);
343     //
344     for (int iw=0;iw<fNWrapVol;iw++) {
345       if (fLayRadii[j]>fWrapRMin[iw] && fLayRadii[j]<fWrapRMax[iw]) {
346         AliInfo(Form("Will embed layer %d in wrapper volume %d",j,iw));
347         if (fLayZLength[j]>=fWrapZSpan[iw]) AliFatal(Form("ZSpan %.3f of wrapper volume %d is less than ZSpan %.3f of layer %d",
348                                                           fWrapZSpan[iw],iw,fLayZLength[j],j));
349         dest = wrapVols[iw];
350         break;
351       }
352     }
353     fUpGeom[j]->CreateLayer(dest);
354   }
355   delete wrapVols; // delete pointer only, not the volumes
356   //
357 }
358
359 //______________________________________________________________________
360 void AliITSUv1::CreateMaterials() {
361   // Create ITS materials
362   //     This function defines the default materials used in the Geant
363   // Monte Carlo simulations for the geometries AliITSv1, AliITSv3,
364   // AliITSv11Hybrid.
365   // In general it is automatically replaced by
366   // the CreateMaterials routine defined in AliITSv?. Should the function
367   // CreateMaterials not exist for the geometry version you are using this
368   // one is used. See the definition found in AliITSv5 or the other routine
369   // for a complete definition.
370   // Inputs:
371   //   none.
372   // Outputs:
373   //   none.
374   // Return:
375   //   none.
376
377   Int_t   ifield = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
378   Float_t fieldm = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
379
380   Float_t tmaxfd = 0.1; // 1.0; // Degree
381   Float_t stemax = 1.0; // cm
382   Float_t deemax = 0.1; // 30.0; // Fraction of particle's energy 0<deemax<=1
383   Float_t epsil  = 1.0E-4; // 1.0; // cm
384   Float_t stmin  = 0.0; // cm "Default value used"
385
386   Float_t tmaxfdSi = 0.1; // .10000E+01; // Degree
387   Float_t stemaxSi = 0.0075; //  .10000E+01; // cm
388   Float_t deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
389   Float_t epsilSi  = 1.0E-4;// .10000E+01;
390   Float_t stminSi  = 0.0; // cm "Default value used"
391
392   Float_t tmaxfdAir = 0.1; // .10000E+01; // Degree
393   Float_t stemaxAir = .10000E+01; // cm
394   Float_t deemaxAir = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
395   Float_t epsilAir  = 1.0E-4;// .10000E+01;
396   Float_t stminAir  = 0.0; // cm "Default value used"
397
398   // AIR
399   Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
400   Float_t zAir[4]={6.,7.,8.,18.};
401   Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
402   Float_t dAir = 1.20479E-3;
403
404   // Water
405   Float_t aWater[2]={1.00794,15.9994};
406   Float_t zWater[2]={1.,8.};
407   Float_t wWater[2]={0.111894,0.888106};
408   Float_t dWater   = 1.0;
409
410
411   // Kapton
412   Float_t aKapton[4]={1.00794,12.0107, 14.010,15.9994};
413   Float_t zKapton[4]={1.,6.,7.,8.};
414   Float_t wKapton[4]={0.026362,0.69113,0.07327,0.209235};
415   Float_t dKapton   = 1.42;
416  
417   AliMixture(1,"AIR$",aAir,zAir,dAir,4,wAir);
418   AliMedium(1, "AIR$",1,0,ifield,fieldm,tmaxfdAir,stemaxAir,deemaxAir,epsilAir,stminAir);
419
420   AliMixture(2,"WATER$",aWater,zWater,dWater,2,wWater);
421   AliMedium(2, "WATER$",2,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
422
423   AliMaterial(3,"SI$",0.28086E+02,0.14000E+02,0.23300E+01,0.93600E+01,0.99900E+03);
424   AliMedium(3,  "SI$",3,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
425
426   AliMaterial(4,"BERILLIUM$",9.01, 4., 1.848, 35.3, 36.7);// From AliPIPEv3
427   AliMedium(4,  "BERILLIUM$",4,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
428
429   AliMaterial(5,"COPPER$",0.63546E+02,0.29000E+02,0.89600E+01,0.14300E+01,0.99900E+03);
430   AliMedium(5,  "COPPER$",5,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
431
432     
433   // needed for STAVE , Carbon, kapton, Epoxy, flexcable
434
435   //AliMaterial(6,"CARBON$",12.0107,6,2.210,999,999);
436   AliMaterial(6,"CARBON$",12.0107,6,2.210/1.3,999,999);
437   AliMedium(6,  "CARBON$",6,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
438
439   AliMixture(7,"KAPTON(POLYCH2)$", aKapton, zKapton, dKapton, 4, wKapton);
440   AliMedium(7, "KAPTON(POLYCH2)$",7,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
441
442
443  
444   // values below modified as compared to source AliITSv11 !
445
446   //AliMaterial(7,"GLUE$",0.12011E+02,0.60000E+01,0.1930E+01/2.015,999,999); // original
447   AliMaterial(15,"GLUE$",12.011,6,1.93/2.015,999,999);  // conform with ATLAS, Corrado, Stefan
448   AliMedium(15,  "GLUE$",15,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
449
450   // All types of carbon
451   // Unidirectional prepreg
452  AliMaterial(8,"K13D2U2k$",12.0107,6,1.643,999,999);
453  AliMedium(8,  "K13D2U2k$",8,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
454  //Impregnated thread
455  AliMaterial(9,"M60J3K$",12.0107,6,2.21,999,999);
456  AliMedium(9,  "M60J3K$",9,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
457  //Impregnated thread
458  AliMaterial(10,"M55J6K$",12.0107,6,1.63,999,999);
459  AliMedium(10,  "M55J6K$",10,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
460  // Fabric(0/90)
461  AliMaterial(11,"T300$",12.0107,6,1.725,999,999);
462  AliMedium(11,  "T300$",11,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
463  //AMEC Thermasol
464  AliMaterial(12,"FGS003$",12.0107,6,1.6,999,999);
465  AliMedium(12,  "FGS003$",12,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
466  // Carbon fleece
467  AliMaterial(13,"CarbonFleece$",12.0107,6,0.4,999,999);
468  AliMedium(13,  "CarbonFleece$",13,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
469
470   // Flex cable
471   Float_t aFCm[5]={12.0107,1.00794,14.0067,15.9994,26.981538};
472   Float_t zFCm[5]={6.,1.,7.,8.,13.};
473   Float_t wFCm[5]={0.520088819984,0.01983871336,0.0551367996,0.157399667056, 0.247536};
474   //Float_t dFCm = 1.6087;  // original
475   //Float_t dFCm = 2.55;   // conform with STAR
476    Float_t dFCm = 2.595;   // conform with Corrado
477
478   AliMixture(14,"FLEXCABLE$",aFCm,zFCm,dFCm,5,wFCm);
479   AliMedium(14, "FLEXCABLE$",14,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
480
481   AliMaterial(16,"ALUMINUM$",0.26982E+02,0.13000E+02,0.26989E+01,0.89000E+01,0.99900E+03);
482   AliMedium(16,"ALUMINUM$",16,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
483
484 }
485
486 //______________________________________________________________________
487 void AliITSUv1::DefineLayer(const Int_t nlay, const double phi0, const Double_t r,
488                             const Double_t zlen, const Int_t nladd,
489                             const Int_t nmod, const Double_t lthick,
490                             const Double_t dthick, const UInt_t dettypeID,
491                             const Int_t buildLevel)
492 {
493   //     Sets the layer parameters
494   // Inputs:
495   //          nlay    layer number
496   //          phi0    layer phi0
497   //          r       layer radius
498   //          zlen    layer length
499   //          nladd   number of ladders
500   //          nmod    number of modules per ladder
501   //          lthick  ladder thickness (if omitted, defaults to 0)
502   //          dthick  detector thickness (if omitted, defaults to 0)
503   //          buildLevel (if 0, all geometry is build, used for material budget studies)
504   // Outputs:
505   //   none.
506   // Return:
507   //   none.
508   
509   if (nlay >= fNLayers || nlay < 0) {
510     AliError(Form("Wrong layer number (%d)",nlay));
511     return;
512   }
513   
514   fLayTurbo[nlay] = kFALSE;
515   fLayPhi0[nlay] = phi0;
516   fLayRadii[nlay] = r;
517   fLayZLength[nlay] = zlen;
518   fLaddPerLay[nlay] = nladd;
519   fModPerLadd[nlay] = nmod;
520   fLadThick[nlay] = lthick;
521   fDetThick[nlay] = dthick;
522   fDetTypeID[nlay] = dettypeID;
523   fBuildLevel[nlay] = buildLevel;
524     
525 }
526
527 //______________________________________________________________________
528 void AliITSUv1::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t zlen, Int_t nladd,
529                                  Int_t nmod, Double_t width, Double_t tilt,
530                                  Double_t lthick,Double_t dthick,
531                                  UInt_t dettypeID, Int_t buildLevel)
532 {
533   //     Sets the layer parameters for a "turbo" layer
534   //     (i.e. a layer whose ladders overlap in phi)
535   // Inputs:
536   //          nlay    layer number
537   //          phi0    phi of 1st ladder
538   //          r       layer radius
539   //          zlen    layer length
540   //          nladd   number of ladders
541   //          nmod    number of modules per ladder
542   //          width   ladder width
543   //          tilt    layer tilt angle (degrees)
544   //          lthick  ladder thickness (if omitted, defaults to 0)
545   //          dthick  detector thickness (if omitted, defaults to 0)
546   //          dettypeID  ??
547   //          buildLevel (if 0, all geometry is build, used for material budget studies)
548   // Outputs:
549   //   none.
550   // Return:
551   //   none.
552
553   if (nlay >= fNLayers || nlay < 0) {
554     AliError(Form("Wrong layer number (%d)",nlay));
555     return;
556   }
557
558   fLayTurbo[nlay] = kTRUE;
559   fLayPhi0[nlay] = phi0;
560   fLayRadii[nlay] = r;
561   fLayZLength[nlay] = zlen;
562   fLaddPerLay[nlay] = nladd;
563   fModPerLadd[nlay] = nmod;
564   fLadThick[nlay] = lthick;
565   fLadWidth[nlay] = width;
566   fLadTilt[nlay] = tilt;
567   fDetThick[nlay] = dthick;
568   fDetTypeID[nlay] = dettypeID;
569   fBuildLevel[nlay] = buildLevel;
570
571 }
572
573 //______________________________________________________________________
574 void AliITSUv1::GetLayerParameters(Int_t nlay, Double_t &phi0,
575                                    Double_t &r, Double_t &zlen,
576                                    Int_t &nladd, Int_t &nmod,
577                                    Double_t &width, Double_t &tilt,
578                                    Double_t &lthick, Double_t &dthick,
579                                    UInt_t &dettype) const
580 {
581   //     Gets the layer parameters
582   // Inputs:
583   //          nlay    layer number
584   // Outputs:
585   //          phi0    phi of 1st ladder
586   //          r       layer radius
587   //          zlen    layer length
588   //          nladd   number of ladders
589   //          nmod    number of modules per ladder
590   //          width   ladder width
591   //          tilt    ladder tilt angle
592   //          lthick  ladder thickness
593   //          dthick  detector thickness
594   //          dettype detector type
595   // Return:
596   //   none.
597
598   if (nlay >= fNLayers || nlay < 0) {
599     AliError(Form("Wrong layer number (%d)",nlay));
600     return;
601   }
602   
603   phi0   = fLayPhi0[nlay];
604   r      = fLayRadii[nlay];
605   zlen   = fLayZLength[nlay];
606   nladd  = fLaddPerLay[nlay];
607   nmod   = fModPerLadd[nlay];
608   width  = fLadWidth[nlay];
609   tilt   = fLadTilt[nlay];
610   lthick = fLadThick[nlay];
611   dthick = fDetThick[nlay];
612   dettype= fDetTypeID[nlay];
613 }
614
615 //______________________________________________________________________
616 TGeoVolume* AliITSUv1::CreateWrapperVolume(Int_t id)
617 {
618   //     Creates an air-filled wrapper cylindrical volume 
619   // Inputs:
620   //          volume id
621   // Outputs:
622   //          the wrapper volume
623
624   if (fWrapRMin[id]<0 || fWrapRMax[id]<0 || fWrapZSpan[id]<0) AliFatal(Form("Wrapper volume %d was requested but not defined",id));
625   // Now create the actual shape and volume
626   //
627   TGeoTube *tube = new TGeoTube(fWrapRMin[id], fWrapRMax[id], fWrapZSpan[id]/2.);
628
629   TGeoMedium *medAir = gGeoManager->GetMedium("ITS_AIR$");
630
631   char volnam[30];
632   snprintf(volnam, 29, "%s%d", AliITSUGeomTGeo::GetITSWrapVolPattern(),id);
633
634   TGeoVolume *wrapper = new TGeoVolume(volnam, tube, medAir);
635
636   return wrapper;
637 }
638
639 //______________________________________________________________________
640 void AliITSUv1::Init()
641 {
642   //     Initialise the ITS after it has been created.
643   UpdateInternalGeometry();
644   AliITSU::Init();
645   //  
646 }
647
648 //______________________________________________________________________
649 Bool_t AliITSUv1::IsLayerTurbo(Int_t nlay)
650 {
651   //     Returns true if the layer is a "turbo" layer
652   if ( nlay < 0 || nlay > fNLayers ) {
653     AliError(Form("Wrong layer number %d",nlay));
654     return kFALSE;
655   } 
656   else return fUpGeom[nlay]->IsTurbo();
657 }
658
659 //______________________________________________________________________
660 void AliITSUv1::SetDefaults()
661 {
662   // sets the default segmentation, response, digit and raw cluster classes
663 }
664
665 //______________________________________________________________________
666 void AliITSUv1::StepManager()
667 {
668   //    Called for every step in the ITS, then calles the AliITSUHit class
669   // creator with the information to be recoreded about that hit.
670   //     The value of the macro ALIITSPRINTGEOM if set to 1 will allow the
671   // printing of information to a file which can be used to create a .det
672   // file read in by the routine CreateGeometry(). If set to 0 or any other
673   // value except 1, the default behavior, then no such file is created nor
674   // it the extra variables and the like used in the printing allocated.
675   // Inputs:
676   //   none.
677   // Outputs:
678   //   none.
679   // Return:
680   //   none.
681   if(!(this->IsActive())) return;
682   if(!(gMC->TrackCharge())) return;
683   //
684   Int_t copy, lay = 0;
685   Int_t id = gMC->CurrentVolID(copy);
686
687   Bool_t notSens = kFALSE;
688   while ((lay<fNLayers)  && (notSens = (id!=fIdSens[lay]))) ++lay;
689   //printf("R: %.1f | Lay: %d  NotSens: %d\n",positionRS.Pt(), lay, notSens);
690            
691   if (notSens) return;
692
693   if(gMC->IsTrackExiting()) {
694     AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS);
695   } // if Outer ITS mother Volume
696
697   static TLorentzVector position, momentum; // Saves on calls to construtors
698   static AliITSUHit hit;// Saves on calls to constructors
699
700   TClonesArray &lhits = *(Hits());
701   Int_t   cpn0, cpn1, mod, status = 0;
702   //
703   // Track status
704   if(gMC->IsTrackInside())      status +=  1;
705   if(gMC->IsTrackEntering())    status +=  2;
706   if(gMC->IsTrackExiting())     status +=  4;
707   if(gMC->IsTrackOut())         status +=  8;
708   if(gMC->IsTrackDisappeared()) status += 16;
709   if(gMC->IsTrackStop())        status += 32;
710   if(gMC->IsTrackAlive())       status += 64;
711
712   //
713   // retrieve the indices with the volume path
714   //
715   if (lay < 0 || lay >= fNLayers) {
716     AliError(Form("Invalid value: lay=%d. Not an ITS sensitive volume",lay));
717     return; // not an ITS sensitive volume.
718   } else {
719     copy = 1;
720     gMC->CurrentVolOffID(1,cpn1);
721     gMC->CurrentVolOffID(2,cpn0);
722   } //
723
724   mod = fGeomTGeo->GetModuleIndex(lay,cpn0,cpn1);
725   //RS2DEL  fInitGeom.DecodeDetector(mod,lay+1,cpn0,cpn1,copy);
726   //
727   // Fill hit structure.
728   //
729   hit.SetModule(mod);
730   hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
731   gMC->TrackPosition(position);
732   gMC->TrackMomentum(momentum);
733   hit.SetPosition(position);
734   hit.SetTime(gMC->TrackTime());
735   hit.SetMomentum(momentum);
736   hit.SetStatus(status);
737   hit.SetEdep(gMC->Edep());
738   hit.SetShunt(GetIshunt());
739   if(gMC->IsTrackEntering()){
740     hit.SetStartPosition(position);
741     hit.SetStartTime(gMC->TrackTime());
742     hit.SetStartStatus(status);
743     return; // don't save entering hit.
744   } // end if IsEntering
745     // Fill hit structure with this new hit.
746     //Info("StepManager","Calling Copy Constructor");
747   new(lhits[fNhits++]) AliITSUHit(hit); // Use Copy Construtor.
748   // Save old position... for next hit.
749   hit.SetStartPosition(position);
750   hit.SetStartTime(gMC->TrackTime());
751   hit.SetStartStatus(status);
752
753   return;
754 }
755
756 //______________________________________________________________________
757 void AliITSUv1::SetLayerDetTypeID(Int_t lr, UInt_t id)
758 {
759   // set det type
760   if (!fDetTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
761   fDetTypeID[lr] = id;
762 }
763
764 //______________________________________________________________________
765 Int_t AliITSUv1::GetLayerDetTypeID(Int_t lr)
766 {
767   // set det type
768   if (!fDetTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
769   return fDetTypeID[lr];
770 }