Skip to content

Commit 24d3b10

Browse files
committed
FCT Segmentation in trapezoids
1 parent 167b8c0 commit 24d3b10

File tree

8 files changed

+271
-4
lines changed

8 files changed

+271
-4
lines changed

Detectors/Upgrades/ALICE3/FCT/base/include/FCTBase/FCTBaseParam.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ namespace fct
2626

2727
enum FCTGeometry {
2828
Default = 0,
29-
Telescope = 1
29+
Telescope = 1,
30+
Segmented = 2
3031
};
3132

3233
struct FCTBaseParam : public o2::conf::ConfigurableParamHelper<FCTBaseParam> {
@@ -42,6 +43,10 @@ struct FCTBaseParam : public o2::conf::ConfigurableParamHelper<FCTBaseParam> {
4243
Float_t etaOut = 1.5;
4344
Float_t Layerx2X0 = 0.01;
4445

46+
// FCTGeometry::Segmented parameters
47+
Int_t nRadSeg = 2;
48+
Int_t nAziSeg = 5;
49+
4550
// FCTGeometry::External file
4651
std::string configFile = ""; // Overrides geoModel parameter when provided
4752

Detectors/Upgrades/ALICE3/FCT/base/include/FCTBase/GeometryTGeo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class GeometryTGeo : public o2::itsmft::GeometryTGeo
101101
static const char* composeSymNameSensor(Int_t d, Int_t lr);
102102

103103
protected:
104-
static constexpr int MAXLAYERS = 15; ///< max number of active layers
104+
static constexpr int MAXLAYERS = 200; ///< max number of active layers/segments
105105

106106
Int_t mNumberOfLayers; ///< number of layers
107107
static std::string sInnerVolumeName; ///< Mother inner volume name

Detectors/Upgrades/ALICE3/FCT/simulation/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@
1111

1212
o2_add_library(FCTSimulation
1313
SOURCES src/FCTLayer.cxx
14+
src/FCTSegment.cxx
1415
src/Detector.cxx
1516
PUBLIC_LINK_LIBRARIES O2::FCTBase
1617
O2::ITSMFTSimulation
1718
ROOT::Physics)
1819

1920
o2_target_root_dictionary(FCTSimulation
2021
HEADERS include/FCTSimulation/Detector.h
21-
include/FCTSimulation/FCTLayer.h)
22+
include/FCTSimulation/FCTLayer.h
23+
include/FCTSimulation/FCTSegment.h)
2224

2325
o2_data_file(COPY data DESTINATION Detectors/FCT/simulation)

Detectors/Upgrades/ALICE3/FCT/simulation/include/FCTSimulation/Detector.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ namespace o2
4646
namespace fct
4747
{
4848
class FCTLayer;
49+
class FCTSegment;
4950
}
5051
} // namespace o2
5152

@@ -54,6 +55,7 @@ namespace o2
5455
namespace fct
5556
{
5657
class FCTLayer;
58+
class FCTSegment;
5759

5860
class Detector : public o2::base::DetImpl<Detector>
5961
{
@@ -113,6 +115,7 @@ class Detector : public o2::base::DetImpl<Detector>
113115

114116
void buildBasicFCT(const FCTBaseParam& param);
115117
void buildFCTV1();
118+
void buildSegmentedFCT(const FCTBaseParam& param);
116119
void buildFCTFromFile(std::string);
117120

118121
GeometryTGeo* mGeometryTGeo; //! access to geometry details
@@ -154,6 +157,7 @@ class Detector : public o2::base::DetImpl<Detector>
154157

155158
std::vector<FCTLayer> mLayers;
156159
std::vector<FCTLayer> mConverterLayers;
160+
std::vector<o2::fct::FCTSegment> mSegments;
157161
bool mIsPipeActivated = true; //! If Alice 3 pipe is present append inner disks to vacuum volume to avoid overlaps
158162

159163
template <typename Det>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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+
/// \file FCTSegment.h
13+
/// \brief Definition of the FCTSegment class
14+
15+
#ifndef ALICEO2_FCT_SEGMENT_H_
16+
#define ALICEO2_FCT_SEGMENT_H_
17+
18+
#include "Rtypes.h" // for Double_t, Int_t, Bool_t, etc
19+
#include "FCTSimulation/Detector.h" // for Detector, Detector::Model
20+
21+
class TGeoVolume;
22+
23+
namespace o2
24+
{
25+
namespace fct
26+
{
27+
28+
/// This class defines the Geometry for the FCT segment TGeo. This is a work class used
29+
/// to study different configurations during the development of the ALICE3 EndCaps
30+
class FCTSegment : public TObject
31+
{
32+
public:
33+
// Default constructor
34+
FCTSegment() = default;
35+
36+
// Segment constructor
37+
FCTSegment(Int_t segmentNumber, std::string segmentName, Double_t x, Double_t y, Double_t z, Double_t vertL, Double_t innerL, Double_t outerL, Double_t rotX, Double_t rotY, Double_t rotZ, Float_t segmentx2X0);
38+
39+
/// Copy constructor
40+
FCTSegment(const FCTSegment&) = default;
41+
42+
/// Assignment operator
43+
FCTSegment& operator=(const FCTSegment&) = default;
44+
45+
/// Default destructor
46+
~FCTSegment() override;
47+
48+
/// getters
49+
auto getSegmentNumber() const { return mSegmentNumber; }
50+
auto getX() const { return mX; }
51+
auto getY() const { return mY; }
52+
auto getZ() const { return mZ; }
53+
auto getXRot() const { return mX; }
54+
auto getYRot() const { return mY; }
55+
auto getZRot() const { return mZ; }
56+
auto getVertL() const { return mVertL; }
57+
auto getInnerL() const { return mInnerL; }
58+
auto getOuterL() const { return mOuterL; }
59+
auto getx2X0() const { return mx2X0; }
60+
61+
/// Creates the actual Segment and places inside its mother volume
62+
/// \param motherVolume the TGeoVolume owing the volume structure
63+
virtual void createSegment(TGeoVolume* motherVolume);
64+
65+
private:
66+
Int_t mSegmentNumber = -1; ///< Current segment number
67+
std::string mSegmentName; ///< Current segment name
68+
Double_t mVertL; ///< Vertical length of the trapezoid
69+
Double_t mInnerL; ///< Inner side length of the trapezoid
70+
Double_t mOuterL; ///< Outer side length of the trapezoid
71+
Double_t mX; ///< X position of the segment
72+
Double_t mY; ///< Y position of the segment
73+
Double_t mZ; ///< Z position of the segment
74+
Double_t mRotX; ///< X rotation of the segment
75+
Double_t mRotY; ///< X rotation of the segment
76+
Double_t mRotZ; ///< X rotation of the segment
77+
Double_t mChipThickness; ///< Chip thickness
78+
Double_t mx2X0; ///< segment material budget x/X0
79+
80+
ClassDefOverride(FCTSegment, 0); // ALICE 3 EndCaps geometry
81+
};
82+
} // namespace fct
83+
} // namespace o2
84+
85+
#endif

Detectors/Upgrades/ALICE3/FCT/simulation/src/Detector.cxx

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "FCTBase/GeometryTGeo.h"
1717
#include "FCTSimulation/Detector.h"
1818
#include "FCTSimulation/FCTLayer.h"
19+
#include "FCTSimulation/FCTSegment.h"
1920
#include "FCTBase/FCTBaseParam.h"
2021

2122
#include "DetectorsBase/Stack.h"
@@ -203,6 +204,58 @@ void Detector::buildBasicFCT(const FCTBaseParam& param)
203204
}
204205
}
205206

207+
void Detector::buildSegmentedFCT(const FCTBaseParam& param){
208+
// Build the FCT with its layers segmented in trapezoids. The z distance is the same as the default configuration
209+
LOG(info) << "Building FCT Detector: Segmented Telescope";
210+
211+
int numberOfLayers = 11;
212+
Float_t layersx2X0 = 1.e-2;
213+
std::vector<std::array<Float_t, 4>> layersConfig{
214+
{442.0, 5.0, 17.0, layersx2X0}, // {z_layer, r_in, r_out, Layerx2X0}
215+
{444.0, 5.0, 17.0, layersx2X0},
216+
{446.0, 5.0, 17.0, layersx2X0},
217+
{448.0, 5.0, 17.0, layersx2X0},
218+
{450.0, 5.0, 17.0, layersx2X0},
219+
{452.0, 5.0, 17.0, layersx2X0},
220+
{460.0, 5.0, 17.0, layersx2X0},
221+
{470.0, 5.0, 18.0, layersx2X0},
222+
{480.0, 5.0, 18.0, layersx2X0},
223+
{490.0, 5.0, 19.0, layersx2X0},
224+
{500.0, 5.0, 19.0, layersx2X0}};
225+
226+
mLayerID.clear();
227+
mLayerName.clear();
228+
mLayers.clear();
229+
230+
Double_t segAngle = 2.*TMath::Pi() / (Double_t)param.nAziSeg;
231+
const Float_t kRadDeg = 180./TMath::Pi();
232+
int segmentNumber = 0;
233+
for (int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
234+
Double_t zPosTrap = layersConfig[layerNumber][0];
235+
Double_t rIn = layersConfig[layerNumber][1];
236+
Double_t rOut = layersConfig[layerNumber][2];
237+
Double_t x2X0 = layersConfig[layerNumber][3];
238+
Double_t radialSegLength = (rOut - rIn) / ((Double_t)(param.nRadSeg));
239+
Double_t trapezoidVertLength = radialSegLength*TMath::Cos(segAngle/2.);
240+
for (int radialNumber = 0; radialNumber < param.nRadSeg; radialNumber++) {
241+
for (int azimuthalNumber = 0; azimuthalNumber < param.nAziSeg; azimuthalNumber++) {
242+
Double_t innerTrapLength = TMath::Sqrt(2. * (rIn + radialNumber * radialSegLength)*(rIn + radialNumber * radialSegLength) * (1. - TMath::Cos(segAngle)));
243+
Double_t outerTrapLength = TMath::Sqrt(2. * (rIn + (radialNumber + 1) * radialSegLength)*(rIn + (radialNumber + 1) * radialSegLength) * (1. - TMath::Cos(segAngle)));
244+
Double_t innerTrapCenterR = (rIn + radialNumber * radialSegLength)*TMath::Cos(segAngle/2.);
245+
Double_t outerTrapCenterR = (rIn + (radialNumber + 1) * radialSegLength)*TMath::Cos(segAngle/2.);
246+
Double_t rTrapCenter = outerTrapCenterR - 0.5*(outerTrapCenterR - innerTrapCenterR);
247+
Double_t xPosTrap = rTrapCenter * TMath::Cos(azimuthalNumber * segAngle);
248+
Double_t yPosTrap = rTrapCenter * TMath::Sin(azimuthalNumber * segAngle);
249+
Double_t xRot = -90 + azimuthalNumber*segAngle*kRadDeg;
250+
std::string segmentName = GeometryTGeo::getFCTLayerPattern() + std::to_string(segmentNumber);
251+
mSegments.emplace_back(segmentNumber, segmentName, xPosTrap, yPosTrap, zPosTrap, trapezoidVertLength, innerTrapLength, outerTrapLength, xRot, 0., 0., x2X0);
252+
segmentNumber++;
253+
}
254+
}
255+
}
256+
mNumberOfLayers = segmentNumber;
257+
}
258+
206259
//_________________________________________________________________________________________________
207260
void Detector::buildFCTV1()
208261
{
@@ -479,6 +532,9 @@ void Detector::ConstructGeometry()
479532
case Telescope:
480533
buildBasicFCT(fctBaseParam); // BasicFCT = Parametrized telescopic detector (equidistant layers)
481534
break;
535+
case Segmented:
536+
buildSegmentedFCT(fctBaseParam); // Layers of the FCT are segmented in trapezoids.
537+
break;
482538
default:
483539
LOG(fatal) << "Invalid Geometry.\n";
484540
break;
@@ -536,15 +592,25 @@ void Detector::createGeometry()
536592
for (Int_t iLayer = 0; iLayer < mConverterLayers.size(); iLayer++) {
537593
mConverterLayers[iLayer].createLayer(volFCT);
538594
}
595+
for (Int_t iSegment = 0; iSegment < mSegments.size(); iSegment++){
596+
mSegments[iSegment].createSegment(volFCT);
597+
}
539598
vALIC->AddNode(volFCT, 2, new TGeoTranslation(0., 30., 0.));
540599
}
541600

542-
LOG(info) << "Registering FCT SensitiveLayerIDs:";
601+
if(!mLayers.size()){LOG(info) << "Registering FCT SensitiveLayerIDs:";}
543602
for (int iLayer = 0; iLayer < mLayers.size(); iLayer++) {
544603
auto layerID = gMC ? TVirtualMC::GetMC()->VolId(Form("%s_%d", GeometryTGeo::getFCTSensorPattern(), mLayers[iLayer].getLayerNumber())) : 0;
545604
mLayerID.push_back(layerID);
546605
LOG(info) << " mLayerID[" << mLayers[iLayer].getLayerNumber() << "] = " << layerID;
547606
}
607+
608+
if(!mSegments.size()){LOG(info) << "Registering FCT SensitiveSegmentIDs:";}
609+
for (int iSegment = 0; iSegment < mSegments.size(); iSegment++) {
610+
auto segmentID = gMC ? TVirtualMC::GetMC()->VolId(Form("%s_%d", GeometryTGeo::getFCTSensorPattern(), mSegments[iSegment].getSegmentNumber())) : 0;
611+
mLayerID.push_back(segmentID);
612+
LOG(info) << " mSegmentID[" << mSegments[iSegment].getSegmentNumber() << "] = " << segmentID;
613+
}
548614
}
549615

550616
//_________________________________________________________________________________________________
@@ -563,6 +629,13 @@ void Detector::defineSensitiveVolumes()
563629
LOG(info) << "Adding FCT Sensitive Volume => " << v->GetName();
564630
AddSensitiveVolume(v);
565631
}
632+
633+
for (Int_t iSegment = 0; iSegment < mSegments.size(); iSegment++) {
634+
volumeName = o2::fct::GeometryTGeo::getFCTSensorPattern() + std::to_string(mSegments[iSegment].getSegmentNumber());
635+
v = geoManager->GetVolume(Form("%s_%d", GeometryTGeo::getFCTSensorPattern(), mSegments[iSegment].getSegmentNumber()));
636+
LOG(info) << "Adding FCT Sensitive Volume => " << v->GetName();
637+
AddSensitiveVolume(v);
638+
}
566639
}
567640

568641
//_________________________________________________________________________________________________
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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+
/// \file FCTSegment.cxx
13+
/// \brief Implementation of the FCTSegment class
14+
/// \author Mario Sitta <sitta@to.infn.it>
15+
/// \author Chinorat Kobdaj (kobdaj@g.sut.ac.th)
16+
17+
#include "FCTSimulation/FCTSegment.h"
18+
#include "FCTBase/GeometryTGeo.h"
19+
#include "FCTSimulation/Detector.h"
20+
21+
#include <fairlogger/Logger.h> // for LOG
22+
23+
#include <TGeoManager.h> // for TGeoManager, gGeoManager
24+
#include <TGeoMatrix.h> // for TGeoCombiTrans, TGeoRotation, etc
25+
#include <TGeoMedium.h>
26+
#include <TGeoArb8.h> // for TGeoTrap
27+
#include <TGeoVolume.h> // for TGeoVolume, TGeoVolumeAssembly
28+
#include <TGeoCompositeShape.h> // for TGeoCompositeShape
29+
#include <TGeoMatrix.h> // for TGeoCombiTrans
30+
#include "TMathBase.h" // for Abs
31+
#include <TMath.h> // for Sin, RadToDeg, DegToRad, Cos, Tan, etc
32+
33+
#include <cstdio> // for snprintf
34+
35+
using namespace TMath;
36+
using namespace o2::fct;
37+
using namespace o2::itsmft;
38+
39+
ClassImp(FCTSegment);
40+
41+
FCTSegment::~FCTSegment() = default;
42+
43+
FCTSegment::FCTSegment(Int_t segmentNumber, std::string segmentName, Double_t x, Double_t y, Double_t z, Double_t vertL, Double_t innerL, Double_t outerL, Double_t rotX, Double_t rotY, Double_t rotZ, Float_t segmentx2X0) :
44+
mSegmentNumber(segmentNumber), mSegmentName(segmentName), mx2X0(segmentx2X0),
45+
mX(x), mY(y), mZ(z), mRotX(rotX), mRotY(rotY), mRotZ(rotZ),
46+
mVertL(vertL), mInnerL(innerL), mOuterL(outerL)
47+
{
48+
49+
Float_t Si_X0 = 9.37; // In cm
50+
mChipThickness = mx2X0 * Si_X0;
51+
LOG(info) << "Creating FCT segment: segment " << mSegmentNumber;
52+
LOG(info) << " Using silicon X0 = " << Si_X0 << " to emulate segment radiation length.";
53+
LOG(info) << " Segment z = " << mZ << " ; vertL = " << mVertL << " ; innerL = " << mInnerL << " ; outerL = " << mOuterL << " ; x2X0 = " << mx2X0 << " ; ChipThickness = " << mChipThickness;
54+
}
55+
56+
void FCTSegment::createSegment(TGeoVolume* motherVolume)
57+
{
58+
if (mSegmentNumber < 0) {
59+
return;
60+
}
61+
// Create tube, set sensitive volume, add to mother volume
62+
63+
std::string chipName = o2::fct::GeometryTGeo::getFCTChipPattern() + std::to_string(mSegmentNumber),
64+
sensName = Form("%s_%d", GeometryTGeo::getFCTSensorPattern(), mSegmentNumber);
65+
TGeoTrap *sensor = new TGeoTrap(mChipThickness/2., 0., 0.,
66+
mVertL/2., mInnerL/2., mOuterL/2., 0.,
67+
mVertL/2., mInnerL/2., mOuterL/2., 0.);
68+
TGeoTrap *chip = new TGeoTrap(mChipThickness/2., 0., 0.,
69+
mVertL/2., mInnerL/2., mOuterL/2., 0.,
70+
mVertL/2., mInnerL/2., mOuterL/2., 0.);
71+
TGeoTrap *segment = new TGeoTrap(mChipThickness/2., 0., 0.,
72+
mVertL/2., mInnerL/2., mOuterL/2., 0.,
73+
mVertL/2., mInnerL/2., mOuterL/2., 0.);
74+
75+
TGeoMedium* medSi = gGeoManager->GetMedium("FCT_SILICON$");
76+
TGeoMedium* medAir = gGeoManager->GetMedium("FCT_AIR$");
77+
78+
TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
79+
sensVol->SetLineColor(kSpring + 5);
80+
TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
81+
chipVol->SetLineColor(kSpring + 5);
82+
TGeoVolume* segmentVol = new TGeoVolume(mSegmentName.c_str(), segment, medAir);
83+
segmentVol->SetLineColor(kSpring + 5);
84+
85+
LOG(info) << "Inserting " << sensVol->GetName() << " inside " << chipVol->GetName();
86+
chipVol->AddNode(sensVol, 1, nullptr);
87+
88+
LOG(info) << "Inserting " << chipVol->GetName() << " inside " << segmentVol->GetName();
89+
segmentVol->AddNode(chipVol, 1, nullptr);
90+
91+
// Finally put everything in the mother volume
92+
auto FwdSegmentRotation = new TGeoRotation("FwdSegmentRotation", mRotX, mRotY, mRotZ);
93+
auto FwdSegmentCombiTrans = new TGeoCombiTrans(mX, mY, mZ, FwdSegmentRotation);
94+
95+
LOG(info) << "Inserting " << segmentVol->GetName() << " inside " << motherVolume->GetName();
96+
motherVolume->AddNode(segmentVol, 1, FwdSegmentCombiTrans);
97+
}

Detectors/Upgrades/ALICE3/FCT/simulation/src/FCTSimulationLinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#pragma link off all functions;
1717

1818
#pragma link C++ class o2::fct::FCTLayer + ;
19+
#pragma link C++ class o2::fct::FCTSegment + ;
1920
#pragma link C++ class o2::fct::Detector + ;
2021
#pragma link C++ class o2::base::DetImpl < o2::fct::Detector> + ;
2122

0 commit comments

Comments
 (0)