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