Skip to content

Commit 13af406

Browse files
committed
Build tubes geometry
1 parent bd21af9 commit 13af406

File tree

5 files changed

+252
-151
lines changed

5 files changed

+252
-151
lines changed

source/tdis/tracking/ActsGeometryService.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ void tdis::tracking::ActsGeometryService::Init() {
368368

369369

370370
/// Return the telescope detector
371-
gGeometry = tdis::tracking::buildDetector(
371+
gGeometry = tdis::tracking::buildOriginalDetector(
372372
nominalContext, // gctx is the detector element dependent geometry context
373373
m_detector_elements, // detectorStore is the store for the detector element
374374
m_plane_positions, // positions are the positions of different layers in the longitudinal direction

source/tdis/tracking/BuildMtpcDetector.cpp

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
#include "Acts/Geometry/PlaneLayer.hpp"
2323
#include "Acts/Geometry/TrackingGeometry.hpp"
2424
#include "Acts/Geometry/TrackingVolume.hpp"
25+
#include <Acts/Geometry/CylinderLayer.hpp>
2526
#include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
27+
#include "Acts/Material/HomogeneousVolumeMaterial.hpp"
2628
#include "Acts/Material/Material.hpp"
2729
#include "Acts/Material/MaterialSlab.hpp"
2830
#include "Acts/Surfaces/RadialBounds.hpp"
@@ -32,8 +34,12 @@
3234
#include "Acts/Utilities/Logger.hpp"
3335
#include "BuildMtpcDetector.hpp"
3436

35-
std::unique_ptr<const Acts::TrackingGeometry>
36-
tdis::tracking::buildDetector(
37+
38+
#include <memory>
39+
#include <vector>
40+
/*
41+
static std::unique_ptr<const Acts::TrackingGeometry>
42+
tdis::tracking::buildOriginalDetector(
3743
const typename tdis::tracking::MtpcDetectorElement::ContextType &gctx,
3844
std::vector<std::shared_ptr<tdis::tracking::MtpcDetectorElement> > &detectorStore,
3945
const std::vector<double> &positions,
@@ -128,3 +134,127 @@ tdis::tracking::buildDetector(
128134
// Build and return tracking geometry
129135
return std::make_unique<Acts::TrackingGeometry>(trackVolume);
130136
}
137+
*/
138+
139+
/** This geometry uses cylindrical surfaces with:
140+
* - R (radius) of each cylinder - corresponding to each of mTPC ring center
141+
* - The length of each cylinder in z direction equal to whole detector length
142+
* This way the finding a point on a plane for ACTS Kalman filtering is easy in terms of Z coordinate
143+
* Then each cylinder correspond to MtpcDetectorElement in detectorStore
144+
*/
145+
std::unique_ptr<const Acts::TrackingGeometry>
146+
tdis::tracking::buildCylindricalDetector(
147+
const typename MtpcDetectorElement::ContextType& gctx,
148+
std::unordered_map<uint32_t, std::shared_ptr<MtpcDetectorElement>>& surfaceStore)
149+
{
150+
using namespace Acts;
151+
using namespace Acts::UnitLiterals;
152+
153+
// Define Argon gas material properties at STP
154+
double radiationLength = 19.55_m; // Radiation length in mm (19.55 m)
155+
double interactionLength = 70.0_m; // Interaction length in mm (70 m)
156+
double atomicMass = 39.948; // Atomic mass of Argon
157+
double atomicNumber = 18; // Atomic number of Argon
158+
double massDensity = 1.66e-6_g / 1_mm3; // Mass density in g/mm³
159+
160+
// Create Argon gas material
161+
Material argonGas = Material::fromMassDensity(
162+
radiationLength, interactionLength, atomicMass, atomicNumber, massDensity);
163+
164+
// Define constants
165+
double innerRadius = 50_mm; // 5 cm in mm
166+
double outerRadius = 150_mm; // 15 cm in mm
167+
double cylinderLength = 550_mm; // 55 cm in mm
168+
double halfLength = cylinderLength / 2.0; // Half-length of the cylinder
169+
int numRings = 21; // Number of concentric rings
170+
double radialStep = (outerRadius - innerRadius) / numRings;
171+
172+
// Create vector to hold cylinder layers
173+
std::vector<std::shared_ptr<const CylinderLayer>> cylinderLayers;
174+
175+
for (int i = 0; i < numRings; ++i) {
176+
// Calculate the radius of the current ring (centered within its radial step)
177+
double radius = innerRadius + (i + 0.5) * radialStep;
178+
179+
// Define the cylinder bounds
180+
auto cylinderBounds = std::make_shared<const CylinderBounds>(radius, halfLength);
181+
182+
// Create the detector element
183+
uint32_t id = static_cast<uint32_t>(i); // Ring index, 0 for innermost
184+
185+
auto elementTransform = std::make_shared<const Transform3>(Transform3::Identity());
186+
187+
// Create the detector element
188+
auto detElem = std::make_shared<MtpcDetectorElement>(
189+
id,
190+
elementTransform,
191+
cylinderBounds,
192+
radialStep // Thickness of the layer
193+
// No surface material assigned
194+
);
195+
196+
// Store the detector element
197+
surfaceStore[id] = detElem;
198+
199+
// Get the surface from the detector element
200+
auto cylinderSurface = detElem->surface().getSharedPtr();
201+
202+
// Create a vector of surfaces
203+
std::vector<std::shared_ptr<const Surface>> surfaces;
204+
surfaces.push_back(cylinderSurface);
205+
206+
// Create the SurfaceArray
207+
auto surfaceArray = std::make_unique<SurfaceArray>(
208+
Transform3(Vector3(0, 0, 0)), // Center at origin
209+
std::move(surfaces));
210+
211+
// Now create the CylinderLayer using the create method
212+
auto cylinderLayer = CylinderLayer::create(
213+
Transform3::Identity(), // Transform
214+
cylinderBounds, // Cylinder bounds
215+
std::move(surfaceArray), // Surface array
216+
radialStep, // Layer thickness
217+
nullptr, // No approach descriptor
218+
LayerType::sensitive); // Layer type
219+
220+
// Add the layer to the vector
221+
cylinderLayers.push_back(std::move(cylinderLayer));
222+
}
223+
224+
// Create a LayerArray from the cylinder layers
225+
Acts::LayerArrayCreator::Config layerArrayCreatorConfig;
226+
LayerArrayCreator layerArrayCreator(layerArrayCreatorConfig);
227+
auto layerArray = layerArrayCreator.layerArray(
228+
GeometryContext(),
229+
cylinderLayers,
230+
innerRadius,
231+
outerRadius,
232+
BinningType::arbitrary,
233+
BinningValue::binR);
234+
235+
// Define the cylinder volume bounds (outermost dimensions)
236+
auto volumeBounds = std::make_shared<CylinderVolumeBounds>(
237+
innerRadius, outerRadius, halfLength);
238+
239+
// Create the material for the volume
240+
auto volumeMaterial = std::make_shared<HomogeneousVolumeMaterial>(argonGas);
241+
242+
// Create the tracking volume with the layers
243+
auto trackingVolume = std::make_shared<TrackingVolume>(
244+
Transform3::Identity(), // No transformation (centered at origin)
245+
volumeBounds, // Volume bounds
246+
volumeMaterial, // Volume material
247+
std::move(layerArray), // Layer array
248+
nullptr, // No contained volumes
249+
MutableTrackingVolumeVector{},
250+
"TPCVolume");
251+
252+
// Create the TrackingGeometry with the tracking volume as the world volume
253+
auto trackingGeometry = std::make_unique<TrackingGeometry>(trackingVolume);
254+
255+
return trackingGeometry;
256+
}
257+
258+
259+
260+

source/tdis/tracking/BuildMtpcDetector.hpp

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,15 @@ class TrackingGeometry;
2323

2424
namespace tdis::tracking {
2525

26-
/// Global method to build the telescope tracking geometry
27-
///
28-
/// @param gctx is the detector element dependent geometry context
29-
/// @param detectorStore is the store for the detector element
30-
/// @param positions are the positions of different layers in the longitudinal
31-
/// direction
32-
/// @param stereoAngles are the stereo angles of different layers, which are
33-
/// rotation angles around the longitudinal (normal)
34-
/// direction
35-
/// @param offsets is the offset (u, v) of the layers in the transverse plane
36-
/// @param bounds is the surface bound values, i.e. minR and maxR
37-
/// @param thickness is the material thickness of each layer
38-
39-
/// @param binValue indicates which axis the detector surface normals are
40-
/// parallel to
41-
std::unique_ptr<const Acts::TrackingGeometry> buildDetector(
42-
const typename MtpcDetectorElement::ContextType& gctx,
43-
std::vector<std::shared_ptr<MtpcDetectorElement>>& detectorStore,
44-
const std::vector<double>& positions,
45-
const std::vector<double>& stereoAngles,
46-
const std::array<double, 2>& offsets,
47-
const std::array<double, 2>& bounds,
48-
double thickness,
49-
Acts::BinningValue binValue = Acts::BinningValue::binZ);
26+
27+
/** This geometry uses cylindrical surfaces with:
28+
* - R (radius) of each cylinder - corresponding to each of mTPC ring center
29+
* - The length of each cylinder in z direction equal to whole detector length
30+
* This way the finding a point on a plane for ACTS Kalman filtering is easy in terms of Z coordinate
31+
* Then each cylinder correspond to MtpcDetectorElement in detectorStore
32+
*/
33+
std::unique_ptr<const Acts::TrackingGeometry> buildCylindricalDetector(
34+
const typename MtpcDetectorElement::ContextType& gctx,
35+
std::unordered_map<uint32_t, std::shared_ptr<MtpcDetectorElement>>& surfaceStore);
5036

5137
} // namespace ActsExamples::Telescope
Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,73 @@
1-
// This file is part of the Acts project.
2-
//
3-
// Copyright (C) 2020-2021 CERN for the benefit of the Acts project
4-
//
5-
// This Source Code Form is subject to the terms of the Mozilla Public
6-
// License, v. 2.0. If a copy of the MPL was not distributed with this
7-
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
8-
9-
#include "Acts/Surfaces/DiscSurface.hpp"
10-
#include "Acts/Surfaces/PlaneSurface.hpp"
111
#include "MtpcDetectorElement.hpp"
122

3+
#include "Acts/Geometry/GeometryContext.hpp"
4+
#include "Acts/Surfaces/CylinderBounds.hpp"
5+
#include "Acts/Surfaces/Surface.hpp"
136

14-
tdis::tracking::MtpcDetectorElement::MtpcDetectorElement(
15-
std::shared_ptr<const Acts::Transform3> transform,
16-
std::shared_ptr<const Acts::DiscBounds> dBounds,
17-
double thickness,
18-
int gem_plane_id,
19-
std::shared_ptr<const Acts::ISurfaceMaterial> material)
20-
: Acts::DetectorElementBase(),
21-
m_elementTransform(std::move(transform)),
22-
m_elementSurface(Acts::Surface::makeShared<Acts::DiscSurface>(dBounds, *this)),
23-
m_elementThickness(thickness),
24-
m_gem_plane_id(gem_plane_id),
25-
m_elementDiscBounds(std::move(dBounds)) {
26-
m_elementSurface->assignSurfaceMaterial(std::move(material));
27-
}
7+
#include <Acts/Surfaces/CylinderSurface.hpp>
8+
9+
#include "Acts/Definitions/Algebra.hpp"
10+
11+
namespace tdis::tracking {
12+
// Implementation
13+
14+
inline MtpcDetectorElement::MtpcDetectorElement(
15+
uint32_t planeId,
16+
std::shared_ptr<const Acts::Transform3> transform,
17+
std::shared_ptr<const Acts::CylinderBounds> cBounds,
18+
double thickness,
19+
std::shared_ptr<const Acts::ISurfaceMaterial> material)
20+
: m_elementTransform(std::move(transform)),
21+
m_elementThickness(thickness),
22+
m_elementCylinderBounds(std::move(cBounds)),
23+
m_id(planeId)
24+
{
25+
// Create the cylinder surface
26+
m_elementSurface = Acts::Surface::makeShared<Acts::CylinderSurface>(
27+
this, // Detector element pointer
28+
*m_elementTransform,
29+
*m_elementCylinderBounds);
30+
31+
if (material) {
32+
m_elementSurface->assignSurfaceMaterial(material);
33+
}
34+
}
35+
36+
inline const Acts::Surface& MtpcDetectorElement::surface() const { return *m_elementSurface; }
37+
38+
inline Acts::Surface& MtpcDetectorElement::surface() { return *m_elementSurface; }
39+
40+
inline double MtpcDetectorElement::thickness() const { return m_elementThickness; }
41+
42+
inline const Acts::Transform3& MtpcDetectorElement::transform(const Acts::GeometryContext& gctx) const
43+
{
44+
// Check if a different transform than the nominal exists
45+
if (!m_alignedTransforms.empty()) {
46+
// Cast into the right context object
47+
auto alignContext = gctx.get<ContextType>();
48+
return (*m_alignedTransforms[alignContext.iov].get());
49+
}
50+
// Return the standard transform if not found
51+
return nominalTransform(gctx);
52+
}
53+
54+
inline const Acts::Transform3& MtpcDetectorElement::nominalTransform(const Acts::GeometryContext& /*gctx*/) const
55+
{
56+
return *m_elementTransform;
57+
}
58+
59+
inline void MtpcDetectorElement::addAlignedTransform(std::unique_ptr<Acts::Transform3> alignedTransform, unsigned int iov)
60+
{
61+
// Ensure the vector is large enough
62+
auto size = m_alignedTransforms.size();
63+
if (iov >= size) {
64+
m_alignedTransforms.resize(iov + 1);
65+
}
66+
m_alignedTransforms[iov] = std::move(alignedTransform);
67+
}
68+
69+
inline const std::vector<std::unique_ptr<Acts::Transform3>>&
70+
MtpcDetectorElement::alignedTransforms() const {
71+
return m_alignedTransforms;
72+
}
73+
}

0 commit comments

Comments
 (0)