Project
Loading...
Searching...
No Matches
TRKLayer.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
14#include "TRKBase/Specs.h"
15
16#include "Framework/Logger.h"
17
18#include <TGeoTube.h>
19#include <TGeoBBox.h>
20#include <TGeoVolume.h>
21
22#include <TMath.h>
23
24namespace o2
25{
26namespace trk
27{
28TRKCylindricalLayer::TRKCylindricalLayer(int layerNumber, std::string layerName, float rInn, float length, float thickOrX2X0, MatBudgetParamMode mode)
29 : mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mLength(length)
30{
32 mChipThickness = thickOrX2X0;
33 mX2X0 = thickOrX2X0 / Si_X0;
34 mOuterRadius = rInn + thickOrX2X0;
35 } else if (mode == MatBudgetParamMode::X2X0) {
36 mX2X0 = thickOrX2X0;
37 mChipThickness = thickOrX2X0 * Si_X0;
38 mOuterRadius = rInn + thickOrX2X0 * Si_X0;
39 }
40
41 LOGP(info, "Creating layer: id: {} rInner: {} rOuter: {} zLength: {} x2X0: {}", mLayerNumber, mInnerRadius, mOuterRadius, mLength, mX2X0);
42}
43
45{
46 TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
48 TGeoShape* sensor = new TGeoTube(mInnerRadius, mInnerRadius + sSensorThickness, mLength / 2);
49 TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
50 sensVol->SetLineColor(kYellow);
51
52 return sensVol;
53};
54
56{
57 TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
59 TGeoShape* metalStack = new TGeoTube(mInnerRadius + sSensorThickness, mInnerRadius + mChipThickness, mLength / 2);
60 TGeoVolume* metalVol = new TGeoVolume(metalName.c_str(), metalStack, medSi);
61 metalVol->SetLineColor(kGray);
62
63 return metalVol;
64};
65
66void TRKCylindricalLayer::createLayer(TGeoVolume* motherVolume)
67{
68 TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$");
69 TGeoTube* layer = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mLength / 2);
70 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
71 layerVol->SetLineColor(kYellow);
72
73 TGeoVolume* sensVol = createSensor();
74 LOGP(debug, "Inserting {} in {} ", sensVol->GetName(), layerVol->GetName());
75 layerVol->AddNode(sensVol, 1, nullptr);
76
77 TGeoVolume* metalVol = createMetalStack();
78 LOGP(debug, "Inserting {} in {} ", metalVol->GetName(), layerVol->GetName());
79 layerVol->AddNode(metalVol, 1, nullptr);
80
81 LOGP(debug, "Inserting {} in {} ", layerVol->GetName(), motherVolume->GetName());
82 motherVolume->AddNode(layerVol, 1, nullptr);
83}
84
86
87TRKSegmentedLayer::TRKSegmentedLayer(int layerNumber, std::string layerName, float rInn, int numberOfModules, float thickOrX2X0, MatBudgetParamMode mode)
88 : TRKCylindricalLayer(layerNumber, layerName, rInn, numberOfModules * sModuleLength, thickOrX2X0, mode), mNumberOfModules(numberOfModules)
89{
90}
91
93{
94 TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
96 TGeoShape* sensor = new TGeoBBox((sChipWidth - sDeadzoneWidth) / 2, sSensorThickness / 2, sChipLength / 2);
97 TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
98 sensVol->SetLineColor(kYellow);
99
100 return sensVol;
101}
102
104{
105 TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
107 TGeoShape* deadzone = new TGeoBBox(sDeadzoneWidth / 2, sSensorThickness / 2, sChipLength / 2);
108 TGeoVolume* deadVol = new TGeoVolume(deadName.c_str(), deadzone, medSi);
109 deadVol->SetLineColor(kGray);
110
111 return deadVol;
112}
113
115{
116 TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
118 TGeoShape* metalStack = new TGeoBBox(sChipWidth / 2, (mChipThickness - sSensorThickness) / 2, sChipLength / 2);
119 TGeoVolume* metalVol = new TGeoVolume(metalName.c_str(), metalStack, medSi);
120 metalVol->SetLineColor(kGray);
121
122 return metalVol;
123}
124
126{
127 TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
129 TGeoShape* chip = new TGeoBBox(sChipWidth / 2, mChipThickness / 2, sChipLength / 2);
130 TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
131 chipVol->SetLineColor(kYellow);
132
133 TGeoVolume* sensVol = createSensor();
134 TGeoCombiTrans* transSens = new TGeoCombiTrans();
135 // transSens->SetTranslation(-sDeadzoneWidth / 2, -(mChipThickness - sSensorThickness) / 2, 0);
136 transSens->SetTranslation(-sDeadzoneWidth / 2, (mChipThickness - sSensorThickness) / 2, 0);
137 LOGP(debug, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
138 chipVol->AddNode(sensVol, 1, transSens);
139
140 TGeoVolume* deadVol = createDeadzone();
141 TGeoCombiTrans* transDead = new TGeoCombiTrans();
142 // transDead->SetTranslation((sChipWidth - sDeadzoneWidth) / 2, -(mChipThickness - sSensorThickness) / 2, 0);
143 transDead->SetTranslation((sChipWidth - sDeadzoneWidth) / 2, (mChipThickness - sSensorThickness) / 2, 0);
144 LOGP(debug, "Inserting {} in {} ", deadVol->GetName(), chipVol->GetName());
145 chipVol->AddNode(deadVol, 1, transDead);
146
147 TGeoVolume* metalVol = createMetalStack();
148 TGeoCombiTrans* transMetal = new TGeoCombiTrans();
149 // transMetal->SetTranslation(0, sSensorThickness / 2, 0);
150 transMetal->SetTranslation(0, -sSensorThickness / 2, 0);
151 LOGP(debug, "Inserting {} in {} ", metalVol->GetName(), chipVol->GetName());
152 chipVol->AddNode(metalVol, 1, transMetal);
153
154 return chipVol;
155}
156
158{
159 TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
161 TGeoShape* module = new TGeoBBox(sModuleWidth / 2, mChipThickness / 2, sModuleLength / 2);
162 TGeoVolume* moduleVol = new TGeoVolume(moduleName.c_str(), module, medSi);
163 moduleVol->SetLineColor(kYellow);
164
165 for (int iChip = 0; iChip < sHalfNumberOfChips; iChip++) {
166 TGeoVolume* chipVolLeft = createChip();
169 TGeoCombiTrans* transLeft = new TGeoCombiTrans();
170 transLeft->SetTranslation(xLeft, 0, zLeft);
171 TGeoRotation* rot = new TGeoRotation();
172 rot->RotateY(180);
173 transLeft->SetRotation(rot);
174 LOGP(debug, "Inserting {} in {} ", chipVolLeft->GetName(), moduleVol->GetName());
175 moduleVol->AddNode(chipVolLeft, iChip * 2, transLeft);
176
177 TGeoVolume* chipVolRight = createChip();
180 TGeoCombiTrans* transRight = new TGeoCombiTrans();
181 transRight->SetTranslation(xRight, 0, zRight);
182 LOGP(debug, "Inserting {} in {} ", chipVolRight->GetName(), moduleVol->GetName());
183 moduleVol->AddNode(chipVolRight, iChip * 2 + 1, transRight);
184 }
185
186 return moduleVol;
187}
188
190
191TRKMLLayer::TRKMLLayer(int layerNumber, std::string layerName, float rInn, int numberOfModules, float thickOrX2X0, MatBudgetParamMode mode)
192 : TRKSegmentedLayer(layerNumber, layerName, rInn, numberOfModules, thickOrX2X0, mode)
193{
194}
195
197{
198 TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$");
200 TGeoShape* stave = new TGeoBBox(sStaveWidth / 2, mChipThickness / 2, mLength / 2);
201 TGeoVolume* staveVol = new TGeoVolume(staveName.c_str(), stave, medAir);
202 staveVol->SetLineColor(kYellow);
203
204 for (int iModule = 0; iModule < mNumberOfModules; iModule++) {
205 TGeoVolume* moduleVol = createModule();
206 double zPos = -0.5 * mNumberOfModules * sModuleLength + (iModule + 0.5) * sModuleLength;
207 TGeoCombiTrans* trans = new TGeoCombiTrans();
208 trans->SetTranslation(0, 0, zPos);
209 LOGP(debug, "Inserting {} in {} ", moduleVol->GetName(), staveVol->GetName());
210 staveVol->AddNode(moduleVol, iModule, trans);
211 }
212
213 return staveVol;
214}
215
216void TRKMLLayer::createLayer(TGeoVolume* motherVolume)
217{
218 TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$");
219 TGeoTube* layer = new TGeoTube(mInnerRadius - 0.333 * sLogicalVolumeThickness, mInnerRadius + 0.667 * sLogicalVolumeThickness, mLength / 2);
220 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
221 layerVol->SetLineColor(kYellow);
222
223 // Compute the number of staves
224 int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / sStaveWidth);
225 nStaves += nStaves % 2; // Require an even number of staves
226
227 // Compute the size of the overlap region
228 double theta = 2 * TMath::Pi() / nStaves;
229 double theta1 = std::atan(sStaveWidth / 2 / mInnerRadius);
230 double st = std::sin(theta);
231 double ct = std::cos(theta);
232 double theta2 = std::atan((mInnerRadius * st - sStaveWidth / 2 * ct) / (mInnerRadius * ct + sStaveWidth / 2 * st));
233 double overlap = (theta1 - theta2) * mInnerRadius;
234 LOGP(info, "Creating a layer with {} staves and {} mm overlap", nStaves, overlap * 10);
235
236 for (int iStave = 0; iStave < nStaves; iStave++) {
237 TGeoVolume* staveVol = createStave();
238 TGeoCombiTrans* trans = new TGeoCombiTrans();
239 double theta = 360. * iStave / nStaves;
240 // TGeoRotation* rot = new TGeoRotation("rot", theta - 90 + 4, 0, 0);
241 TGeoRotation* rot = new TGeoRotation("rot", theta + 90 + 4, 0, 0);
242 trans->SetRotation(rot);
243 trans->SetTranslation(mInnerRadius * std::cos(2. * TMath::Pi() * iStave / nStaves), mInnerRadius * std::sin(2 * TMath::Pi() * iStave / nStaves), 0);
244 LOGP(debug, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName());
245 layerVol->AddNode(staveVol, iStave, trans);
246 }
247
248 LOGP(debug, "Inserting {} in {} ", layerVol->GetName(), motherVolume->GetName());
249 motherVolume->AddNode(layerVol, 1, nullptr);
250}
251
253
254TRKOTLayer::TRKOTLayer(int layerNumber, std::string layerName, float rInn, int numberOfModules, float thickOrX2X0, MatBudgetParamMode mode)
255 : TRKSegmentedLayer(layerNumber, layerName, rInn, numberOfModules, thickOrX2X0, mode)
256{
257}
258
260{
261 TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
263 TGeoShape* halfStave = new TGeoBBox(sHalfStaveWidth / 2, mChipThickness / 2, mLength / 2);
264 TGeoVolume* halfStaveVol = new TGeoVolume(halfStaveName.c_str(), halfStave, medSi);
265 halfStaveVol->SetLineColor(kYellow);
266
267 for (int iModule = 0; iModule < mNumberOfModules; iModule++) {
268 TGeoVolume* moduleVol = createModule();
269 double zPos = -0.5 * mNumberOfModules * sModuleLength + (iModule + 0.5) * sModuleLength;
270 TGeoCombiTrans* trans = new TGeoCombiTrans();
271 trans->SetTranslation(0, 0, zPos);
272 LOGP(debug, "Inserting {} in {} ", moduleVol->GetName(), halfStaveVol->GetName());
273 halfStaveVol->AddNode(moduleVol, iModule, trans);
274 }
275
276 return halfStaveVol;
277}
278
280{
282 TGeoVolume* staveVol = new TGeoVolumeAssembly(staveName.c_str());
283
284 TGeoVolume* halfStaveVolLeft = createHalfStave();
285 TGeoCombiTrans* transLeft = new TGeoCombiTrans();
286 transLeft->SetTranslation(-(sHalfStaveWidth - sInStaveOverlap) / 2, 0, 0);
287 LOGP(debug, "Inserting {} in {} ", halfStaveVolLeft->GetName(), staveVol->GetName());
288 staveVol->AddNode(halfStaveVolLeft, 0, transLeft);
289
290 TGeoVolume* halfStaveVolRight = createHalfStave();
291 TGeoCombiTrans* transRight = new TGeoCombiTrans();
292 transRight->SetTranslation((sHalfStaveWidth - sInStaveOverlap) / 2, 0.2, 0);
293 LOGP(debug, "Inserting {} in {} ", halfStaveVolRight->GetName(), staveVol->GetName());
294 staveVol->AddNode(halfStaveVolRight, 1, transRight);
295
296 return staveVol;
297}
298
299void TRKOTLayer::createLayer(TGeoVolume* motherVolume)
300{
301 TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$");
302 TGeoTube* layer = new TGeoTube(mInnerRadius - 0.333 * sLogicalVolumeThickness, mInnerRadius + 0.667 * sLogicalVolumeThickness, mLength / 2);
303 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
304 layerVol->SetLineColor(kYellow);
305
306 // Compute the number of staves
307 int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / sStaveWidth);
308 nStaves += nStaves % 2; // Require an even number of staves
309
310 // Compute the size of the overlap region
311 double theta = 2 * TMath::Pi() / nStaves;
312 double theta1 = std::atan(sStaveWidth / 2 / mInnerRadius);
313 double st = std::sin(theta);
314 double ct = std::cos(theta);
315 double theta2 = std::atan((mInnerRadius * st - sStaveWidth / 2 * ct) / (mInnerRadius * ct + sStaveWidth / 2 * st));
316 double overlap = (theta1 - theta2) * mInnerRadius;
317 LOGP(info, "Creating a layer with {} staves and {} mm overlap", nStaves, overlap * 10);
318
319 for (int iStave = 0; iStave < nStaves; iStave++) {
320 TGeoVolume* staveVol = createStave();
321 TGeoCombiTrans* trans = new TGeoCombiTrans();
322 double theta = 360. * iStave / nStaves;
323 // TGeoRotation* rot = new TGeoRotation("rot", theta - 90, 0, 0);
324 TGeoRotation* rot = new TGeoRotation("rot", theta + 90, 0, 0);
325 trans->SetRotation(rot);
326 trans->SetTranslation(mInnerRadius * std::cos(2. * TMath::Pi() * iStave / nStaves), mInnerRadius * std::sin(2 * TMath::Pi() * iStave / nStaves), 0);
327 LOGP(debug, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName());
328 layerVol->AddNode(staveVol, iStave, trans);
329 }
330
331 LOGP(debug, "Inserting {} in {} ", layerVol->GetName(), motherVolume->GetName());
332 motherVolume->AddNode(layerVol, 1, nullptr);
333}
334// ClassImp(TRKLayer);
335
336} // namespace trk
337} // namespace o2
std::ostringstream debug
specs of the ALICE3 TRK
benchmark::State & st
static const char * getTRKStavePattern()
static const char * getTRKChipPattern()
static const char * getTRKSensorPattern()
static const char * getTRKDeadzonePattern()
static const char * getTRKHalfStavePattern()
static const char * getTRKMetalStackPattern()
static const char * getTRKModulePattern()
static constexpr float Si_X0
Definition TRKLayer.h:62
virtual void createLayer(TGeoVolume *motherVolume)
Definition TRKLayer.cxx:66
virtual TGeoVolume * createSensor()
Definition TRKLayer.cxx:44
virtual TGeoVolume * createMetalStack()
Definition TRKLayer.cxx:55
static constexpr double sSensorThickness
Definition TRKLayer.h:60
void createLayer(TGeoVolume *motherVolume) override
Definition TRKLayer.cxx:216
TGeoVolume * createStave() override
Definition TRKLayer.cxx:196
TGeoVolume * createHalfStave()
Definition TRKLayer.cxx:259
void createLayer(TGeoVolume *motherVolume) override
Definition TRKLayer.cxx:299
TGeoVolume * createStave() override
Definition TRKLayer.cxx:279
static constexpr double sChipWidth
Definition TRKLayer.h:86
TGeoVolume * createMetalStack() override
Definition TRKLayer.cxx:114
static constexpr float sLogicalVolumeThickness
Definition TRKLayer.h:94
static constexpr int sHalfNumberOfChips
Definition TRKLayer.h:91
TGeoVolume * createSensor() override
Definition TRKLayer.cxx:92
TGeoVolume * createModule()
Definition TRKLayer.cxx:157
static constexpr double sChipLength
Definition TRKLayer.h:87
TGeoVolume * createChip()
Definition TRKLayer.cxx:125
static constexpr double sDeadzoneWidth
Definition TRKLayer.h:88
static constexpr double sModuleLength
Definition TRKLayer.h:89
static constexpr double sModuleWidth
Definition TRKLayer.h:90
TGeoVolume * createDeadzone()
Definition TRKLayer.cxx:103
GLenum mode
Definition glcorearb.h:266
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
constexpr double outerEdgeLongSide
Definition Specs.h:92
constexpr double outerEdgeShortSide
Definition Specs.h:93
MatBudgetParamMode
Definition TRKLayer.h:25
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52