Project
Loading...
Searching...
No Matches
Detector.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
20
21#include "DetectorsBase/Stack.h"
23
24// FairRoot includes
25#include "FairDetector.h" // for FairDetector
26#include <fairlogger/Logger.h> // for LOG, LOG_IF
27#include "FairRootManager.h" // for FairRootManager
28#include "FairRun.h" // for FairRun
29#include "FairRuntimeDb.h" // for FairRuntimeDb
30#include "FairVolume.h" // for FairVolume
31#include "FairRootManager.h"
32
33#include "TGeoManager.h" // for TGeoManager, gGeoManager
34#include "TGeoTube.h" // for TGeoTube
35#include "TGeoPcon.h" // for TGeoPcon
36#include "TGeoVolume.h" // for TGeoVolume, TGeoVolumeAssembly
37#include "TString.h" // for TString, operator+
38#include "TVirtualMC.h" // for gMC, TVirtualMC
39#include "TVirtualMCStack.h" // for TVirtualMCStack
40
41#include <cstdio> // for NULL, snprintf
42
43class FairModule;
44
45class TGeoMedium;
46
47class TParticle;
48
49using namespace o2::ft3;
50using o2::itsmft::Hit;
51
52//_________________________________________________________________________________________________
54 : o2::base::DetImpl<Detector>("FT3", kTRUE),
55 mTrackData(),
56 mHits(o2::utils::createSimVector<o2::itsmft::Hit>())
57{
58}
59
60//_________________________________________________________________________________________________
61void Detector::buildFT3FromFile(std::string configFileName)
62{
63 // Geometry description from file. One line per disk
64 // z_layer r_in r_out Layerx2X0
65 // This simple file reader is not failproof. Do not add empty lines!
66
67 /*
68 # Sample FT3 configuration
69 # z_layer r_in r_out Layerx2X0
70 -45.3 2.5 9.26 0.0042
71 -46.7 2.5 9.26 0.0042
72 -48.6 2.5 9.8 0.0042
73 -50.0 2.5 9.8 0.0042
74 -52.4 2.5 10.43 0.0042
75 -53.8 2.5 10.43 0.0042
76 -67.7 3.82 13.01 0.0042
77 -69.1 3.82 13.01 0.0042
78 -76.1 3.92 14.35 0.0042
79 -77.5 3.92 14.35 0.0042
80 */
81
82 mLayerName.clear();
83 mLayers.clear();
84 mLayerID.clear();
85 mLayerName.resize(1);
86 mLayers.resize(1);
87
88 LOG(info) << "Building FT3 Detector: From file";
89 LOG(info) << " FT3 detector configuration: " << configFileName;
90 std::ifstream ifs(configFileName.c_str());
91 if (!ifs.good()) {
92 LOG(fatal) << " Invalid FT3Base.configFile!";
93 }
94 std::string tempstr;
95 float z_layer, r_in, r_out, Layerx2X0;
96 char delimiter;
97 int layerNumber = 0;
98 while (std::getline(ifs, tempstr)) {
99 if (tempstr[0] == '#') {
100 LOG(info) << " Comment: " << tempstr;
101 continue;
102 }
103 std::istringstream iss(tempstr);
104 iss >> z_layer;
105 iss >> r_in;
106 iss >> r_out;
107 iss >> Layerx2X0;
108
109 int direction = 1; // Forwards
110 if (z_layer < 0) {
111 // Backwards
112 direction = 0;
113 }
114
115 std::string directionName = std::to_string(direction);
116 std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber);
117 mLayerName[0].push_back(layerName);
118 LOG(info) << "Adding Layer " << layerName << " at z = " << z_layer << " ; direction = " << direction << " ; r_in = " << r_in << " ; r_out = " << r_out << " x/X0 = " << Layerx2X0;
119 auto& thisLayer = mLayers[0].emplace_back(direction, layerNumber, layerName, z_layer, r_in, r_out, Layerx2X0);
120 layerNumber++;
121 }
122
123 mNumberOfLayers = layerNumber;
124 LOG(info) << " Loaded FT3 Detector with " << mNumberOfLayers << " layers";
125}
126
127//_________________________________________________________________________________________________
129{
130 // Export FT3 Layout description to file. One line per disk
131 // z_layer r_in r_out Layerx2X0
132
133 std::string configFileName = "FT3_layout.cfg";
134
135 LOG(info) << "Exporting FT3 Detector layout to " << configFileName;
136
137 std::ofstream fOut(configFileName.c_str(), std::ios::out);
138 if (!fOut) {
139 printf("Cannot open file\n");
140 return;
141 }
142 fOut << "# z_layer r_in r_out Layerx2X0" << std::endl;
143 for (auto layers_dir : mLayers) {
144 for (auto layer : layers_dir) {
145 fOut << layer.getZ() << " " << layer.getInnerRadius() << " " << layer.getOuterRadius() << " " << layer.getx2X0() << std::endl;
146 }
147 }
148}
149
150//_________________________________________________________________________________________________
152{
153 // Build a basic parametrized FT3 detector with nLayers equally spaced between z_first and z_first+z_length
154 // Covering pseudo rapidity [etaIn,etaOut]. Silicon thinkness computed to match layer x/X0
155
156 LOG(info) << "Building FT3 Detector: Conical Telescope";
157
158 auto z_first = param.z0;
159 auto z_length = param.zLength;
160 auto etaIn = param.etaIn;
161 auto etaOut = param.etaOut;
162 auto Layerx2X0 = param.Layerx2X0;
163 mNumberOfLayers = param.nLayers;
164 mLayerName.resize(2);
165 mLayerName[0].resize(mNumberOfLayers);
166 mLayerName[1].resize(mNumberOfLayers);
167 mLayerID.clear();
168 mLayers.resize(2);
169
170 for (int direction : {0, 1}) {
171 for (int layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) {
172 std::string layerName = GeometryTGeo::getFT3LayerPattern() + std::to_string(layerNumber + mNumberOfLayers * direction);
173 mLayerName[direction][layerNumber] = layerName;
174
175 // Adds evenly spaced layers
176 float layerZ = z_first + (layerNumber * z_length / (mNumberOfLayers - 1)) * std::copysign(1, z_first);
177 float rIn = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaIn))));
178 float rOut = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaOut))));
179 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, layerZ, rIn, rOut, Layerx2X0);
180 }
181 }
182}
183
184//_________________________________________________________________________________________________
186{
187 //Build FT3 detector according to
188 //https://indico.cern.ch/event/992488/contributions/4174473/attachments/2168881/3661331/tracker_parameters_werner_jan_11_2021.pdf
189
190 LOG(info) << "Building FT3 Detector: V1";
191
192 mNumberOfLayers = 10;
193 float sensorThickness = 30.e-4;
194 float layersx2X0 = 1.e-2;
195 std::vector<std::array<float, 5>> layersConfig{
196 {26., .5, 3., 0.1f * layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0}
197 {30., .5, 3., 0.1f * layersx2X0},
198 {34., .5, 3., 0.1f * layersx2X0},
199 {77., 3.5, 35., layersx2X0},
200 {100., 3.5, 35., layersx2X0},
201 {122., 3.5, 35., layersx2X0},
202 {150., 3.5, 80.f, layersx2X0},
203 {180., 3.5, 80.f, layersx2X0},
204 {220., 3.5, 80.f, layersx2X0},
205 {279., 3.5, 80.f, layersx2X0}};
206
207 mLayerName.resize(2);
208 mLayerName[0].resize(mNumberOfLayers);
209 mLayerName[1].resize(mNumberOfLayers);
210 mLayerID.clear();
211 mLayers.resize(2);
212
213 for (auto direction : {0, 1}) {
214 for (int layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) {
215 std::string directionName = std::to_string(direction);
216 std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber);
217 mLayerName[direction][layerNumber] = layerName;
218 auto& z = layersConfig[layerNumber][0];
219
220 auto& rIn = layersConfig[layerNumber][1];
221 auto& rOut = layersConfig[layerNumber][2];
222 auto& x0 = layersConfig[layerNumber][3];
223
224 LOG(info) << "Adding Layer " << layerName << " at z = " << z;
225 // Add layers
226 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0);
227 }
228 }
229}
230
231//_________________________________________________________________________________________________
233{
234 // Build FT3 detector according to
235 // https://www.overleaf.com/project/6051acc870e39aaeb4653621
236
237 LOG(info) << "Building FT3 Detector: V3b";
238
239 mNumberOfLayers = 12;
240 float sensorThickness = 30.e-4;
241 float layersx2X0 = 1.e-2;
242 std::vector<std::array<float, 5>> layersConfig{
243 {26., .5, 3., 0.1f * layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0}
244 {30., .5, 3., 0.1f * layersx2X0},
245 {34., .5, 3., 0.1f * layersx2X0},
246 {77., 5.0, 35., layersx2X0},
247 {100., 5.0, 35., layersx2X0},
248 {122., 5.0, 35., layersx2X0},
249 {150., 5.5, 80.f, layersx2X0},
250 {180., 6.6, 80.f, layersx2X0},
251 {220., 8.1, 80.f, layersx2X0},
252 {279., 10.2, 80.f, layersx2X0},
253 {340., 12.5, 80.f, layersx2X0},
254 {400., 14.7, 80.f, layersx2X0}};
255
256 mLayerName.resize(2);
257 mLayerName[0].resize(mNumberOfLayers);
258 mLayerName[1].resize(mNumberOfLayers);
259 mLayerID.clear();
260 mLayers.resize(2);
261
262 for (auto direction : {0, 1}) {
263 for (int layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) {
264 std::string directionName = std::to_string(direction);
265 std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber);
266 mLayerName[direction][layerNumber] = layerName;
267 auto& z = layersConfig[layerNumber][0];
268
269 auto& rIn = layersConfig[layerNumber][1];
270 auto& rOut = layersConfig[layerNumber][2];
271 auto& x0 = layersConfig[layerNumber][3];
272
273 LOG(info) << "Adding Layer " << layerName << " at z = " << z;
274 // Add layers
275 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0);
276 }
277 }
278}
279
281{
282 // Build the FT3 detector according to changes proposed during
283 // https://indico.cern.ch/event/1407704/
284 // to adhere to the changes that were presented at the ALICE 3 Upgrade days in March 2024
285 // Inner radius at C-side to 7 cm
286 // Inner radius at A-side stays at 5 cm
287
288 LOG(info) << "Building FT3 Detector: After Upgrade Days March 2024 version";
289
290 mNumberOfLayers = 12;
291 float sensorThickness = 30.e-4;
292 float layersx2X0 = 1.e-2;
293 std::vector<std::array<float, 5>> layersConfigCSide{
294 {26., .5, 2.5, 0.1f * layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0}
295 {30., .5, 2.5, 0.1f * layersx2X0},
296 {34., .5, 2.5, 0.1f * layersx2X0},
297 {77., 7.0, 35., layersx2X0},
298 {100., 7.0, 35., layersx2X0},
299 {122., 7.0, 35., layersx2X0},
300 {150., 7.0, 68.f, layersx2X0},
301 {180., 7.0, 68.f, layersx2X0},
302 {220., 7.0, 68.f, layersx2X0},
303 {260., 7.0, 68.f, layersx2X0},
304 {300., 7.0, 68.f, layersx2X0},
305 {350., 7.0, 68.f, layersx2X0}};
306
307 std::vector<std::array<float, 5>> layersConfigASide{
308 {26., .5, 2.5, 0.1f * layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0}
309 {30., .5, 2.5, 0.1f * layersx2X0},
310 {34., .5, 2.5, 0.1f * layersx2X0},
311 {77., 5.0, 35., layersx2X0},
312 {100., 5.0, 35., layersx2X0},
313 {122., 5.0, 35., layersx2X0},
314 {150., 5.0, 68.f, layersx2X0},
315 {180., 5.0, 68.f, layersx2X0},
316 {220., 5.0, 68.f, layersx2X0},
317 {260., 5.0, 68.f, layersx2X0},
318 {300., 5.0, 68.f, layersx2X0},
319 {350., 5.0, 68.f, layersx2X0}};
320
321 mLayerName.resize(2);
322 mLayerName[0].resize(mNumberOfLayers);
323 mLayerName[1].resize(mNumberOfLayers);
324 mLayerID.clear();
325 mLayers.resize(2);
326
327 for (auto direction : {0, 1}) {
328 for (int layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) {
329 std::string directionName = std::to_string(direction);
330 std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber);
331 mLayerName[direction][layerNumber] = layerName;
332 float z, rIn, rOut, x0;
333 if (direction == 0) { // C-Side
334 z = layersConfigCSide[layerNumber][0];
335 rIn = layersConfigCSide[layerNumber][1];
336 rOut = layersConfigCSide[layerNumber][2];
337 x0 = layersConfigCSide[layerNumber][3];
338 } else if (direction == 1) { // A-Side
339 z = layersConfigASide[layerNumber][0];
340 rIn = layersConfigASide[layerNumber][1];
341 rOut = layersConfigASide[layerNumber][2];
342 x0 = layersConfigASide[layerNumber][3];
343 }
344
345 LOG(info) << "Adding Layer " << layerName << " at z = " << z;
346 // Add layers
347 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0);
348 }
349 }
350}
351
352//_________________________________________________________________________________________________
354{
355 // Build FT3 detector according to the scoping document
356
357 LOG(info) << "Building FT3 Detector: Scoping document version";
358
359 mNumberOfLayers = 12;
360 float sensorThickness = 30.e-4;
361 float layersx2X0 = 1.e-2;
362 std::vector<std::array<float, 5>> layersConfig{
363 {26., .5, 2.5, 0.1f * layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0}
364 {30., .5, 2.5, 0.1f * layersx2X0},
365 {34., .5, 2.5, 0.1f * layersx2X0},
366 {77., 5.0, 35., layersx2X0},
367 {100., 5.0, 35., layersx2X0},
368 {122., 5.0, 35., layersx2X0},
369 {150., 5.0, 68.f, layersx2X0},
370 {180., 5.0, 68.f, layersx2X0},
371 {220., 5.0, 68.f, layersx2X0},
372 {260., 5.0, 68.f, layersx2X0},
373 {300., 5.0, 68.f, layersx2X0},
374 {350., 5.0, 68.f, layersx2X0}};
375
376 mLayerName.resize(2);
377 mLayerName[0].resize(mNumberOfLayers);
378 mLayerName[1].resize(mNumberOfLayers);
379 mLayerID.clear();
380 mLayers.resize(2);
381
382 for (auto direction : {0, 1}) {
383 for (int layerNumber = 0; layerNumber < mNumberOfLayers; layerNumber++) {
384 std::string directionName = std::to_string(direction);
385 std::string layerName = GeometryTGeo::getFT3LayerPattern() + directionName + std::string("_") + std::to_string(layerNumber);
386 mLayerName[direction][layerNumber] = layerName;
387 auto& z = layersConfig[layerNumber][0];
388
389 auto& rIn = layersConfig[layerNumber][1];
390 auto& rOut = layersConfig[layerNumber][2];
391 auto& x0 = layersConfig[layerNumber][3];
392
393 LOG(info) << "Adding Layer " << layerName << " at z = " << z;
394 // Add layers
395 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, z, rIn, rOut, x0);
396 }
397 }
398}
399
400//_________________________________________________________________________________________________
402 : o2::base::DetImpl<Detector>("FT3", active),
403 mTrackData(),
404 mHits(o2::utils::createSimVector<o2::itsmft::Hit>())
405{
406
407 // FT3 Base configuration parameters
408 auto& ft3BaseParam = FT3BaseParam::Instance();
409
410 if (ft3BaseParam.configFile != "") {
411 LOG(info) << "FT3 Geometry configuration file provided. Overriding FT3Base.geoModel configuration.";
412 buildFT3FromFile(ft3BaseParam.configFile);
413
414 } else {
415 switch (ft3BaseParam.geoModel) {
416 case Default:
417 buildFT3NewVacuumVessel(); // FT3 after Upgrade days March 2024
418 break;
419 case Telescope:
420 buildBasicFT3(ft3BaseParam); // BasicFT3 = Parametrized telescopic detector (equidistant layers)
421 break;
422 default:
423 LOG(fatal) << "Invalid Geometry.\n";
424 break;
425 }
426 }
427 exportLayout();
428}
429
430//_________________________________________________________________________________________________
432 : o2::base::DetImpl<Detector>(rhs),
433 mTrackData(),
434
436 mHits(o2::utils::createSimVector<o2::itsmft::Hit>())
437{
438 mLayerID = rhs.mLayerID;
439 mLayerName = rhs.mLayerName;
440 mNumberOfLayers = rhs.mNumberOfLayers;
441}
442
443//_________________________________________________________________________________________________
445{
446
447 if (mHits) {
448 // delete mHits;
450 }
451}
452
453//_________________________________________________________________________________________________
455{
456 // The standard = operator
457 // Inputs:
458 // Detector &h the sourse of this copy
459 // Outputs:
460 // none.
461 // Return:
462 // A copy of the sourse hit h
463
464 if (this == &rhs) {
465 return *this;
466 }
467
468 // base class assignment
470
471 mLayerID = rhs.mLayerID;
472 mLayerName = rhs.mLayerName;
473 mNumberOfLayers = rhs.mNumberOfLayers;
474 mLayers = rhs.mLayers;
475 mTrackData = rhs.mTrackData;
476
478 mHits = nullptr;
479
480 return *this;
481}
482
483//_________________________________________________________________________________________________
485{
486 // Define the list of sensitive volumes
487 LOG(info) << "Initialize FT3 O2Detector";
488
489 mGeometryTGeo = GeometryTGeo::Instance();
490
491 defineSensitiveVolumes();
492}
493
494//_________________________________________________________________________________________________
495bool Detector::ProcessHits(FairVolume* vol)
496{
497 // This method is called from the MC stepping
498 if (!(fMC->TrackCharge())) {
499 return kFALSE;
500 }
501
502 int lay = 0, volID = vol->getMCid();
503 while ((lay <= mLayerID.size()) && (volID != mLayerID[lay])) {
504 ++lay;
505 }
506
507 auto stack = (o2::data::Stack*)fMC->GetStack();
508
509 bool startHit = false, stopHit = false;
510 unsigned char status = 0;
511 if (fMC->IsTrackEntering()) {
512 status |= Hit::kTrackEntering;
513 }
514 if (fMC->IsTrackInside()) {
515 status |= Hit::kTrackInside;
516 }
517 if (fMC->IsTrackExiting()) {
518 status |= Hit::kTrackExiting;
519 }
520 if (fMC->IsTrackOut()) {
521 status |= Hit::kTrackOut;
522 }
523 if (fMC->IsTrackStop()) {
524 status |= Hit::kTrackStopped;
525 }
526 if (fMC->IsTrackAlive()) {
527 status |= Hit::kTrackAlive;
528 }
529
530 // track is entering or created in the volume
531 if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) {
532 startHit = true;
533 } else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) {
534 stopHit = true;
535 }
536
537 // increment energy loss at all steps except entrance
538 if (!startHit) {
539 mTrackData.mEnergyLoss += fMC->Edep();
540 }
541 if (!(startHit | stopHit)) {
542 return kFALSE; // do noting
543 }
544 if (startHit) {
545 mTrackData.mEnergyLoss = 0.;
546 fMC->TrackMomentum(mTrackData.mMomentumStart);
547 fMC->TrackPosition(mTrackData.mPositionStart);
548 mTrackData.mTrkStatusStart = status;
549 mTrackData.mHitStarted = true;
550 }
551 if (stopHit) {
552 TLorentzVector positionStop;
553 fMC->TrackPosition(positionStop);
554 // Retrieve the indices with the volume path
555 int chipindex = lay;
556
557 Hit* p = addHit(stack->GetCurrentTrackNumber(), chipindex, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
558 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
559 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
560 // p->SetTotalEnergy(vmc->Etot());
561
562 // RS: not sure this is needed
563 // Increment number of Detector det points in TParticle
564 stack->addHit(GetDetId());
565 }
566
567 return kTRUE;
568}
569
570//_________________________________________________________________________________________________
572{
573 int ifield = 2;
574 float fieldm = 10.0;
576
577 float tmaxfdSi = 0.1; // .10000E+01; // Degree
578 float stemaxSi = 0.0075; // .10000E+01; // cm
579 float deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
580 float epsilSi = 1.0E-4; // .10000E+01;
581 float stminSi = 0.0; // cm "Default value used"
582
583 float tmaxfdAir = 0.1; // .10000E+01; // Degree
584 float stemaxAir = .10000E+01; // cm
585 float deemaxAir = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
586 float epsilAir = 1.0E-4; // .10000E+01;
587 float stminAir = 0.0; // cm "Default value used"
588
589 // AIR
590 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
591 float zAir[4] = {6., 7., 8., 18.};
592 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
593 float dAir = 1.20479E-3;
594
595 o2::base::Detector::Mixture(1, "AIR$", aAir, zAir, dAir, 4, wAir);
596 o2::base::Detector::Medium(1, "AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
597
598 o2::base::Detector::Material(3, "SILICON$", 0.28086E+02, 0.14000E+02, 0.23300E+01, 0.93600E+01, 0.99900E+03);
599 o2::base::Detector::Medium(3, "SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
600}
601
602//_________________________________________________________________________________________________
604
605//_________________________________________________________________________________________________
607{
608 // This will create a branch in the output tree called Hit, setting the last
609 // parameter to kFALSE means that this collection will not be written to the file,
610 // it will exist only during the simulation
611
612 if (FairRootManager::Instance()) {
613 FairRootManager::Instance()->RegisterAny(addNameTo("Hit").data(), mHits, kTRUE);
614 }
615}
616
617//_________________________________________________________________________________________________
619{
620 if (!o2::utils::ShmManager::Instance().isOperational()) {
621 mHits->clear();
622 }
623}
624
625//_________________________________________________________________________________________________
627{
628 // Create detector materials
630
631 // Construct the detector geometry
633}
634
635//_________________________________________________________________________________________________
637{
638
639 mGeometryTGeo = GeometryTGeo::Instance();
640
641 TGeoVolume* volFT3 = new TGeoVolumeAssembly(GeometryTGeo::getFT3VolPattern());
642 TGeoVolume* volIFT3 = new TGeoVolumeAssembly(GeometryTGeo::getFT3InnerVolPattern());
643
644 LOG(info) << "GeometryBuilder::buildGeometry volume name = " << GeometryTGeo::getFT3VolPattern();
645
646 TGeoVolume* vALIC = gGeoManager->GetVolume("barrel");
647 if (!vALIC) {
648 LOG(fatal) << "Could not find the top volume";
649 }
650
651 TGeoVolume* A3IPvac = gGeoManager->GetVolume("OUT_PIPEVACUUM");
652 if (!A3IPvac) {
653 LOG(info) << "Running simulation with no beam pipe.";
654 }
655
656 LOG(debug) << "FT3 createGeometry: "
657 << Form("gGeoManager name is %s title is %s", gGeoManager->GetName(), gGeoManager->GetTitle());
658
659 if (mLayers.size() == 2) { // V1 and telescope
660 if (!A3IPvac) {
661 for (int direction : {0, 1}) { // Backward layers at mLayers[0]; Forward layers at mLayers[1]
662 std::string directionString = direction ? "Forward" : "Backward";
663 LOG(info) << "Creating FT3 " << directionString << " layers:";
664 for (int iLayer = 0; iLayer < mLayers[direction].size(); iLayer++) {
665 mLayers[direction][iLayer].createLayer(volFT3);
666 }
667 }
668 vALIC->AddNode(volFT3, 2, new TGeoTranslation(0., 30., 0.));
669 } else { // If beampipe is enabled append inner disks to beampipe filling volume, this should be temporary.
670 for (int direction : {0, 1}) {
671 std::string directionString = direction ? "Forward" : "Backward";
672 LOG(info) << "Creating FT3 " << directionString << " layers:";
673 for (int iLayer = 0; iLayer < mLayers[direction].size(); iLayer++) {
674 if (iLayer < 3) {
675 mLayers[direction][iLayer].createLayer(volIFT3);
676 } else {
677 mLayers[direction][iLayer].createLayer(volFT3);
678 }
679 }
680 }
681 A3IPvac->AddNode(volIFT3, 2, new TGeoTranslation(0., 0., 0.));
682 vALIC->AddNode(volFT3, 2, new TGeoTranslation(0., 30., 0.));
683 }
684
685 for (auto direction : {0, 1}) {
686 std::string directionString = direction ? "Forward" : "Backward";
687 LOG(info) << "Registering FT3 " << directionString << " LayerIDs:";
688 for (int iLayer = 0; iLayer < mLayers[direction].size(); iLayer++) {
689 auto layerID = gMC ? TVirtualMC::GetMC()->VolId(Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), direction, iLayer)) : 0;
690 mLayerID.push_back(layerID);
691 LOG(info) << " " << directionString << " layer " << iLayer << " LayerID " << layerID;
692 }
693 }
694 }
695
696 if (mLayers.size() == 1) { // All layers registered at mLayers[0], used when building from file
697 LOG(info) << "Creating FT3 layers:";
698 if (A3IPvac) {
699 for (int iLayer = 0; iLayer < mLayers[0].size(); iLayer++) {
700 if (std::abs(mLayers[0][iLayer].getZ()) < 25) {
701 mLayers[0][iLayer].createLayer(volIFT3);
702 } else {
703 mLayers[0][iLayer].createLayer(volFT3);
704 }
705 }
706 A3IPvac->AddNode(volIFT3, 2, new TGeoTranslation(0., 0., 0.));
707 vALIC->AddNode(volFT3, 2, new TGeoTranslation(0., 30., 0.));
708 } else {
709 for (int iLayer = 0; iLayer < mLayers[0].size(); iLayer++) {
710 mLayers[0][iLayer].createLayer(volFT3);
711 }
712 vALIC->AddNode(volFT3, 2, new TGeoTranslation(0., 30., 0.));
713 }
714 LOG(info) << "Registering FT3 LayerIDs:";
715 for (int iLayer = 0; iLayer < mLayers[0].size(); iLayer++) {
716 auto layerID = gMC ? TVirtualMC::GetMC()->VolId(Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), 0, iLayer)) : 0;
717 mLayerID.push_back(layerID);
718 LOG(info) << " mLayerID[" << iLayer << "] = " << layerID;
719 }
720 }
721}
722
723//_________________________________________________________________________________________________
724void Detector::defineSensitiveVolumes()
725{
726 TGeoManager* geoManager = gGeoManager;
727 TGeoVolume* v;
728
729 TString volumeName;
730 LOG(info) << "Adding FT3 Sensitive Volumes";
731
732 // The names of the FT3 sensitive volumes have the format: FT3Sensor_(0,1)_(0...sNumberLayers-1)
733 if (mLayers.size() == 2) {
734 for (int direction : {0, 1}) {
735 for (int iLayer = 0; iLayer < mNumberOfLayers; iLayer++) {
737 v = geoManager->GetVolume(Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), direction, iLayer));
738 LOG(info) << "Adding FT3 Sensitive Volume => " << v->GetName();
739 AddSensitiveVolume(v);
740 }
741 }
742 }
743
744 if (mLayers.size() == 1) {
745 for (int iLayer = 0; iLayer < mLayers[0].size(); iLayer++) {
747 v = geoManager->GetVolume(Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), mLayers[0][iLayer].getDirection(), iLayer));
748 LOG(info) << "Adding FT3 Sensitive Volume => " << v->GetName();
749 AddSensitiveVolume(v);
750 }
751 }
752}
753
754//_________________________________________________________________________________________________
755Hit* Detector::addHit(int trackID, int detID, const TVector3& startPos, const TVector3& endPos,
756 const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus,
757 unsigned char endStatus)
758{
759 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
760 return &(mHits->back());
761}
762
Definition of the Stack class.
Definition of the ITSMFT Hit class.
Definition of the FT3Layer class.
ClassImp(IdPath)
uint32_t stack
Definition RawData.h:1
Definition of the GeometryTGeo class.
Definition of the Detector class.
std::ostringstream debug
Detector & operator=(const Detector &)
Definition Detector.cxx:46
void Mixture(Int_t imat, const char *name, Float_t *a, Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat)
Definition Detector.cxx:66
void Medium(Int_t numed, const char *name, Int_t nmat, Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd, Float_t stemax, Float_t deemax, Float_t epsil, Float_t stmin, Float_t *ubuf=nullptr, Int_t nbuf=0)
Definition Detector.cxx:72
static void initFieldTrackingParams(int &mode, float &maxfield)
Definition Detector.cxx:143
void Material(Int_t imat, const char *name, Float_t a, Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t *buf=nullptr, Int_t nwbuf=0)
Definition Detector.cxx:59
std::string addNameTo(const char *ext) const
Definition Detector.h:150
std::vector< std::vector< TString > > mLayerName
Definition Detector.h:127
void buildFT3FromFile(std::string)
Definition Detector.cxx:61
Detector()
Default constructor.
Definition Detector.cxx:53
std::vector< Int_t > mLayerID
Definition Detector.h:126
void buildBasicFT3(const FT3BaseParam &param)
Definition Detector.cxx:151
void buildFT3NewVacuumVessel()
Definition Detector.cxx:280
void exportLayout()
access to geometry details
Definition Detector.cxx:128
Int_t mNumberOfLayers
Definition Detector.h:128
static const char * getFT3SensorPattern()
static const char * getFT3LayerPattern()
static const char * getFT3VolPattern()
static const char * getFT3InnerVolPattern()
void Reset() override
Definition Detector.cxx:280
void Register() override
Definition Detector.cxx:269
void ConstructGeometry() override
Definition Detector.cxx:69
o2::itsmft::Hit * addHit(int trackID, int detID, const TVector3 &startPos, const TVector3 &endPos, const TVector3 &startMom, double startE, double endTime, double eLoss, unsigned char startStatus, unsigned char endStatus)
Definition Detector.cxx:372
void InitializeO2Detector() override
Definition Detector.cxx:242
void EndOfEvent() override
Definition Detector.cxx:267
bool ProcessHits(FairVolume *v=nullptr) override
Definition Detector.cxx:287
static GeometryTGeo * Instance()
static ShmManager & Instance()
Definition ShmManager.h:61
const GLdouble * v
Definition glcorearb.h:832
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat x0
Definition glcorearb.h:5034
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLenum GLfloat param
Definition glcorearb.h:271
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
void freeSimVector(std::vector< T > *ptr)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
Common utility functions.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"