Project
Loading...
Searching...
No Matches
DescriptorInnerBarrelITS2.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
12#include "FairDetector.h" // for FairDetector
13#include <fairlogger/Logger.h> // for LOG, LOG_IF
14#include "FairRootManager.h" // for FairRootManager
15#include "FairRun.h" // for FairRun
16#include "FairRuntimeDb.h" // for FairRuntimeDb
17#include "FairVolume.h" // for FairVolume
18#include "FairRootManager.h"
19
20#include "TGeoManager.h" // for TGeoManager, gGeoManager
21#include "TGeoTube.h" // for TGeoTube
22#include "TGeoPcon.h" // for TGeoPcon
23#include "TGeoVolume.h" // for TGeoVolume, TGeoVolumeAssembly
24#include "TString.h" // for TString, operator+
25#include "TVirtualMC.h" // for gMC, TVirtualMC
26#include "TVirtualMCStack.h" // for TVirtualMCStack
27
34
35using namespace o2::its;
36
40
41//________________________________________________________________
50
51//________________________________________________________________
60
61//________________________________________________________________
63{
64 // build ITS2 upgrade detector
65 mTurboLayer.resize(mNumLayers);
66 mLayerPhi0.resize(mNumLayers);
67 mLayerRadii.resize(mNumLayers);
68 mStavePerLayer.resize(mNumLayers);
69 mUnitPerStave.resize(mNumLayers);
70 mChipThickness.resize(mNumLayers);
72 mStaveTilt.resize(mNumLayers);
73 mStaveWidth.resize(mNumLayers);
74 mChipTypeID.resize(mNumLayers);
75 mBuildLevel.resize(mNumLayers);
76 mLayer.resize(mNumLayers);
77
78 // Radii are from last TDR (ALICE-TDR-017.pdf Tab. 1.1)
79 std::vector<std::array<double, 6>> IBdat;
80 IBdat.emplace_back(std::array<double, 6>{2.24, 2.34, 2.67, 9., 16.42, 12});
81 IBdat.emplace_back(std::array<double, 6>{3.01, 3.15, 3.46, 9., 12.18, 16});
82 IBdat.emplace_back(std::array<double, 6>{3.78, 3.93, 4.21, 9., 9.55, 20});
83
84 for (auto idLayer{0u}; idLayer < mNumLayers; ++idLayer) {
85 mTurboLayer[idLayer] = true;
86 mLayerPhi0[idLayer] = IBdat[idLayer][4];
87 mLayerRadii[idLayer] = IBdat[idLayer][1];
88 mStavePerLayer[idLayer] = IBdat[idLayer][5];
89 mUnitPerStave[idLayer] = IBdat[idLayer][3];
90 mChipThickness[idLayer] = 50.e-4;
92 mStaveTilt[idLayer] = radii2Turbo(IBdat[idLayer][0], IBdat[idLayer][1], IBdat[idLayer][2], o2::itsmft::SegmentationAlpide::SensorSizeRows);
94 mChipTypeID[idLayer] = 0;
95 mBuildLevel[idLayer] = buildLevel;
96
97 LOG(info) << "L# " << idLayer << " Phi:" << mLayerPhi0[idLayer] << " R:" << mLayerRadii[idLayer] << " Nst:" << mStavePerLayer[idLayer] << " Nunit:" << mUnitPerStave[idLayer]
98 << " W:" << mStaveWidth[idLayer] << " Tilt:" << mStaveTilt[idLayer] << " Lthick:" << mChipThickness[idLayer] << " Dthick:" << mDetectorThickness[idLayer]
99 << " DetID:" << mChipTypeID[idLayer] << " B:" << mBuildLevel[idLayer];
100 }
101
102 mWrapperMinRadius = 2.1;
103 mWrapperMaxRadius = 16.4;
104 mWrapperZSpan = 70.;
105}
106
107//________________________________________________________________
108V3Layer* DescriptorInnerBarrelITS2::createLayer(int idLayer, TGeoVolume* dest)
109{
110 if (idLayer >= mNumLayers) {
111 LOG(fatal) << "Trying to define layer " << idLayer << " of inner barrel, but only " << mNumLayers << " layers expected!";
112 return nullptr;
113 }
114
115 if (mTurboLayer[idLayer]) {
116 mLayer[idLayer] = new V3Layer(idLayer, true, false);
117 mLayer[idLayer]->setStaveWidth(mStaveWidth[idLayer]);
118 mLayer[idLayer]->setStaveTilt(mStaveTilt[idLayer]);
119 } else {
120 mLayer[idLayer] = new V3Layer(idLayer, false);
121 }
122
123 mLayer[idLayer]->setPhi0(mLayerPhi0[idLayer]);
124 mLayer[idLayer]->setRadius(mLayerRadii[idLayer]);
125 mLayer[idLayer]->setNumberOfStaves(mStavePerLayer[idLayer]);
126 mLayer[idLayer]->setNumberOfUnits(mUnitPerStave[idLayer]);
127 mLayer[idLayer]->setChipType(mChipTypeID[idLayer]);
128 mLayer[idLayer]->setBuildLevel(mBuildLevel[idLayer]);
129
130 mLayer[idLayer]->setStaveModel(V3Layer::kIBModel4);
131
132 if (mChipThickness[idLayer] != 0) {
133 mLayer[idLayer]->setChipThick(mChipThickness[idLayer]);
134 }
135 if (mDetectorThickness[idLayer] != 0) {
136 mLayer[idLayer]->setSensorThick(mDetectorThickness[idLayer]);
137 }
138
139 mLayer[idLayer]->createLayer(dest);
140
141 return mLayer[idLayer]; // is this needed?
142}
143
144//________________________________________________________________
146{
147 //
148 // Creates the Inner Barrel Service structures
149 //
150 // Input:
151 // motherVolume : the volume hosting the services
152 //
153 // Output:
154 //
155 // Return:
156 //
157 // Created: 15 May 2019 Mario Sitta
158 // (partially based on P.Namwongsa implementation in AliRoot)
159 // Updated: 19 Jun 2019 Mario Sitta IB Side A added
160 // Updated: 21 Oct 2019 Mario Sitta CYSS added
161 //
162
163 auto& itsBaseParam = ITSBaseParam::Instance();
164
165 std::unique_ptr<V3Services> mServicesGeometry(new V3Services("ITS"));
166
167 if (itsBaseParam.buildEndWheels) {
168 // Create the End Wheels on Side A
169 TGeoVolume* endWheelsA = mServicesGeometry.get()->createIBEndWheelsSideA();
170 dest->AddNode(endWheelsA, 1, nullptr);
171
172 // Create the End Wheels on Side C
173 TGeoVolume* endWheelsC = mServicesGeometry.get()->createIBEndWheelsSideC();
174 dest->AddNode(endWheelsC, 1, nullptr);
175 }
176 if (itsBaseParam.buildCYSSAssembly) {
177 // Create the CYSS Assembly (i.e. the supporting half cylinder and cone)
178 TGeoVolume* cyss = mServicesGeometry.get()->createCYSSAssembly();
179 dest->AddNode(cyss, 1, nullptr);
180 }
181 mServicesGeometry.get()->createIBGammaConvWire(dest);
182}
183
184//________________________________________________________________
185void DescriptorInnerBarrelITS2::addAlignableVolumesLayer(int idLayer, int wrapperLayerId, TString& parentPath, int& lastUID)
186{
187 //
188 // Add alignable volumes for a Layer and its daughters
189 //
190 // Created: 06 Mar 2018 Mario Sitta First version (mainly ported from AliRoot)
191 // Updated: 06 Jul 2021 Mario Sitta Do not set Layer as alignable volume
192 //
193
194 TString wrpV = wrapperLayerId != -1 ? Form("%s%d_1", GeometryTGeo::getITSWrapVolPattern(), wrapperLayerId) : "";
195 TString path = Form("%s/%s/%s%d_1", parentPath.Data(), wrpV.Data(), GeometryTGeo::getITSLayerPattern(), idLayer);
196 TString sname = GeometryTGeo::composeSymNameLayer(idLayer);
197
198 int nHalfBarrel = mLayer[idLayer]->getNumberOfHalfBarrelsPerParent();
199 int start = nHalfBarrel > 0 ? 0 : -1;
200 for (int iHalfBarrel{start}; iHalfBarrel < nHalfBarrel; ++iHalfBarrel) {
201 addAlignableVolumesHalfBarrel(idLayer, iHalfBarrel, path, lastUID);
202 }
203}
204
205void DescriptorInnerBarrelITS2::addAlignableVolumesHalfBarrel(int idLayer, int iHalfBarrel, TString& parentPath, int& lastUID) const
206{
207 //
208 // Add alignable volumes for a Half barrel and its daughters
209 //
210 // Created: 28 Jun 2021 Mario Sitta First version (based on similar methods)
211 //
212
213 TString path = parentPath;
214 if (iHalfBarrel >= 0) {
215 path = Form("%s/%s%d_%d", parentPath.Data(), GeometryTGeo::getITSHalfBarrelPattern(), idLayer, iHalfBarrel);
216 TString sname = GeometryTGeo::composeSymNameHalfBarrel(idLayer, iHalfBarrel);
217
218 LOG(debug) << "Add " << sname << " <-> " << path;
219
220 if (!gGeoManager->SetAlignableEntry(sname.Data(), path.Data())) {
221 LOG(fatal) << "Unable to set alignable entry ! " << sname << " : " << path;
222 }
223 }
224
225 int nStaves = mLayer[idLayer]->getNumberOfStavesPerParent();
226 for (int iStave{0}; iStave < nStaves; ++iStave) {
227 addAlignableVolumesStave(idLayer, iHalfBarrel, iStave, path, lastUID);
228 }
229}
230
231void DescriptorInnerBarrelITS2::addAlignableVolumesStave(int idLayer, int iHalfBarrel, int iStave, TString& parentPath, int& lastUID) const
232{
233 //
234 // Add alignable volumes for a Stave and its daughters
235 //
236 // Created: 06 Mar 2018 Mario Sitta First version (mainly ported from AliRoot)
237 // Updated: 29 Jun 2021 Mario Sitta Hal Barrel index added
238 //
239
240 TString path = Form("%s/%s%d_%d", parentPath.Data(), GeometryTGeo::getITSStavePattern(), idLayer, iStave);
241 TString sname = GeometryTGeo::composeSymNameStave(idLayer, iHalfBarrel, iStave);
242
243 LOG(debug) << "Add " << sname << " <-> " << path;
244
245 if (!gGeoManager->SetAlignableEntry(sname.Data(), path.Data())) {
246 LOG(fatal) << "Unable to set alignable entry ! " << sname << " : " << path;
247 }
248
249 int nHalfStave = mLayer[idLayer]->getNumberOfHalfStavesPerParent();
250 int start = nHalfStave > 0 ? 0 : -1;
251 for (int iHalfStave{start}; iHalfStave < nHalfStave; ++iHalfStave) {
252 addAlignableVolumesHalfStave(idLayer, iHalfBarrel, iStave, iHalfStave, path, lastUID);
253 }
254}
255
256void DescriptorInnerBarrelITS2::addAlignableVolumesHalfStave(int idLayer, int iHalfBarrel, int iStave, int iHalfStave, TString& parentPath, int& lastUID) const
257{
258 //
259 // Add alignable volumes for a HalfStave (if any) and its daughters
260 //
261 // Created: 06 Mar 2018 Mario Sitta First version (mainly ported from AliRoot)
262 // Updated: 29 Jun 2021 Mario Sitta Hal Barrel index added
263 //
264
265 TString path = parentPath;
266 if (iHalfStave >= 0) {
267 path = Form("%s/%s%d_%d", parentPath.Data(), GeometryTGeo::getITSHalfStavePattern(), idLayer, iHalfStave);
268 TString sname = GeometryTGeo::composeSymNameHalfStave(idLayer, iHalfBarrel, iStave, iHalfStave);
269
270 LOG(debug) << "Add " << sname << " <-> " << path;
271
272 if (!gGeoManager->SetAlignableEntry(sname.Data(), path.Data())) {
273 LOG(fatal) << "Unable to set alignable entry ! " << sname << " : " << path;
274 }
275 }
276
277 int nModules = mLayer[idLayer]->getNumberOfModulesPerParent();
278 int start = nModules > 0 ? 0 : -1;
279 for (int iModule{start}; iModule < nModules; iModule++) {
280 addAlignableVolumesModule(idLayer, iHalfBarrel, iStave, iHalfStave, iModule, path, lastUID);
281 }
282}
283
284void DescriptorInnerBarrelITS2::addAlignableVolumesModule(int idLayer, int iHalfBarrel, int iStave, int iHalfStave, int iModule, TString& parentPath, int& lastUID) const
285{
286 //
287 // Add alignable volumes for a Module (if any) and its daughters
288 //
289 // Created: 06 Mar 2018 Mario Sitta First version (mainly ported from AliRoot)
290 // Updated: 29 Jun 2021 Mario Sitta Hal Barrel index added
291 //
292
293 TString path = parentPath;
294 if (iModule >= 0) {
295 path = Form("%s/%s%d_%d", parentPath.Data(), GeometryTGeo::getITSModulePattern(), idLayer, iModule);
296 TString sname = GeometryTGeo::composeSymNameModule(idLayer, iHalfBarrel, iStave, iHalfStave, iModule);
297
298 LOG(debug) << "Add " << sname << " <-> " << path;
299
300 if (!gGeoManager->SetAlignableEntry(sname.Data(), path.Data())) {
301 LOG(fatal) << "Unable to set alignable entry ! " << sname << " : " << path;
302 }
303 }
304
305 int nChips = mLayer[idLayer]->getNumberOfChipsPerParent();
306 for (int iChip{0}; iChip < nChips; ++iChip) {
307 addAlignableVolumesChip(idLayer, iHalfBarrel, iStave, iHalfStave, iModule, iChip, path, lastUID);
308 }
309}
310
311void DescriptorInnerBarrelITS2::addAlignableVolumesChip(int idLayer, int iHalfBarrel, int iStave, int iHalfStave, int iModule, int iChip, TString& parentPath, int& lastUID) const
312{
313 //
314 // Add alignable volumes for a Chip
315 //
316 // Created: 06 Mar 2018 Mario Sitta First version (mainly ported from AliRoot)
317 // Updated: 29 Jun 2021 Mario Sitta Hal Barrel index added
318 //
319
320 TString path = Form("%s/%s%d_%d", parentPath.Data(), GeometryTGeo::getITSChipPattern(), idLayer, iChip);
321 TString sname = GeometryTGeo::composeSymNameChip(idLayer, iHalfBarrel, iStave, iHalfStave, iModule, iChip);
323
324 LOG(debug) << "Add " << sname << " <-> " << path;
325
326 if (!gGeoManager->SetAlignableEntry(sname, path.Data(), modUID)) {
327 LOG(fatal) << "Unable to set alignable entry ! " << sname << " : " << path;
328 }
329
330 return;
331}
Definition of the DescriptorInnerBarrelITS2 class.
Definition of the GeometryTGeo class.
ClassImp(IdPath)
Definition of the SegmentationAlpide class.
Definition of the V3Layer class.
Definition of the V3Services class.
std::ostringstream debug
static int getSensID(o2::detectors::DetID detid, int sensid)
static constexpr ID ITS
Definition DetID.h:63
V3Layer * createLayer(int idLayer, TGeoVolume *dest)
void addAlignableVolumesLayer(int idLayer, int wrapperLayerId, TString &parentPath, int &lastUID)
std::vector< int > mChipTypeID
Vector of detector thickness.
std::vector< int > mBuildLevel
Vector of unique chip ID.
std::vector< double > mDetectorThickness
Vector of layer radius.
std::vector< double > mLayerRadii
sensor thickness
double radii2Turbo(double rMin, double rMid, double rMax, double sensW) const
static const char * getITSLayerPattern()
static const char * composeSymNameLayer(int lr, bool isITS3=false)
sym name of the layer
static const char * getITSHalfBarrelPattern()
static const char * composeSymNameHalfBarrel(int lr, int hba, bool isITS3=false)
Sym name of the half barrel at given layer.
static const char * composeSymNameHalfStave(int lr, int hba, int sta, int ssta, bool isITS3=false)
Sym name of the stave at given layer/halfbarrel.
static const char * composeSymNameChip(int lr, int hba, int sta, int ssta, int mod, int chip, bool isITS3=false)
Sym name of the chip in the given layer/halfbarrel/stave/substave/module.
static const char * getITSChipPattern()
static const char * composeSymNameModule(int lr, int hba, int sta, int ssta, int mod, bool isITS3=false)
Sym name of the substave at given layer/halfbarrel/stave.
static const char * getITSModulePattern()
static const char * composeSymNameStave(int lr, int hba, int sta, bool isITS3=false)
Sym name of the stave at given layer.
static const char * getITSHalfStavePattern()
static const char * getITSStavePattern()
static const char * getITSWrapVolPattern()
This class defines the Geometry for the Services of the ITS Upgrade using TGeo.
Definition V3Services.h:39
static constexpr float SensorLayerThickness
static constexpr float SensorSizeRows
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
GLuint start
Definition glcorearb.h:469
constexpr unsigned int nChips
Definition SpecsV2.h:131
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"