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