Project
Loading...
Searching...
No Matches
Station345Geometry.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
16
17#include "Materials.h"
18#include "Station345Geometry.h"
19
20#include <TGeoCompositeShape.h>
21#include <TGeoManager.h>
22#include <TGeoMedium.h>
23#include <TGeoShape.h>
24#include <TGeoTube.h>
25#include <TGeoVolume.h>
26#include <TMath.h>
27
28#include <rapidjson/document.h>
29#include <rapidjson/filereadstream.h>
30
31#include <iostream>
32#include <string>
33#include <array>
34
35using namespace rapidjson;
36using namespace std;
37
38namespace o2
39{
40namespace mch
41{
42
44
45// gas
46const float kGasLength = 40.;
47const float kGasHalfHeight = 40. / 2;
48const float kGasHalfThickness = 0.25;
49
50// PCB = gas + 2*(cathode + insulator)
51const float kPCBLength = kGasLength;
52const float kShortPCBLength = 35.;
53const float kRoundedPCBLength = 42.5;
54const float kR1PCBLength = 19.25;
55const float kPCBHalfHeight = 58. / 2;
56
57const float kCathodeHalfThickness = 0.002 / 2;
58const float kInsuHalfThickness = 0.04 / 2;
59
61
62// slat panel = honeycomb nomex + 2 carbon fiber skins
63const float kSlatPanelHalfHeight = 42.5 / 2;
64
65const float kGlueHalfThickness = 0.004 / 2;
66const float kNomexBulkHalfThickness = 0.025 / 2;
67const float kCarbonHalfThickness = 0.02 / 2;
68const float kNomexHalfThickness = 0.8 / 2;
69
70// spacers (noryl)
72const float kHoriSpacerHalfHeight = 1.95 / 2;
73const float kVertSpacerHalfLength = 2.5 / 2;
74const float kRoundedSpacerHalfLength = 1.;
75
76// border (rohacell)
77const float kBorderHalfHeight = 2.5;
79
80// DualSampas (parameters from the PRR)
81const float kDualSampaHalfLength = 3.2 / 2;
82const float kDualSampaHalfHeight = 2.5;
83const float kDualSampaHalfThickness = 0.027 / 2; // to be confirmed
85
87// Low voltage (values from AliRoot)
88const float kLVCableHalfHeight = 2.6 / 2;
89const float kLVCableHalfThickness = 0.026 / 2;
90
92const float kCarbonSupportHalfThickness = 0.03 / 2;
93const float kGlueSupportHalfThickness = 0.02 / 2;
94const float kNomexSupportHalfThickness = 1.5 / 2;
95const float kSt3SupportHalfHeight = 361. / 2;
96const float kSt4SupportHalfHeight = 530. / 2;
97const float kSt5SupportHalfHeight = 570. / 2;
98const float kCh5SupportHalfLength = 162. / 2;
99const float kCh6SupportHalfLength = 167. / 2;
100const float kSt45SupportHalfLength = 260. / 2;
101
102// Inner radii
103const float kSt3Radius = 29.5;
104const float kSt45Radius = 37.5;
105
106// Y position of the rounded slats
107const float kSt3RoundedSlatYPos = 37.8;
108const float kSt45RoundedSlatYPos = 38.2;
109
110// PCB types {name, number of DualSampa array = (nUP bending, nDOWN bending, nUP non-bending, nDOWN non-bending)}
111const map<string, array<int, 4>> kPcbTypes = {{"B1N1", {10, 10, 7, 7}}, {"B2N2-", {5, 5, 4, 3}}, {"B2N2+", {5, 5, 3, 4}}, {"B3-N3", {3, 2, 2, 2}}, {"B3+N3", {2, 3, 2, 2}}, {"R1", {3, 4, 2, 3}}, {"R2", {13, 4, 9, 3}}, {"R3", {13, 1, 10, 0}}, {"S2-", {4, 5, 3, 3}}, {"S2+", {5, 4, 3, 3}}};
112
113// Slat types
114const map<string, vector<string>> kSlatTypes = {{"122000SR1", {"S2-", "B2N2+", "B1N1", "R1"}},
115 {"112200SR2", {"S2-", "B2N2+", "B1N1", "R2"}},
116 {"122200S", {"B1N1", "B2N2-", "B2N2-", "S2+"}},
117 {"222000N", {"B2N2-", "B2N2-", "B2N2-"}},
118 {"220000N", {"B2N2-", "B2N2-"}},
119 {"122000NR1", {"B2N2+", "B2N2+", "B1N1", "R1"}},
120 {"112200NR2", {"B2N2+", "B2N2+", "B1N1", "R2"}},
121 {"122200N", {"B1N1", "B2N2-", "B2N2-", "B2N2-"}},
122 {"122330N", {"B1N1", "B2N2+", "B2N2-", "B3-N3", "B3-N3"}},
123 {"112233NR3", {"B3+N3", "B3+N3", "B2N2+", "B2N2-", "B1N1", "R3"}},
124 {"112230N", {"B1N1", "B1N1", "B2N2-", "B2N2-", "B3-N3"}},
125 {"222330N", {"B2N2+", "B2N2+", "B2N2-", "B3-N3", "B3-N3"}},
126 {"223300N", {"B2N2+", "B2N2-", "B3-N3", "B3-N3"}},
127 {"333000N", {"B3-N3", "B3-N3", "B3-N3"}},
128 {"330000N", {"B3-N3", "B3-N3"}},
129 {"112233N", {"B1N1", "B1N1", "B2N2+", "B2N2-", "B3-N3", "B3-N3"}},
130 {"222333N",
131 {"B2N2+", "B2N2+", "B2N2+", "B3-N3", "B3-N3", "B3-N3"}},
132 {"223330N", {"B2N2+", "B2N2+", "B3-N3", "B3-N3", "B3-N3"}},
133 {"333300N", {"B3+N3", "B3-N3", "B3-N3", "B3-N3"}}};
134
135extern const string jsonSlatDescription;
136
137TGeoVolume* getDualSampa()
138{
140}
141
142bool isRounded(string name)
143{
144 return name.find('R') < name.size();
145}
146
147bool isShort(string name)
148{
149 return name.find('S') < name.size();
150}
151
152TGeoCompositeShape* getRoundedShape(const char* name, float halfThickness, float xPos, float yPos, float radius)
153{
155
156 // create the position where the hole will be created
157 const char* shiftName = Form("%sX%.1fY%.1fShift", name, TMath::Abs(xPos), TMath::Abs(yPos));
158 auto shift = new TGeoTranslation(shiftName, xPos, yPos, 0.);
159 shift->RegisterYourself();
160
161 // create the tube that create the hole
162 const char* tubeName = Form("%sR%.1fHole", name, radius);
163 new TGeoTube(tubeName, 0., radius, halfThickness);
164
165 const char* shapeName = Form("%sX%.1fY%.1fR%.1fShape", name, TMath::Abs(xPos), TMath::Abs(yPos), radius);
166
167 // create the hole in the box and return the built shape
168 return new TGeoCompositeShape(shapeName, Form("%sBox-%s:%s", name, tubeName, shiftName));
169}
170
171//______________________________________________________________________________
173{
175
176 const auto kSpacerMed = assertMedium(Medium::Noryl);
177
178 // the left vertical spacer (identical to any slat)
179 gGeoManager->MakeBox("Left spacer", kSpacerMed, kVertSpacerHalfLength, kSlatPanelHalfHeight, kSpacerHalfThickness);
180
181 // the top spacers and borders : 4 lengths possible according to the PCB shape
183 // top spacer
184 gGeoManager->MakeBox(Form("Top spacer %.2f long", length), kSpacerMed, length / 2, kHoriSpacerHalfHeight, kSpacerHalfThickness);
185
186 // top border
187 gGeoManager->MakeBox(Form("Top border %.2f long", length), assertMedium(Medium::Rohacell), length / 2, kBorderHalfHeight, kBorderHalfThickness);
188 }
189}
190
191//______________________________________________________________________________
193{
195
200
201 // Define some necessary variables
202 string bendName, nonbendName;
203 float y = 0., shift = 0., length = 0.; // useful parameters for dimensions and positions
204 int nDualSampas = 0;
205
206 // get the DualSampa volume
207 auto* dualSampaVol = getDualSampa();
208
209 for (const auto& [pcbName, dualSampas] : kPcbTypes) { // loop over the PCB types of the array
210
211 auto name = (const char*)pcbName.data();
212
213 auto pcb = new TGeoVolumeAssembly(name);
214
215 // Reset shift variables
216 float gasShift = 0., pcbShift = 0.;
217
218 float gasLength = kGasLength;
219 float pcbLength = kPCBLength;
220
221 int numb = pcbName[1] - '0'; // char -> int conversion
222
223 // change the variables according to the PCB shape if necessary
224 switch (pcbName.front()) {
225 case 'R': // rounded
226 numb = pcbName.back() - '0';
227 gasLength = (numb == 1) ? kR1PCBLength : kGasLength;
228 pcbLength = (numb == 1) ? kR1PCBLength : kRoundedPCBLength;
229 gasShift = gasLength - kGasLength;
230 pcbShift = pcbLength - kPCBLength;
231
232 bendName = Form("%sB", name);
233 nonbendName = Form("%sN", name);
234 break;
235 case 'S': // shortened
236 gasLength = kShortPCBLength;
237 pcbLength = kShortPCBLength;
238 bendName = Form("S2B%c", pcbName.back());
239 nonbendName = Form("S2N%c", pcbName.back());
240 break;
241 default: // normal
242 bendName = (numb == 3) ? pcbName.substr(0, 3) : pcbName.substr(0, 2);
243 nonbendName = (numb == 3) ? pcbName.substr(3) : pcbName.substr(2);
244 }
245
246 float borderLength = pcbLength;
247
248 // create the volume of each material (a box by default)
249 // sensitive gas
250 auto gas = new TGeoVolume(Form("%s gas", name), new TGeoBBox(Form("%sGasBox", name), gasLength / 2., kGasHalfHeight, kGasHalfThickness), assertMedium(Medium::Gas));
251
252 float x = pcbLength / 2;
253 float halfHeight = kPCBHalfHeight;
254
255 // bending cathode
256 auto bend = new TGeoVolume(bendName.data(), new TGeoBBox(Form("%sBendBox", name), x, halfHeight, kCathodeHalfThickness), assertMedium(Medium::Copper));
257
258 // non-bending cathode
259 auto nonbend = new TGeoVolume(nonbendName.data(), new TGeoBBox(Form("%sNonBendBox", name), x, halfHeight, kCathodeHalfThickness), assertMedium(Medium::Copper));
260
261 // insulating material
262 auto insu = new TGeoVolume(Form("%s insulator", name), new TGeoBBox(Form("%sInsuBox", name), x, halfHeight, kInsuHalfThickness), assertMedium(Medium::FR4));
263
264 // bottom spacer (noryl)
265 auto spacer = new TGeoVolume(Form("%s bottom spacer", name), new TGeoBBox(Form("%sBottomSpacerBox", name), x, kHoriSpacerHalfHeight, kSpacerHalfThickness), assertMedium(Medium::Noryl));
266
267 // change the volume shape if we are creating a rounded PCB
268 if (isRounded(pcbName)) {
269 // LHC beam pipe radius ("R3" -> it is a slat of a station 4 or 5)
270 float radius = (numb == 3) ? kSt45Radius : kSt3Radius;
271 // y position of the PCB center w.r.t the beam pipe shape
272 switch (numb) {
273 case 1:
274 y = 0.; // central for "R1"
275 break;
276 case 2:
277 y = kSt3RoundedSlatYPos; // "R2" -> station 3
278 break;
279 default:
280 y = kSt45RoundedSlatYPos; // "R3" -> station 4 or 5
281 break;
282 }
283 // compute the radius of curvature of the PCB we want to create
284 float curvRad = radius + 2 * kRoundedSpacerHalfLength;
285
286 x = kRoundedPCBLength - gasLength / 2 - kVertSpacerHalfLength;
287 gas->SetShape(getRoundedShape(Form("%sGas", name), kGasHalfThickness, x, -y, curvRad));
288
289 x = kRoundedPCBLength - pcbLength / 2 - kVertSpacerHalfLength;
290
291 bend->SetShape(getRoundedShape(Form("%sBend", name), kCathodeHalfThickness, x, -y, curvRad));
292
293 nonbend->SetShape(getRoundedShape(Form("%sNonBend", name), kCathodeHalfThickness, x, -y, curvRad));
294
295 insu->SetShape(getRoundedShape(Form("%sInsu", name), kInsuHalfThickness, x, -y, curvRad));
296
297 if (pcbName.back() != '1') { // change the bottom spacer and border shape for "R2" and "R3" PCBs
298
299 spacer->SetShape(getRoundedShape(Form("%sBottomSpacer", name), kSpacerHalfThickness, x, -y + kGasHalfHeight + kHoriSpacerHalfHeight, radius));
300
301 borderLength -= (pcbName.back() == '3') ? curvRad : curvRad + kRoundedSpacerHalfLength;
302 }
303 }
304
306 float halfThickness = kGasHalfThickness;
307 pcb->AddNode(gas, 1, new TGeoTranslation(gasShift / 2, 0., 0.));
308 float z = halfThickness;
309
310 halfThickness = kCathodeHalfThickness;
311 x = pcbShift / 2;
312 z += halfThickness;
313 pcb->AddNode(bend, 1, new TGeoTranslation(x, 0., z));
314 pcb->AddNode(nonbend, 2, new TGeoTranslation(x, 0., -z));
315 z += halfThickness;
316
317 halfThickness = kInsuHalfThickness;
318 z += halfThickness;
319 pcb->AddNode(insu, 1, new TGeoTranslation(x, 0., z));
320 pcb->AddNode(insu, 2, new TGeoTranslation(x, 0., -z));
321 z += halfThickness;
322
323 // the horizontal spacers
325 pcb->AddNode(gGeoManager->GetVolume(Form("Top spacer %.2f long", pcbLength)), 1, new TGeoTranslation(x, y, 0.));
326 pcb->AddNode(spacer, 1, new TGeoTranslation(x, -y, 0.));
327
328 // the borders
330 pcb->AddNode(gGeoManager->GetVolume(Form("Top border %.2f long", pcbLength)), 1, new TGeoTranslation(x, y, 0.));
331 x = (pcbShift - pcbLength + borderLength) / 2;
332 pcb->AddNode(gGeoManager->MakeBox(Form("%s bottom border", name), assertMedium(Medium::Rohacell),
333 borderLength / 2, kBorderHalfHeight, kBorderHalfThickness),
334 1, new TGeoTranslation(x, -y, 0.));
335
336 // the DualSampa read-out cards
337 halfThickness = kDualSampaHalfThickness;
338 z += halfThickness;
339 for (int i = 0; i < dualSampas.size(); i++) {
340
341 nDualSampas = dualSampas[i];
342 length = (i % 2) ? borderLength : pcbLength;
343 shift = (i % 2) ? TMath::Power(-1, isRounded(pcbName)) * (pcbLength - borderLength) : 0.;
344 y = TMath::Power(-1, i % 2) * kDualSampaYPos;
345 z = TMath::Power(-1, i / 2) * TMath::Abs(z);
346
347 for (int j = 0; j < nDualSampas; j++) {
348 pcb->AddNode(dualSampaVol, 100 * i + j,
349 new TGeoTranslation((j - nDualSampas / 2) * (length / nDualSampas) - (nDualSampas % 2 - 1) * (length / (2 * nDualSampas)) +
350 (pcbShift + shift) / 2,
351 y, z));
352 }
353 } // end of the MANUs loop
354 } // end of the PCBs loop
355}
356
357//______________________________________________________________________________
359{
362
363 const auto kSpacerMed = assertMedium(Medium::Noryl);
364 auto leftSpacer = gGeoManager->GetVolume("Left spacer");
365
366 // Mirror rotation for the slat panel on the non-bending side
367 auto mirror = new TGeoRotation();
368 mirror->ReflectZ(true);
369
370 for (const auto& [typeName, pcbVector] : kSlatTypes) {
371
372 auto name = (const char*)typeName.data(); // slat name (easier to name volumes)
373
374 // create the slat volume assembly
375 auto slat = new TGeoVolumeAssembly(name);
376
377 // Reset slat variables
378 float direction = TMath::Power(-1, isRounded(typeName)); // rounded and "normal" slats are built in opposite x-axis direction (mapping convention)
379 float halfLength = 2 * 2 * kVertSpacerHalfLength; // vertical spacers
380 float center = (pcbVector.size() - 1) * kGasLength / 2;
381 float panelShift = 0.;
382 int iVol = 0;
383
384 // loop over the number of PCBs in the current slat
385 for (const auto& pcb : pcbVector) {
386
387 float gasLength = kGasLength;
388 float pcbLength = kPCBLength;
389
390 switch (pcb.front()) {
391 case 'R':
392 pcbLength = (pcb.back() == '1') ? kR1PCBLength : kRoundedPCBLength;
393 panelShift += pcbLength - kRoundedPCBLength;
394 break;
395 case 'S':
396 pcbLength = kShortPCBLength;
397 gasLength = kShortPCBLength;
398 panelShift += direction * (pcbLength - kPCBLength);
399 break;
400 }
401
402 halfLength += pcbLength;
403
404 // place the corresponding PCB volume in the slat and correct the origin of the slat
405 slat->AddNode(gGeoManager->GetVolume(pcb.data()), iVol + 1,
406 new TGeoTranslation(iVol * kPCBLength - direction * (kPCBLength - gasLength) / 2 - center, 0, 0));
407 iVol++;
408
409 } // end of the PCBs loop
410 panelShift /= 2;
411 halfLength /= 2;
412
413 // compute the LV cable length
414 float cableHalfLength = (typeName.find('3') < typeName.size()) ? kSt45SupportHalfLength : kCh5SupportHalfLength;
415 if (typeName == "122200N") {
416 cableHalfLength = kCh6SupportHalfLength;
417 }
418 cableHalfLength -= halfLength;
419 if (typeName == "122330N") {
420 cableHalfLength -= kGasLength / 2;
421 }
422
423 float rightSpacerHalfHeight = kSlatPanelHalfHeight;
424 if (isRounded(typeName)) {
425 halfLength -= kVertSpacerHalfLength; // don't count the vertical spacer length twice in the case of rounded slat
426 rightSpacerHalfHeight = kGasHalfHeight; // to avoid overlaps with the horizontal spacers
427 }
428
429 // right vertical spacer
430 auto rightSpacer = new TGeoVolume(Form("%s right spacer", name),
431 new TGeoBBox(Form("%sRightSpacerBox", name), kVertSpacerHalfLength, rightSpacerHalfHeight, kSpacerHalfThickness), kSpacerMed);
432
433 // glue a slat panel on each side of the PCBs
434 auto panel = new TGeoVolumeAssembly(Form("%s panel", name));
435
436 float x = halfLength;
437 float halfHeight = kSlatPanelHalfHeight;
438
439 // glue
440 auto glue = new TGeoVolume(Form("%s panel glue", name), new TGeoBBox(Form("%sGlueBox", name), x, halfHeight, kGlueHalfThickness), assertMedium(Medium::Glue));
441
442 // nomex (bulk)
443 auto nomexBulk = new TGeoVolume(Form("%s panel nomex (bulk)", name), new TGeoBBox(Form("%sNomexBulkBox", name), x, halfHeight, kNomexBulkHalfThickness), assertMedium(Medium::BulkNomex));
444
445 // carbon fiber
446 auto carbon = new TGeoVolume(Form("%s panel carbon fiber", name), new TGeoBBox(Form("%sCarbonBox", name), x, halfHeight, kCarbonHalfThickness), assertMedium(Medium::Carbon));
447
448 // nomex (honeycomb)
449 auto nomex = new TGeoVolume(Form("%s panel nomex (honeycomb)", name), new TGeoBBox(Form("%sNomexBox", name), x, halfHeight, kNomexHalfThickness), assertMedium(Medium::HoneyNomex));
450
451 // change the volume shape if we are creating a rounded slat
452 if (isRounded(typeName)) {
453
454 // LHC beam pipe radius ("NR3" -> it is a slat of a station 4 or 5)
455 float radius = (typeName.back() == '3') ? kSt45Radius : kSt3Radius;
456
457 // extreme angle values for the rounded spacer
458 float angMin = 90., angMax = 180.;
459
460 // position of the slat center w.r.t the beam pipe center
461 x = halfLength - kVertSpacerHalfLength;
462 float y = 0.;
463 float xRoundedPos = x + panelShift;
464
465 // change the LV cable length for st.3 slats
466 cableHalfLength = (isShort(typeName)) ? kCh5SupportHalfLength : kCh6SupportHalfLength;
467
468 // change the above values if necessary
469 switch (typeName.back()) { // get the last character
470 case '1': // central for "S(N)R1"
471 y = 0.;
472 x = 2 * kPCBLength - panelShift + kVertSpacerHalfLength;
474 angMin = angMax - TMath::RadToDeg() * TMath::ACos((kRoundedPCBLength - kR1PCBLength - kRoundedSpacerHalfLength) / radius);
475 angMax = -angMin;
476 break;
477 case '2': // "S(N)R2" -> station 3
479 angMax = angMax - TMath::RadToDeg() * TMath::ASin((y - kSlatPanelHalfHeight) / (radius + kRoundedSpacerHalfLength));
480 break;
481 default: // "NR3" -> station 4 or 5
483 angMax = angMax - TMath::RadToDeg() * TMath::ASin((y - kSlatPanelHalfHeight) / (radius + kRoundedSpacerHalfLength));
484 cableHalfLength = kSt45SupportHalfLength;
485 break;
486 }
487
488 cableHalfLength -= (x + halfLength) / 2;
489
490 // create and place the rounded spacer
491 slat->AddNode(gGeoManager->MakeTubs(Form("%s rounded spacer", name), kSpacerMed, radius,
492 radius + 2 * kRoundedSpacerHalfLength, kSpacerHalfThickness, angMin, angMax),
493 1, new TGeoTranslation(xRoundedPos, -y, 0.));
494
495 glue->SetShape(getRoundedShape(Form("%sGlue", name), kGlueHalfThickness, x, -y, radius));
496
497 nomexBulk->SetShape(getRoundedShape(Form("%sNomexBulk", name), kNomexBulkHalfThickness, x, -y, radius));
498
499 carbon->SetShape(getRoundedShape(Form("%sCarbon", name), kCarbonHalfThickness, x, -y, radius));
500
501 nomex->SetShape(getRoundedShape(Form("%sNomex", name), kNomexHalfThickness, x, -y, radius));
502
503 rightSpacer->SetShape(getRoundedShape(Form("%sRightSpacer", name), kSpacerHalfThickness, 0., -y, radius));
504
505 } // end of the "rounded" condition
506
507 // place all the layers in the slat panel volume assembly (the panel origin is on the glue edge !)
508
509 float halfThickness = kGlueHalfThickness;
510 float z = halfThickness;
511 panel->AddNode(glue, 1, new TGeoTranslation(0., 0., z));
512 z += halfThickness;
513
514 halfThickness = kNomexBulkHalfThickness;
515 z += halfThickness;
516 panel->AddNode(nomexBulk, 1, new TGeoTranslation(0., 0., z));
517 z += halfThickness;
518
519 halfThickness = kGlueHalfThickness;
520 z += halfThickness;
521 panel->AddNode(glue, 2, new TGeoTranslation(0., 0., z));
522 z += halfThickness;
523
524 halfThickness = kCarbonHalfThickness;
525 z += halfThickness;
526 panel->AddNode(carbon, 1, new TGeoTranslation(0., 0., z));
527 z += halfThickness;
528
529 halfThickness = kNomexHalfThickness;
530 z += halfThickness;
531 panel->AddNode(nomex, 1, new TGeoTranslation(0., 0., z));
532 z += halfThickness;
533
534 halfThickness = kCarbonHalfThickness;
535 z += halfThickness;
536 panel->AddNode(carbon, 2, new TGeoTranslation(0., 0., z));
537
538 // place the panel volume on each side of the slat volume assembly
539 x = panelShift;
541 slat->AddNode(panel, 1, new TGeoTranslation(x, 0., z));
542 slat->AddNode(panel, 2, new TGeoCombiTrans(x, 0., -z, mirror));
543
544 // place the vertical spacers
545 x = halfLength - kVertSpacerHalfLength;
546 slat->AddNode(leftSpacer, 1, new TGeoTranslation(-(x - panelShift), 0., 0.));
547 // don't place a right spacer for S(N)R1 slat
548 if (typeName.back() != '1') {
549 slat->AddNode(rightSpacer, 1, new TGeoTranslation(x + panelShift, 0., 0.));
550 }
551
552 // place the LV cables (top and bottom)
553 auto LVcable = gGeoManager->MakeBox(Form("%s LV cable", name), assertMedium(Medium::Copper), cableHalfLength + kVertSpacerHalfLength, kLVCableHalfHeight, kLVCableHalfThickness);
554 x = direction * (x + cableHalfLength + direction * panelShift);
555
557 slat->AddNode(LVcable, 1, new TGeoTranslation(x, y, 0));
558 slat->AddNode(LVcable, 2, new TGeoTranslation(x, -y, 0));
559
560 } // end of the slat loop
561}
562
563//______________________________________________________________________________
565{
567
568 // dimensions
569 float halfLength = 0., halfHeight = 0.;
570
571 for (int i = 5; i <= 10; i++) {
572
573 // define the support panel volume
574 auto support = new TGeoVolumeAssembly(Form("Chamber %d support panel", i));
575
576 if (i <= 6) { // station 3 half-chambers
577 halfHeight = kSt3SupportHalfHeight;
578 halfLength = (i == 5) ? kCh5SupportHalfLength : kCh6SupportHalfLength;
579 } else { // station 4 or 5
580 halfLength = kSt45SupportHalfLength;
581 halfHeight = (i <= 8) ? kSt4SupportHalfHeight : kSt5SupportHalfHeight;
582 }
583
584 // LHC beam pipe radius at the given chamber z position
585 float radius = (i <= 6) ? kSt3Radius : kSt45Radius;
586
587 float x = -halfLength + kVertSpacerHalfLength;
588
589 float halfThickness = kNomexSupportHalfThickness;
590 float z = 0.;
591
592 // create a box for the nomex volume
593 const char* nomexName = Form("NomexSupportPanelCh%d", i);
594 new TGeoBBox(Form("%sBox", nomexName), halfLength, halfHeight, halfThickness);
595
596 support->AddNode(new TGeoVolume(nomexName, getRoundedShape(nomexName, halfThickness, x, 0., radius), assertMedium(Medium::HoneyNomex)),
597 i, new TGeoTranslation(halfLength, 0., z));
598
599 z += halfThickness; // increment this value when adding a new layer
600
601 // create a box for the glue volume
602 halfThickness = kGlueSupportHalfThickness;
603 const char* glueName = Form("GlueSupportPanelCh%d", i);
604 new TGeoBBox(Form("%sBox", glueName), halfLength, halfHeight, halfThickness);
605
606 auto glue = new TGeoVolume(glueName, getRoundedShape(glueName, halfThickness, x, 0., radius), assertMedium(Medium::Glue));
607
608 // place it on each side of the nomex volume
609 z += halfThickness;
610 support->AddNode(glue, 1, new TGeoTranslation(halfLength, 0., z));
611 support->AddNode(glue, 2, new TGeoTranslation(halfLength, 0., -z));
612 z += halfThickness;
613
614 // create a box for the carbon volume
615 halfThickness = kCarbonSupportHalfThickness;
616 const char* carbonName = Form("CarbonSupportPanelCh%d", i);
617 new TGeoBBox(Form("%sBox", carbonName), halfLength, halfHeight, halfThickness);
618
619 auto carbon = new TGeoVolume(carbonName, getRoundedShape(carbonName, halfThickness, x, 0., radius), assertMedium(Medium::Carbon));
620
621 // place it on each side of the glue volume
622 z += halfThickness;
623 support->AddNode(carbon, 1, new TGeoTranslation(halfLength, 0., z));
624 support->AddNode(carbon, 2, new TGeoTranslation(halfLength, 0., -z));
625
626 } // end of the chamber loop
627}
628
629//______________________________________________________________________________
630void buildHalfChambers(TGeoVolume& topVolume)
631{
634
635 // read the json containing all the necessary parameters to place the slat volumes in the half-chambers
636 StringStream is(jsonSlatDescription.c_str());
637
638 Document doc;
639 doc.ParseStream(is);
640
641 // get the "half-chambers" array
642 Value& hChs = doc["HalfChambers"];
643 assert(hChs.IsArray());
644
645 // mother volume to place the half-chambers
646 auto motherVolume = &topVolume;
647
648 // loop over the objects (half-chambers) of the array
649 for (const auto& halfCh : hChs.GetArray()) {
650 // check that "halfCh" is an object
651 if (!halfCh.IsObject()) {
652 throw runtime_error("Can't create the half-chambers : wrong Value input");
653 }
654
655 int moduleID = halfCh["moduleID"].GetInt();
656 const string name = halfCh["name"].GetString();
657 // get the chamber number (if the chamber name has a '0' at the 3rd digit, take the number after; otherwise it's the
658 // chamber 10)
659 int nCh = (name.find('0') == 2) ? name[3] - '0' : 10;
660
661 auto halfChVol = new TGeoVolumeAssembly(name.data());
662
663 // place the support panel corresponding to the chamber number
664 auto supRot = new TGeoRotation();
665 if (moduleID % 2) {
666 supRot->RotateY(180.);
667 }
668 halfChVol->AddNode(gGeoManager->GetVolume(Form("Chamber %d support panel", nCh)), moduleID, supRot);
669
670 // place the slat volumes on the different nodes of the half-chamber
671 for (const auto& slat : halfCh["nodes"].GetArray()) {
672 // check that "slat" is an object
673 if (!slat.IsObject()) {
674 throw runtime_error("Can't create the slat : wrong Value input");
675 }
676
677 int detID = slat["detID"].GetInt();
678
679 // place the slat on the half-chamber volume
680 halfChVol->AddNode(
681 gGeoManager->GetVolume(slat["type"].GetString()), detID,
682 new TGeoCombiTrans(slat["position"][0].GetDouble(), slat["position"][1].GetDouble(),
683 slat["position"][2].GetDouble(),
684 new TGeoRotation(Form("Slat%drotation", detID), slat["rotation"][0].GetDouble(),
685 slat["rotation"][1].GetDouble(), slat["rotation"][2].GetDouble(),
686 slat["rotation"][3].GetDouble(), slat["rotation"][4].GetDouble(),
687 slat["rotation"][5].GetDouble())));
688
689 } // end of the node loop
690
691 auto halfChCTrans = new TGeoCombiTrans(halfCh["position"][0].GetDouble(), halfCh["position"][1].GetDouble(), halfCh["position"][2].GetDouble(),
692 new TGeoRotation(
693 Form("%srotation", name.data()),
694 halfCh["rotation"][0].GetDouble(), halfCh["rotation"][1].GetDouble(),
695 halfCh["rotation"][2].GetDouble(), halfCh["rotation"][3].GetDouble(),
696 halfCh["rotation"][4].GetDouble(), halfCh["rotation"][5].GetDouble()));
697
698 // change the mother volume if the Dipole and/or 'YOUT2' are present in the geometry
699 if ((nCh == 5 || nCh == 6) && gGeoManager->GetVolume("Dipole")) {
700 motherVolume = gGeoManager->GetVolume("DDIP");
701
702 // z > 0 convention for dipole volumes
703 // the dipole passive volume will be rotated 180 around y
704 // when put into cave, so have to compensate for that here
705 halfChCTrans->RotateY(180.);
706 }
707
708 if (nCh > 6 && gGeoManager->GetVolume("YOUT2")) {
709 motherVolume = gGeoManager->GetVolume("YOUT2");
710 }
711
712 // place the half-chamber in the mother volume
713 motherVolume->AddNode(halfChVol, moduleID, halfChCTrans);
714
715 } // end of the half-chambers loop
716}
717
718//______________________________________________________________________________
719vector<TGeoVolume*> getStation345SensitiveVolumes()
720{
722
723 vector<TGeoVolume*> sensitiveVolumeNames;
724 for (const auto& [name, nonUsed] : kPcbTypes) {
725
726 auto vol = gGeoManager->GetVolume(Form("%s gas", name.c_str()));
727
728 if (!vol) {
729 throw runtime_error(Form("could not get expected volume %s", name.c_str()));
730 } else {
731 sensitiveVolumeNames.push_back(vol);
732 }
733 }
734 return sensitiveVolumeNames;
735}
736
737//______________________________________________________________________________
738void createStation345Geometry(TGeoVolume& topVolume)
739{
742
743 // create the identical volumes shared by many elements
745
746 // create the different PCB types
747 createPCBs();
748
749 // create the support panels
751
752 // create the different slat types
753 createSlats();
754
755 // create and place the half-chambers in the top volume
756 buildHalfChambers(topVolume);
757}
758
759//______________________________________________________________________________
760
763 R"(
764{
765 "HalfChambers": [
766 {
767 "name":"SC05I",
768 "moduleID":8,
769 "position":[0.00, -0.1074, -959.75],
770 "rotation":[90, 0, 90.794, 90, 0.794, 90],
771 "nodes":[
772 {
773 "detID":500,
774 "type":"122000SR1",
775 "position":[81.25, 0.00, 4.00],
776 "rotation":[90, 180, 90, 90, 180, 0]
777 },
778 {
779 "detID":501,
780 "type":"112200SR2",
781 "position":[81.25, 37.80, -4.00],
782 "rotation":[90, 180, 90, 90, 180, 0]
783 },
784 {
785 "detID":502,
786 "type":"122200S",
787 "position":[81.25, 75.50, 4.00],
788 "rotation":[90, 0, 90, 270, 180, 0]
789 },
790 {
791 "detID":503,
792 "type":"222000N",
793 "position":[61.25, 112.80, -4.00],
794 "rotation":[90, 0, 90, 90, 0, 0]
795 },
796 {
797 "detID":504,
798 "type":"220000N",
799 "position":[41.25, 146.50, 4.00],
800 "rotation":[90, 0, 90, 270, 180, 0]
801 },
802 {
803 "detID":514,
804 "type":"220000N",
805 "position":[41.25, -146.50, 4.00],
806 "rotation":[90, 0, 90, 270, 180, 0]
807 },
808 {
809 "detID":515,
810 "type":"222000N",
811 "position":[61.25, -112.80, -4.00],
812 "rotation":[90, 0, 90, 90, 0, 0]
813 },
814 {
815 "detID":516,
816 "type":"122200S",
817 "position":[81.25, -75.50, 4.00],
818 "rotation":[90, 0, 90, 270, 180, 0]
819 },
820 {
821 "detID":517,
822 "type":"112200SR2",
823 "position":[81.25, -37.80, -4.00],
824 "rotation":[90, 180, 90, 270, 0, 0]
825 }
826 ]
827 },
828
829 {
830 "name":"SC05O",
831 "moduleID":9,
832 "position":[0.00, 0.1074, -975.25],
833 "rotation":[90, 0, 90.794, 90, 0.794, 90],
834 "nodes":[
835 {
836 "detID":505,
837 "type":"220000N",
838 "position":[-41.25, 146.50, -4.00],
839 "rotation":[90, 180, 90, 270, 0, 0]
840 },
841 {
842 "detID":506,
843 "type":"222000N",
844 "position":[-61.25, 112.80, 4.00],
845 "rotation":[90, 180, 90, 90, 180, 0]
846 },
847 {
848 "detID":507,
849 "type":"122200S",
850 "position":[-81.25, 75.50, -4.00],
851 "rotation":[90, 180, 90, 270, 0, 0]
852 },
853 {
854 "detID":508,
855 "type":"112200SR2",
856 "position":[-81.25, 37.80, 4.00],
857 "rotation":[90, 0, 90, 90, 0, 0]
858 },
859 {
860 "detID":509,
861 "type":"122000SR1",
862 "position":[-81.25, 0.00, -4.00],
863 "rotation":[90, 0, 90, 90, 0, 0]
864 },
865 {
866 "detID":510,
867 "type":"112200SR2",
868 "position":[-81.25, -37.80, 4.00],
869 "rotation":[90, 0, 90, 270, 180, 0]
870 },
871 {
872 "detID":511,
873 "type":"122200S",
874 "position":[-81.25, -75.50, -4.00],
875 "rotation":[90, 180, 90, 270, 0, 0]
876 },
877 {
878 "detID":512,
879 "type":"222000N",
880 "position":[-61.25, -112.80, 4.00],
881 "rotation":[90, 180, 90, 90, 180, 0]
882 },
883 {
884 "detID":513,
885 "type":"220000N",
886 "position":[-41.25, -146.50, -4.00],
887 "rotation":[90, 180, 90, 270, 0, 0]
888 }
889 ]
890 },
891
892 {
893 "name":"SC06I",
894 "moduleID":10,
895 "position":[0.00, -0.1074, -990.75],
896 "rotation":[90, 0, 90.794, 90, 0.794, 90],
897 "nodes":[
898 {
899 "detID":600,
900 "type":"122000NR1",
901 "position":[81.25, 0.00, 4.00],
902 "rotation":[90, 180, 90, 90, 180, 0]
903 },
904 {
905 "detID":601,
906 "type":"112200NR2",
907 "position":[81.25, 37.80, -4.00],
908 "rotation":[90, 180, 90, 90, 180, 0]
909 },
910 {
911 "detID":602,
912 "type":"122200N",
913 "position":[81.25, 75.50, 4.00],
914 "rotation":[90, 0, 90, 270, 180, 0]
915 },
916 {
917 "detID":603,
918 "type":"222000N",
919 "position":[61.25, 112.80, -4.00],
920 "rotation":[90, 0, 90, 90, 0, 0]
921 },
922 {
923 "detID":604,
924 "type":"220000N",
925 "position":[41.25, 146.50, 4.00],
926 "rotation":[90, 0, 90, 270, 180, 0]
927 },
928 {
929 "detID":614,
930 "type":"220000N",
931 "position":[41.25, -146.50, 4.00],
932 "rotation":[90, 0, 90, 270, 180, 0]
933 },
934 {
935 "detID":615,
936 "type":"222000N",
937 "position":[61.25, -112.80, -4.00],
938 "rotation":[90, 0, 90, 90, 0, 0]
939 },
940 {
941 "detID":616,
942 "type":"122200N",
943 "position":[81.25, -75.50, 4.00],
944 "rotation":[90, 0, 90, 270, 180, 0]
945 },
946 {
947 "detID":617,
948 "type":"112200NR2",
949 "position":[81.25, -37.80, -4.00],
950 "rotation":[90, 180, 90, 270, 0, 0]
951 }
952 ]
953 },
954
955 {
956 "name":"SC06O",
957 "moduleID":11,
958 "position":[0.00, 0.1074, -1006.25],
959 "rotation":[90, 0, 90.794, 90, 0.794, 90],
960 "nodes":[
961 {
962 "detID":605,
963 "type":"220000N",
964 "position":[-41.25, 146.50, -4.00],
965 "rotation":[90, 180, 90, 270, 0, 0]
966 },
967 {
968 "detID":606,
969 "type":"222000N",
970 "position":[-61.25, 112.80, 4.00],
971 "rotation":[90, 180, 90, 90, 180, 0]
972 },
973 {
974 "detID":607,
975 "type":"122200N",
976 "position":[-81.25, 75.50, -4.00],
977 "rotation":[90, 180, 90, 270, 0, 0]
978 },
979 {
980 "detID":608,
981 "type":"112200NR2",
982 "position":[-81.25, 37.80, 4.00],
983 "rotation":[90, 0, 90, 90, 0, 0]
984 },
985 {
986 "detID":609,
987 "type":"122000NR1",
988 "position":[-81.25, 0.00, -4.00],
989 "rotation":[90, 0, 90, 90, 0, 0]
990 },
991 {
992 "detID":610,
993 "type":"112200NR2",
994 "position":[-81.25, -37.80, 4.00],
995 "rotation":[90, 0, 90, 270, 180, 0]
996 },
997 {
998 "detID":611,
999 "type":"122200N",
1000 "position":[-81.25, -75.5, -4.00],
1001 "rotation":[90, 180, 90, 270, 0, 0]
1002 },
1003 {
1004 "detID":612,
1005 "type":"222000N",
1006 "position":[-61.25, -112.80, 4.00],
1007 "rotation":[90, 180, 90, 90, 180, 0]
1008 },
1009 {
1010 "detID":613,
1011 "type":"220000N",
1012 "position":[-41.25, -146.50, -4.00],
1013 "rotation":[90, 180, 90, 270, 0, 0]
1014 }
1015 ]
1016 },
1017
1018 {
1019 "name":"SC07I",
1020 "moduleID":12,
1021 "position":[0.00, -0.1074, -1268.75],
1022 "rotation":[90, 0, 90.794, 90, 0.794, 90],
1023 "nodes":[
1024 {
1025 "detID":700,
1026 "type":"122330N",
1027 "position":[140.00, 0.00, 4.25],
1028 "rotation":[90, 0, 90, 270, 180, 0]
1029 },
1030 {
1031 "detID":701,
1032 "type":"112233NR3",
1033 "position":[121.25, 38.20, -4.25],
1034 "rotation":[90, 180, 90, 90, 180, 0]
1035 },
1036 {
1037 "detID":702,
1038 "type":"112230N",
1039 "position":[101.25, 72.60, 4.25],
1040 "rotation":[90, 0, 90, 270, 180, 0]
1041 },
1042 {
1043 "detID":703,
1044 "type":"222330N",
1045 "position":[101.25, 109.20, -4.25],
1046 "rotation":[90, 0, 90, 90, 0, 0]
1047 },
1048 {
1049 "detID":704,
1050 "type":"223300N",
1051 "position":[81.25, 138.50, 4.25],
1052 "rotation":[90, 0, 90, 270, 180, 0]
1053 },
1054 {
1055 "detID":705,
1056 "type":"333000N",
1057 "position":[61.25, 175.50, -4.25],
1058 "rotation":[90, 0, 90, 90, 0, 0]
1059 },
1060 {
1061 "detID":706,
1062 "type":"330000N",
1063 "position":[41.25, 204.50, 4.25],
1064 "rotation":[90, 0, 90, 270, 180, 0]
1065 },
1066 {
1067 "detID":720,
1068 "type":"330000N",
1069 "position":[41.25, -204.50, 4.25],
1070 "rotation":[90, 0, 90, 270, 180, 0]
1071 },
1072 {
1073 "detID":721,
1074 "type":"333000N",
1075 "position":[61.25, -175.50, -4.25],
1076 "rotation":[90, 0, 90, 90, 0, 0]
1077 },
1078 {
1079 "detID":722,
1080 "type":"223300N",
1081 "position":[81.25, -138.50, 4.25],
1082 "rotation":[90, 0, 90, 270, 180, 0]
1083 },
1084 {
1085 "detID":723,
1086 "type":"222330N",
1087 "position":[101.25, -109.20, -4.25],
1088 "rotation":[90, 0, 90, 90, 0, 0]
1089 },
1090 {
1091 "detID":724,
1092 "type":"112230N",
1093 "position":[101.25, -72.60, 4.25],
1094 "rotation":[90, 0, 90, 270, 180, 0]
1095 },
1096 {
1097 "detID":725,
1098 "type":"112233NR3",
1099 "position":[121.25, -38.20, -4.25],
1100 "rotation":[90, 180, 90, 270, 0, 0]
1101 }
1102 ]
1103 },
1104
1105 {
1106 "name":"SC07O",
1107 "moduleID":13,
1108 "position":[0.00, -0.1074, -1284.25],
1109 "rotation":[90, 0, 90.794, 90, 0.794, 90],
1110 "nodes":[
1111 {
1112 "detID":707,
1113 "type":"330000N",
1114 "position":[-41.25, 204.5, -4.25],
1115 "rotation":[90, 180, 90, 270, 0, 0]
1116 },
1117 {
1118 "detID":708,
1119 "type":"333000N",
1120 "position":[-61.25, 175.50, 4.25],
1121 "rotation":[90, 180, 90, 90, 180, 0]
1122 },
1123 {
1124 "detID":709,
1125 "type":"223300N",
1126 "position":[-81.25, 138.50, -4.25],
1127 "rotation":[90, 180, 90, 270, 0, 0]
1128 },
1129 {
1130 "detID":710,
1131 "type":"222330N",
1132 "position":[-101.25, 109.20, 4.25],
1133 "rotation":[90, 180, 90, 90, 180, 0]
1134 },
1135 {
1136 "detID":711,
1137 "type":"112230N",
1138 "position":[-101.25, 72.60, -4.25],
1139 "rotation":[90, 180, 90, 270, 0, 0]
1140 },
1141 {
1142 "detID":712,
1143 "type":"112233NR3",
1144 "position":[-121.25, 38.20, 4.25],
1145 "rotation":[90, 0, 90, 90, 0, 0]
1146 },
1147 {
1148 "detID":713,
1149 "type":"122330N",
1150 "position":[-140.00, 0.00, -4.25],
1151 "rotation":[90, 180, 90, 270, 0, 0]
1152 },
1153 {
1154 "detID":714,
1155 "type":"112233NR3",
1156 "position":[-121.25, -38.20, 4.25],
1157 "rotation":[90, 0, 90, 270, 180, 0]
1158 },
1159 {
1160 "detID":715,
1161 "type":"112230N",
1162 "position":[-101.25, -72.60, -4.25],
1163 "rotation":[90, 180, 90, 270, 0, 0]
1164 },
1165 {
1166 "detID":716,
1167 "type":"222330N",
1168 "position":[-101.25, -109.20, 4.25],
1169 "rotation":[90, 180, 90, 90, 180, 0]
1170 },
1171 {
1172 "detID":717,
1173 "type":"223300N",
1174 "position":[-81.25, -138.50, -4.25],
1175 "rotation":[90, 180, 90, 270, 0, 0]
1176 },
1177 {
1178 "detID":718,
1179 "type":"333000N",
1180 "position":[-61.25, -175.50, 4.25],
1181 "rotation":[90, 180, 90, 90, 180, 0]
1182 },
1183 {
1184 "detID":719,
1185 "type":"330000N",
1186 "position":[-41.25, -204.50, -4.25],
1187 "rotation":[90, 180, 90, 270, 0, 0]
1188 }
1189 ]
1190 },
1191
1192 {
1193 "name":"SC08I",
1194 "moduleID":14,
1195 "position":[0.00, -0.1074, -1299.75],
1196 "rotation":[90, 0, 90.794, 90, 0.794, 90],
1197 "nodes":[
1198 {
1199 "detID":800,
1200 "type":"122330N",
1201 "position":[140.00, 0.00, 4.25],
1202 "rotation":[90, 0, 90, 270, 180, 0]
1203 },
1204 {
1205 "detID":801,
1206 "type":"112233NR3",
1207 "position":[121.25, 38.20, -4.25],
1208 "rotation":[90, 180, 90, 90, 180, 0]
1209 },
1210 {
1211 "detID":802,
1212 "type":"112230N",
1213 "position":[101.25, 76.05, 4.25],
1214 "rotation":[90, 0, 90, 270, 180, 0]
1215 },
1216 {
1217 "detID":803,
1218 "type":"222330N",
1219 "position":[101.25, 113.60, -4.25],
1220 "rotation":[90, 0, 90, 90, 0, 0]
1221 },
1222 {
1223 "detID":804,
1224 "type":"223300N",
1225 "position":[81.25, 143.00, 4.25],
1226 "rotation":[90, 0, 90, 270, 180, 0]
1227 },
1228 {
1229 "detID":805,
1230 "type":"333000N",
1231 "position":[61.25, 180.00, -4.25],
1232 "rotation":[90, 0, 90, 90, 0, 0]
1233 },
1234 {
1235 "detID":806,
1236 "type":"330000N",
1237 "position":[41.25, 208.60, 4.25],
1238 "rotation":[90, 0, 90, 270, 180, 0]
1239 },
1240 {
1241 "detID":820,
1242 "type":"330000N",
1243 "position":[41.25, -208.60, 4.25],
1244 "rotation":[90, 0, 90, 270, 180, 0]
1245 },
1246 {
1247 "detID":821,
1248 "type":"333000N",
1249 "position":[61.25, -180.00, -4.25],
1250 "rotation":[90, 0, 90, 90, 0, 0]
1251 },
1252 {
1253 "detID":822,
1254 "type":"223300N",
1255 "position":[81.25, -143.00, 4.25],
1256 "rotation":[90, 0, 90, 270, 180, 0]
1257 },
1258 {
1259 "detID":823,
1260 "type":"222330N",
1261 "position":[101.25, -113.60, -4.25],
1262 "rotation":[90, 0, 90, 90, 0, 0]
1263 },
1264 {
1265 "detID":824,
1266 "type":"112230N",
1267 "position":[101.25, -76.05, 4.25],
1268 "rotation":[90, 0, 90, 270, 180, 0]
1269 },
1270 {
1271 "detID":825,
1272 "type":"112233NR3",
1273 "position":[121.25, -38.20, -4.25],
1274 "rotation":[90, 180, 90, 270, 180, 0]
1275 }
1276 ]
1277 },
1278
1279 {
1280 "name":"SC08O",
1281 "moduleID":15,
1282 "position":[0.00, -0.1074, -1315.25],
1283 "rotation":[90, 0, 90.794, 90, 0.794, 90],
1284 "nodes":[
1285 {
1286 "detID":807,
1287 "type":"330000N",
1288 "position":[-41.25, 208.60, -4.25],
1289 "rotation":[90, 180, 90, 270, 0, 0]
1290 },
1291 {
1292 "detID":808,
1293 "type":"333000N",
1294 "position":[-61.25, 180.00, 4.25],
1295 "rotation":[90, 180, 90, 90, 180, 0]
1296 },
1297 {
1298 "detID":809,
1299 "type":"223300N",
1300 "position":[-81.25, 143.00, -4.25],
1301 "rotation":[90, 180, 90, 270, 0, 0]
1302 },
1303 {
1304 "detID":810,
1305 "type":"222330N",
1306 "position":[-101.25, 113.60, 4.25],
1307 "rotation":[90, 180, 90, 90, 180, 0]
1308 },
1309 {
1310 "detID":811,
1311 "type":"112230N",
1312 "position":[-101.25, 76.05, -4.25],
1313 "rotation":[90, 180, 90, 270, 0, 0]
1314 },
1315 {
1316 "detID":812,
1317 "type":"112233NR3",
1318 "position":[-121.25, 38.20, 4.25],
1319 "rotation":[90, 0, 90, 90, 0, 0]
1320 },
1321 {
1322 "detID":813,
1323 "type":"122330N",
1324 "position":[-140.00, 0.00, -4.25],
1325 "rotation":[90, 180, 90, 270, 0, 0]
1326 },
1327 {
1328 "detID":814,
1329 "type":"112233NR3",
1330 "position":[-121.25, -38.20, 4.25],
1331 "rotation":[90, 0, 90, 270, 180, 0]
1332 },
1333 {
1334 "detID":815,
1335 "type":"112230N",
1336 "position":[-101.25, -76.05, -4.25],
1337 "rotation":[90, 180, 90, 270, 0, 0]
1338 },
1339 {
1340 "detID":816,
1341 "type":"222330N",
1342 "position":[-101.25, -113.60, 4.25],
1343 "rotation":[90, 180, 90, 90, 180, 0]
1344 },
1345 {
1346 "detID":817,
1347 "type":"223300N",
1348 "position":[-81.25, -143.00, -4.25],
1349 "rotation":[90, 180, 90, 270, 0, 0]
1350 },
1351 {
1352 "detID":818,
1353 "type":"333000N",
1354 "position":[-61.25, -180.00, 4.25],
1355 "rotation":[90, 180, 90, 90, 180, 0]
1356 },
1357 {
1358 "detID":819,
1359 "type":"330000N",
1360 "position":[-41.25, -208.60, -4.25],
1361 "rotation":[90, 180, 90, 270, 0, 0]
1362 }
1363 ]
1364 },
1365
1366 {
1367 "name":"SC09I",
1368 "moduleID":16,
1369 "position":[0.00, -0.1074, -1398.85],
1370 "rotation":[90, 0, 90.794, 90, 0.794, 90],
1371 "nodes":[
1372 {
1373 "detID":900,
1374 "type":"122330N",
1375 "position":[140.00, 0.00, 4.25],
1376 "rotation":[90, 0, 90, 270, 180, 0]
1377 },
1378 {
1379 "detID":901,
1380 "type":"112233NR3",
1381 "position":[121.25, 38.20, -4.25],
1382 "rotation":[90, 180, 90, 90, 180, 0]
1383 },
1384 {
1385 "detID":902,
1386 "type":"112233N",
1387 "position":[121.25, 76.10, 4.25],
1388 "rotation":[90, 0, 90, 270, 180, 0]
1389 },
1390 {
1391 "detID":903,
1392 "type":"222333N",
1393 "position":[121.25, 113.70, -4.25],
1394 "rotation":[90, 0, 90, 90, 0, 0]
1395 },
1396 {
1397 "detID":904,
1398 "type":"223330N",
1399 "position":[101.25, 151.00, 4.25],
1400 "rotation":[90, 0, 90, 270, 180, 0]
1401 },
1402 {
1403 "detID":905,
1404 "type":"333300N",
1405 "position":[81.25, 188.05, -4.25],
1406 "rotation":[90, 0, 90, 90, 0, 0]
1407 },
1408 {
1409 "detID":906,
1410 "type":"333000N",
1411 "position":[61.25, 224.80, 4.25],
1412 "rotation":[90, 0, 90, 270, 180, 0]
1413 },
1414 {
1415 "detID":920,
1416 "type":"333000N",
1417 "position":[61.25, -224.80, 4.25],
1418 "rotation":[90, 0, 90, 270, 180, 0]
1419 },
1420 {
1421 "detID":921,
1422 "type":"333300N",
1423 "position":[81.25, -188.05, -4.25],
1424 "rotation":[90, 0, 90, 90, 0, 0]
1425 },
1426 {
1427 "detID":922,
1428 "type":"223330N",
1429 "position":[101.25, -151.00, 4.25],
1430 "rotation":[90, 0, 90, 270, 180, 0]
1431 },
1432 {
1433 "detID":923,
1434 "type":"222333N",
1435 "position":[121.25, -113.70, -4.25],
1436 "rotation":[90, 0, 90, 90, 0, 0]
1437 },
1438 {
1439 "detID":924,
1440 "type":"112233N",
1441 "position":[121.25, -76.10, 4.25],
1442 "rotation":[90, 0, 90, 270, 180, 0]
1443 },
1444 {
1445 "detID":925,
1446 "type":"112233NR3",
1447 "position":[121.25, -38.20, -4.25],
1448 "rotation":[90, 180, 90, 270, 0, 0]
1449 }
1450 ]
1451 },
1452
1453 {
1454 "name":"SC09O",
1455 "moduleID":17,
1456 "position":[0.00, -0.1074, -1414.35],
1457 "rotation":[90, 0, 90.794, 90, 0.794, 90],
1458 "nodes":[
1459 {
1460 "detID":907,
1461 "type":"333000N",
1462 "position":[-61.25, 224.80, -4.25],
1463 "rotation":[90, 180, 90, 270, 0, 0]
1464 },
1465 {
1466 "detID":908,
1467 "type":"333300N",
1468 "position":[-81.25, 188.05, 4.25],
1469 "rotation":[90, 180, 90, 90, 180, 0]
1470 },
1471 {
1472 "detID":909,
1473 "type":"223330N",
1474 "position":[-101.25, 151.00, -4.25],
1475 "rotation":[90, 180, 90, 270, 0, 0]
1476 },
1477 {
1478 "detID":910,
1479 "type":"222333N",
1480 "position":[-121.25, 113.70, 4.25],
1481 "rotation":[90, 180, 90, 90, 180, 0]
1482 },
1483 {
1484 "detID":911,
1485 "type":"112233N",
1486 "position":[-121.25, 76.10, -4.25],
1487 "rotation":[90, 180, 90, 270, 0, 0]
1488 },
1489 {
1490 "detID":912,
1491 "type":"112233NR3",
1492 "position":[-121.25, 38.20, 4.25],
1493 "rotation":[90, 0, 90, 90, 0, 0]
1494 },
1495 {
1496 "detID":913,
1497 "type":"122330N",
1498 "position":[-140.00, 0.00, -4.25],
1499 "rotation":[90, 180, 90, 270, 0, 0]
1500 },
1501 {
1502 "detID":914,
1503 "type":"112233NR3",
1504 "position":[-121.25, -38.20, 4.25],
1505 "rotation":[90, 0, 90, 270, 180, 0]
1506 },
1507 {
1508 "detID":915,
1509 "type":"112233N",
1510 "position":[-121.25, -76.10, -4.25],
1511 "rotation":[90, 180, 90, 270, 0, 0]
1512 },
1513 {
1514 "detID":916,
1515 "type":"222333N",
1516 "position":[-121.25, -113.70, 4.25],
1517 "rotation":[90, 180, 90, 90, 180, 0]
1518 },
1519 {
1520 "detID":917,
1521 "type":"223330N",
1522 "position":[-101.25, -151, -4.25],
1523 "rotation":[90, 180, 90, 270, 0, 0]
1524 },
1525 {
1526 "detID":918,
1527 "type":"333300N",
1528 "position":[-81.25, -188.05, 4.25],
1529 "rotation":[90, 180, 90, 90, 180, 0]
1530 },
1531 {
1532 "detID":919,
1533 "type":"333000N",
1534 "position":[-61.25, -224.80, -4.25],
1535 "rotation":[90, 180, 90, 270, 0, 0]
1536 }
1537 ]
1538 },
1539
1540 {
1541 "name":"SC10I",
1542 "moduleID":18,
1543 "position":[0.00, -0.1074, -1429.85],
1544 "rotation":[90, 0, 90.794, 90, 0.794, 90],
1545 "nodes":[
1546 {
1547 "detID":1000,
1548 "type":"122330N",
1549 "position":[140.00, 0.00, 4.25],
1550 "rotation":[90, 0, 90, 270, 180, 0]
1551 },
1552 {
1553 "detID":1001,
1554 "type":"112233NR3",
1555 "position":[121.25, 38.20, -4.25],
1556 "rotation":[90, 180, 90, 90, 180, 0]
1557 },
1558 {
1559 "detID":1002,
1560 "type":"112233N",
1561 "position":[121.25, 76.10, 4.25],
1562 "rotation":[90, 0, 90, 270, 180, 0]
1563 },
1564 {
1565 "detID":1003,
1566 "type":"222333N",
1567 "position":[121.25, 113.70, -4.25],
1568 "rotation":[90, 0, 90, 90, 0, 0]
1569 },
1570 {
1571 "detID":1004,
1572 "type":"223330N",
1573 "position":[101.25, 151.00, 4.25],
1574 "rotation":[90, 0, 90, 270, 180, 0]
1575 },
1576 {
1577 "detID":1005,
1578 "type":"333300N",
1579 "position":[81.25, 188.05, -4.25],
1580 "rotation":[90, 0, 90, 90, 0, 0]
1581 },
1582 {
1583 "detID":1006,
1584 "type":"333000N",
1585 "position":[61.25, 224.80, 4.25],
1586 "rotation":[90, 0, 90, 270, 180, 0]
1587 },
1588 {
1589 "detID":1020,
1590 "type":"333000N",
1591 "position":[61.25, -224.80, 4.25],
1592 "rotation":[90, 0, 90, 270, 180, 0]
1593 },
1594 {
1595 "detID":1021,
1596 "type":"333300N",
1597 "position":[81.25, -188.05, -4.25],
1598 "rotation":[90, 0, 90, 90, 0, 0]
1599 },
1600 {
1601 "detID":1022,
1602 "type":"223330N",
1603 "position":[101.25, -151.00, 4.25],
1604 "rotation":[90, 0, 90, 270, 180, 0]
1605 },
1606 {
1607 "detID":1023,
1608 "type":"222333N",
1609 "position":[121.25, -113.70, -4.25],
1610 "rotation":[90, 0, 90, 90, 0, 0]
1611 },
1612 {
1613 "detID":1024,
1614 "type":"112233N",
1615 "position":[121.25, -76.10, 4.25],
1616 "rotation":[90, 0, 90, 270, 180, 0]
1617 },
1618 {
1619 "detID":1025,
1620 "type":"112233NR3",
1621 "position":[121.25, -38.20, -4.25],
1622 "rotation":[90, 180, 90, 270, 0, 0]
1623 }
1624 ]
1625 },
1626
1627 {
1628 "name":"SC10O",
1629 "moduleID":19,
1630 "position":[0.00, -0.1074, -1445.35],
1631 "rotation":[90, 0, 90.794, 90, 0.794, 90],
1632 "nodes":[
1633 {
1634 "detID":1007,
1635 "type":"333000N",
1636 "position":[-61.25, 224.80, -4.25],
1637 "rotation":[90, 180, 90, 270, 0, 0]
1638 },
1639 {
1640 "detID":1008,
1641 "type":"333300N",
1642 "position":[-81.25, 188.05, 4.25],
1643 "rotation":[90, 180, 90, 90, 180, 0]
1644 },
1645 {
1646 "detID":1009,
1647 "type":"223330N",
1648 "position":[-101.25, 151.00, -4.25],
1649 "rotation":[90, 180, 90, 270, 0, 0]
1650 },
1651 {
1652 "detID":1010,
1653 "type":"222333N",
1654 "position":[-121.25, 113.70, 4.25],
1655 "rotation":[90, 180, 90, 90, 180, 0]
1656 },
1657 {
1658 "detID":1011,
1659 "type":"112233N",
1660 "position":[-121.25, 76.10, -4.25],
1661 "rotation":[90, 180, 90, 270, 0, 0]
1662 },
1663 {
1664 "detID":1012,
1665 "type":"112233NR3",
1666 "position":[-121.25, 38.20, 4.25],
1667 "rotation":[90, 0, 90, 90, 0, 0]
1668 },
1669 {
1670 "detID":1013,
1671 "type":"122330N",
1672 "position":[-140.00, 0.00, -4.25],
1673 "rotation":[90, 180, 90, 270, 0, 0]
1674 },
1675 {
1676 "detID":1014,
1677 "type":"112233NR3",
1678 "position":[-121.25, -38.20, 4.25],
1679 "rotation":[90, 0, 90, 270, 180, 0]
1680 },
1681 {
1682 "detID":1015,
1683 "type":"112233N",
1684 "position":[-121.25, -76.10, -4.25],
1685 "rotation":[90, 180, 90, 270, 0, 0]
1686 },
1687 {
1688 "detID":1016,
1689 "type":"222333N",
1690 "position":[-121.25, -113.70, 4.25],
1691 "rotation":[90, 180, 90, 90, 180, 0]
1692 },
1693 {
1694 "detID":1017,
1695 "type":"223330N",
1696 "position":[-101.25, -151.00, -4.25],
1697 "rotation":[90, 180, 90, 270, 0, 0]
1698 },
1699 {
1700 "detID":1018,
1701 "type":"333300N",
1702 "position":[-81.25, -188.05, 4.25],
1703 "rotation":[90, 180, 90, 90, 180, 0]
1704 },
1705 {
1706 "detID":1019,
1707 "type":"333000N",
1708 "position":[-61.25, -224.80, -4.25],
1709 "rotation":[90, 180, 90, 270, 0, 0]
1710 }
1711 ]
1712 }
1713 ]
1714}
1715
1716)";
1717} // namespace mch
1718} // namespace o2
o2::monitoring::tags::Value Value
int32_t i
Implementation of the MID materials definitions.
uint32_t j
Definition RawData.h:0
Implementation of the slat-stations geometry.
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint const GLchar * name
Definition glcorearb.h:781
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
RuntimeErrorRef runtime_error(const char *)
const float kHoriSpacerHalfHeight
TGeoVolume * getDualSampa()
const float kR1PCBLength
const float kRoundedPCBLength
const float kSt45RoundedSlatYPos
const float kShortPCBLength
const float kGlueSupportHalfThickness
void createStation345Geometry(TGeoVolume &topVolume)
const float kGasLength
Constants.
const float kDualSampaHalfLength
const float kSt5SupportHalfHeight
const float kSt4SupportHalfHeight
const float kBorderHalfHeight
const double kGasHalfThickness
const float kPCBLength
const float kVertSpacerHalfLength
const double kPCBHalfThickness
TGeoMedium * assertMedium(int imed)
const float kCarbonHalfThickness
const float kSt3SupportHalfHeight
const float kCh6SupportHalfLength
const float kLVCableHalfHeight
Cables (copper)
const float kSt45SupportHalfLength
TGeoCompositeShape * getRoundedShape(const char *name, float halfThickness, float xPos, float yPos, float radius)
const float kGasHalfHeight
const double kInsuHalfThickness
const float kLVCableHalfThickness
const float kNomexBulkHalfThickness
const float kDualSampaYPos
const float kBorderHalfThickness
const string jsonSlatDescription
Json string describing all the necessary parameters to place the slats in the half-chambers.
const map< string, vector< string > > kSlatTypes
vector< TGeoVolume * > getStation345SensitiveVolumes()
const float kRoundedSpacerHalfLength
const float kSt3RoundedSlatYPos
const float kSt3Radius
const float kDualSampaHalfHeight
@ HoneyNomex
Definition Materials.h:28
@ Rohacell
Definition Materials.h:33
@ BulkNomex
Definition Materials.h:29
const float kCh5SupportHalfLength
const map< string, array< int, 4 > > kPcbTypes
const float kNomexSupportHalfThickness
void buildHalfChambers(TGeoVolume &topVolume)
bool isRounded(string name)
const float kCarbonSupportHalfThickness
Support panels.
const float kSlatPanelHalfHeight
const float kPCBHalfHeight
const double kCathodeHalfThickness
const float kNomexHalfThickness
const float kGlueHalfThickness
const float kSt45Radius
bool isShort(string name)
void createSupportPanels()
const float kSpacerHalfThickness
void createCommonVolumes()
const float kDualSampaHalfThickness
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.