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