File indexing completed on 2026-09-21 08:20:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/GenericDetector/ProtoLayerCreator.hpp"
0010
0011 #include "Acts/Utilities/TransformHelpers.hpp"
0012
0013 using Acts::VectorHelpers::phi;
0014
0015 namespace ActsExamples::Generic {
0016
0017 std::vector<ProtoLayerSurfaces> ProtoLayerCreator::centralProtoLayers(
0018 const Acts::GeometryContext& gctx) const {
0019
0020 std::vector<ProtoLayerSurfaces> cpLayers;
0021
0022
0023
0024 std::size_t numcLayers = m_cfg.centralLayerRadii.size();
0025 if (numcLayers != 0u) {
0026 ACTS_DEBUG("Configured to build " << numcLayers
0027 << " active central layers.");
0028 cpLayers.reserve(numcLayers);
0029
0030 for (std::size_t icl = 0; icl < numcLayers; ++icl) {
0031
0032 double layerR = m_cfg.centralLayerRadii.at(icl);
0033
0034 ACTS_DEBUG("Build layer " << icl << " with target radius = " << layerR);
0035
0036
0037 std::vector<std::shared_ptr<Acts::Surface>> sVector;
0038
0039 double layerEnvelopeCoverZ =
0040 !m_cfg.centralLayerEnvelopes.empty()
0041 ? m_cfg.centralLayerEnvelopes.at(icl).second
0042 : 0.;
0043
0044 double modulePhiTilt = m_cfg.centralModuleTiltPhi.at(icl);
0045 double moduleHalfX = m_cfg.centralModuleHalfX.at(icl);
0046 double moduleHalfY = m_cfg.centralModuleHalfY.at(icl);
0047 double moduleThickness = m_cfg.centralModuleThickness.at(icl);
0048
0049 auto moduleBounds =
0050 std::make_shared<Acts::RectangleBounds>(moduleHalfX, moduleHalfY);
0051 std::size_t nCentralModules =
0052 m_cfg.centralModuleBinningSchema.at(icl).first *
0053 m_cfg.centralModuleBinningSchema.at(icl).second;
0054
0055 ACTS_DEBUG("- number of modules "
0056 << nCentralModules << " ( from "
0057 << m_cfg.centralModuleBinningSchema.at(icl).first << " x "
0058 << m_cfg.centralModuleBinningSchema.at(icl).second << " )");
0059
0060 sVector.reserve(nCentralModules);
0061
0062
0063
0064 std::shared_ptr<const Acts::ISurfaceMaterial> moduleMaterialPtr = nullptr;
0065 if (!m_cfg.centralModuleMaterial.empty()) {
0066
0067 moduleMaterialPtr = m_cfg.centralModuleMaterial.at(icl);
0068 }
0069
0070
0071 if (m_cfg.centralModulePositions.at(icl).size() != nCentralModules) {
0072 ACTS_WARNING("Mismatching module numbers, configuration error!");
0073 ACTS_WARNING("- Binning schema suggests : " << nCentralModules);
0074 ACTS_WARNING("- Positions provided are : "
0075 << m_cfg.centralModulePositions.at(icl).size());
0076 }
0077
0078 for (auto& moduleCenter : m_cfg.centralModulePositions.at(icl)) {
0079
0080 double modulePhi = phi(moduleCenter);
0081
0082 Acts::Vector3 moduleLocalZ(std::cos(modulePhi + modulePhiTilt),
0083 std::sin(modulePhi + modulePhiTilt), 0.);
0084
0085 Acts::Vector3 moduleLocalY(0., 0., 1);
0086
0087 Acts::Vector3 moduleLocalX(-std::sin(modulePhi + modulePhiTilt),
0088 std::cos(modulePhi + modulePhiTilt), 0.);
0089
0090 Acts::RotationMatrix3 moduleRotation;
0091 moduleRotation.col(0) = moduleLocalX;
0092 moduleRotation.col(1) = moduleLocalY;
0093 moduleRotation.col(2) = moduleLocalZ;
0094
0095 Acts::Transform3 moduleTransform =
0096 Acts::makeTransform3(moduleRotation, moduleCenter);
0097
0098 if (!m_cfg.centralModuleFrontsideStereo.empty() &&
0099 m_cfg.centralModuleFrontsideStereo.at(icl) != 0.) {
0100
0101 double stereo = m_cfg.centralModuleFrontsideStereo.at(icl);
0102 moduleTransform *= Acts::AngleAxis3(-stereo, Acts::Vector3::UnitZ());
0103 }
0104
0105 auto moduleElement = m_cfg.detectorElementFactory(
0106 moduleTransform, moduleBounds, moduleThickness, moduleMaterialPtr);
0107
0108 sVector.push_back(moduleElement->surface().getSharedPtr());
0109
0110
0111 if (!m_cfg.centralModuleBacksideGap.empty()) {
0112
0113
0114 Acts::Vector3 bsModuleCenter =
0115 moduleCenter +
0116 m_cfg.centralModuleBacksideGap.at(icl) * moduleLocalZ;
0117 Acts::Transform3 bsModuleTransform =
0118 Acts::makeTransform3(moduleRotation, bsModuleCenter);
0119
0120 if (!m_cfg.centralModuleBacksideStereo.empty()) {
0121
0122 double stereoBackSide = m_cfg.centralModuleBacksideStereo.at(icl);
0123 bsModuleTransform *=
0124 Acts::AngleAxis3(-stereoBackSide, Acts::Vector3::UnitZ());
0125 }
0126
0127 auto bsModuleElement =
0128 m_cfg.detectorElementFactory(bsModuleTransform, moduleBounds,
0129 moduleThickness, moduleMaterialPtr);
0130
0131 sVector.push_back(bsModuleElement->surface().getSharedPtr());
0132 }
0133 }
0134
0135 std::size_t phiBins = m_cfg.centralModuleBinningSchema.at(icl).first;
0136 phiBins *= m_cfg.centralLayerBinMultipliers.first;
0137 std::size_t zBins = m_cfg.centralModuleBinningSchema.at(icl).second;
0138 zBins *= m_cfg.centralLayerBinMultipliers.second;
0139
0140
0141 Acts::MutableProtoLayer pl(gctx, sVector);
0142 pl.envelope[Acts::AxisDirection::AxisR] = {m_cfg.approachSurfaceEnvelope,
0143 m_cfg.approachSurfaceEnvelope};
0144 pl.envelope[Acts::AxisDirection::AxisZ] = {layerEnvelopeCoverZ,
0145 layerEnvelopeCoverZ};
0146
0147
0148 ProtoLayerSurfaces pls{std::move(pl), sVector, phiBins, zBins};
0149 cpLayers.push_back(std::move(pls));
0150 }
0151 }
0152 return cpLayers;
0153 }
0154
0155 std::vector<ProtoLayerSurfaces> ProtoLayerCreator::negativeProtoLayers(
0156 const Acts::GeometryContext& gctx) const {
0157 return createProtoLayers(gctx, -1);
0158 }
0159
0160 std::vector<ProtoLayerSurfaces> ProtoLayerCreator::positiveProtoLayers(
0161 const Acts::GeometryContext& gctx) const {
0162 return createProtoLayers(gctx, 1);
0163 }
0164
0165 ProtoLayerCreator::ProtoLayerCreator(const ProtoLayerCreator::Config& cfg,
0166 std::unique_ptr<const Acts::Logger> log)
0167 : m_cfg(cfg), m_logger(std::move(log)) {
0168 if (!m_cfg.detectorElementFactory) {
0169 throw std::invalid_argument("Detector element factory is not set");
0170 }
0171 }
0172
0173 std::vector<ProtoLayerSurfaces> ProtoLayerCreator::createProtoLayers(
0174 const Acts::GeometryContext& gctx, int side) const {
0175
0176
0177 std::vector<ProtoLayerSurfaces> epLayers;
0178
0179
0180 std::size_t numpnLayers = m_cfg.posnegLayerPositionsZ.size();
0181 if (numpnLayers != 0u) {
0182 ACTS_DEBUG("Configured to build 2 * "
0183 << numpnLayers << " passive positive/negative side layers.");
0184 epLayers.reserve(numpnLayers);
0185
0186
0187 for (std::size_t ipnl = 0; ipnl < numpnLayers; ++ipnl) {
0188
0189 ACTS_VERBOSE("- building layer "
0190 << ipnl << " and " << numpnLayers + ipnl << " at z = "
0191 << side * m_cfg.posnegLayerPositionsZ.at(ipnl));
0192
0193
0194 double layerEnvelopeR = m_cfg.posnegLayerEnvelopeR.at(ipnl);
0195
0196 std::vector<std::shared_ptr<Acts::Surface>> esVector;
0197
0198 std::size_t ipnR = 0;
0199 for (auto& discModulePositions : m_cfg.posnegModulePositions.at(ipnl)) {
0200 ACTS_VERBOSE("- building ring " << ipnR << " for this layer.");
0201
0202
0203 double moduleThickness = m_cfg.posnegModuleThickness.at(ipnl).at(ipnR);
0204 double moduleMinHalfX = m_cfg.posnegModuleMinHalfX.at(ipnl).at(ipnR);
0205 double moduleMaxHalfX = 0.;
0206 if (m_cfg.posnegModuleMaxHalfX.size() > ipnl &&
0207 m_cfg.posnegModuleMaxHalfX.at(ipnl).size() > ipnR) {
0208 moduleMaxHalfX = m_cfg.posnegModuleMaxHalfX.at(ipnl).at(ipnR);
0209 }
0210 double moduleHalfY = m_cfg.posnegModuleHalfY.at(ipnl).at(ipnR);
0211
0212
0213 std::shared_ptr<const Acts::PlanarBounds> moduleBounds;
0214 if (moduleMaxHalfX != 0. && moduleMinHalfX != moduleMaxHalfX) {
0215 moduleBounds = std::make_shared<Acts::TrapezoidBounds>(
0216 moduleMinHalfX, moduleMaxHalfX, moduleHalfY);
0217 } else {
0218 moduleBounds = std::make_shared<Acts::RectangleBounds>(moduleMinHalfX,
0219 moduleHalfY);
0220 }
0221
0222
0223 std::shared_ptr<const Acts::ISurfaceMaterial> moduleMaterialPtr =
0224 nullptr;
0225 if (!m_cfg.posnegModuleMaterial.empty()) {
0226
0227 moduleMaterialPtr = m_cfg.posnegModuleMaterial.at(ipnl).at(ipnR);
0228 }
0229
0230
0231 for (auto& ringModulePosition : discModulePositions) {
0232
0233 double modulePhi = phi(ringModulePosition);
0234
0235 Acts::Vector3 moduleCenter(ringModulePosition);
0236 moduleCenter.z() *= side;
0237
0238 Acts::Vector3 moduleLocalY(std::cos(modulePhi), std::sin(modulePhi),
0239 0.);
0240
0241 Acts::Vector3 moduleLocalZ(0., 0., side * 1.);
0242 Acts::Vector3 moduleLocalX = moduleLocalY.cross(moduleLocalZ);
0243
0244
0245 Acts::RotationMatrix3 moduleRotation;
0246 moduleRotation.col(0) = moduleLocalX;
0247 moduleRotation.col(1) = moduleLocalY;
0248 moduleRotation.col(2) = moduleLocalZ;
0249
0250 const Acts::Transform3 moduleTransform =
0251 Acts::makeTransform3(moduleRotation, moduleCenter);
0252
0253
0254 auto moduleElement =
0255 m_cfg.detectorElementFactory(moduleTransform, moduleBounds,
0256 moduleThickness, moduleMaterialPtr);
0257
0258 esVector.push_back(moduleElement->surface().getSharedPtr());
0259
0260 if (!m_cfg.posnegModuleBacksideGap.empty()) {
0261
0262 moduleCenter =
0263 moduleCenter +
0264 m_cfg.posnegModuleBacksideGap.at(ipnl).at(ipnR) * moduleLocalZ;
0265
0266 Acts::Transform3 bsModuleTransform =
0267 Acts::makeTransform3(moduleRotation, moduleCenter);
0268
0269 if (!m_cfg.posnegModuleBacksideStereo.empty()) {
0270
0271 double stereoBackSide =
0272 m_cfg.posnegModuleBacksideStereo.at(ipnl).at(ipnR);
0273 bsModuleTransform *=
0274 Acts::AngleAxis3(-stereoBackSide, Acts::Vector3::UnitZ());
0275 }
0276
0277 auto bsModuleElement = m_cfg.detectorElementFactory(
0278 bsModuleTransform, moduleBounds, moduleThickness,
0279 moduleMaterialPtr);
0280
0281 esVector.push_back(bsModuleElement->surface().getSharedPtr());
0282 }
0283 }
0284
0285 ++ipnR;
0286 }
0287
0288 std::size_t layerBinsR = m_cfg.posnegModulePhiBins.at(ipnl).size();
0289
0290 if (layerBinsR > 1) {
0291
0292 layerBinsR *= m_cfg.posnegLayerBinMultipliers.first;
0293 }
0294 std::size_t layerBinsPhi = 0;
0295
0296 for (unsigned int phiBins : m_cfg.posnegModulePhiBins.at(ipnl)) {
0297 layerBinsPhi = phiBins < layerBinsPhi ? phiBins : layerBinsPhi;
0298 layerBinsPhi *= m_cfg.posnegLayerBinMultipliers.second;
0299 }
0300
0301 Acts::MutableProtoLayer ple(gctx, esVector);
0302 ple.envelope[Acts::AxisDirection::AxisR] = {layerEnvelopeR,
0303 layerEnvelopeR};
0304 ple.envelope[Acts::AxisDirection::AxisZ] = {
0305 m_cfg.approachSurfaceEnvelope, m_cfg.approachSurfaceEnvelope};
0306
0307
0308 ProtoLayerSurfaces ples{std::move(ple), esVector, layerBinsR,
0309 layerBinsPhi};
0310 epLayers.push_back(std::move(ples));
0311 }
0312 }
0313 return epLayers;
0314 }
0315
0316 }