|
22 | 22 | #include "Acts/Geometry/PlaneLayer.hpp"
|
23 | 23 | #include "Acts/Geometry/TrackingGeometry.hpp"
|
24 | 24 | #include "Acts/Geometry/TrackingVolume.hpp"
|
| 25 | +#include <Acts/Geometry/CylinderLayer.hpp> |
25 | 26 | #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
|
| 27 | +#include "Acts/Material/HomogeneousVolumeMaterial.hpp" |
26 | 28 | #include "Acts/Material/Material.hpp"
|
27 | 29 | #include "Acts/Material/MaterialSlab.hpp"
|
28 | 30 | #include "Acts/Surfaces/RadialBounds.hpp"
|
|
32 | 34 | #include "Acts/Utilities/Logger.hpp"
|
33 | 35 | #include "BuildMtpcDetector.hpp"
|
34 | 36 |
|
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( |
37 | 43 | const typename tdis::tracking::MtpcDetectorElement::ContextType &gctx,
|
38 | 44 | std::vector<std::shared_ptr<tdis::tracking::MtpcDetectorElement> > &detectorStore,
|
39 | 45 | const std::vector<double> &positions,
|
@@ -128,3 +134,127 @@ tdis::tracking::buildDetector(
|
128 | 134 | // Build and return tracking geometry
|
129 | 135 | return std::make_unique<Acts::TrackingGeometry>(trackVolume);
|
130 | 136 | }
|
| 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 | + |
0 commit comments