13 #include "TGeoManager.h"
14 #include "TGeoMatrix.h"
18 std::unique_ptr<const Logger> logger)
19 : m_cfg(), m_logger(std::move(logger)) {
31 std::unique_ptr<const Logger> newLogger) {
32 m_logger = std::move(newLogger);
65 if (gGeoManager ==
nullptr) {
71 std::vector<LayerConfig> layerConfigs = m_cfg.layerConfigurations[type + 1];
72 std::string layerType = m_layerTypes[type + 1];
75 std::string addonOutput = m_cfg.layerSplitToleranceR[type + 1] > 0.
76 ? std::string(
", splitting in r")
78 addonOutput += m_cfg.layerSplitToleranceZ[type + 1] > 0.
79 ? std::string(
", splitting in z")
81 addonOutput += std::string(
".");
84 ACTS_DEBUG(layerType <<
" layers : found " << layerConfigs.size()
85 <<
" configuration(s)" + addonOutput);
86 for (
auto layerCfg : layerConfigs) {
88 using LayerSurfaceVector = std::vector<std::shared_ptr<const Surface>>;
89 LayerSurfaceVector layerSurfaces;
91 ACTS_DEBUG(
"- layer configuration found for layer "
92 << layerCfg.layerName <<
" with sensor " << layerCfg.sensorName);
93 ACTS_DEBUG(
"- layers radially bound to rmin/rmax = "
94 << layerCfg.parseRangeR.first <<
"/"
95 << layerCfg.parseRangeR.second);
97 TGeoVolume* tvolume = gGeoManager->GetTopVolume();
98 if (tvolume !=
nullptr) {
100 resolveSensitive(gctx, layerSurfaces, tvolume,
nullptr, TGeoIdentity(),
104 "- number of senstive sensors found : " << layerSurfaces.size());
107 auto fillLayer = [&](
const LayerSurfaceVector lSurfaces,
112 pl.
envR = {lCfg.envelope.first, lCfg.envelope.second};
113 pl.
envZ = {lCfg.envelope.second, lCfg.envelope.second};
114 layers.push_back(m_cfg.layerCreator->cylinderLayer(
115 gctx, lSurfaces, lCfg.binsLoc0, lCfg.binsLoc1, pl));
118 pl.
envR = {lCfg.envelope.first, lCfg.envelope.second};
119 pl.
envZ = {lCfg.envelope.second, lCfg.envelope.second};
120 layers.push_back(m_cfg.layerCreator->discLayer(
121 gctx, lSurfaces, lCfg.binsLoc0, lCfg.binsLoc1, pl));
126 if (layerCfg.splitParametersR.empty() and
127 layerCfg.splitParametersZ.empty()) {
129 fillLayer(layerSurfaces, layerCfg);
133 std::vector<LayerSurfaceVector> splitLayerSurfaces = {layerSurfaces};
138 const std::vector<LayerSurfaceVector>& preSplitSurfaces,
139 double splitTolerance,
140 std::pair<double, double> splitRange = {0., 0.},
141 std::vector<double> splitParameters = {})
142 -> std::vector<LayerSurfaceVector> {
143 ACTS_DEBUG(
"- split attempt in " << splitValue);
144 ACTS_DEBUG(
"- split layers seperated by more than " << splitTolerance);
146 bool reevaluate = splitParameters.empty();
148 ACTS_DEBUG(
"- split parameters to be re-evaluated");
152 std::vector<LayerSurfaceVector> postSplitSurfaces;
154 for (
const auto& surfaceSet : preSplitSurfaces) {
155 ACTS_DEBUG(
"- split surface set with " << surfaceSet.size()
160 for (
const auto&
surface : surfaceSet) {
162 double surfacePar =
surface->binningPositionValue(gctx, bValue);
163 registerSplit(splitParameters, surfacePar, splitTolerance,
168 ACTS_DEBUG(
"- split range is = " << splitRange.first <<
", "
169 << splitRange.second);
171 << splitParameters.size());
173 std::vector<LayerSurfaceVector> setSplitSurfaces{
174 splitParameters.size(), LayerSurfaceVector{}};
176 for (
const auto&
surface : surfaceSet) {
178 double surfacePar =
surface->binningPositionValue(gctx, bValue);
180 for (
const auto& splitPar : splitParameters) {
181 if (
std::abs(splitPar - surfacePar) < splitTolerance) {
182 setSplitSurfaces[isplit].push_back(
surface);
188 postSplitSurfaces.insert(postSplitSurfaces.end(),
189 setSplitSurfaces.begin(),
190 setSplitSurfaces.end());
193 splitParameters.clear();
196 unsigned int iss = 0;
197 ACTS_VERBOSE(
" - splitting yielded " << postSplitSurfaces.size()
198 <<
" surface sets:");
199 for (
const auto& sset : postSplitSurfaces) {
200 ACTS_VERBOSE(
" - set " << iss++ <<
" has " << sset.size()
205 return postSplitSurfaces;
209 if (m_cfg.layerSplitToleranceR[type + 1] > 0.) {
211 splitLayerSurfaces = splitSurfaces(
212 "r",
binR, splitLayerSurfaces, m_cfg.layerSplitToleranceR[type + 1],
213 layerCfg.splitRangeR, layerCfg.splitParametersR);
215 layerCfg.splitParametersZ.clear();
221 if (m_cfg.layerSplitToleranceZ[type + 1] > 0.) {
223 splitLayerSurfaces = splitSurfaces(
224 "z",
binZ, splitLayerSurfaces, m_cfg.layerSplitToleranceZ[type + 1],
225 layerCfg.splitRangeZ, layerCfg.splitParametersZ);
230 for (
const auto& slSurfaces : splitLayerSurfaces) {
231 ACTS_VERBOSE(
" - layer " << il++ <<
" has " << slSurfaces.size()
233 fillLayer(slSurfaces, layerCfg);
241 std::vector<std::shared_ptr<const Acts::Surface>>& layerSurfaces,
242 TGeoVolume* tgVolume, TGeoNode* tgNode,
const TGeoMatrix& tgTransform,
243 LayerConfig& layerConfig,
int type,
bool correctBranch,
244 const std::string&
offset) {
245 if (tgVolume !=
nullptr) {
246 std::string volumeName = tgVolume->GetName();
249 <<
" - checking for volume name "
253 bool correctVolume = correctBranch;
254 if (!correctVolume &&
255 (volumeName.find(layerConfig.
layerName) != std::string::npos ||
256 match(layerConfig.
layerName.c_str(), volumeName.c_str()))) {
257 correctVolume =
true;
261 auto daugthers = tgVolume->GetNodes();
263 ACTS_VERBOSE(offset <<
"has " << tgVolume->GetNdaughters()
266 TIter iObj(daugthers);
268 while (
TObject* obj = iObj()) {
270 TGeoNode* node =
dynamic_cast<TGeoNode*
>(obj);
271 if (node !=
nullptr) {
272 resolveSensitive(gctx, layerSurfaces,
nullptr, node, tgTransform,
273 layerConfig, type, correctVolume, offset +
" ");
281 if (tgNode !=
nullptr) {
283 const TGeoMatrix* tgMatrix = tgNode->GetMatrix();
286 TGeoHMatrix parseTransform =
287 TGeoCombiTrans(tgTransform) * TGeoCombiTrans(*tgMatrix);
290 const Double_t* translation = parseTransform.GetTranslation();
292 double x = m_cfg.unit * translation[0];
293 double y = m_cfg.unit * translation[1];
294 double z = m_cfg.unit * translation[2];
295 double r = std::sqrt(x * x + y * y);
298 std::string tNodeName = tgNode->GetName();
300 <<
" - checking for sensor name "
306 (tNodeName.find(layerConfig.
sensorName) != std::string::npos ||
307 match(layerConfig.
sensorName.c_str(), tNodeName.c_str()))) {
309 <<
"' found in branch '" << layerConfig.
layerName
315 bool insideParseRange = r >= layerConfig.
parseRangeR.first and
318 if (insideParseRange and ((type == 0) || type * z > 0.)) {
323 m_cfg.identifierProvider !=
nullptr
324 ? m_cfg.identifierProvider->identify(gctx, *tgNode)
326 auto tgElement = std::make_shared<const Acts::TGeoDetectorElement>(
327 identifier, tgNode, &tgTransform, layerConfig.
localAxes,
330 m_elementStore.push_back(tgElement);
332 layerSurfaces.push_back(tgElement->surface().getSharedPtr());
335 double surfaceR = tgElement->surface().binningPositionValue(gctx,
binR);
336 double surfaceZ = tgElement->surface().binningPositionValue(gctx,
binZ);
339 if (m_cfg.layerSplitToleranceR[type + 1] > 0.) {
341 m_cfg.layerSplitToleranceR[type + 1],
345 if (m_cfg.layerSplitToleranceZ[type + 1] > 0.) {
347 m_cfg.layerSplitToleranceZ[type + 1],
350 }
else if (type * z < 0) {
352 }
else if (not insideParseRange) {
353 ACTS_VERBOSE(
"[xx] cancelled by parse range on side " << type);
360 ACTS_VERBOSE(offset <<
"[<<] not accepted, stepping down.");
362 TGeoHMatrix nTransform =
363 TGeoCombiTrans(tgTransform) * TGeoCombiTrans(*tgMatrix);
364 std::string suffix =
"_transform";
365 nTransform.SetName((tNodeName + suffix).c_str());
367 TGeoVolume* nodeVolume = tgNode->GetVolume();
369 resolveSensitive(gctx, layerSurfaces, nodeVolume,
nullptr, nTransform,
370 layerConfig, type, correctBranch, offset +
" ");