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