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, 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 fChipThick = new Double_t[fNLayers];
136 fStaveWidth = new Double_t[fNLayers];
137 fStaveTilt = new Double_t[fNLayers];
138 fSensThick = 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 [] fChipThick;
177 delete [] fStaveWidth;
178 delete [] fStaveTilt;
179 delete [] fSensThick;
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 (fChipThick[j] < 0) AliFatal(Form("Wrong chip thickness for layer %d (%f)",j,fChipThick[j]));
359 if (fLayTurbo[j] && fStaveWidth[j] <= 0) AliFatal(Form("Wrong stave width for layer %d (%f)",j,fStaveWidth[j]));
360 if (fSensThick[j] < 0) AliFatal(Form("Wrong sensor thickness for layer %d (%f)",j,fSensThick[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 (fChipThick[j] == 0) AliInfo(Form("Chip thickness for layer %d not set, using default",j));
368 if (fSensThick[j] == 0) AliInfo(Form("Sensor 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 (fChipThick[j] != 0) fUpGeom[j]->SetChipThick(fChipThick[j]);
410 if (fSensThick[j] != 0) fUpGeom[j]->SetSensorThick(fSensThick[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 CreateSuppCyl(kTRUE,wrapVols[0]);
425 CreateSuppCyl(kFALSE,wrapVols[2]);
427 delete[] wrapVols; // delete pointer only, not the volumes
431 //____________________________________________________________
433 void AliITSUv1::CreateSuppCyl(const Bool_t innerBarrel,TGeoVolume *dest,const TGeoManager *mgr){
434 // Creates the Service Barrel (as a simple cylinder) for IB and OB
436 // innerBarrel : if true, build IB service barrel, otherwise for OB
437 // dest : the mother volume holding the service barrel
438 // mgr : the gGeoManager pointer (used to get the material)
441 Double_t rminIB = 4.7;
442 Double_t rminOB = 43.4;
444 Double_t cInt = 0.22; //dimensioni cilindro di supporto interno
445 Double_t cExt = 1.00; //dimensioni cilindro di supporto esterno
446 // Double_t phi1 = 180;
447 // Double_t phi2 = 360;
450 TGeoMedium *medCarbonFleece = mgr->GetMedium("ITS_CarbonFleece$");
453 zLenOB=((TGeoTube*)(dest->GetShape()))->GetDz();
454 // TGeoTube*ibSuppSh = new TGeoTubeSeg(rminIB,rminIB+cInt,zLenOB,phi1,phi2);
455 TGeoTube*ibSuppSh = new TGeoTube(rminIB,rminIB+cInt,zLenOB);
456 TGeoVolume *ibSupp = new TGeoVolume("ibSuppCyl",ibSuppSh,medCarbonFleece);
457 dest->AddNode(ibSupp,1);
460 zLenOB=((TGeoTube*)(dest->GetShape()))->GetDz();
461 TGeoTube*obSuppSh=new TGeoTube(rminOB,rminOB+cExt,zLenOB);
462 TGeoVolume *obSupp=new TGeoVolume("obSuppCyl",obSuppSh,medCarbonFleece);
463 dest->AddNode(obSupp,1);
469 //______________________________________________________________________
470 void AliITSUv1::CreateMaterials() {
471 // Create ITS materials
472 // This function defines the default materials used in the Geant
473 // Monte Carlo simulations for the geometries AliITSv1, AliITSv3,
475 // In general it is automatically replaced by
476 // the CreateMaterials routine defined in AliITSv?. Should the function
477 // CreateMaterials not exist for the geometry version you are using this
478 // one is used. See the definition found in AliITSv5 or the other routine
479 // for a complete definition.
487 Int_t ifield = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
488 Float_t fieldm = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
490 Float_t tmaxfd = 0.1; // 1.0; // Degree
491 Float_t stemax = 1.0; // cm
492 Float_t deemax = 0.1; // 30.0; // Fraction of particle's energy 0<deemax<=1
493 Float_t epsil = 1.0E-4; // 1.0; // cm
494 Float_t stmin = 0.0; // cm "Default value used"
496 Float_t tmaxfdSi = 0.1; // .10000E+01; // Degree
497 Float_t stemaxSi = 0.0075; // .10000E+01; // cm
498 Float_t deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
499 Float_t epsilSi = 1.0E-4;// .10000E+01;
500 Float_t stminSi = 0.0; // cm "Default value used"
502 Float_t tmaxfdAir = 0.1; // .10000E+01; // Degree
503 Float_t stemaxAir = .10000E+01; // cm
504 Float_t deemaxAir = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
505 Float_t epsilAir = 1.0E-4;// .10000E+01;
506 Float_t stminAir = 0.0; // cm "Default value used"
509 Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
510 Float_t zAir[4]={6.,7.,8.,18.};
511 Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
512 Float_t dAir = 1.20479E-3;
515 Float_t aWater[2]={1.00794,15.9994};
516 Float_t zWater[2]={1.,8.};
517 Float_t wWater[2]={0.111894,0.888106};
518 Float_t dWater = 1.0;
522 Float_t aKapton[4]={1.00794,12.0107, 14.010,15.9994};
523 Float_t zKapton[4]={1.,6.,7.,8.};
524 Float_t wKapton[4]={0.026362,0.69113,0.07327,0.209235};
525 Float_t dKapton = 1.42;
527 AliMixture(1,"AIR$",aAir,zAir,dAir,4,wAir);
528 AliMedium(1, "AIR$",1,0,ifield,fieldm,tmaxfdAir,stemaxAir,deemaxAir,epsilAir,stminAir);
530 AliMixture(2,"WATER$",aWater,zWater,dWater,2,wWater);
531 AliMedium(2, "WATER$",2,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
533 AliMaterial(3,"SI$",0.28086E+02,0.14000E+02,0.23300E+01,0.93600E+01,0.99900E+03);
534 AliMedium(3, "SI$",3,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
536 AliMaterial(4,"BERILLIUM$",9.01, 4., 1.848, 35.3, 36.7);// From AliPIPEv3
537 AliMedium(4, "BERILLIUM$",4,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
539 AliMaterial(5,"COPPER$",0.63546E+02,0.29000E+02,0.89600E+01,0.14300E+01,0.99900E+03);
540 AliMedium(5, "COPPER$",5,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
543 // needed for STAVE , Carbon, kapton, Epoxy, flexcable
545 //AliMaterial(6,"CARBON$",12.0107,6,2.210,999,999);
546 AliMaterial(6,"CARBON$",12.0107,6,2.210/1.3,999,999);
547 AliMedium(6, "CARBON$",6,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
549 AliMixture(7,"KAPTON(POLYCH2)$", aKapton, zKapton, dKapton, 4, wKapton);
550 AliMedium(7, "KAPTON(POLYCH2)$",7,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
554 // values below modified as compared to source AliITSv11 !
556 //AliMaterial(7,"GLUE$",0.12011E+02,0.60000E+01,0.1930E+01/2.015,999,999); // original
557 AliMaterial(15,"GLUE$",12.011,6,1.93/2.015,999,999); // conform with ATLAS, Corrado, Stefan
558 AliMedium(15, "GLUE$",15,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
560 // All types of carbon
561 // Unidirectional prepreg
562 AliMaterial(8,"K13D2U2k$",12.0107,6,1.643,999,999);
563 AliMedium(8, "K13D2U2k$",8,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
564 AliMaterial(17,"K13D2U120$",12.0107,6,1.583,999,999);
565 AliMedium(17, "K13D2U120$",17,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
567 AliMaterial(9,"M60J3K$",12.0107,6,2.12,999,999);
568 AliMedium(9, "M60J3K$",9,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
570 AliMaterial(10,"M55J6K$",12.0107,6,1.63,999,999);
571 AliMedium(10, "M55J6K$",10,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
573 AliMaterial(11,"T300$",12.0107,6,1.725,999,999);
574 AliMedium(11, "T300$",11,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
576 AliMaterial(12,"FGS003$",12.0107,6,1.6,999,999);
577 AliMedium(12, "FGS003$",12,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
579 AliMaterial(13,"CarbonFleece$",12.0107,6,0.4,999,999);
580 AliMedium(13, "CarbonFleece$",13,0,ifield,fieldm,tmaxfdSi,stemaxSi,deemaxSi,epsilSi,stminSi);
583 Float_t aFCm[5]={12.0107,1.00794,14.0067,15.9994,26.981538};
584 Float_t zFCm[5]={6.,1.,7.,8.,13.};
585 Float_t wFCm[5]={0.520088819984,0.01983871336,0.0551367996,0.157399667056, 0.247536};
586 //Float_t dFCm = 1.6087; // original
587 //Float_t dFCm = 2.55; // conform with STAR
588 Float_t dFCm = 2.595; // conform with Corrado
590 AliMixture(14,"FLEXCABLE$",aFCm,zFCm,dFCm,5,wFCm);
591 AliMedium(14, "FLEXCABLE$",14,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
593 AliMaterial(16,"ALUMINUM$",0.26982E+02,0.13000E+02,0.26989E+01,0.89000E+01,0.99900E+03);
594 AliMedium(16,"ALUMINUM$",16,0,ifield,fieldm,tmaxfd,stemax,deemax,epsil,stmin);
598 //______________________________________________________________________
599 void AliITSUv1::DefineLayer(Int_t nlay, double phi0, Double_t r,
600 Double_t zlen, Int_t nstav,
601 Int_t nunit, Double_t lthick,
602 Double_t dthick, UInt_t dettypeID,
605 // Sets the layer parameters
611 // nstav number of staves
612 // nunit IB: number of chips per stave
613 // OB: number of modules per half stave
614 // lthick chip thickness (if omitted, defaults to 0)
615 // dthick sensor thickness (if omitted, defaults to 0)
617 // buildLevel (if 0, all geometry is build, used for material budget studies)
623 AliInfo(Form("L# %d Phi:%+.3f R:%+7.3f DZ:%7.2f Nst:%2d Nunit:%2d Lthick:%.4f Dthick:%.4f DetID:%d B:%d",
624 nlay,phi0,r,zlen,nstav,nunit,lthick,dthick,dettypeID,buildLevel));
626 if (nlay >= fNLayers || nlay < 0) {
627 AliError(Form("Wrong layer number (%d)",nlay));
631 fLayTurbo[nlay] = kFALSE;
632 fLayPhi0[nlay] = phi0;
634 fLayZLength[nlay] = zlen;
635 fStavPerLay[nlay] = nstav;
636 fUnitPerStave[nlay] = nunit;
637 fChipThick[nlay] = lthick;
638 fSensThick[nlay] = dthick;
639 fChipTypeID[nlay] = dettypeID;
640 fBuildLevel[nlay] = buildLevel;
644 //______________________________________________________________________
645 void AliITSUv1::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t zlen, Int_t nstav,
646 Int_t nunit, Double_t width, Double_t tilt,
647 Double_t lthick,Double_t dthick,
648 UInt_t dettypeID, Int_t buildLevel)
650 // Sets the layer parameters for a "turbo" layer
651 // (i.e. a layer whose staves overlap in phi)
654 // phi0 phi of 1st stave
657 // nstav number of staves
658 // nunit IB: number of chips per stave
659 // OB: number of modules per half stave
661 // tilt layer tilt angle (degrees)
662 // lthick chip thickness (if omitted, defaults to 0)
663 // dthick sensor thickness (if omitted, defaults to 0)
665 // buildLevel (if 0, all geometry is build, used for material budget studies)
671 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",
672 nlay,phi0,r,zlen,nstav,nunit,width,tilt,lthick,dthick,dettypeID,buildLevel));
674 if (nlay >= fNLayers || nlay < 0) {
675 AliError(Form("Wrong layer number (%d)",nlay));
679 fLayTurbo[nlay] = kTRUE;
680 fLayPhi0[nlay] = phi0;
682 fLayZLength[nlay] = zlen;
683 fStavPerLay[nlay] = nstav;
684 fUnitPerStave[nlay] = nunit;
685 fChipThick[nlay] = lthick;
686 fStaveWidth[nlay] = width;
687 fStaveTilt[nlay] = tilt;
688 fSensThick[nlay] = dthick;
689 fChipTypeID[nlay] = dettypeID;
690 fBuildLevel[nlay] = buildLevel;
694 //______________________________________________________________________
695 void AliITSUv1::GetLayerParameters(Int_t nlay, Double_t &phi0,
696 Double_t &r, Double_t &zlen,
697 Int_t &nstav, Int_t &nmod,
698 Double_t &width, Double_t &tilt,
699 Double_t <hick, Double_t &dthick,
700 UInt_t &dettype) const
702 // Gets the layer parameters
706 // phi0 phi of 1st stave
709 // nstav number of staves
710 // nmod IB: number of chips per stave
711 // OB: number of modules per half stave
713 // tilt stave tilt angle
714 // lthick chip thickness
715 // dthick sensor thickness
716 // dettype detector type
720 if (nlay >= fNLayers || nlay < 0) {
721 AliError(Form("Wrong layer number (%d)",nlay));
725 phi0 = fLayPhi0[nlay];
727 zlen = fLayZLength[nlay];
728 nstav = fStavPerLay[nlay];
729 nmod = fUnitPerStave[nlay];
730 width = fStaveWidth[nlay];
731 tilt = fStaveTilt[nlay];
732 lthick = fChipThick[nlay];
733 dthick = fSensThick[nlay];
734 dettype= fChipTypeID[nlay];
737 //______________________________________________________________________
738 TGeoVolume* AliITSUv1::CreateWrapperVolume(Int_t id)
740 // Creates an air-filled wrapper cylindrical volume
744 // the wrapper volume
746 if (fWrapRMin[id]<0 || fWrapRMax[id]<0 || fWrapZSpan[id]<0) AliFatal(Form("Wrapper volume %d was requested but not defined",id));
747 // Now create the actual shape and volume
749 TGeoTube *tube = new TGeoTube(fWrapRMin[id], fWrapRMax[id], fWrapZSpan[id]/2.);
751 TGeoMedium *medAir = gGeoManager->GetMedium("ITS_AIR$");
754 snprintf(volnam, 29, "%s%d", AliITSUGeomTGeo::GetITSWrapVolPattern(),id);
756 TGeoVolume *wrapper = new TGeoVolume(volnam, tube, medAir);
761 //______________________________________________________________________
762 void AliITSUv1::Init()
764 // Initialise the ITS after it has been created.
765 UpdateInternalGeometry();
770 //______________________________________________________________________
771 Bool_t AliITSUv1::IsLayerTurbo(Int_t nlay)
773 // Returns true if the layer is a "turbo" layer
774 if ( nlay < 0 || nlay > fNLayers ) {
775 AliError(Form("Wrong layer number %d",nlay));
778 else return fUpGeom[nlay]->IsTurbo();
781 //______________________________________________________________________
782 void AliITSUv1::SetDefaults()
784 // sets the default segmentation, response, digit and raw cluster classes
787 //______________________________________________________________________
788 void AliITSUv1::StepManager()
790 // Called for every step in the ITS, then calles the AliITSUHit class
791 // creator with the information to be recoreded about that hit.
792 // The value of the macro ALIITSPRINTGEOM if set to 1 will allow the
793 // printing of information to a file which can be used to create a .det
794 // file read in by the routine CreateGeometry(). If set to 0 or any other
795 // value except 1, the default behavior, then no such file is created nor
796 // it the extra variables and the like used in the printing allocated.
804 if(!(this->IsActive())) return;
805 if(!(TVirtualMC::GetMC()->TrackCharge())) return;
808 Int_t id = TVirtualMC::GetMC()->CurrentVolID(copy);
810 Bool_t notSens = kFALSE;
811 while ((lay<fNLayers) && (notSens = (id!=fIdSens[lay]))) ++lay;
812 //printf("R: %.1f | Lay: %d NotSens: %d\n",positionRS.Pt(), lay, notSens);
816 if (lay < 0 || lay >= fNLayers) {
817 AliError(Form("Invalid value: lay=%d. Not an ITS sensitive volume",lay));
818 return; // not an ITS sensitive volume.
821 static TLorentzVector position, momentum; // Saves on calls to construtors
822 static AliITSUHit hit;// Saves on calls to constructors
824 TClonesArray &lhits = *(Hits());
825 Int_t chipID, status = 0;
828 if(TVirtualMC::GetMC()->IsTrackInside()) status += 1;
829 if(TVirtualMC::GetMC()->IsTrackEntering()) status += 2;
830 if(TVirtualMC::GetMC()->IsTrackExiting()) {
831 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS);
833 } // if Outer ITS mother Volume
834 if(TVirtualMC::GetMC()->IsTrackOut()) status += 8;
835 if(TVirtualMC::GetMC()->IsTrackDisappeared()) status += 16;
836 if(TVirtualMC::GetMC()->IsTrackStop()) status += 32;
837 if(TVirtualMC::GetMC()->IsTrackAlive()) status += 64;
839 // retrieve the indices with the volume path
841 TVirtualMC::GetMC()->TrackPosition(position);
842 int chip=-1,module=-1,sstave=-1,stave=-1,level=0; // volume copies on different levels
843 TVirtualMC::GetMC()->CurrentVolOffID(++level,chip);
844 if (fGeomTGeo->GetNModules(lay)>0) TVirtualMC::GetMC()->CurrentVolOffID(++level,module);
845 if (fGeomTGeo->GetNHalfStaves(lay)>0) TVirtualMC::GetMC()->CurrentVolOffID(++level,sstave);
846 TVirtualMC::GetMC()->CurrentVolOffID(++level,stave);
848 chipID = fGeomTGeo->GetChipIndex(lay,stave,sstave,module,chip);
849 // Fill hit structure.
852 hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
853 TVirtualMC::GetMC()->TrackPosition(position);
854 TVirtualMC::GetMC()->TrackMomentum(momentum);
855 hit.SetPosition(position);
856 hit.SetTime(TVirtualMC::GetMC()->TrackTime());
857 hit.SetMomentum(momentum);
858 hit.SetStatus(status);
859 hit.SetEdep(TVirtualMC::GetMC()->Edep());
860 hit.SetShunt(GetIshunt());
861 if(TVirtualMC::GetMC()->IsTrackEntering()){
862 hit.SetStartPosition(position);
863 hit.SetStartTime(TVirtualMC::GetMC()->TrackTime());
864 hit.SetStartStatus(status);
865 return; // don't save entering hit.
866 } // end if IsEntering
867 // Fill hit structure with this new hit.
868 //Info("StepManager","Calling Copy Constructor");
869 new(lhits[fNhits++]) AliITSUHit(hit); // Use Copy Construtor.
870 // Save old position... for next hit.
871 hit.SetStartPosition(position);
872 hit.SetStartTime(TVirtualMC::GetMC()->TrackTime());
873 hit.SetStartStatus(status);
878 //______________________________________________________________________
879 void AliITSUv1::SetLayerChipTypeID(Int_t lr, UInt_t id)
882 if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
883 fChipTypeID[lr] = id;
886 //______________________________________________________________________
887 Int_t AliITSUv1::GetLayerChipTypeID(Int_t lr)
890 if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
891 return fChipTypeID[lr];