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 radiatorTile = new TGeoArb8(radZ / 2);
71 radiatorTile->SetVertex(0, -radThick / 2, -radYmin / 2);
72 radiatorTile->SetVertex(1, -radThick / 2, radYmin / 2);
73 radiatorTile->SetVertex(2, radThick / 2, radYmin / 2);
74 radiatorTile->SetVertex(3, radThick / 2, -radYmin / 2);
75 radiatorTile->SetVertex(4, -radThick / 2, -radYmax / 2);
76 radiatorTile->SetVertex(5, -radThick / 2, radYmax / 2);
77 radiatorTile->SetVertex(6, radThick / 2, radYmax / 2);
78 radiatorTile->SetVertex(7, radThick / 2, -radYmax / 2);
79
80 TGeoVolume* radiatorTileVol = new TGeoVolume(Form("radTile_%d_%d", rPosId, radTileCount), radiatorTile, medAerogel);
81 radiatorTileVol->SetLineColor(kOrange - 8);
82 radiatorTileVol->SetLineWidth(1);
83
84 auto* rotRadiator = new TGeoRotation(Form("radTileRotation_%d_%d", radTileCount, rPosId));
85 rotRadiator->RotateY(-thetaBDeg);
86 rotRadiator->RotateZ(radTileCount * deltaPhiDeg);
87
88 auto* rotTransRadiator = new TGeoCombiTrans(radRad0 * TMath::Cos(radTileCount * TMath::Pi() / (nTilesPhi / 2)),
89 radRad0 * TMath::Sin(radTileCount * TMath::Pi() / (nTilesPhi / 2)),
90 radRad0 * TMath::Tan(thetaB),
91 rotRadiator);
92
93 motherVolume->AddNode(radiatorTileVol, 1, rotTransRadiator);
94 radTileCount++;
95 }
96
97 // Photosensor tiles
98 for (auto& photoTile : photoTiles) {
99 photoTile = new TGeoArb8(photZ / 2);
100 photoTile->SetVertex(0, -photThick / 2, -photYmin / 2);
101 photoTile->SetVertex(1, -photThick / 2, photYmin / 2);
102 photoTile->SetVertex(2, photThick / 2, photYmin / 2);
103 photoTile->SetVertex(3, photThick / 2, -photYmin / 2);
104 photoTile->SetVertex(4, -photThick / 2, -photYmax / 2);
105 photoTile->SetVertex(5, -photThick / 2, photYmax / 2);
106 photoTile->SetVertex(6, photThick / 2, photYmax / 2);
107 photoTile->SetVertex(7, photThick / 2, -photYmax / 2);
108
109 TGeoVolume* photoTileVol = new TGeoVolume(Form("photoTile_%d_%d", rPosId, photTileCount), photoTile, medSi);
110 photoTileVol->SetLineColor(kOrange - 8);
111 photoTileVol->SetLineWidth(1);
112
113 auto* rotPhoto = new TGeoRotation(Form("photoTileRotation_%d_%d", photTileCount, rPosId));
114 rotPhoto->RotateY(-thetaBDeg);
115 rotPhoto->RotateZ(photTileCount * deltaPhiDeg);
116 auto* rotTransPhoto = new TGeoCombiTrans(photR0 * TMath::Cos(photTileCount * TMath::Pi() / (nTilesPhi / 2)),
117 photR0 * TMath::Sin(photTileCount * TMath::Pi() / (nTilesPhi / 2)),
118 photR0 * TMath::Tan(thetaB),
119 rotPhoto);
120
121 motherVolume->AddNode(photoTileVol, 1, rotTransPhoto);
122 photTileCount++;
123 }
124
125 // Argon sectors "connect" radiator and photosensor tiles, they are not really physical
126 for (auto& argonSector : argonSectors) {
127 float separation{(aerDetDistance - radThick - photThick)};
128 auto* radiator = radiatorTiles[argSectorsCount];
129 auto* photosensor = photoTiles[argSectorsCount];
130 argonSector = new TGeoArb8(separation / 2);
131
132 argonSector->SetVertex(0, -photZ / 2, -photYmin / 2);
133 argonSector->SetVertex(1, -photZ / 2, photYmin / 2);
134 argonSector->SetVertex(2, photZ / 2, photYmax / 2);
135 argonSector->SetVertex(3, photZ / 2, -photYmax / 2);
136 argonSector->SetVertex(4, -radZ / 2, -radYmin / 2);
137 argonSector->SetVertex(5, -radZ / 2, radYmin / 2);
138 argonSector->SetVertex(6, radZ / 2, radYmax / 2);
139 argonSector->SetVertex(7, radZ / 2, -radYmax / 2);
140
141 TGeoVolume* argonSectorVol = new TGeoVolume(Form("argonSector_%d_%d", rPosId, argSectorsCount), argonSector, medAr);
142 argonSectorVol->SetVisibility(kTRUE);
143 argonSectorVol->SetLineColor(kOrange - 8);
144 argonSectorVol->SetLineWidth(1);
145 auto* rotArgon = new TGeoRotation(Form("argonSectorRotation_%d_%d", argSectorsCount, rPosId));
146 rotArgon->RotateY(-90 - thetaBDeg);
147 rotArgon->RotateZ(argSectorsCount * deltaPhiDeg);
148 auto* rotTransArgon = new TGeoCombiTrans((radRad0 + TMath::Cos(thetaB) * (separation + radThick) / 2) * TMath::Cos(argSectorsCount * TMath::Pi() / (nTilesPhi / 2)),
149 (radRad0 + TMath::Cos(thetaB) * (separation + radThick) / 2) * TMath::Sin(argSectorsCount * TMath::Pi() / (nTilesPhi / 2)),
150 radRad0 * TMath::Tan(thetaB) + TMath::Sin(thetaB) * (separation + radThick) / 2,
151 rotArgon);
152 motherVolume->AddNode(argonSectorVol, 1, rotTransArgon);
153 argSectorsCount++;
154 }
155}
156
158 float rMin,
159 float rMax,
160 float zAerogelMin,
161 float dZAerogel,
162 float zArgonMin,
163 float dZArgon,
164 float zSiliconMin,
165 float dZSilicon) : mName{name},
166 mRmin{rMin},
167 mRmax{rMax},
168 mZAerogelMin{zAerogelMin},
169 mDZAerogel{dZAerogel},
170 mZArgonMin{zArgonMin},
171 mDZArgon{dZArgon},
172 mZSiliconMin{zSiliconMin},
173 mDZSilicon{dZSilicon}
174{
175}
176
178 float rMin,
179 float rMax,
180 float zAerogelMin,
181 float dZAerogel,
182 float zArgonMin,
183 float dZArgon,
184 float zSiliconMin,
185 float dZSilicon) : mName{name},
186 mRmin{rMin},
187 mRmax{rMax},
188 mZAerogelMin{zAerogelMin},
189 mDZAerogel{dZAerogel},
190 mZArgonMin{zArgonMin},
191 mDZArgon{dZArgon},
192 mZSiliconMin{zSiliconMin},
193 mDZSilicon{dZSilicon}
194{
195}
196
197void FWDRich::createFWDRich(TGeoVolume* motherVolume)
198{
199 TGeoMedium* medAerogel = gGeoManager->GetMedium("RCH_AEROGEL$");
200 if (!medAerogel) {
201 LOGP(fatal, "RICH: Aerogel medium not found");
202 }
203 TGeoMedium* medSi = gGeoManager->GetMedium("RCH_SILICON$");
204 if (!medSi) {
205 LOGP(fatal, "RICH: Silicon medium not found");
206 }
207 TGeoMedium* medAr = gGeoManager->GetMedium("RCH_ARGON$");
208 if (!medAr) {
209 LOGP(fatal, "RICH: Argon medium not found");
210 }
211
212 // Create the aerogel volume
213 TGeoTube* aerogel = new TGeoTube(mRmin, mRmax, mDZAerogel / 2);
214 TGeoVolume* aerogelVol = new TGeoVolume(mName.c_str(), aerogel, medAerogel);
215 aerogelVol->SetLineColor(kOrange - 8);
216
217 TGeoTranslation* transAerogel = new TGeoTranslation(0, 0, mZAerogelMin + mDZAerogel / 2);
218 motherVolume->AddNode(aerogelVol, 1, transAerogel);
219
220 // Create the argon volume
221 TGeoTube* argon = new TGeoTube(mRmin, mRmax, mDZArgon / 2);
222 TGeoVolume* argonVol = new TGeoVolume(mName.c_str(), argon, medAr);
223 argonVol->SetLineColor(kOrange - 9);
224
225 TGeoTranslation* transArgon = new TGeoTranslation(0, 0, mZArgonMin + mDZArgon / 2);
226 motherVolume->AddNode(argonVol, 1, transArgon);
227
228 // Create the silicon volume
229 TGeoTube* silicon = new TGeoTube(mRmin, mRmax, mDZSilicon / 2);
230 TGeoVolume* siliconVol = new TGeoVolume(mName.c_str(), silicon, medSi);
231 siliconVol->SetLineColor(kOrange - 8);
232
233 TGeoTranslation* transSilicon = new TGeoTranslation(0, 0, mZSiliconMin + mDZSilicon / 2);
234 motherVolume->AddNode(siliconVol, 1, transSilicon);
235}
236
237void BWDRich::createBWDRich(TGeoVolume* motherVolume)
238{
239 TGeoMedium* medAerogel = gGeoManager->GetMedium("RCH_AEROGEL$");
240 if (!medAerogel) {
241 LOGP(fatal, "RICH: Aerogel medium not found");
242 }
243 TGeoMedium* medSi = gGeoManager->GetMedium("RCH_SILICON$");
244 if (!medSi) {
245 LOGP(fatal, "RICH: Silicon medium not found");
246 }
247 TGeoMedium* medAr = gGeoManager->GetMedium("RCH_ARGON$");
248 if (!medAr) {
249 LOGP(fatal, "RICH: Argon medium not found");
250 }
251
252 // Create the aerogel volume
253 TGeoTube* aerogel = new TGeoTube(mRmin, mRmax, mDZAerogel / 2);
254 TGeoVolume* aerogelVol = new TGeoVolume(mName.c_str(), aerogel, medAerogel);
255 aerogelVol->SetLineColor(kOrange - 8);
256
257 TGeoTranslation* transAerogel = new TGeoTranslation(0, 0, -mZAerogelMin - mDZAerogel / 2);
258 motherVolume->AddNode(aerogelVol, 1, transAerogel);
259
260 // Create the argon volume
261 TGeoTube* argon = new TGeoTube(mRmin, mRmax, mDZArgon / 2);
262 TGeoVolume* argonVol = new TGeoVolume(mName.c_str(), argon, medAr);
263 argonVol->SetLineColor(kOrange - 8);
264
265 TGeoTranslation* transArgon = new TGeoTranslation(0, 0, -mZArgonMin - mDZArgon / 2);
266 motherVolume->AddNode(argonVol, 1, transArgon);
267
268 // Create the silicon volume
269 TGeoTube* silicon = new TGeoTube(mRmin, mRmax, mDZSilicon / 2);
270 TGeoVolume* siliconVol = new TGeoVolume(mName.c_str(), silicon, medSi);
271 siliconVol->SetLineColor(kOrange - 8);
272
273 TGeoTranslation* transSilicon = new TGeoTranslation(0, 0, -mZSiliconMin - mDZSilicon / 2);
274 motherVolume->AddNode(siliconVol, 1, transSilicon);
275}
276
277} // namespace rich
278} // namespace o2
void createBWDRich(TGeoVolume *motherVolume)
Definition RICHRing.cxx:237
std::string mName
Definition RICHRing.h:121
std::string mName
Definition RICHRing.h:86
void createFWDRich(TGeoVolume *motherVolume)
Definition RICHRing.cxx:197
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 ...