Previous version of v1 geom from Mario was incorrectly merged
[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   AliInfo(Form("L# %d Phi:%+.3f R:%+7.3f DZ:%7.2f Nst:%2d Nunit:%2d Lthick:%.4f Dthick:%.4f DetID:%d B:%d",
581                nlay,phi0,r,zlen,nstav,nunit,lthick,dthick,dettypeID,buildLevel));
582
583   if (nlay >= fNLayers || nlay < 0) {
584     AliError(Form("Wrong layer number (%d)",nlay));
585     return;
586   }
587   
588   fLayTurbo[nlay] = kFALSE;
589   fLayPhi0[nlay] = phi0;
590   fLayRadii[nlay] = r;
591   fLayZLength[nlay] = zlen;
592   fStavPerLay[nlay] = nstav;
593   fUnitPerStave[nlay] = nunit;
594   fStaveThick[nlay] = lthick;
595   fDetThick[nlay] = dthick;
596   fChipTypeID[nlay] = dettypeID;
597   fBuildLevel[nlay] = buildLevel;
598     
599 }
600
601 //______________________________________________________________________
602 void AliITSUv1::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t zlen, Int_t nstav,
603                                  Int_t nunit, Double_t width, Double_t tilt,
604                                  Double_t lthick,Double_t dthick,
605                                  UInt_t dettypeID, Int_t buildLevel)
606 {
607   //     Sets the layer parameters for a "turbo" layer
608   //     (i.e. a layer whose staves overlap in phi)
609   // Inputs:
610   //          nlay    layer number
611   //          phi0    phi of 1st stave
612   //          r       layer radius
613   //          zlen    layer length
614   //          nstav   number of staves
615   //          nunit   IB: number of chips per stave
616   //                  OB: number of modules per half stave
617   //          width   stave width
618   //          tilt    layer tilt angle (degrees)
619   //          lthick  stave thickness (if omitted, defaults to 0)
620   //          dthick  detector thickness (if omitted, defaults to 0)
621   //          dettypeID  ??
622   //          buildLevel (if 0, all geometry is build, used for material budget studies)
623   // Outputs:
624   //   none.
625   // Return:
626   //   none.
627
628   AliInfo(Form("L# %d Phi:%+.3f R:%+7.3f DZ:%7.2f Nst:%2d Nunit:%2d W:%7.4f Tilt:%+.3f Lthick:%.4f Dthick:%.4f DetID:%d B:%d",
629                nlay,phi0,r,zlen,nstav,nunit,width,tilt,lthick,dthick,dettypeID,buildLevel));
630
631   if (nlay >= fNLayers || nlay < 0) {
632     AliError(Form("Wrong layer number (%d)",nlay));
633     return;
634   }
635
636   fLayTurbo[nlay] = kTRUE;
637   fLayPhi0[nlay] = phi0;
638   fLayRadii[nlay] = r;
639   fLayZLength[nlay] = zlen;
640   fStavPerLay[nlay] = nstav;
641   fUnitPerStave[nlay] = nunit;
642   fStaveThick[nlay] = lthick;
643   fStaveWidth[nlay] = width;
644   fStaveTilt[nlay] = tilt;
645   fDetThick[nlay] = dthick;
646   fChipTypeID[nlay] = dettypeID;
647   fBuildLevel[nlay] = buildLevel;
648
649 }
650
651 //______________________________________________________________________
652 void AliITSUv1::GetLayerParameters(Int_t nlay, Double_t &phi0,
653                                    Double_t &r, Double_t &zlen,
654                                    Int_t &nstav, Int_t &nmod,
655                                    Double_t &width, Double_t &tilt,
656                                    Double_t &lthick, Double_t &dthick,
657                                    UInt_t &dettype) const
658 {
659   //     Gets the layer parameters
660   // Inputs:
661   //          nlay    layer number
662   // Outputs:
663   //          phi0    phi of 1st stave
664   //          r       layer radius
665   //          zlen    layer length
666   //          nstav   number of staves
667   //          nmod    IB: number of chips per stave
668   //                  OB: number of modules per half stave
669   //          width   stave width
670   //          tilt    stave tilt angle
671   //          lthick  stave thickness
672   //          dthick  detector thickness
673   //          dettype detector type
674   // Return:
675   //   none.
676
677   if (nlay >= fNLayers || nlay < 0) {
678     AliError(Form("Wrong layer number (%d)",nlay));
679     return;
680   }
681   
682   phi0   = fLayPhi0[nlay];
683   r      = fLayRadii[nlay];
684   zlen   = fLayZLength[nlay];
685   nstav  = fStavPerLay[nlay];
686   nmod   = fUnitPerStave[nlay];
687   width  = fStaveWidth[nlay];
688   tilt   = fStaveTilt[nlay];
689   lthick = fStaveThick[nlay];
690   dthick = fDetThick[nlay];
691   dettype= fChipTypeID[nlay];
692 }
693
694 //______________________________________________________________________
695 TGeoVolume* AliITSUv1::CreateWrapperVolume(Int_t id)
696 {
697   //     Creates an air-filled wrapper cylindrical volume 
698   // Inputs:
699   //          volume id
700   // Outputs:
701   //          the wrapper volume
702
703   if (fWrapRMin[id]<0 || fWrapRMax[id]<0 || fWrapZSpan[id]<0) AliFatal(Form("Wrapper volume %d was requested but not defined",id));
704   // Now create the actual shape and volume
705   //
706   TGeoTube *tube = new TGeoTube(fWrapRMin[id], fWrapRMax[id], fWrapZSpan[id]/2.);
707
708   TGeoMedium *medAir = gGeoManager->GetMedium("ITS_AIR$");
709
710   char volnam[30];
711   snprintf(volnam, 29, "%s%d", AliITSUGeomTGeo::GetITSWrapVolPattern(),id);
712
713   TGeoVolume *wrapper = new TGeoVolume(volnam, tube, medAir);
714
715   return wrapper;
716 }
717
718 //______________________________________________________________________
719 void AliITSUv1::Init()
720 {
721   //     Initialise the ITS after it has been created.
722   UpdateInternalGeometry();
723   AliITSU::Init();
724   //  
725 }
726
727 //______________________________________________________________________
728 Bool_t AliITSUv1::IsLayerTurbo(Int_t nlay)
729 {
730   //     Returns true if the layer is a "turbo" layer
731   if ( nlay < 0 || nlay > fNLayers ) {
732     AliError(Form("Wrong layer number %d",nlay));
733     return kFALSE;
734   } 
735   else return fUpGeom[nlay]->IsTurbo();
736 }
737
738 //______________________________________________________________________
739 void AliITSUv1::SetDefaults()
740 {
741   // sets the default segmentation, response, digit and raw cluster classes
742 }
743
744 //______________________________________________________________________
745 void AliITSUv1::StepManager()
746 {
747   //    Called for every step in the ITS, then calles the AliITSUHit class
748   // creator with the information to be recoreded about that hit.
749   //     The value of the macro ALIITSPRINTGEOM if set to 1 will allow the
750   // printing of information to a file which can be used to create a .det
751   // file read in by the routine CreateGeometry(). If set to 0 or any other
752   // value except 1, the default behavior, then no such file is created nor
753   // it the extra variables and the like used in the printing allocated.
754   // Inputs:
755   //   none.
756   // Outputs:
757   //   none.
758   // Return:
759   //   none.
760   //
761   if(!(this->IsActive())) return;
762   if(!(gMC->TrackCharge())) return;
763   //
764   Int_t copy, lay = 0;
765   Int_t id = gMC->CurrentVolID(copy);
766
767   Bool_t notSens = kFALSE;
768   while ((lay<fNLayers)  && (notSens = (id!=fIdSens[lay]))) ++lay;
769   //printf("R: %.1f | Lay: %d  NotSens: %d\n",positionRS.Pt(), lay, notSens);
770            
771   if (notSens) return;
772   //
773   if (lay < 0 || lay >= fNLayers) {
774     AliError(Form("Invalid value: lay=%d. Not an ITS sensitive volume",lay));
775     return; // not an ITS sensitive volume.
776   } 
777   //
778   static TLorentzVector position, momentum; // Saves on calls to construtors
779   static AliITSUHit hit;// Saves on calls to constructors
780   //
781   TClonesArray &lhits = *(Hits());
782   Int_t chipID, status = 0;
783   //
784   // Track status
785   if(gMC->IsTrackInside())      status +=  1;
786   if(gMC->IsTrackEntering())    status +=  2;
787   if(gMC->IsTrackExiting()) {
788     AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS);
789     status +=  4;
790   } // if Outer ITS mother Volume
791   if(gMC->IsTrackOut())         status +=  8;
792   if(gMC->IsTrackDisappeared()) status += 16;
793   if(gMC->IsTrackStop())        status += 32;
794   if(gMC->IsTrackAlive())       status += 64;
795   //
796   // retrieve the indices with the volume path
797   //
798   gMC->TrackPosition(position);
799   int chip=-1,module=-1,sstave=-1,stave=-1,level=0; // volume copies on different levels
800   gMC->CurrentVolOffID(++level,chip);
801   if (fGeomTGeo->GetNModules(lay)>0)    gMC->CurrentVolOffID(++level,module);
802   if (fGeomTGeo->GetNHalfStaves(lay)>0) gMC->CurrentVolOffID(++level,sstave);
803   gMC->CurrentVolOffID(++level,stave);
804   //
805   chipID = fGeomTGeo->GetChipIndex(lay,stave,sstave,module,chip);
806   // Fill hit structure.
807   //
808   hit.SetChip(chipID);
809   hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
810   gMC->TrackPosition(position);
811   gMC->TrackMomentum(momentum);
812   hit.SetPosition(position);
813   hit.SetTime(gMC->TrackTime());
814   hit.SetMomentum(momentum);
815   hit.SetStatus(status);
816   hit.SetEdep(gMC->Edep());
817   hit.SetShunt(GetIshunt());
818   if(gMC->IsTrackEntering()){
819     hit.SetStartPosition(position);
820     hit.SetStartTime(gMC->TrackTime());
821     hit.SetStartStatus(status);
822     return; // don't save entering hit.
823   } // end if IsEntering
824     // Fill hit structure with this new hit.
825     //Info("StepManager","Calling Copy Constructor");
826   new(lhits[fNhits++]) AliITSUHit(hit); // Use Copy Construtor.
827   // Save old position... for next hit.
828   hit.SetStartPosition(position);
829   hit.SetStartTime(gMC->TrackTime());
830   hit.SetStartStatus(status);
831
832   return;
833 }
834
835 //______________________________________________________________________
836 void AliITSUv1::SetLayerChipTypeID(Int_t lr, UInt_t id)
837 {
838   // set det type
839   if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
840   fChipTypeID[lr] = id;
841 }
842
843 //______________________________________________________________________
844 Int_t AliITSUv1::GetLayerChipTypeID(Int_t lr)
845 {
846   // set det type
847   if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
848   return fChipTypeID[lr];
849 }