]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/UPGRADE/AliITSUv1.cxx
Fixing a memory leak
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSUv1.cxx
CommitLineData
b705c75b 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"
57using namespace TMath;
58
59
60ClassImp(AliITSUv1)
61
62//______________________________________________________________________
63AliITSUv1::AliITSUv1()
64: fNWrapVol(0)
65 ,fWrapRMin(0)
66 ,fWrapRMax(0)
67 ,fWrapZSpan(0)
c55b10c2 68 ,fLay2WrapV(0)
b705c75b 69 ,fLayTurbo(0)
70 ,fLayPhi0(0)
71 ,fLayRadii(0)
72 ,fLayZLength(0)
852af72e 73 ,fStavPerLay(0)
c55b10c2 74 ,fUnitPerStave(0)
75 ,fStaveThick(0)
76 ,fStaveWidth(0)
77 ,fStaveTilt(0)
b705c75b 78 ,fDetThick(0)
852af72e 79 ,fChipTypeID(0)
b705c75b 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//______________________________________________________________________
34e8fe1d 95AliITSUv1::AliITSUv1(const char *title, Int_t nlay)
b705c75b 96 :AliITSU(title,nlay)
97 ,fNWrapVol(0)
98 ,fWrapRMin(0)
99 ,fWrapRMax(0)
100 ,fWrapZSpan(0)
c55b10c2 101 ,fLay2WrapV(0)
b705c75b 102 ,fLayTurbo(0)
103 ,fLayPhi0(0)
104 ,fLayRadii(0)
105 ,fLayZLength(0)
852af72e 106 ,fStavPerLay(0)
c55b10c2 107 ,fUnitPerStave(0)
108 ,fStaveThick(0)
109 ,fStaveWidth(0)
110 ,fStaveTilt(0)
b705c75b 111 ,fDetThick(0)
852af72e 112 ,fChipTypeID(0)
b705c75b 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 //
c55b10c2 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];
b705c75b 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++) {
c55b10c2 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;
b705c75b 157 }
158 }
159}
160
161//______________________________________________________________________
162AliITSUv1::~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;
852af72e 174 delete [] fStavPerLay;
c55b10c2 175 delete [] fUnitPerStave;
176 delete [] fStaveThick;
177 delete [] fStaveWidth;
178 delete [] fStaveTilt;
b705c75b 179 delete [] fDetThick;
852af72e 180 delete [] fChipTypeID;
b705c75b 181 delete [] fBuildLevel;
182 delete [] fUpGeom;
183 delete [] fWrapRMin;
184 delete [] fWrapRMax;
185 delete [] fWrapZSpan;
c55b10c2 186 delete [] fLay2WrapV;
b705c75b 187}
188
189//______________________________________________________________________
c55b10c2 190void AliITSUv1::AddAlignableVolumes() const
191{
b705c75b 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.
b705c75b 200 AliInfo("Add ITS alignable volumes");
201
202 if (!gGeoManager) { AliFatal("TGeoManager doesn't exist !"); return; }
b705c75b 203 //
c55b10c2 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//______________________________________________________________________
217void 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//______________________________________________________________________
235void 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()));
b705c75b 244 //
c55b10c2 245 const AliITSUv1Layer* lrobj = fUpGeom[lr];
246 int nsstave = lrobj->GetNHalfStavesPerParent();
247 int start = nsstave>0 ? 0:-1;
b705c75b 248 //
c55b10c2 249 for (int sst=start; sst<nsstave; sst++) AddAlignableVolumesHalfStave(lr,st,sst,path,lastUID);
250}
251
252//______________________________________________________________________
253void 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()));
b705c75b 264 //
c55b10c2 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//______________________________________________________________________
274void 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()));
b705c75b 285 //
b705c75b 286 }
287 //
c55b10c2 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//______________________________________________________________________
295void 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 //
b705c75b 307}
308
309//______________________________________________________________________
310void 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//______________________________________________________________________
324void 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//______________________________________________________________________
334void 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++) {
c55b10c2 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]));
b705c75b 361 //
362 if (j > 0) {
c55b10c2 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]));
b705c75b 365 } // if (j > 0)
366
c55b10c2 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));
b705c75b 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 //
c55b10c2 382 fLay2WrapV = new Int_t[fNLayers];
383
b705c75b 384 // Now create the actual geometry
385 for (Int_t j=0; j<fNLayers; j++) {
386 TGeoVolume* dest = vITSV;
c55b10c2 387 fLay2WrapV[j] = -1;
b705c75b 388 //
389 if (fLayTurbo[j]) {
390 fUpGeom[j] = new AliITSUv1Layer(j,kTRUE,kFALSE);
c55b10c2 391 fUpGeom[j]->SetStaveWidth(fStaveWidth[j]);
392 fUpGeom[j]->SetStaveTilt(fStaveTilt[j]);
b705c75b 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]);
852af72e 399 fUpGeom[j]->SetNStaves(fStavPerLay[j]);
c55b10c2 400 fUpGeom[j]->SetNUnits(fUnitPerStave[j]);
852af72e 401 fUpGeom[j]->SetChipType(fChipTypeID[j]);
b705c75b 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 //
c55b10c2 409 if (fStaveThick[j] != 0) fUpGeom[j]->SetStaveThick(fStaveThick[j]);
410 if (fDetThick[j] != 0) fUpGeom[j]->SetSensorThick(fDetThick[j]);
b705c75b 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];
c55b10c2 418 fLay2WrapV[j] = iw;
2b9468b2 419 break;
b705c75b 420 }
421 }
422 fUpGeom[j]->CreateLayer(dest);
423 }
9545fc92 424 delete[] wrapVols; // delete pointer only, not the volumes
b705c75b 425 //
426}
427
428//______________________________________________________________________
429void 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//______________________________________________________________________
34e8fe1d 556void AliITSUv1::DefineLayer(Int_t nlay, double phi0, Double_t r,
557 Double_t zlen, Int_t nstav,
558 Int_t nunit, Double_t lthick,
559 Double_t dthick, UInt_t dettypeID,
560 Int_t buildLevel)
b705c75b 561{
562 // Sets the layer parameters
563 // Inputs:
564 // nlay layer number
565 // phi0 layer phi0
566 // r layer radius
567 // zlen layer length
852af72e 568 // nstav number of staves
c55b10c2 569 // nunit IB: number of chips per stave
570 // OB: number of modules per half stave
852af72e 571 // lthick stave thickness (if omitted, defaults to 0)
b705c75b 572 // dthick detector thickness (if omitted, defaults to 0)
c55b10c2 573 // dettypeID ??
b705c75b 574 // buildLevel (if 0, all geometry is build, used for material budget studies)
575 // Outputs:
576 // none.
577 // Return:
578 // none.
2b9468b2 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
b705c75b 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;
852af72e 592 fStavPerLay[nlay] = nstav;
c55b10c2 593 fUnitPerStave[nlay] = nunit;
594 fStaveThick[nlay] = lthick;
b705c75b 595 fDetThick[nlay] = dthick;
852af72e 596 fChipTypeID[nlay] = dettypeID;
b705c75b 597 fBuildLevel[nlay] = buildLevel;
598
599}
600
601//______________________________________________________________________
852af72e 602void AliITSUv1::DefineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Double_t zlen, Int_t nstav,
c55b10c2 603 Int_t nunit, Double_t width, Double_t tilt,
b705c75b 604 Double_t lthick,Double_t dthick,
605 UInt_t dettypeID, Int_t buildLevel)
606{
607 // Sets the layer parameters for a "turbo" layer
852af72e 608 // (i.e. a layer whose staves overlap in phi)
b705c75b 609 // Inputs:
610 // nlay layer number
852af72e 611 // phi0 phi of 1st stave
b705c75b 612 // r layer radius
613 // zlen layer length
852af72e 614 // nstav number of staves
c55b10c2 615 // nunit IB: number of chips per stave
616 // OB: number of modules per half stave
852af72e 617 // width stave width
b705c75b 618 // tilt layer tilt angle (degrees)
852af72e 619 // lthick stave thickness (if omitted, defaults to 0)
b705c75b 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
2b9468b2 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
b705c75b 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;
852af72e 640 fStavPerLay[nlay] = nstav;
c55b10c2 641 fUnitPerStave[nlay] = nunit;
642 fStaveThick[nlay] = lthick;
643 fStaveWidth[nlay] = width;
644 fStaveTilt[nlay] = tilt;
b705c75b 645 fDetThick[nlay] = dthick;
852af72e 646 fChipTypeID[nlay] = dettypeID;
b705c75b 647 fBuildLevel[nlay] = buildLevel;
648
649}
650
651//______________________________________________________________________
652void AliITSUv1::GetLayerParameters(Int_t nlay, Double_t &phi0,
653 Double_t &r, Double_t &zlen,
852af72e 654 Int_t &nstav, Int_t &nmod,
b705c75b 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:
852af72e 663 // phi0 phi of 1st stave
b705c75b 664 // r layer radius
665 // zlen layer length
852af72e 666 // nstav number of staves
c55b10c2 667 // nmod IB: number of chips per stave
668 // OB: number of modules per half stave
852af72e 669 // width stave width
670 // tilt stave tilt angle
671 // lthick stave thickness
b705c75b 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];
852af72e 685 nstav = fStavPerLay[nlay];
c55b10c2 686 nmod = fUnitPerStave[nlay];
687 width = fStaveWidth[nlay];
688 tilt = fStaveTilt[nlay];
689 lthick = fStaveThick[nlay];
b705c75b 690 dthick = fDetThick[nlay];
852af72e 691 dettype= fChipTypeID[nlay];
b705c75b 692}
693
694//______________________________________________________________________
695TGeoVolume* 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//______________________________________________________________________
719void AliITSUv1::Init()
720{
721 // Initialise the ITS after it has been created.
722 UpdateInternalGeometry();
723 AliITSU::Init();
724 //
725}
726
727//______________________________________________________________________
728Bool_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//______________________________________________________________________
739void AliITSUv1::SetDefaults()
740{
741 // sets the default segmentation, response, digit and raw cluster classes
742}
743
744//______________________________________________________________________
745void 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.
c55b10c2 760 //
b705c75b 761 if(!(this->IsActive())) return;
2942f542 762 if(!(TVirtualMC::GetMC()->TrackCharge())) return;
b705c75b 763 //
764 Int_t copy, lay = 0;
2942f542 765 Int_t id = TVirtualMC::GetMC()->CurrentVolID(copy);
b705c75b 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;
c55b10c2 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 //
b705c75b 778 static TLorentzVector position, momentum; // Saves on calls to construtors
779 static AliITSUHit hit;// Saves on calls to constructors
c55b10c2 780 //
b705c75b 781 TClonesArray &lhits = *(Hits());
c55b10c2 782 Int_t chipID, status = 0;
b705c75b 783 //
784 // Track status
2942f542 785 if(TVirtualMC::GetMC()->IsTrackInside()) status += 1;
786 if(TVirtualMC::GetMC()->IsTrackEntering()) status += 2;
787 if(TVirtualMC::GetMC()->IsTrackExiting()) {
c55b10c2 788 AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kITS);
789 status += 4;
790 } // if Outer ITS mother Volume
2942f542 791 if(TVirtualMC::GetMC()->IsTrackOut()) status += 8;
792 if(TVirtualMC::GetMC()->IsTrackDisappeared()) status += 16;
793 if(TVirtualMC::GetMC()->IsTrackStop()) status += 32;
794 if(TVirtualMC::GetMC()->IsTrackAlive()) status += 64;
b705c75b 795 //
796 // retrieve the indices with the volume path
797 //
2942f542 798 TVirtualMC::GetMC()->TrackPosition(position);
c55b10c2 799 int chip=-1,module=-1,sstave=-1,stave=-1,level=0; // volume copies on different levels
2942f542 800 TVirtualMC::GetMC()->CurrentVolOffID(++level,chip);
801 if (fGeomTGeo->GetNModules(lay)>0) TVirtualMC::GetMC()->CurrentVolOffID(++level,module);
802 if (fGeomTGeo->GetNHalfStaves(lay)>0) TVirtualMC::GetMC()->CurrentVolOffID(++level,sstave);
803 TVirtualMC::GetMC()->CurrentVolOffID(++level,stave);
b705c75b 804 //
c55b10c2 805 chipID = fGeomTGeo->GetChipIndex(lay,stave,sstave,module,chip);
b705c75b 806 // Fill hit structure.
807 //
c55b10c2 808 hit.SetChip(chipID);
b705c75b 809 hit.SetTrack(gAlice->GetMCApp()->GetCurrentTrackNumber());
2942f542 810 TVirtualMC::GetMC()->TrackPosition(position);
811 TVirtualMC::GetMC()->TrackMomentum(momentum);
b705c75b 812 hit.SetPosition(position);
2942f542 813 hit.SetTime(TVirtualMC::GetMC()->TrackTime());
b705c75b 814 hit.SetMomentum(momentum);
815 hit.SetStatus(status);
2942f542 816 hit.SetEdep(TVirtualMC::GetMC()->Edep());
b705c75b 817 hit.SetShunt(GetIshunt());
2942f542 818 if(TVirtualMC::GetMC()->IsTrackEntering()){
b705c75b 819 hit.SetStartPosition(position);
2942f542 820 hit.SetStartTime(TVirtualMC::GetMC()->TrackTime());
b705c75b 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);
2942f542 829 hit.SetStartTime(TVirtualMC::GetMC()->TrackTime());
b705c75b 830 hit.SetStartStatus(status);
831
832 return;
833}
834
835//______________________________________________________________________
852af72e 836void AliITSUv1::SetLayerChipTypeID(Int_t lr, UInt_t id)
b705c75b 837{
838 // set det type
852af72e 839 if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
840 fChipTypeID[lr] = id;
b705c75b 841}
842
843//______________________________________________________________________
852af72e 844Int_t AliITSUv1::GetLayerChipTypeID(Int_t lr)
b705c75b 845{
846 // set det type
852af72e 847 if (!fChipTypeID || fNLayers<=lr) AliFatal(Form("Number of layers %d, %d is manipulated",fNLayers,lr));
848 return fChipTypeID[lr];
b705c75b 849}