]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/UPGRADE/AliITSUv1.cxx
Switching to the TDR naming schema (I cross my fingers)
[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   ,fStavPerLay(0)
73   ,fModPerStav(0)
74   ,fStaThick(0)
75   ,fStaWidth(0)
76   ,fStaTilt(0)
77   ,fDetThick(0)
78   ,fChipTypeID(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   ,fStavPerLay(0)
105   ,fModPerStav(0)
106   ,fStaThick(0)
107   ,fStaWidth(0)
108   ,fStaTilt(0)
109   ,fDetThick(0)
110   ,fChipTypeID(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   fStavPerLay = new Int_t[fNLayers];
132   fModPerStav = new Int_t[fNLayers];
133   fStaThick   = new Double_t[fNLayers];
134   fStaWidth   = new Double_t[fNLayers];
135   fStaTilt    = new Double_t[fNLayers];
136   fDetThick   = new Double_t[fNLayers];
137   fChipTypeID  = 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       fStavPerLay[j] = 0;
149       fModPerStav[j] = 0;
150       fStaWidth[j] = 0.;
151       fDetThick[j] = 0.;
152       fChipTypeID[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 [] fStavPerLay;
173   delete [] fModPerStav;
174   delete [] fStaThick;
175   delete [] fStaWidth;
176   delete [] fStaTilt;
177   delete [] fDetThick;
178   delete [] fChipTypeID;
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<fStavPerLay[lr]; ld++) {
222       //
223       TString pthL = Form("%s/%s%d_%d",pth.Data(),AliITSUGeomTGeo::GetITSStavePattern(),lr,ld);
224       //printf("SetAlignable: %s %s\n",snmL.Data(),pthL.Data());
225       gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameStave(lr,ld),pthL.Data());
226       //
227       for (int md=0; md<fModPerStav[lr]; md++) {
228         //
229         TString pthM = Form("%s/%s%d_%d",pthL.Data(),AliITSUGeomTGeo::GetITSChipPattern(),lr,md);
230         //
231         // RS: Attention, this is a hack: AliGeomManager cannot accomodate all ITSU chips w/o
232         // conflicts with TPC. For this reason we define the UID of the chip to be simply its ID
233         //      int modUID = AliGeomManager::LayerToVolUID(lr+1,modNum++); // here modNum would be chip within the layer
234         int modUID = AliITSUGeomTGeo::ChipVolUID( modNum++ );
235         // 
236         gGeoManager->SetAlignableEntry(AliITSUGeomTGeo::ComposeSymNameChip(lr,ld,md),pthM.Data(),modUID);
237         //
238       }
239     }
240   }
241   //
242   */
243 }
244
245 //______________________________________________________________________
246 void AliITSUv1::SetNWrapVolumes(Int_t n)
247 {
248   // book arrays for wrapper volumes
249   if (fNWrapVol) AliFatal(Form("%d wrapper volumes already defined",fNWrapVol));
250   if (n<1) return;
251   fNWrapVol = n;
252   fWrapRMin = new Double_t[fNWrapVol];
253   fWrapRMax = new Double_t[fNWrapVol];
254   fWrapZSpan= new Double_t[fNWrapVol];
255   for (int i=fNWrapVol;i--;) fWrapRMin[i]=fWrapRMax[i]=fWrapZSpan[i]=-1;
256   //
257 }
258
259 //______________________________________________________________________
260 void AliITSUv1::DefineWrapVolume(Int_t id, Double_t rmin,Double_t rmax, Double_t zspan)
261 {
262   // set parameters of id-th wrapper volume
263   if (id>=fNWrapVol||id<0) AliFatal(Form("id=%d of wrapper volume is not in 0-%d range",id,fNWrapVol-1));
264   fWrapRMin[id] = rmin;
265   fWrapRMax[id] = rmax;
266   fWrapZSpan[id] = zspan;
267 }
268
269 //______________________________________________________________________
270 void AliITSUv1::CreateGeometry() {
271
272   // Create the geometry and insert it in the mother volume ITSV
273   TGeoManager *geoManager = gGeoManager;
274
275   TGeoVolume *vALIC = geoManager->GetVolume("ALIC");
276
277   new TGeoVolumeAssembly(AliITSUGeomTGeo::GetITSVolPattern());
278   TGeoVolume *vITSV = geoManager->GetVolume(AliITSUGeomTGeo::GetITSVolPattern());
279   vITSV->SetUniqueID(AliITSUGeomTGeo::GetUIDShift()); // store modID -> midUUID bitshift
280   vALIC->AddNode(vITSV, 2, 0);  // Copy number is 2 to cheat AliGeoManager::CheckSymNamesLUT
281   //
282   const Int_t kLength=100;
283   Char_t vstrng[kLength] = "xxxRS"; //?
284   vITSV->SetTitle(vstrng);
285   //
286   // Check that we have all needed parameters
287   if (fNLayers <= 0) AliFatal(Form("Wrong number of layers (%d)",fNLayers));
288   //
289   for (Int_t j=0; j<fNLayers; j++) {
290     if (fLayRadii[j] <= 0)                 AliFatal(Form("Wrong layer radius for layer %d (%f)",j,fLayRadii[j]));
291     if (fLayZLength[j] <= 0)               AliFatal(Form("Wrong layer length for layer %d (%f)",j,fLayZLength[j]));
292     if (fStavPerLay[j] <= 0)               AliFatal(Form("Wrong number of staves for layer %d (%d)",j,fStavPerLay[j]));
293     if (fModPerStav[j] <= 0)               AliFatal(Form("Wrong number of chips for layer %d (%d)",j,fModPerStav[j]));
294     if (fStaThick[j] < 0)                  AliFatal(Form("Wrong stave thickness for layer %d (%f)",j,fStaThick[j]));
295     if (fLayTurbo[j] && fStaWidth[j] <= 0) AliFatal(Form("Wrong stave width for layer %d (%f)",j,fStaWidth[j]));
296     if (fDetThick[j] < 0)                  AliFatal(Form("Wrong chip thickness for layer %d (%f)",j,fDetThick[j]));
297     //
298     if (j > 0) {
299       if (fLayRadii[j]<=fLayRadii[j-1])    AliFatal(Form("Layer %d radius (%f) is smaller than layer %d radius (%f)",
300                                                          j,fLayRadii[j],j-1,fLayRadii[j-1]));
301     } // if (j > 0)
302
303     if (fStaThick[j] == 0) AliInfo(Form("Stave thickness for layer %d not set, using default",j));
304     if (fDetThick[j] == 0) AliInfo(Form("Chip thickness for layer %d not set, using default",j));
305
306   } // for (Int_t j=0; j<fNLayers; j++)
307
308   // Create the wrapper volumes
309   TGeoVolume **wrapVols = 0;
310   if (fNWrapVol) {
311     wrapVols = new TGeoVolume*[fNWrapVol];
312     for (int id=0;id<fNWrapVol;id++) {
313       wrapVols[id] = CreateWrapperVolume(id);
314       vITSV->AddNode(wrapVols[id], 1, 0);
315     }
316   }
317   //
318   // Now create the actual geometry
319   for (Int_t j=0; j<fNLayers; j++) {
320     TGeoVolume* dest = vITSV;
321     //
322     if (fLayTurbo[j]) {
323       fUpGeom[j] = new AliITSUv1Layer(j,kTRUE,kFALSE);
324       fUpGeom[j]->SetStaveWidth(fStaWidth[j]);
325       fUpGeom[j]->SetStaveTilt(fStaTilt[j]);
326     }
327     else fUpGeom[j] = new AliITSUv1Layer(j,kFALSE);
328     //
329     fUpGeom[j]->SetPhi0(fLayPhi0[j]);
330     fUpGeom[j]->SetRadius(fLayRadii[j]);
331     fUpGeom[j]->SetZLength(fLayZLength[j]);
332     fUpGeom[j]->SetNStaves(fStavPerLay[j]);
333     fUpGeom[j]->SetNChips(fModPerStav[j]);
334     fUpGeom[j]->SetChipType(fChipTypeID[j]);
335     fUpGeom[j]->SetBuildLevel(fBuildLevel[j]);
336     if (j < 3)
337       fUpGeom[j]->SetStaveModel(fStaveModelIB);
338     else
339       fUpGeom[j]->SetStaveModel(fStaveModelOB);
340     AliDebug(1,Form("fBuildLevel: %d\n",fBuildLevel[j]));
341     //
342     if (fStaThick[j] != 0) fUpGeom[j]->SetStaveThick(fStaThick[j]);
343     if (fDetThick[j] != 0) fUpGeom[j]->SetSensorThick(fDetThick[j]);
344     //
345     for (int iw=0;iw<fNWrapVol;iw++) {
346       if (fLayRadii[j]>fWrapRMin[iw] && fLayRadii[j]<fWrapRMax[iw]) {
347         AliInfo(Form("Will embed layer %d in wrapper volume %d",j,iw));
348         if (fLayZLength[j]>=fWrapZSpan[iw]) AliFatal(Form("ZSpan %.3f of wrapper volume %d is less than ZSpan %.3f of layer %d",
349                                                           fWrapZSpan[iw],iw,fLayZLength[j],j));
350         dest = wrapVols[iw];
351         break;
352       }
353     }
354     fUpGeom[j]->CreateLayer(dest);
355   }
356   delete[] wrapVols; // delete pointer only, not the volumes
357   //
358 }
359
360 //______________________________________________________________________
361 void AliITSUv1::CreateMaterials() {
362   // Create ITS materials
363   //     This function defines the default materials used in the Geant
364   // Monte Carlo simulations for the geometries AliITSv1, AliITSv3,
365   // AliITSv11Hybrid.
366   // In general it is automatically replaced by
367   // the CreateMaterials routine defined in AliITSv?. Should the function
368   // CreateMaterials not exist for the geometry version you are using this
369   // one is used. See the definition found in AliITSv5 or the other routine
370   // for a complete definition.
371   // Inputs:
372   //   none.
373   // Outputs:
374   //   none.
375   // Return:
376   //   none.
377
378   Int_t   ifield = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
379   Float_t fieldm = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
380
381   Float_t tmaxfd = 0.1; // 1.0; // Degree
382   Float_t stemax = 1.0; // cm
383   Float_t deemax = 0.1; // 30.0; // Fraction of particle's energy 0<deemax<=1
384   Float_t epsil  = 1.0E-4; // 1.0; // cm
385   Float_t stmin  = 0.0; // cm "Default value used"
386
387   Float_t tmaxfdSi = 0.1; // .10000E+01; // Degree
388   Float_t stemaxSi = 0.0075; //  .10000E+01; // cm
389   Float_t deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
390   Float_t epsilSi  = 1.0E-4;// .10000E+01;
391   Float_t stminSi  = 0.0; // cm "Default value used"
392
393   Float_t tmaxfdAir = 0.1; // .10000E+01; // Degree
394   Float_t stemaxAir = .10000E+01; // cm
395   Float_t deemaxAir = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
396   Float_t epsilAir  = 1.0E-4;// .10000E+01;
397   Float_t stminAir  = 0.0; // cm "Default value used"
398
399   // AIR
400   Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
401   Float_t zAir[4]={6.,7.,8.,18.};
402   Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
403   Float_t dAir = 1.20479E-3;
404
405   // Water
406   Float_t aWater[2]={1.00794,15.9994};
407   Float_t zWater[2]={1.,8.};
408   Float_t wWater[2]={0.111894,0.888106};
409   Float_t dWater   = 1.0;
410
411
412   // Kapton
413   Float_t aKapton[4]={1.00794,12.0107, 14.010,15.9994};
414   Float_t zKapton[4]={1.,6.,7.,8.};
415   Float_t wKapton[4]={0.026362,0.69113,0.07327,0.209235};
416   Float_t dKapton   = 1.42;
417  
418   AliMixture(1,"AIR$",aAir,zAir,dAir,4,wAir);
419   AliMedium(1, "AIR$",1,0,ifield,fieldm,tmaxfdAir,stemaxAir,deemaxAir,epsilAir,stminAir);
420
421   AliMixture(2,"WATER$",aWater,zWater,dWater,2,wWater);
422   AliMedium(2, "WATER$",2,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
423
424   AliMaterial(3,"SI$",0.28086E+02,0.14000E+02,0.23300E+01,0.93600E+01,0.99900E+03);
425   AliMedium(3,  "SI$",3,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
426
427   AliMaterial(4,"BERILLIUM$",9.01, 4., 1.848, 35.3, 36.7);// From AliPIPEv3
428   AliMedium(4,  "BERILLIUM$",4,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
429
430   AliMaterial(5,"COPPER$",0.63546E+02,0.29000E+02,0.89600E+01,0.14300E+01,0.99900E+03);
431   AliMedium(5,  "COPPER$",5,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
432
433     
434   // needed for STAVE , Carbon, kapton, Epoxy, flexcable
435
436   //AliMaterial(6,"CARBON$",12.0107,6,2.210,999,999);
437   AliMaterial(6,"CARBON$",12.0107,6,2.210/1.3,999,999);
438   AliMedium(6,  "CARBON$",6,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
439
440   AliMixture(7,"KAPTON(POLYCH2)$", aKapton, zKapton, dKapton, 4, wKapton);
441   AliMedium(7, "KAPTON(POLYCH2)$",7,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
442
443
444  
445   // values below modified as compared to source AliITSv11 !
446
447   //AliMaterial(7,"GLUE$",0.12011E+02,0.60000E+01,0.1930E+01/2.015,999,999); // original
448   AliMaterial(15,"GLUE$",12.011,6,1.93/2.015,999,999);  // conform with ATLAS, Corrado, Stefan
449   AliMedium(15,  "GLUE$",15,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
450
451   // All types of carbon
452   // Unidirectional prepreg
453  AliMaterial(8,"K13D2U2k$",12.0107,6,1.643,999,999);
454  AliMedium(8,  "K13D2U2k$",8,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
455  //Impregnated thread
456  AliMaterial(9,"M60J3K$",12.0107,6,2.21,999,999);
457  AliMedium(9,  "M60J3K$",9,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
458  //Impregnated thread
459  AliMaterial(10,"M55J6K$",12.0107,6,1.63,999,999);
460  AliMedium(10,  "M55J6K$",10,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
461  // Fabric(0/90)
462  AliMaterial(11,"T300$",12.0107,6,1.725,999,999);
463  AliMedium(11,  "T300$",11,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
464  //AMEC Thermasol
465  AliMaterial(12,"FGS003$",12.0107,6,1.6,999,999);
466  AliMedium(12,  "FGS003$",12,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
467  // Carbon fleece
468  AliMaterial(13,"CarbonFleece$",12.0107,6,0.4,999,999);
469  AliMedium(13,  "CarbonFleece$",13,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
470
471   // Flex cable
472   Float_t aFCm[5]={12.0107,1.00794,14.0067,15.9994,26.981538};
473   Float_t zFCm[5]={6.,1.,7.,8.,13.};
474   Float_t wFCm[5]={0.520088819984,0.01983871336,0.0551367996,0.157399667056, 0.247536};
475   //Float_t dFCm = 1.6087;  // original
476   //Float_t dFCm = 2.55;   // conform with STAR
477    Float_t dFCm = 2.595;   // conform with Corrado
478
479   AliMixture(14,"FLEXCABLE$",aFCm,zFCm,dFCm,5,wFCm);
480   AliMedium(14, "FLEXCABLE$",14,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
481
482   AliMaterial(16,"ALUMINUM$",0.26982E+02,0.13000E+02,0.26989E+01,0.89000E+01,0.99900E+03);
483   AliMedium(16,"ALUMINUM$",16,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
484
485 }
486
487 //______________________________________________________________________
488 void AliITSUv1::DefineLayer(const Int_t nlay, const double phi0, const Double_t r,
489                             const Double_t zlen, const Int_t nstav,
490                             const Int_t nmod, const Double_t lthick,
491                             const Double_t dthick, const UInt_t dettypeID,
492                             const Int_t buildLevel)
493 {
494   //     Sets the layer parameters
495   // Inputs:
496   //          nlay    layer number
497   //          phi0    layer phi0
498   //          r       layer radius
499   //          zlen    layer length
500   //          nstav   number of staves
501   //          nmod    number of chips per stave
502   //          lthick  stave thickness (if omitted, defaults to 0)
503   //          dthick  detector thickness (if omitted, defaults to 0)
504   //          buildLevel (if 0, all geometry is build, used for material budget studies)
505   // Outputs:
506   //   none.
507   // Return:
508   //   none.
509   
510   if (nlay >= fNLayers || nlay < 0) {
511     AliError(Form("Wrong layer number (%d)",nlay));
512     return;
513   }
514   
515   fLayTurbo[nlay] = kFALSE;
516   fLayPhi0[nlay] = phi0;
517   fLayRadii[nlay] = r;
518   fLayZLength[nlay] = zlen;
519   fStavPerLay[nlay] = nstav;
520   fModPerStav[nlay] = nmod;
521   fStaThick[nlay] = lthick;
522   fDetThick[nlay] = dthick;
523   fChipTypeID[nlay] = dettypeID;
524   fBuildLevel[nlay] = buildLevel;
525     
526 }
527
528 //______________________________________________________________________
529 void AliITSUv1::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t zlen, Int_t nstav,
530                                  Int_t nmod, Double_t width, Double_t tilt,
531                                  Double_t lthick,Double_t dthick,
532                                  UInt_t dettypeID, Int_t buildLevel)
533 {
534   //     Sets the layer parameters for a "turbo" layer
535   //     (i.e. a layer whose staves overlap in phi)
536   // Inputs:
537   //          nlay    layer number
538   //          phi0    phi of 1st stave
539   //          r       layer radius
540   //          zlen    layer length
541   //          nstav   number of staves
542   //          nmod    number of chips per stave
543   //          width   stave width
544   //          tilt    layer tilt angle (degrees)
545   //          lthick  stave thickness (if omitted, defaults to 0)
546   //          dthick  detector thickness (if omitted, defaults to 0)
547   //          dettypeID  ??
548   //          buildLevel (if 0, all geometry is build, used for material budget studies)
549   // Outputs:
550   //   none.
551   // Return:
552   //   none.
553
554   if (nlay >= fNLayers || nlay < 0) {
555     AliError(Form("Wrong layer number (%d)",nlay));
556     return;
557   }
558
559   fLayTurbo[nlay] = kTRUE;
560   fLayPhi0[nlay] = phi0;
561   fLayRadii[nlay] = r;
562   fLayZLength[nlay] = zlen;
563   fStavPerLay[nlay] = nstav;
564   fModPerStav[nlay] = nmod;
565   fStaThick[nlay] = lthick;
566   fStaWidth[nlay] = width;
567   fStaTilt[nlay] = tilt;
568   fDetThick[nlay] = dthick;
569   fChipTypeID[nlay] = dettypeID;
570   fBuildLevel[nlay] = buildLevel;
571
572 }
573
574 //______________________________________________________________________
575 void AliITSUv1::GetLayerParameters(Int_t nlay, Double_t &phi0,
576                                    Double_t &r, Double_t &zlen,
577                                    Int_t &nstav, Int_t &nmod,
578                                    Double_t &width, Double_t &tilt,
579                                    Double_t &lthick, Double_t &dthick,
580                                    UInt_t &dettype) const
581 {
582   //     Gets the layer parameters
583   // Inputs:
584   //          nlay    layer number
585   // Outputs:
586   //          phi0    phi of 1st stave
587   //          r       layer radius
588   //          zlen    layer length
589   //          nstav   number of staves
590   //          nmod    number of chips per stave
591   //          width   stave width
592   //          tilt    stave tilt angle
593   //          lthick  stave thickness
594   //          dthick  detector thickness
595   //          dettype detector type
596   // Return:
597   //   none.
598
599   if (nlay >= fNLayers || nlay < 0) {
600     AliError(Form("Wrong layer number (%d)",nlay));
601     return;
602   }
603   
604   phi0   = fLayPhi0[nlay];
605   r      = fLayRadii[nlay];
606   zlen   = fLayZLength[nlay];
607   nstav  = fStavPerLay[nlay];
608   nmod   = fModPerStav[nlay];
609   width  = fStaWidth[nlay];
610   tilt   = fStaTilt[nlay];
611   lthick = fStaThick[nlay];
612   dthick = fDetThick[nlay];
613   dettype= fChipTypeID[nlay];
614 }
615
616 //______________________________________________________________________
617 TGeoVolume* AliITSUv1::CreateWrapperVolume(Int_t id)
618 {
619   //     Creates an air-filled wrapper cylindrical volume 
620   // Inputs:
621   //          volume id
622   // Outputs:
623   //          the wrapper volume
624
625   if (fWrapRMin[id]<0 || fWrapRMax[id]<0 || fWrapZSpan[id]<0) AliFatal(Form("Wrapper volume %d was requested but not defined",id));
626   // Now create the actual shape and volume
627   //
628   TGeoTube *tube = new TGeoTube(fWrapRMin[id], fWrapRMax[id], fWrapZSpan[id]/2.);
629
630   TGeoMedium *medAir = gGeoManager->GetMedium("ITS_AIR$");
631
632   char volnam[30];
633   snprintf(volnam, 29, "%s%d", AliITSUGeomTGeo::GetITSWrapVolPattern(),id);
634
635   TGeoVolume *wrapper = new TGeoVolume(volnam, tube, medAir);
636
637   return wrapper;
638 }
639
640 //______________________________________________________________________
641 void AliITSUv1::Init()
642 {
643   //     Initialise the ITS after it has been created.
644   UpdateInternalGeometry();
645   AliITSU::Init();
646   //  
647 }
648
649 //______________________________________________________________________
650 Bool_t AliITSUv1::IsLayerTurbo(Int_t nlay)
651 {
652   //     Returns true if the layer is a "turbo" layer
653   if ( nlay < 0 || nlay > fNLayers ) {
654     AliError(Form("Wrong layer number %d",nlay));
655     return kFALSE;
656   } 
657   else return fUpGeom[nlay]->IsTurbo();
658 }
659
660 //______________________________________________________________________
661 void AliITSUv1::SetDefaults()
662 {
663   // sets the default segmentation, response, digit and raw cluster classes
664 }
665
666 //______________________________________________________________________
667 void AliITSUv1::StepManager()
668 {
669   //    Called for every step in the ITS, then calles the AliITSUHit class
670   // creator with the information to be recoreded about that hit.
671   //     The value of the macro ALIITSPRINTGEOM if set to 1 will allow the
672   // printing of information to a file which can be used to create a .det
673   // file read in by the routine CreateGeometry(). If set to 0 or any other
674   // value except 1, the default behavior, then no such file is created nor
675   // it the extra variables and the like used in the printing allocated.
676   // Inputs:
677   //   none.
678   // Outputs:
679   //   none.
680   // Return:
681   //   none.
682   if(!(this->IsActive())) return;
683   if(!(gMC->TrackCharge())) return;
684   //
685   Int_t copy, lay = 0;
686   Int_t id = gMC->CurrentVolID(copy);
687
688   Bool_t notSens = kFALSE;
689   while ((lay<fNLayers)  && (notSens = (id!=fIdSens[lay]))) ++lay;
690   //printf("R: %.1f | Lay: %d  NotSens: %d\n",positionRS.Pt(), lay, notSens);
691            
692   if (notSens) return;
693
694   if(gMC->IsTrackExiting()) {
695     AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS);
696   } // if Outer ITS mother Volume
697
698   static TLorentzVector position, momentum; // Saves on calls to construtors
699   static AliITSUHit hit;// Saves on calls to constructors
700
701   TClonesArray &lhits = *(Hits());
702   Int_t   cpn0, cpn1, mod, status = 0;
703   //
704   // Track status
705   if(gMC->IsTrackInside())      status +=  1;
706   if(gMC->IsTrackEntering())    status +=  2;
707   if(gMC->IsTrackExiting())     status +=  4;
708   if(gMC->IsTrackOut())         status +=  8;
709   if(gMC->IsTrackDisappeared()) status += 16;
710   if(gMC->IsTrackStop())        status += 32;
711   if(gMC->IsTrackAlive())       status += 64;
712
713   //
714   // retrieve the indices with the volume path
715   //
716   if (lay < 0 || lay >= fNLayers) {
717     AliError(Form("Invalid value: lay=%d. Not an ITS sensitive volume",lay));
718     return; // not an ITS sensitive volume.
719   } else {
720     copy = 1;
721     gMC->CurrentVolOffID(1,cpn1);
722     gMC->CurrentVolOffID(2,cpn0);
723   } //
724
725   mod = fGeomTGeo->GetChipIndex(lay,cpn0,cpn1);
726   //RS2DEL  fInitGeom.DecodeDetector(mod,lay+1,cpn0,cpn1,copy);
727   //
728   // Fill hit structure.
729   //
730   hit.SetChip(mod);
731   hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
732   gMC->TrackPosition(position);
733   gMC->TrackMomentum(momentum);
734   hit.SetPosition(position);
735   hit.SetTime(gMC->TrackTime());
736   hit.SetMomentum(momentum);
737   hit.SetStatus(status);
738   hit.SetEdep(gMC->Edep());
739   hit.SetShunt(GetIshunt());
740   if(gMC->IsTrackEntering()){
741     hit.SetStartPosition(position);
742     hit.SetStartTime(gMC->TrackTime());
743     hit.SetStartStatus(status);
744     return; // don't save entering hit.
745   } // end if IsEntering
746     // Fill hit structure with this new hit.
747     //Info("StepManager","Calling Copy Constructor");
748   new(lhits[fNhits++]) AliITSUHit(hit); // Use Copy Construtor.
749   // Save old position... for next hit.
750   hit.SetStartPosition(position);
751   hit.SetStartTime(gMC->TrackTime());
752   hit.SetStartStatus(status);
753
754   return;
755 }
756
757 //______________________________________________________________________
758 void AliITSUv1::SetLayerChipTypeID(Int_t lr, UInt_t id)
759 {
760   // set det type
761   if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
762   fChipTypeID[lr] = id;
763 }
764
765 //______________________________________________________________________
766 Int_t AliITSUv1::GetLayerChipTypeID(Int_t lr)
767 {
768   // set det type
769   if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
770   return fChipTypeID[lr];
771 }