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