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