Skip to content

Commit

Permalink
Geometry implementation variants introduced
Browse files Browse the repository at this point in the history
  • Loading branch information
DraTeots committed Jan 9, 2025
1 parent 13af406 commit 2cb877e
Show file tree
Hide file tree
Showing 6 changed files with 346 additions and 100 deletions.
6 changes: 5 additions & 1 deletion source/tdis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ add_executable(tdis
tracking/ActsGeometryService.cc
tracking/ActsGeometryService.h
tracking/ReconstructedHitFactory.h
tracking/BuildMtpcDetector.cpp
tracking/BuildMtpcDetector.cpp.v1.bck
tracking/BuildMtpcDetector.hpp
tracking/MtpcDetectorElement.cpp
tracking/MtpcDetectorElement.hpp
Expand All @@ -57,6 +57,10 @@ add_executable(tdis
tracking/KalmanFitterFunction.cpp
tracking/RefittingCalibrator.hpp
tracking/RefittingCalibrator.cpp
tracking/BuildMtpcDetector.hpp
tracking/BuildMtpcDetectorCG.cpp
tracking/BuildMtpcDetectorGEM.cpp
tracking/BuildMtpcDetectorGEM.hpp

)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,104 +37,7 @@

#include <memory>
#include <vector>
/*
static std::unique_ptr<const Acts::TrackingGeometry>
tdis::tracking::buildOriginalDetector(
const typename tdis::tracking::MtpcDetectorElement::ContextType &gctx,
std::vector<std::shared_ptr<tdis::tracking::MtpcDetectorElement> > &detectorStore,
const std::vector<double> &positions,
const std::vector<double> &stereoAngles,
const std::array<double, 2> &offsets,
const std::array<double, 2> &bounds,
double thickness,
Acts::BinningValue binValue)
{
using namespace Acts::UnitLiterals;
// The radial bounds for disc surface
const auto rBounds = std::make_shared<const Acts::RadialBounds>(bounds[0], bounds[1]);
// Material of the surfaces
Acts::Material silicon = Acts::Material::fromMassDensity(9.370_cm, 46.52_cm, 28.0855, 14, 2.329_g / 1_cm3);
Acts::MaterialSlab matProp(silicon, thickness);
const auto surfaceMaterial = std::make_shared<Acts::HomogeneousSurfaceMaterial>(matProp);
// Construct the rotation
// This assumes the binValue is binX, binY or binZ. No reset is necessary in
// case of binZ
Acts::RotationMatrix3 rotation = Acts::RotationMatrix3::Identity();
if (binValue == Acts::BinningValue::binX) {
rotation.col(0) = Acts::Vector3(0, 0, -1);
rotation.col(1) = Acts::Vector3(0, 1, 0);
rotation.col(2) = Acts::Vector3(1, 0, 0);
} else if (binValue == Acts::BinningValue::binY) {
rotation.col(0) = Acts::Vector3(1, 0, 0);
rotation.col(1) = Acts::Vector3(0, 0, -1);
rotation.col(2) = Acts::Vector3(0, 1, 0);
}
// Construct the surfaces and layers
std::size_t nLayers = positions.size();
std::vector<Acts::LayerPtr> layers(nLayers);
for (unsigned int i = 0; i < nLayers; ++i) {
// The translation without rotation yet
Acts::Translation3 trans(offsets[0], offsets[1], positions[i]);
// The entire transformation (the coordinate system, whose center is defined
// by trans, will be rotated as well)
Acts::Transform3 trafo(rotation * trans);
// rotate around local z axis by stereo angle
auto stereo = stereoAngles[i];
trafo *= Acts::AngleAxis3(stereo, Acts::Vector3::UnitZ());
// Create the detector element
std::shared_ptr<MtpcDetectorElement> detElement = nullptr;

detElement = std::make_shared<MtpcDetectorElement>(std::make_shared<const Acts::Transform3>(trafo), rBounds, 1._um, i, surfaceMaterial);
// Get the surface
auto surface = detElement->surface().getSharedPtr();
// Add the detector element to the detector store
detectorStore.push_back(std::move(detElement));
// Construct the surface array (one surface contained)
std::unique_ptr<Acts::SurfaceArray> surArray(new Acts::SurfaceArray(surface));
// Construct the layer
layers[i] = Acts::DiscLayer::create(trafo, rBounds, std::move(surArray), thickness);
// Associate the layer to the surface
auto mutableSurface = const_cast<Acts::Surface *>(surface.get());
mutableSurface->associateLayer(*layers[i]);
}
// The volume transform
Acts::Translation3 transVol(offsets[0], offsets[1], (positions.front() + positions.back()) * 0.5);
Acts::Transform3 trafoVol(rotation * transVol);
// The volume bounds is set to be a bit larger than either cubic with planes
// or cylinder with discs
auto length = positions.back() - positions.front();
std::shared_ptr<Acts::VolumeBounds> boundsVol = nullptr;
boundsVol = std::make_shared<Acts::CylinderVolumeBounds>(std::max(bounds[0] - 5.0_mm, 0.), bounds[1] + 5._mm, length + 10._mm);
Acts::LayerArrayCreator::Config lacConfig;
Acts::LayerArrayCreator layArrCreator(lacConfig, Acts::getDefaultLogger("LayerArrayCreator", Acts::Logging::INFO));
Acts::LayerVector layVec;
for (unsigned int i = 0; i < nLayers; i++) {
layVec.push_back(layers[i]);
}
// Create the layer array
Acts::GeometryContext genGctx{gctx};
std::unique_ptr<const Acts::LayerArray> layArr(layArrCreator.layerArray(genGctx, layVec, positions.front() - 2._mm, positions.back() + 2._mm, Acts::BinningType::arbitrary, binValue));
// Build the tracking volume
auto trackVolume = std::make_shared<Acts::TrackingVolume>(trafoVol, boundsVol, nullptr, std::move(layArr), nullptr, Acts::MutableTrackingVolumeVector{}, "Telescope");
// Build and return tracking geometry
return std::make_unique<Acts::TrackingGeometry>(trackVolume);
}
*/

/** This geometry uses cylindrical surfaces with:
* - R (radius) of each cylinder - corresponding to each of mTPC ring center
Expand Down Expand Up @@ -215,7 +118,7 @@ tdis::tracking::buildCylindricalDetector(
std::move(surfaceArray), // Surface array
radialStep, // Layer thickness
nullptr, // No approach descriptor
LayerType::sensitive); // Layer type
LayerType::active); // Layer type

// Add the layer to the vector
cylinderLayers.push_back(std::move(cylinderLayer));
Expand Down
152 changes: 152 additions & 0 deletions source/tdis/tracking/BuildMtpcDetectorCG.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// This file is part of the Acts project.
//
// Copyright (C) 2020-2021 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "BuildMtpcDetector.hpp"

#include <Acts/Definitions/Algebra.hpp>
#include <Acts/Definitions/Units.hpp>
#include <Acts/Geometry/CylinderLayer.hpp>
#include <Acts/Geometry/CylinderVolumeBounds.hpp>
#include <Acts/Geometry/GeometryContext.hpp>
#include <Acts/Geometry/ILayerArrayCreator.hpp>
#include <Acts/Geometry/LayerArrayCreator.hpp>
#include <Acts/Geometry/TrackingGeometry.hpp>
#include <Acts/Geometry/TrackingVolume.hpp>
#include <Acts/Material/HomogeneousVolumeMaterial.hpp>
#include <Acts/Material/Material.hpp>
#include <Acts/Material/MaterialSlab.hpp>
#include <Acts/Surfaces/SurfaceArray.hpp>
#include <Acts/Utilities/BinningType.hpp>
#include <Acts/Utilities/Logger.hpp>

#include <memory>
#include <vector>
#include <unordered_map>

#include "MtpcDetectorElement.hpp"

namespace tdis {
namespace tracking {

/** This geometry uses cylindrical surfaces with:
* - R (radius) of each cylinder - corresponding to each mTPC ring center
* - The length of each cylinder in Z direction equal to the entire detector length (55 cm)
* Then each cylinder corresponds to an MtpcDetectorElement in the detector store.
*/
std::unique_ptr<const Acts::TrackingGeometry>
buildCylindricalDetector(
const MtpcDetectorElement::ContextType& gctx,
std::unordered_map<uint32_t, std::shared_ptr<MtpcDetectorElement>>& surfaceStore)
{
using namespace Acts;
using namespace Acts::UnitLiterals;

// Define Argon gas material properties at STP
double radiationLength = 19.55_m; // ~ 19.55 m in mm
double interactionLength = 70.0_m; // ~ 70.0 m in mm
double atomicMass = 39.948; // Argon
double atomicNumber = 18; // Argon
double massDensity = 1.66e-6_g / 1_mm3; // g/mm^3

// Create Argon gas material
Material argonGas = Material::fromMassDensity(
radiationLength, interactionLength, atomicMass, atomicNumber, massDensity);

// Geometry parameters
double innerRadius = 50_mm; // 5 cm
double outerRadius = 150_mm; // 15 cm
double cylinderLength = 550_mm; // 55 cm
double halfLength = cylinderLength / 2.0;
int numRings = 21; // 21 concentric rings
double radialStep = (outerRadius - innerRadius) / numRings;

// We store the final layers as generic Layer pointers
std::vector<std::shared_ptr<const Layer>> cylinderLayers;
cylinderLayers.reserve(numRings);

for (int i = 0; i < numRings; ++i) {
// Calculate the radius of the current ring
double radius = innerRadius + (i + 0.5) * radialStep;

// Cylinder bounds
auto cylinderBounds =
std::make_shared<const CylinderBounds>(radius, halfLength);

// Unique ID for the ring
uint32_t id = static_cast<uint32_t>(i);

// Identity transform for the element
auto elementTransform = std::make_shared<const Transform3>(Transform3::Identity());

// Create the MtpcDetectorElement
auto detElem = std::make_shared<MtpcDetectorElement>(
id,
elementTransform,
cylinderBounds,
radialStep // thickness
);

// Store it for later reference
surfaceStore[id] = detElem;

// Extract the cylinder surface
auto cylinderSurface = detElem->surface().getSharedPtr();

// Create a single-surface SurfaceArray
// SurfaceArray offers a constructor that takes one Surface
auto surfaceArray = std::make_unique<SurfaceArray>(cylinderSurface);

// Create a CylinderLayer
auto cylinderLayer = CylinderLayer::create(
Transform3::Identity(), // transform
cylinderBounds, // cylinder bounds
std::move(surfaceArray), // single-surface array
radialStep, // layer thickness
nullptr, // no approach descriptor
LayerType::active // the layer is active
);

cylinderLayers.push_back(std::move(cylinderLayer));
}

// Create a layer array from the cylinder layers
LayerArrayCreator::Config layerArrayCreatorConfig;
LayerArrayCreator layerArrayCreator(layerArrayCreatorConfig);

auto layerArray = layerArrayCreator.layerArray(
GeometryContext(), // geometry context
cylinderLayers, // vector of shared_ptr<const Layer>
innerRadius, // min radius
outerRadius, // max radius
BinningType::arbitrary,
BinningValue::binR);

// Volume bounds (outermost dimensions)
auto volumeBounds = std::make_shared<CylinderVolumeBounds>(
innerRadius, outerRadius, halfLength);

// Assign volume material
auto volumeMaterial = std::make_shared<HomogeneousVolumeMaterial>(argonGas);

// Create the tracking volume
auto trackingVolume = std::make_shared<TrackingVolume>(
Transform3::Identity(), // center at origin
volumeBounds, // shape/bounds
volumeMaterial, // Argon fill
std::move(layerArray), // cylinder layers
nullptr, // no contained volumes
MutableTrackingVolumeVector{},
"TPCVolume");

// Finally, create the TrackingGeometry with this single volume as world
auto trackingGeometry = std::make_unique<TrackingGeometry>(trackingVolume);
return trackingGeometry;
}

} // namespace tracking
} // namespace tdis
Loading

0 comments on commit 2cb877e

Please sign in to comment.