Project
Loading...
Searching...
No Matches
MIDLayer.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 <TGeoManager.h>
15#include <TMath.h>
16
17#include "Framework/Logger.h"
18
19#include <TGeoTube.h>
20#include <TGeoVolume.h>
21#include <TGeoBBox.h>
22
23namespace o2::mi3
24{
25MIDLayer::MIDLayer(int layerNumber,
26 std::string layerName,
27 float rInn,
28 float length,
29 int nstaves,
30 float zOffset,
31 int nModulesZ,
32 float staveWidth,
33 int nBars) : mName(layerName),
34 mRadius(rInn),
35 mLength(length),
36 mZOffset(zOffset),
37 mStaveWidth(staveWidth),
38 mNumber(layerNumber),
39 mNStaves(nstaves),
40 mNModulesZ(nModulesZ),
41 mNBars(nBars)
42{
43 mStaves.reserve(nstaves);
44 LOGP(debug, "Constructing MIDLayer: {} with inner radius: {}, length: {} cm, {} staves and {} modules/stave", mName, mRadius, mLength, mNStaves, mNModulesZ);
45 for (int iStave = 0; iStave < mNStaves; ++iStave) {
46 mStaves.emplace_back(GeometryTGeo::composeSymNameStave(layerNumber, iStave),
47 mRadius,
48 TMath::TwoPi() / (float)nstaves * iStave,
49 mNumber,
50 iStave,
51 mLength,
52 !(layerNumber % 2) ? 59.8f : 61.75f,
53 0.5f,
54 mNModulesZ,
55 mNBars);
56 }
57}
58
59MIDLayer::Stave::Stave(std::string staveName,
60 float radDistance,
61 float rotAngle,
62 int layer,
63 int number,
64 float staveLength,
65 float staveWidth,
66 float staveThickness,
67 int nModulesZ,
68 int nBars) : mName(staveName),
69 mRadDistance(radDistance),
70 mRotAngle(rotAngle),
71 mLength(staveLength),
72 mWidth(staveWidth),
73 mThickness(staveThickness),
74 mLayer(layer),
75 mNumber(number),
76 mNModulesZ(nModulesZ)
77{
78 // nBars=-1 uses default calibrated for standard radii
79 int effNBars = (nBars < 0) ? (!(mLayer % 2) ? 23 : 20) : nBars;
80 float moduleOffset = -effNBars * 5.2f / 2.f; // 5.2 = 2*barWidth + barSpacing
81 // Staves are ideal shapes made of air including the modules, for now.
82 LOGP(debug, "\t\tConstructing MIDStave: {} layer: {} at angle {} nBars={}", mName, mLayer, mRotAngle * TMath::RadToDeg(), effNBars);
83 mModules.reserve(nModulesZ);
84 for (int iModule = 0; iModule < mNModulesZ; ++iModule) {
85 mModules.emplace_back(GeometryTGeo::composeSymNameModule(mLayer, mNumber, iModule),
86 mLayer,
87 mNumber,
88 iModule,
89 effNBars,
90 -staveLength,
91 !(mLayer % 2) ? 49.9f : 61.75f);
92 }
93}
94
95MIDLayer::Stave::Module::Module(std::string moduleName,
96 int layer,
97 int stave,
98 int number,
99 int nBars,
100 float zOffset,
101 float barLength,
102 float barSpacing,
103 float barWidth,
104 float barThickness) : mName(moduleName),
105 mNBars(nBars),
106 mLayer(layer),
107 mStave(stave),
108 mNumber(number),
109 mZOffset(zOffset),
110 mBarSpacing(barSpacing),
111 mBarWidth(barWidth),
112 mBarLength(barLength),
113 mBarThickness(barThickness)
114{
115 mSensors.reserve(nBars);
116 LOGP(debug, "\t\t\tConstructing MIDModule: {}", mName);
117 for (int iBar = 0; iBar < mNBars; ++iBar) {
118 mSensors.emplace_back(GeometryTGeo::composeSymNameSensor(mLayer, mStave, mNumber, iBar),
119 mLayer,
120 mStave,
121 mNumber,
122 iBar,
123 -mNBars * 5.2f / 2.f, // moduleOffset derived from nBars
124 !(mLayer % 2) ? 49.9f : 61.75f); // sensor length
125 }
126}
127
128MIDLayer::Stave::Module::Sensor::Sensor(std::string sensorName,
129 int layer,
130 int stave,
131 int module,
132 int number,
133 float moduleOffset,
134 float sensorLength,
135 float sensorWidth,
136 float sensorThickness,
137 float sensorSpacing) : mName(sensorName),
138 mLayer(layer),
139 mStave(stave),
140 mModule(module),
141 mNumber(number),
142 mModuleOffset(moduleOffset),
143 mWidth(sensorWidth),
144 mLength(sensorLength),
145 mThickness(sensorThickness),
146 mSpacing(sensorSpacing)
147{
148 LOGP(debug, "\t\t\t\tConstructing MIDSensor: {}", mName);
149}
150
151void MIDLayer::createLayer(TGeoVolume* motherVolume)
152{
153 LOGP(debug, "Creating MIDLayer: {} at zOffset={} cm", mName, mZOffset);
154 TGeoVolumeAssembly* layerVolume = new TGeoVolumeAssembly(mName.c_str());
155 if (mZOffset != 0.f) {
156 motherVolume->AddNode(layerVolume, 0, new TGeoTranslation(0, 0, mZOffset));
157 } else {
158 motherVolume->AddNode(layerVolume, 0);
159 }
160 for (auto& stave : mStaves) {
161 stave.createStave(layerVolume);
162 }
163}
164
165void MIDLayer::Stave::createStave(TGeoVolume* motherVolume)
166{
167 LOGP(debug, "\tCreating MIDStave: {} layer: {}", mName, mLayer);
168 TGeoVolumeAssembly* staveVolume = new TGeoVolumeAssembly(mName.c_str());
169 // Create the modules
170 for (auto& module : mModules) {
171 module.createModule(staveVolume);
172 }
173
174 TGeoCombiTrans* staveTrans = new TGeoCombiTrans(mRadDistance * TMath::Cos(mRotAngle),
175 mRadDistance * TMath::Sin(mRotAngle),
176 0,
177 new TGeoRotation("rot", 90 + mRotAngle * TMath::RadToDeg(), 0, 0));
178 motherVolume->AddNode(staveVolume, 0, staveTrans);
179}
180
181void MIDLayer::Stave::Module::createModule(TGeoVolume* motherVolume)
182{
183 // Module is an air box with floating bars inside for the moment
184 auto sumWidth = ((mBarWidth * 2 + mBarSpacing) * mNBars) / 2;
185 LOGP(debug, "\t\t\tCreating MIDModule: {} with ", mName);
186 TGeoVolumeAssembly* moduleVolume = new TGeoVolumeAssembly(mName.c_str() /*, module, airMed*/);
187
188 // Create the bars
189 for (auto& sensor : mSensors) {
190 sensor.createSensor(moduleVolume);
191 }
192 TGeoCombiTrans* modTrans = nullptr;
193 if (!(mLayer % 2)) {
194 modTrans = new TGeoCombiTrans(0, 0, mZOffset + mNumber * 2 * mBarLength + mBarLength, nullptr);
195 } else {
196 modTrans = new TGeoCombiTrans(0, 0, mZOffset + mNumber * 2 * sumWidth + sumWidth, nullptr);
197 }
198 motherVolume->AddNode(moduleVolume, 0, modTrans);
199}
200
201void MIDLayer::Stave::Module::Sensor::createSensor(TGeoVolume* motherVolume)
202{
203 LOGP(debug, "\t\t\t\tCreating MIDSensor: {}", mName);
204 TGeoBBox* sensor = nullptr;
205 if (!(mLayer % 2)) {
206 sensor = new TGeoBBox(mName.c_str(), mWidth, mThickness, mLength);
207 } else {
208 sensor = new TGeoBBox(mName.c_str(), mLength, mThickness, mWidth);
209 }
210 auto* polyMed = gGeoManager->GetMedium("MI3_POLYSTYRENE");
211 // Simple unique name without slashes so gMC->VolId() resolves correctly during stepping
212 auto volName = Form("MIDSensor_L%d_S%d_M%d_B%d", mLayer, mStave, mNumber, mNumber);
213 TGeoVolume* sensorVolume = new TGeoVolume(volName, sensor, polyMed);
214 sensorVolume->SetVisibility(true);
215 auto totWidth = mWidth + mSpacing / 2;
216 TGeoTranslation* sensorTrans = nullptr;
217 if (!(mLayer % 2)) {
218 sensorTrans = new TGeoTranslation(mModuleOffset + 2 * totWidth * mNumber + totWidth, 0, 0);
219 sensorVolume->SetLineColor(kAzure + 4);
220 sensorVolume->SetTransparency(50);
221 } else {
222 sensorTrans = new TGeoTranslation(0, 0, mModuleOffset + 2 * totWidth * mNumber + totWidth);
223 sensorVolume->SetLineColor(kAzure + 4);
224 sensorVolume->SetTransparency(50);
225 }
226 motherVolume->AddNode(sensorVolume, 0, sensorTrans);
227}
228} // namespace o2::mi3
std::ostringstream debug
static const char * composeSymNameSensor(const int layer, const int stave, const int module, const int sensor)
static const char * composeSymNameModule(const int layer, const int stave, const int module)
static const char * composeSymNameStave(const int layer, const int stave)
MIDLayer()=default
void createLayer(TGeoVolume *motherVolume)
Definition MIDLayer.cxx:151
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310