Project
Loading...
Searching...
No Matches
RICHRing.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#include "Framework/Logger.h"
16
17#include <TGeoManager.h>
18#include <TGeoTube.h>
19#include <TGeoVolume.h>
20#include <TGeoArb8.h>
21
22namespace o2
23{
24namespace rich
25{
26
27Ring::Ring(int rPosId,
28 int nTilesPhi,
29 float rMin,
30 float rMax,
31 float radThick,
32 float radYmin,
33 float radYmax,
34 float radZ,
35 float photThick,
36 float photYmin,
37 float photYmax,
38 float photZ,
39 float radRad0,
40 float photR0,
41 float aerDetDistance,
42 float thetaB,
43 const std::string motherName)
44 : mNTiles{nTilesPhi}, mPosId{rPosId}, mRadThickness{radThick}
45{
46 TGeoManager* geoManager = gGeoManager;
47 TGeoVolume* motherVolume = geoManager->GetVolume(motherName.c_str());
48 TGeoMedium* medAerogel = gGeoManager->GetMedium("RCH_AEROGEL$");
49 if (!medAerogel) {
50 LOGP(fatal, "RICH: Aerogel medium not found");
51 }
52 TGeoMedium* medSi = gGeoManager->GetMedium("RCH_SILICON$");
53 if (!medSi) {
54 LOGP(fatal, "RICH: Silicon medium not found");
55 }
56 TGeoMedium* medAr = gGeoManager->GetMedium("RCH_ARGON$");
57 if (!medAr) {
58 LOGP(fatal, "RICH: Argon medium not found");
59 }
60 std::vector<TGeoArb8*> radiatorTiles(nTilesPhi), photoTiles(nTilesPhi), argonSectors(nTilesPhi);
61 LOGP(info, "Creating ring: id: {} with {} tiles. ", rPosId, nTilesPhi);
62 LOGP(info, "Rmin: {} Rmax: {} RadThick: {} RadYmin: {} RadYmax: {} RadZ: {} PhotThick: {} PhotYmin: {} PhotYmax: {} PhotZ: {}, zTransRad: {}, zTransPhot: {}, ThetaB: {}",
63 rMin, rMax, radThick, radYmin, radYmax, radZ, photThick, photYmin, photYmax, photZ, radRad0, photR0, thetaB);
64
65 float deltaPhiDeg = 360.0 / nTilesPhi; // Transformation are constructed in degrees...
66 float thetaBDeg = thetaB * 180.0 / TMath::Pi();
67 int radTileCount{0}, photTileCount{0}, argSectorsCount{0};
68 // Radiator tiles
69 for (auto& radiatorTile : radiatorTiles) {
70 // Local Z is the thin (radial) dimension, looking outward from the IP
71 // (previously this was local X, while for running with ACTS we need local Z).
72 // The placement rotation below is adjusted by +90 deg about Y
73 // to keep the tile in the same physical position.
74 radiatorTile = new TGeoArb8(radThick / 2);
75 radiatorTile->SetVertex(0, radZ / 2, -radYmin / 2);
76 radiatorTile->SetVertex(1, -radZ / 2, -radYmax / 2);
77 radiatorTile->SetVertex(2, -radZ / 2, radYmax / 2);
78 radiatorTile->SetVertex(3, radZ / 2, radYmin / 2);
79 radiatorTile->SetVertex(4, radZ / 2, -radYmin / 2);
80 radiatorTile->SetVertex(5, -radZ / 2, -radYmax / 2);
81 radiatorTile->SetVertex(6, -radZ / 2, radYmax / 2);
82 radiatorTile->SetVertex(7, radZ / 2, radYmin / 2);
83
84 TGeoVolume* radiatorTileVol = new TGeoVolume(Form("radTile_%d_%d", rPosId, radTileCount), radiatorTile, medAerogel);
85 radiatorTileVol->SetLineColor(kOrange - 8);
86 radiatorTileVol->SetLineWidth(1);
87
88 auto* rotRadiator = new TGeoRotation(Form("radTileRotation_%d_%d", radTileCount, rPosId));
89 rotRadiator->RotateY(90.0 - thetaBDeg); // +90 compensates the X->Z swap of the tile's local axes
90 rotRadiator->RotateZ(radTileCount * deltaPhiDeg);
91
92 auto* rotTransRadiator = new TGeoCombiTrans(radRad0 * TMath::Cos(radTileCount * TMath::Pi() / (nTilesPhi / 2)),
93 radRad0 * TMath::Sin(radTileCount * TMath::Pi() / (nTilesPhi / 2)),
94 radRad0 * TMath::Tan(thetaB),
95 rotRadiator);
96
97 motherVolume->AddNode(radiatorTileVol, 1, rotTransRadiator);
98 radTileCount++;
99 }
100
101 // Photosensor tiles
102 for (auto& photoTile : photoTiles) {
103 // Local Z is the thin (radial) dimension, looking outward from the IP
104 photoTile = new TGeoArb8(photThick / 2);
105 photoTile->SetVertex(0, photZ / 2, -photYmin / 2);
106 photoTile->SetVertex(1, -photZ / 2, -photYmax / 2);
107 photoTile->SetVertex(2, -photZ / 2, photYmax / 2);
108 photoTile->SetVertex(3, photZ / 2, photYmin / 2);
109 photoTile->SetVertex(4, photZ / 2, -photYmin / 2);
110 photoTile->SetVertex(5, -photZ / 2, -photYmax / 2);
111 photoTile->SetVertex(6, -photZ / 2, photYmax / 2);
112 photoTile->SetVertex(7, photZ / 2, photYmin / 2);
113
114 TGeoVolume* photoTileVol = new TGeoVolume(Form("%s_%d_%d", GeometryTGeo::getRICHSensorPattern(), rPosId, photTileCount), photoTile, medSi);
115 photoTileVol->SetLineColor(kOrange - 8);
116 photoTileVol->SetLineWidth(1);
117
118 auto* rotPhoto = new TGeoRotation(Form("photoTileRotation_%d_%d", photTileCount, rPosId));
119 rotPhoto->RotateY(90.0 - thetaBDeg); // +90 compensates the X->Z swap of the tile's local axes
120 rotPhoto->RotateZ(photTileCount * deltaPhiDeg);
121 auto* rotTransPhoto = new TGeoCombiTrans(photR0 * TMath::Cos(photTileCount * TMath::Pi() / (nTilesPhi / 2)),
122 photR0 * TMath::Sin(photTileCount * TMath::Pi() / (nTilesPhi / 2)),
123 photR0 * TMath::Tan(thetaB),
124 rotPhoto);
125
126 motherVolume->AddNode(photoTileVol, 1, rotTransPhoto);
127 photTileCount++;
128 }
129
130 // Argon sectors "connect" radiator and photosensor tiles, they are not really physical
131 for (auto& argonSector : argonSectors) {
132 float separation{(aerDetDistance - radThick - photThick)};
133 auto* radiator = radiatorTiles[argSectorsCount];
134 auto* photosensor = photoTiles[argSectorsCount];
135 argonSector = new TGeoArb8(separation / 2);
136
137 argonSector->SetVertex(0, -photZ / 2, -photYmin / 2);
138 argonSector->SetVertex(1, -photZ / 2, photYmin / 2);
139 argonSector->SetVertex(2, photZ / 2, photYmax / 2);
140 argonSector->SetVertex(3, photZ / 2, -photYmax / 2);
141 argonSector->SetVertex(4, -radZ / 2, -radYmin / 2);
142 argonSector->SetVertex(5, -radZ / 2, radYmin / 2);
143 argonSector->SetVertex(6, radZ / 2, radYmax / 2);
144 argonSector->SetVertex(7, radZ / 2, -radYmax / 2);
145
146 TGeoVolume* argonSectorVol = new TGeoVolume(Form("argonSector_%d_%d", rPosId, argSectorsCount), argonSector, medAr);
147 argonSectorVol->SetVisibility(kTRUE);
148 argonSectorVol->SetLineColor(kOrange - 8);
149 argonSectorVol->SetLineWidth(1);
150 auto* rotArgon = new TGeoRotation(Form("argonSectorRotation_%d_%d", argSectorsCount, rPosId));
151 rotArgon->RotateY(-90 - thetaBDeg);
152 rotArgon->RotateZ(argSectorsCount * deltaPhiDeg);
153 auto* rotTransArgon = new TGeoCombiTrans((radRad0 + TMath::Cos(thetaB) * (separation + radThick) / 2) * TMath::Cos(argSectorsCount * TMath::Pi() / (nTilesPhi / 2)),
154 (radRad0 + TMath::Cos(thetaB) * (separation + radThick) / 2) * TMath::Sin(argSectorsCount * TMath::Pi() / (nTilesPhi / 2)),
155 radRad0 * TMath::Tan(thetaB) + TMath::Sin(thetaB) * (separation + radThick) / 2,
156 rotArgon);
157 motherVolume->AddNode(argonSectorVol, 1, rotTransArgon);
158 argSectorsCount++;
159 }
160}
161
163 float rMin,
164 float rMax,
165 float zAerogelMin,
166 float dZAerogel,
167 float zArgonMin,
168 float dZArgon,
169 float zSiliconMin,
170 float dZSilicon) : mName{name},
171 mRmin{rMin},
172 mRmax{rMax},
173 mZAerogelMin{zAerogelMin},
174 mDZAerogel{dZAerogel},
175 mZArgonMin{zArgonMin},
176 mDZArgon{dZArgon},
177 mZSiliconMin{zSiliconMin},
178 mDZSilicon{dZSilicon}
179{
180}
181
183 float rMin,
184 float rMax,
185 float zAerogelMin,
186 float dZAerogel,
187 float zArgonMin,
188 float dZArgon,
189 float zSiliconMin,
190 float dZSilicon) : mName{name},
191 mRmin{rMin},
192 mRmax{rMax},
193 mZAerogelMin{zAerogelMin},
194 mDZAerogel{dZAerogel},
195 mZArgonMin{zArgonMin},
196 mDZArgon{dZArgon},
197 mZSiliconMin{zSiliconMin},
198 mDZSilicon{dZSilicon}
199{
200}
201
202void FWDRich::createFWDRich(TGeoVolume* motherVolume)
203{
204 TGeoMedium* medAerogel = gGeoManager->GetMedium("RCH_AEROGEL$");
205 if (!medAerogel) {
206 LOGP(fatal, "RICH: Aerogel medium not found");
207 }
208 TGeoMedium* medSi = gGeoManager->GetMedium("RCH_SILICON$");
209 if (!medSi) {
210 LOGP(fatal, "RICH: Silicon medium not found");
211 }
212 TGeoMedium* medAr = gGeoManager->GetMedium("RCH_ARGON$");
213 if (!medAr) {
214 LOGP(fatal, "RICH: Argon medium not found");
215 }
216
217 // Create the aerogel volume
218 TGeoTube* aerogel = new TGeoTube(mRmin, mRmax, mDZAerogel / 2);
219 TGeoVolume* aerogelVol = new TGeoVolume(mName.c_str(), aerogel, medAerogel);
220 aerogelVol->SetLineColor(kOrange - 8);
221
222 TGeoTranslation* transAerogel = new TGeoTranslation(0, 0, mZAerogelMin + mDZAerogel / 2);
223 motherVolume->AddNode(aerogelVol, 1, transAerogel);
224
225 // Create the argon volume
226 TGeoTube* argon = new TGeoTube(mRmin, mRmax, mDZArgon / 2);
227 TGeoVolume* argonVol = new TGeoVolume(mName.c_str(), argon, medAr);
228 argonVol->SetLineColor(kOrange - 9);
229
230 TGeoTranslation* transArgon = new TGeoTranslation(0, 0, mZArgonMin + mDZArgon / 2);
231 motherVolume->AddNode(argonVol, 1, transArgon);
232
233 // Create the silicon volume
234 TGeoTube* silicon = new TGeoTube(mRmin, mRmax, mDZSilicon / 2);
235 TGeoVolume* siliconVol = new TGeoVolume(mName.c_str(), silicon, medSi);
236 siliconVol->SetLineColor(kOrange - 8);
237
238 TGeoTranslation* transSilicon = new TGeoTranslation(0, 0, mZSiliconMin + mDZSilicon / 2);
239 motherVolume->AddNode(siliconVol, 1, transSilicon);
240}
241
242void BWDRich::createBWDRich(TGeoVolume* motherVolume)
243{
244 TGeoMedium* medAerogel = gGeoManager->GetMedium("RCH_AEROGEL$");
245 if (!medAerogel) {
246 LOGP(fatal, "RICH: Aerogel medium not found");
247 }
248 TGeoMedium* medSi = gGeoManager->GetMedium("RCH_SILICON$");
249 if (!medSi) {
250 LOGP(fatal, "RICH: Silicon medium not found");
251 }
252 TGeoMedium* medAr = gGeoManager->GetMedium("RCH_ARGON$");
253 if (!medAr) {
254 LOGP(fatal, "RICH: Argon medium not found");
255 }
256
257 // Create the aerogel volume
258 TGeoTube* aerogel = new TGeoTube(mRmin, mRmax, mDZAerogel / 2);
259 TGeoVolume* aerogelVol = new TGeoVolume(mName.c_str(), aerogel, medAerogel);
260 aerogelVol->SetLineColor(kOrange - 8);
261
262 TGeoTranslation* transAerogel = new TGeoTranslation(0, 0, -mZAerogelMin - mDZAerogel / 2);
263 motherVolume->AddNode(aerogelVol, 1, transAerogel);
264
265 // Create the argon volume
266 TGeoTube* argon = new TGeoTube(mRmin, mRmax, mDZArgon / 2);
267 TGeoVolume* argonVol = new TGeoVolume(mName.c_str(), argon, medAr);
268 argonVol->SetLineColor(kOrange - 8);
269
270 TGeoTranslation* transArgon = new TGeoTranslation(0, 0, -mZArgonMin - mDZArgon / 2);
271 motherVolume->AddNode(argonVol, 1, transArgon);
272
273 // Create the silicon volume
274 TGeoTube* silicon = new TGeoTube(mRmin, mRmax, mDZSilicon / 2);
275 TGeoVolume* siliconVol = new TGeoVolume(mName.c_str(), silicon, medSi);
276 siliconVol->SetLineColor(kOrange - 8);
277
278 TGeoTranslation* transSilicon = new TGeoTranslation(0, 0, -mZSiliconMin - mDZSilicon / 2);
279 motherVolume->AddNode(siliconVol, 1, transSilicon);
280}
281
282} // namespace rich
283} // namespace o2
void createBWDRich(TGeoVolume *motherVolume)
Definition RICHRing.cxx:242
std::string mName
Definition RICHRing.h:123
std::string mName
Definition RICHRing.h:88
void createFWDRich(TGeoVolume *motherVolume)
Definition RICHRing.cxx:202
static const char * getRICHSensorPattern()
Ring()=default
GLuint const GLchar * name
Definition glcorearb.h:781
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...