File indexing completed on 2025-04-11 07:57:20
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<const 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 std::shared_ptr<Acts::Transform3> mutableModuleTransform =
0094 std::make_shared<Acts::Transform3>(
0095 Acts::Translation3(moduleCenter) * moduleRotation);
0096
0097 if (!m_cfg.centralModuleFrontsideStereo.empty() &&
0098 m_cfg.centralModuleFrontsideStereo.at(icl) != 0.) {
0099
0100 double stereo = m_cfg.centralModuleFrontsideStereo.at(icl);
0101 (*mutableModuleTransform) *=
0102 Acts::AngleAxis3(-stereo, Acts::Vector3::UnitZ());
0103 }
0104
0105
0106 auto moduleTransform = std::const_pointer_cast<const Acts::Transform3>(
0107 mutableModuleTransform);
0108
0109 auto moduleElement = m_cfg.detectorElementFactory(
0110 moduleTransform, moduleBounds, moduleThickness, moduleMaterialPtr);
0111
0112
0113 sVector.push_back(moduleElement->surface().getSharedPtr());
0114
0115
0116 if (!m_cfg.centralModuleBacksideGap.empty()) {
0117
0118
0119 Acts::Vector3 bsModuleCenter =
0120 moduleCenter +
0121 m_cfg.centralModuleBacksideGap.at(icl) * moduleLocalZ;
0122 mutableModuleTransform = std::make_shared<Acts::Transform3>(
0123 Acts::Translation3(bsModuleCenter) * moduleRotation);
0124
0125 if (!m_cfg.centralModuleBacksideStereo.empty()) {
0126
0127 double stereoBackSide = m_cfg.centralModuleBacksideStereo.at(icl);
0128 (*mutableModuleTransform) *=
0129 Acts::AngleAxis3(-stereoBackSide, Acts::Vector3::UnitZ());
0130 }
0131
0132 moduleTransform = std::const_pointer_cast<const Acts::Transform3>(
0133 mutableModuleTransform);
0134
0135 auto bsModuleElement =
0136 m_cfg.detectorElementFactory(moduleTransform, moduleBounds,
0137 moduleThickness, moduleMaterialPtr);
0138 }
0139 }
0140
0141 std::size_t phiBins = m_cfg.centralModuleBinningSchema.at(icl).first;
0142 phiBins *= m_cfg.centralLayerBinMultipliers.first;
0143 std::size_t zBins = m_cfg.centralModuleBinningSchema.at(icl).second;
0144 zBins *= m_cfg.centralLayerBinMultipliers.second;
0145
0146
0147 Acts::ProtoLayer pl(gctx, sVector);
0148 pl.envelope[Acts::AxisDirection::AxisR] = {m_cfg.approachSurfaceEnvelope,
0149 m_cfg.approachSurfaceEnvelope};
0150 pl.envelope[Acts::AxisDirection::AxisZ] = {layerEnvelopeCoverZ,
0151 layerEnvelopeCoverZ};
0152
0153
0154 ProtoLayerSurfaces pls{std::move(pl), sVector, phiBins, zBins};
0155 cpLayers.push_back(std::move(pls));
0156 }
0157 }
0158 return cpLayers;
0159 }
0160
0161 std::vector<ProtoLayerSurfaces> ProtoLayerCreator::negativeProtoLayers(
0162 const Acts::GeometryContext& gctx) const {
0163 return createProtoLayers(gctx, -1);
0164 }
0165
0166 std::vector<ProtoLayerSurfaces> ProtoLayerCreator::positiveProtoLayers(
0167 const Acts::GeometryContext& gctx) const {
0168 return createProtoLayers(gctx, 1);
0169 }
0170
0171 ProtoLayerCreator::ProtoLayerCreator(const ProtoLayerCreator::Config& cfg,
0172 std::unique_ptr<const Acts::Logger> log)
0173 : m_cfg(cfg), m_logger(std::move(log)) {
0174 if (!m_cfg.detectorElementFactory) {
0175 throw std::invalid_argument("Detector element factory is not set");
0176 }
0177 }
0178
0179 std::vector<ProtoLayerSurfaces> ProtoLayerCreator::createProtoLayers(
0180 const Acts::GeometryContext& gctx, int side) const {
0181
0182
0183 std::vector<ProtoLayerSurfaces> epLayers;
0184
0185
0186 std::size_t numpnLayers = m_cfg.posnegLayerPositionsZ.size();
0187 if (numpnLayers != 0u) {
0188 ACTS_DEBUG("Configured to build 2 * "
0189 << numpnLayers << " passive positive/negative side layers.");
0190 epLayers.reserve(numpnLayers);
0191
0192
0193 for (std::size_t ipnl = 0; ipnl < numpnLayers; ++ipnl) {
0194
0195 ACTS_VERBOSE("- building layer "
0196 << ipnl << " and " << numpnLayers + ipnl << " at z = "
0197 << side * m_cfg.posnegLayerPositionsZ.at(ipnl));
0198
0199
0200 double layerEnvelopeR = m_cfg.posnegLayerEnvelopeR.at(ipnl);
0201
0202 std::vector<std::shared_ptr<const Acts::Surface>> esVector;
0203
0204 std::size_t ipnR = 0;
0205 for (auto& discModulePositions : m_cfg.posnegModulePositions.at(ipnl)) {
0206 ACTS_VERBOSE("- building ring " << ipnR << " for this layer.");
0207
0208
0209 double moduleThickness = m_cfg.posnegModuleThickness.at(ipnl).at(ipnR);
0210 double moduleMinHalfX = m_cfg.posnegModuleMinHalfX.at(ipnl).at(ipnR);
0211 double moduleMaxHalfX = 0.;
0212 if (m_cfg.posnegModuleMaxHalfX.size() > ipnl &&
0213 m_cfg.posnegModuleMaxHalfX.at(ipnl).size() > ipnR) {
0214 moduleMaxHalfX = m_cfg.posnegModuleMaxHalfX.at(ipnl).at(ipnR);
0215 }
0216 double moduleHalfY = m_cfg.posnegModuleHalfY.at(ipnl).at(ipnR);
0217
0218
0219 std::shared_ptr<const Acts::PlanarBounds> moduleBounds;
0220 if (moduleMaxHalfX != 0. && moduleMinHalfX != moduleMaxHalfX) {
0221 moduleBounds = std::make_shared<Acts::TrapezoidBounds>(
0222 moduleMinHalfX, moduleMaxHalfX, moduleHalfY);
0223 } else {
0224 moduleBounds = std::make_shared<Acts::RectangleBounds>(moduleMinHalfX,
0225 moduleHalfY);
0226 }
0227
0228
0229 std::shared_ptr<const Acts::ISurfaceMaterial> moduleMaterialPtr =
0230 nullptr;
0231 if (!m_cfg.posnegModuleMaterial.empty()) {
0232
0233 moduleMaterialPtr = m_cfg.posnegModuleMaterial.at(ipnl).at(ipnR);
0234 }
0235
0236
0237 for (auto& ringModulePosition : discModulePositions) {
0238
0239 double modulePhi = phi(ringModulePosition);
0240
0241 Acts::Vector3 moduleCenter(ringModulePosition);
0242 moduleCenter.z() *= side;
0243
0244 Acts::Vector3 moduleLocalY(cos(modulePhi), sin(modulePhi), 0.);
0245
0246 Acts::Vector3 moduleLocalZ(0., 0., side * 1.);
0247 Acts::Vector3 moduleLocalX = moduleLocalY.cross(moduleLocalZ);
0248
0249
0250 Acts::RotationMatrix3 moduleRotation;
0251 moduleRotation.col(0) = moduleLocalX;
0252 moduleRotation.col(1) = moduleLocalY;
0253 moduleRotation.col(2) = moduleLocalZ;
0254
0255 std::shared_ptr<const Acts::Transform3> moduleTransform =
0256 std::make_shared<const Acts::Transform3>(
0257 Acts::Translation3(moduleCenter) * moduleRotation);
0258
0259
0260 auto moduleElement =
0261 m_cfg.detectorElementFactory(moduleTransform, moduleBounds,
0262 moduleThickness, moduleMaterialPtr);
0263
0264
0265 if (!m_cfg.posnegModuleBacksideGap.empty()) {
0266
0267 moduleCenter =
0268 moduleCenter +
0269 m_cfg.posnegModuleBacksideGap.at(ipnl).at(ipnR) * moduleLocalZ;
0270
0271 auto mutableModuleTransform = std::make_shared<Acts::Transform3>(
0272 Acts::Translation3(moduleCenter) * moduleRotation);
0273
0274 if (!m_cfg.posnegModuleBacksideStereo.empty()) {
0275
0276 double stereoBackSide =
0277 m_cfg.posnegModuleBacksideStereo.at(ipnl).at(ipnR);
0278 (*mutableModuleTransform) *=
0279 Acts::AngleAxis3(-stereoBackSide, Acts::Vector3::UnitZ());
0280 }
0281
0282 moduleTransform = std::const_pointer_cast<const Acts::Transform3>(
0283 mutableModuleTransform);
0284
0285 auto bsModuleElement = m_cfg.detectorElementFactory(
0286 moduleTransform, moduleBounds, moduleThickness,
0287 moduleMaterialPtr);
0288 }
0289
0290 esVector.push_back(moduleElement->surface().getSharedPtr());
0291 }
0292
0293 ++ipnR;
0294 }
0295
0296 std::size_t layerBinsR = m_cfg.posnegModulePhiBins.at(ipnl).size();
0297
0298 if (layerBinsR > 1) {
0299
0300 layerBinsR *= m_cfg.posnegLayerBinMultipliers.first;
0301 }
0302 std::size_t layerBinsPhi = 0;
0303
0304 for (unsigned int phiBins : m_cfg.posnegModulePhiBins.at(ipnl)) {
0305 layerBinsPhi = phiBins < layerBinsPhi ? phiBins : layerBinsPhi;
0306 layerBinsPhi *= m_cfg.posnegLayerBinMultipliers.second;
0307 }
0308
0309 Acts::ProtoLayer ple(gctx, esVector);
0310 ple.envelope[Acts::AxisDirection::AxisR] = {layerEnvelopeR,
0311 layerEnvelopeR};
0312 ple.envelope[Acts::AxisDirection::AxisZ] = {
0313 m_cfg.approachSurfaceEnvelope, m_cfg.approachSurfaceEnvelope};
0314
0315
0316 ProtoLayerSurfaces ples{std::move(ple), esVector, layerBinsR,
0317 layerBinsPhi};
0318 epLayers.push_back(std::move(ples));
0319 }
0320 }
0321 return epLayers;
0322 }
0323
0324 }