1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 /* $Id: AliITSUv1.cxx */
20 //========================================================================
22 // Geometry for the Upgrade of the Inner Tracking System
24 // Mario Sitta (sitta@to.infn.it)
25 // Chinorat Kobdaj (kobdaj@g.sut.ac.th)
27 //========================================================================
31 // $Log: AliITSUv1.cxx,v $
33 #include <TClonesArray.h>
34 #include <TGeoGlobalMagField.h>
35 #include <TGeoManager.h>
36 #include <TGeoMatrix.h>
37 #include <TGeoPhysicalNode.h>
38 #include <TGeoVolume.h>
41 #include <TLorentzVector.h>
43 #include <TVirtualMC.h>
46 #include "AliITSUHit.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;
62 //______________________________________________________________________
63 AliITSUv1::AliITSUv1()
82 ,fStaveModelIB(kIBModel0)
83 ,fStaveModelOB(kOBModel0)
85 // Standard default constructor
94 //______________________________________________________________________
95 AliITSUv1::AliITSUv1(const char *title,const Int_t nlay)
115 ,fStaveModelIB(kIBModel0)
116 ,fStaveModelOB(kOBModel0)
118 // Standard constructor for the Upgrade geometry.
120 // const char * name Ignored, set to "ITS"
121 // const char * title Arbitrary title
122 // const Int_t nlay Number of layers
124 fLayerName = new TString[fNLayers];
126 for (Int_t j=0; j<fNLayers; j++)
127 fLayerName[j].Form("%s%d",AliITSUGeomTGeo::GetITSSensorPattern(),j); // See AliITSUv1Layer
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];
143 fUpGeom = new AliITSUv1Layer*[fNLayers];
145 if (fNLayers > 0) { // if not, we'll Fatal-ize in CreateGeometry
146 for (Int_t j=0; j<fNLayers; j++) {
151 fUnitPerStave[j] = 0;
161 //______________________________________________________________________
162 AliITSUv1::~AliITSUv1() {
163 // Standard destructor
173 delete [] fLayZLength;
174 delete [] fStavPerLay;
175 delete [] fUnitPerStave;
176 delete [] fStaveThick;
177 delete [] fStaveWidth;
178 delete [] fStaveTilt;
180 delete [] fChipTypeID;
181 delete [] fBuildLevel;
185 delete [] fWrapZSpan;
186 delete [] fLay2WrapV;
189 //______________________________________________________________________
190 void AliITSUv1::AddAlignableVolumes() const
192 // Creates entries for alignable volumes associating the symbolic volume
193 // name with the corresponding volume path.
195 // Records in the alignable entries the transformation matrices converting
196 // TGeo local coordinates (in the RS of alignable volumes) to the tracking
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");
202 if (!gGeoManager) { AliFatal("TGeoManager doesn't exist !"); return; }
204 TString path = Form("ALIC_1/%s_2",AliITSUGeomTGeo::GetITSVolPattern());
205 TString sname = AliITSUGeomTGeo::ComposeSymNameITS();
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()));
212 for (int lr=0; lr<fNLayers; lr++) AddAlignableVolumesLayer(lr,path,lastUID);
216 //______________________________________________________________________
217 void AliITSUv1::AddAlignableVolumesLayer(int lr, TString& parent,Int_t &lastUID) const
219 // add alignable volumes for layer and its daughters
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()));
228 const AliITSUv1Layer* lrobj = fUpGeom[lr];
229 int nstaves = lrobj->GetNStavesPerParent();
230 for (int st=0; st<nstaves; st++) AddAlignableVolumesStave(lr,st,path,lastUID);
234 //______________________________________________________________________
235 void AliITSUv1::AddAlignableVolumesStave(int lr, int st, TString& parent, Int_t &lastUID) const
237 // add alignable volumes for stave and its daughters
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()));
245 const AliITSUv1Layer* lrobj = fUpGeom[lr];
246 int nsstave = lrobj->GetNHalfStavesPerParent();
247 int start = nsstave>0 ? 0:-1;
249 for (int sst=start; sst<nsstave; sst++) AddAlignableVolumesHalfStave(lr,st,sst,path,lastUID);
252 //______________________________________________________________________
253 void AliITSUv1::AddAlignableVolumesHalfStave(int lr, int st, int sst, TString& parent, Int_t &lastUID) const
255 // add alignable volumes for halfstave (if any) and its daughters
257 TString path = parent;
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()));
266 const AliITSUv1Layer* lrobj = fUpGeom[lr];
267 int nmodules = lrobj->GetNModulesPerParent();
268 int start = nmodules>0 ? 0:-1;
270 for (int md=start; md<nmodules; md++) AddAlignableVolumesModule(lr,st,sst,md,path,lastUID);
273 //______________________________________________________________________
274 void AliITSUv1::AddAlignableVolumesModule(int lr, int st, int sst, int md, TString& parent, Int_t &lastUID) const
276 // add alignable volumes for module (if any) and its daughters
278 TString path = parent;
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()));
288 const AliITSUv1Layer* lrobj = fUpGeom[lr];
289 int nchips = lrobj->GetNChipsPerParent();
291 for (int ic=0; ic<nchips; ic++) AddAlignableVolumesChip(lr,st,sst,md,ic,path,lastUID);
294 //______________________________________________________________________
295 void AliITSUv1::AddAlignableVolumesChip(int lr, int st, int sst, int md, int ch, TString& parent, Int_t &lastUID) const
297 // add alignable volumes for chip
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++ );
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));
309 //______________________________________________________________________
310 void AliITSUv1::SetNWrapVolumes(Int_t n)
312 // book arrays for wrapper volumes
313 if (fNWrapVol) AliFatal(Form("%d wrapper volumes already defined",fNWrapVol));
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;
323 //______________________________________________________________________
324 void AliITSUv1::DefineWrapVolume(Int_t id, Double_t rmin,Double_t rmax, Double_t zspan)
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;
333 //______________________________________________________________________
334 void AliITSUv1::CreateGeometry() {
336 // Create the geometry and insert it in the mother volume ITSV
337 TGeoManager *geoManager = gGeoManager;
339 TGeoVolume *vALIC = geoManager->GetVolume("ALIC");
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
346 const Int_t kLength=100;
347 Char_t vstrng[kLength] = "xxxRS"; //?
348 vITSV->SetTitle(vstrng);
350 // Check that we have all needed parameters
351 if (fNLayers <= 0) AliFatal(Form("Wrong number of layers (%d)",fNLayers));
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]));
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]));
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));
370 } // for (Int_t j=0; j<fNLayers; j++)
372 // Create the wrapper volumes
373 TGeoVolume **wrapVols = 0;
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);
382 fLay2WrapV = new Int_t[fNLayers];
384 // Now create the actual geometry
385 for (Int_t j=0; j<fNLayers; j++) {
386 TGeoVolume* dest = vITSV;
390 fUpGeom[j] = new AliITSUv1Layer(j,kTRUE,kFALSE);
391 fUpGeom[j]->SetStaveWidth(fStaveWidth[j]);
392 fUpGeom[j]->SetStaveTilt(fStaveTilt[j]);
394 else fUpGeom[j] = new AliITSUv1Layer(j,kFALSE);
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]);
404 fUpGeom[j]->SetStaveModel(fStaveModelIB);
406 fUpGeom[j]->SetStaveModel(fStaveModelOB);
407 AliDebug(1,Form("fBuildLevel: %d\n",fBuildLevel[j]));
409 if (fStaveThick[j] != 0) fUpGeom[j]->SetStaveThick(fStaveThick[j]);
410 if (fDetThick[j] != 0) fUpGeom[j]->SetSensorThick(fDetThick[j]);
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));
422 fUpGeom[j]->CreateLayer(dest);
424 delete[] wrapVols; // delete pointer only, not the volumes
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,
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.
446 Int_t ifield = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
447 Float_t fieldm = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
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"
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"
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"
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;
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;
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;
486 AliMixture(1,"AIR$",aAir,zAir,dAir,4,wAir);
487 AliMedium(1, "AIR$",1,0,ifield,fieldm,tmaxfdAir,stemaxAir,deemaxAir,epsilAir,stminAir);
489 AliMixture(2,"WATER$",aWater,zWater,dWater,2,wWater);
490 AliMedium(2, "WATER$",2,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
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);
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);
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);
502 // needed for STAVE , Carbon, kapton, Epoxy, flexcable
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);
508 AliMixture(7,"KAPTON(POLYCH2)$", aKapton, zKapton, dKapton, 4, wKapton);
509 AliMedium(7, "KAPTON(POLYCH2)$",7,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
513 // values below modified as compared to source AliITSv11 !
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);
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);
524 AliMaterial(9,"M60J3K$",12.0107,6,2.21,999,999);
525 AliMedium(9, "M60J3K$",9,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
527 AliMaterial(10,"M55J6K$",12.0107,6,1.63,999,999);
528 AliMedium(10, "M55J6K$",10,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
530 AliMaterial(11,"T300$",12.0107,6,1.725,999,999);
531 AliMedium(11, "T300$",11,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
533 AliMaterial(12,"FGS003$",12.0107,6,1.6,999,999);
534 AliMedium(12, "FGS003$",12,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
536 AliMaterial(13,"CarbonFleece$",12.0107,6,0.4,999,999);
537 AliMedium(13, "CarbonFleece$",13,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
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
547 AliMixture(14,"FLEXCABLE$",aFCm,zFCm,dFCm,5,wFCm);
548 AliMedium(14, "FLEXCABLE$",14,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
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);
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)
562 // Sets the layer parameters
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)
574 // buildLevel (if 0, all geometry is build, used for material budget studies)
580 if (nlay >= fNLayers || nlay < 0) {
581 AliError(Form("Wrong layer number (%d)",nlay));
585 fLayTurbo[nlay] = kFALSE;
586 fLayPhi0[nlay] = phi0;
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;
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)
604 // Sets the layer parameters for a "turbo" layer
605 // (i.e. a layer whose staves overlap in phi)
608 // phi0 phi of 1st stave
611 // nstav number of staves
612 // nunit IB: number of chips per stave
613 // OB: number of modules per half stave
615 // tilt layer tilt angle (degrees)
616 // lthick stave thickness (if omitted, defaults to 0)
617 // dthick detector thickness (if omitted, defaults to 0)
619 // buildLevel (if 0, all geometry is build, used for material budget studies)
625 if (nlay >= fNLayers || nlay < 0) {
626 AliError(Form("Wrong layer number (%d)",nlay));
630 fLayTurbo[nlay] = kTRUE;
631 fLayPhi0[nlay] = phi0;
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;
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 <hick, Double_t &dthick,
651 UInt_t &dettype) const
653 // Gets the layer parameters
657 // phi0 phi of 1st stave
660 // nstav number of staves
661 // nmod IB: number of chips per stave
662 // OB: number of modules per half stave
664 // tilt stave tilt angle
665 // lthick stave thickness
666 // dthick detector thickness
667 // dettype detector type
671 if (nlay >= fNLayers || nlay < 0) {
672 AliError(Form("Wrong layer number (%d)",nlay));
676 phi0 = fLayPhi0[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];
688 //______________________________________________________________________
689 TGeoVolume* AliITSUv1::CreateWrapperVolume(Int_t id)
691 // Creates an air-filled wrapper cylindrical volume
695 // the wrapper volume
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
700 TGeoTube *tube = new TGeoTube(fWrapRMin[id], fWrapRMax[id], fWrapZSpan[id]/2.);
702 TGeoMedium *medAir = gGeoManager->GetMedium("ITS_AIR$");
705 snprintf(volnam, 29, "%s%d", AliITSUGeomTGeo::GetITSWrapVolPattern(),id);
707 TGeoVolume *wrapper = new TGeoVolume(volnam, tube, medAir);
712 //______________________________________________________________________
713 void AliITSUv1::Init()
715 // Initialise the ITS after it has been created.
716 UpdateInternalGeometry();
721 //______________________________________________________________________
722 Bool_t AliITSUv1::IsLayerTurbo(Int_t nlay)
724 // Returns true if the layer is a "turbo" layer
725 if ( nlay < 0 || nlay > fNLayers ) {
726 AliError(Form("Wrong layer number %d",nlay));
729 else return fUpGeom[nlay]->IsTurbo();
732 //______________________________________________________________________
733 void AliITSUv1::SetDefaults()
735 // sets the default segmentation, response, digit and raw cluster classes
738 //______________________________________________________________________
739 void AliITSUv1::StepManager()
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.
755 if(!(this->IsActive())) return;
756 if(!(gMC->TrackCharge())) return;
759 Int_t id = gMC->CurrentVolID(copy);
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);
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.
772 static TLorentzVector position, momentum; // Saves on calls to construtors
773 static AliITSUHit hit;// Saves on calls to constructors
775 TClonesArray &lhits = *(Hits());
776 Int_t chipID, status = 0;
779 if(gMC->IsTrackInside()) status += 1;
780 if(gMC->IsTrackEntering()) status += 2;
781 if(gMC->IsTrackExiting()) {
782 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS);
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;
790 // retrieve the indices with the volume path
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);
799 chipID = fGeomTGeo->GetChipIndex(lay,stave,sstave,module,chip);
800 // Fill hit structure.
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);
829 //______________________________________________________________________
830 void AliITSUv1::SetLayerChipTypeID(Int_t lr, UInt_t id)
833 if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
834 fChipTypeID[lr] = id;
837 //______________________________________________________________________
838 Int_t AliITSUv1::GetLayerChipTypeID(Int_t lr)
841 if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
842 return fChipTypeID[lr];