Project
Loading...
Searching...
No Matches
AlpideChip.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
18
21
22#include <TGeoBBox.h> // for TGeoBBox
23#include <TGeoManager.h> // for gGeoManager, TGeoManager
24#include "TGeoVolume.h" // for TGeoVolume
25#include "TGeoMatrix.h" // for TGeoMatrix
26#include <fairlogger/Logger.h> // for LOG
27
28using namespace o2::itsmft;
29
31
32//________________________________________________________________________
33TGeoVolume* AlpideChip::createChip(const Double_t ychip,
34 const Double_t ysens,
35 const char* chipName,
36 const char* sensName,
37 const Bool_t dummy,
38 const TGeoManager* mgr)
39{
40 //
41 // Creates the Alpide Chip
42 // Caller should then use TGeoVolume::SetName to proper set the volume name
43 //
44 // Input:
45 // ychip : the chip Y half dimensions
46 // ysens : the sensor half thickness
47 // chipName,sensName : default volume names (if not passed by caller)
48 // dummy : if true, creates a dummy air volume
49 // (for material budget studies)
50 // mgr : the GeoManager (used only to get the proper material)
51 //
52 // Output:
53 //
54 // Return:
55 //
56 // Created: 20 Oct 2017 Mario Sitta Ported from V3layer
57 //
58
59 Double_t xchip, zchip;
60 Double_t ylen, ypos;
61
64
65 // First create all needed shapes
66 ylen = ysens;
67 if (ysens > ychip) {
68 LOG(warning) << "Sensor half thickness (" << ysens
69 << ") greater than chip half thickness (" << ychip
70 << "), setting equal";
71 ylen = ychip;
72 }
73
74 // The chip
75 TGeoBBox* chip = new TGeoBBox(xchip, ychip, zchip);
76
77 // The sensor
78 TGeoBBox* sensor = new TGeoBBox(xchip, ylen, zchip);
79
80 // The metal layer. Its three half lengths come from SegmentationAlpide constants only, so
81 // it is the same solid in every ALPIDE chip of both ITS and MFT; see the cache below.
82 ylen = 0.5 * sMetalLayerThick;
83
84 // We have all shapes: now create the real volumes
85 TGeoMedium* medSi = mgr->GetMedium("ALPIDE_SI$");
86 if (!medSi) {
87 Int_t fieldType;
88 Float_t maxField;
90 createMaterials(0, fieldType, maxField);
91 medSi = mgr->GetMedium("ALPIDE_SI$");
92 }
93 TGeoMedium* medAir = mgr->GetMedium("ALPIDE_AIR$");
94 TGeoMedium* medMetal = mgr->GetMedium("ALPIDE_METALSTACK$");
95
96 TGeoMedium* medChip;
97
98 if (dummy) {
99 medChip = medAir;
100 } else {
101 medChip = medSi;
102 }
103
104 TGeoVolume* chipVol = new TGeoVolume(chipName, chip, medChip);
105 chipVol->SetVisibility(kTRUE);
106 chipVol->SetLineColor(1);
107 chipVol->SetFillColor(chipVol->GetLineColor());
108 chipVol->SetFillStyle(4000); // 0% transparent
109
110 TGeoVolume* sensVol = new TGeoVolume(sensName, sensor, medChip);
111 sensVol->SetVisibility(kTRUE);
112 sensVol->SetLineColor(8);
113 sensVol->SetLineWidth(1);
114 sensVol->SetFillColor(sensVol->GetLineColor());
115 sensVol->SetFillStyle(4000); // 0% transparent
116
117 // Every chip carries the same metal stack, so build it on the first call and place that one
118 // volume in all the others. It sits at a different height in each chip, but that is the
119 // node's translation below and not a property of the volume.
120 static TGeoManager* metalCacheOwner = nullptr;
121 static TGeoVolume* metalVol = nullptr;
122 if (metalCacheOwner != gGeoManager) {
123 // a new geometry leaves the cached pointer dangling
124 metalCacheOwner = gGeoManager;
125 metalVol = nullptr;
126 }
127
128 if (!metalVol) {
129 TGeoBBox* metallay = new TGeoBBox(xchip, ylen, zchip);
130 metalVol = new TGeoVolume("MetalStack", metallay, medMetal);
131 metalVol->SetVisibility(kTRUE);
132 metalVol->SetLineColor(1);
133 metalVol->SetLineWidth(1);
134 metalVol->SetFillColor(metalVol->GetLineColor());
135 metalVol->SetFillStyle(4000); // 0% transparent
136 }
137
138 TGeoBBox* metallay = (TGeoBBox*)metalVol->GetShape();
139 if (metallay->GetDX() != xchip || metallay->GetDY() != ylen || metallay->GetDZ() != zchip) {
140 LOG(fatal) << "AlpideChip::createChip: the cached MetalStack was built with half lengths "
141 << metallay->GetDX() << "," << metallay->GetDY() << "," << metallay->GetDZ()
142 << " but this call asks for " << xchip << "," << ylen << "," << zchip
143 << " - the single-volume cache assumes the same metal stack in every chip";
144 }
145
146 // Now build up the chip
147 ypos = chip->GetDY() - metallay->GetDY();
148 chipVol->AddNode(metalVol, 1, new TGeoTranslation(0., ypos, 0.));
149
150 ypos -= (metallay->GetDY() + sensor->GetDY());
151 chipVol->AddNode(sensVol, 1, new TGeoTranslation(0., ypos, 0.));
152
153 // Done, return the chip
154 return chipVol;
155}
156
157//________________________________________________________________________
158void AlpideChip::createMaterials(Int_t id, Int_t ifield, Float_t fieldm)
159{
160 // create common materials with the MFT
161
163
164 Float_t tmaxfd = 0.1; // Degree
165 Float_t stemax = 1.0; // cm
166 Float_t deemax = 0.1; // Fraction of particle's energy 0<deemax<=1
167 Float_t epsil = 1.0E-4; // cm
168 Float_t stmin = 0.0; // cm "Default value used"
169
170 Float_t tmaxfdSi = 0.1; // Degree
171 Float_t stemaxSi = 0.0075; // cm
172 Float_t deemaxSi = 0.1; // Fraction of particle's energy 0<deemax<=1
173 Float_t epsilSi = 1.0E-4; // cm
174 Float_t stminSi = 0.0; // cm "Default value used"
175
176 Float_t tmaxfdAir = 0.1; // Degree
177 Float_t stemaxAir = 1.0; // cm
178 Float_t deemaxAir = 0.1; // Fraction of particle's energy 0<deemax<=1
179 Float_t epsilAir = 1.0E-4; // cm
180 Float_t stminAir = 0.0; // cm "Default value used"
181
182 // BEOL (Metal interconnection stack in Si sensors)
183 Float_t aBEOL[3] = {26.982, 28.086, 15.999};
184 Float_t zBEOL[3] = {13, 14, 8}; // Al, Si, O
185 Float_t wBEOL[3] = {0.170, 0.388, 0.442};
186 Float_t dBEOL = 2.28;
187
188 // AIR
189 Float_t aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
190 Float_t zAir[4] = {6., 7., 8., 18.};
191 Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
192 Float_t dAir = 1.20479E-3;
193
194 if (mgr.getMediumID("ALPIDE", id) < 0) {
195 mgr.Mixture("ALPIDE", id, "METALSTACK$", aBEOL, zBEOL, dBEOL, 3, wBEOL);
196 mgr.Medium("ALPIDE", id, "METALSTACK$", id, 0, ifield, fieldm, tmaxfd, stemax, deemax, epsil, stmin);
197 id++;
198 }
199
200 if (mgr.getMediumID("ALPIDE", id) < 0) {
201 mgr.Mixture("ALPIDE", id, "AIR$", aAir, zAir, dAir, 4, wAir);
202 mgr.Medium("ALPIDE", id, "AIR$", id, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
203 id++;
204 }
205
206 if (mgr.getMediumID("ALPIDE", id) < 0) {
207 mgr.Material("ALPIDE", id, "SI$", 0.28086E+02, 0.14000E+02, 0.23300E+01, 0.93600E+01, 0.99900E+03);
208 mgr.Medium("ALPIDE", id, "SI$", id, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
209 }
210}
ClassImp(AlpideChip)
Creates an ALPIDE chip in simulation.
Definition of the Detector class.
Definition of the SegmentationAlpide class.
static void initFieldTrackingParams(int &mode, float &maxfield)
Definition Detector.cxx:143
static MaterialManager & Instance()
static constexpr Double_t sMetalLayerThick
Metal layer thickness (um)
Definition AlpideChip.h:53
static void createMaterials(Int_t id, Int_t fieldType, Float_t maxField)
static TGeoVolume * createChip(Double_t yc, Double_t ys, char const *chipName="AlpideChip", char const *sensName="AlpideSensor", Bool_t dummy=kFALSE, const TGeoManager *mgr=gGeoManager)
static constexpr float SensorSizeCols
static constexpr float SensorSizeRows
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"