EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TGeoLayerBuilder.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TGeoLayerBuilder.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2018 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
15 
16 #include <stdio.h>
17 
18 #include "TGeoManager.h"
19 #include "TGeoMatrix.h"
20 
23  std::unique_ptr<const Logger> logger)
24  : m_cfg(), m_logger(std::move(logger)) {
25  setConfiguration(config);
26 }
27 
29 
32  m_cfg = config;
33 }
34 
36  std::unique_ptr<const Logger> newLogger) {
37  m_logger = std::move(newLogger);
38 }
39 
41  const GeometryContext& gctx) const {
42  // @todo Remove this hack once the m_elementStore mess is sorted out
43  auto mutableThis = const_cast<TGeoLayerBuilder*>(this);
44  LayerVector nVector;
45  mutableThis->buildLayers(gctx, nVector, -1);
46  return nVector;
47 }
48 
50  const GeometryContext& gctx) const {
51  // @todo Remove this hack once the m_elementStore mess is sorted out
52  auto mutableThis = const_cast<TGeoLayerBuilder*>(this);
53  LayerVector cVector;
54  mutableThis->buildLayers(gctx, cVector, 0);
55  return cVector;
56 }
57 
59  const GeometryContext& gctx) const {
60  // @todo Remove this hack once the m_elementStore mess is sorted out
61  auto mutableThis = const_cast<TGeoLayerBuilder*>(this);
62  LayerVector pVector;
63  mutableThis->buildLayers(gctx, pVector, 1);
64  return pVector;
65 }
66 
68  LayerVector& layers, int type) {
69  // Bail out if you have no gGeoManager
70  if (gGeoManager == nullptr) {
71  ACTS_WARNING("No gGeoManager found - bailing out.");
72  return;
73  }
74 
75  using LayerSurfaceVector = std::vector<std::shared_ptr<const Surface>>;
76  LayerSurfaceVector layerSurfaces;
77 
78  std::vector<LayerConfig> layerConfigs = m_cfg.layerConfigurations[type + 1];
79  std::string layerType = m_layerTypes[type + 1];
80 
81  // Appropriate screen output
82  std::string addonOutput = m_cfg.layerSplitToleranceR[type + 1] > 0.
83  ? std::string(", splitting in r")
84  : std::string("");
85  addonOutput += m_cfg.layerSplitToleranceZ[type + 1] > 0.
86  ? std::string(", splitting in z")
87  : std::string("");
88  addonOutput += std::string(".");
89 
90  // Screen output of the configuration
91  ACTS_DEBUG(layerType << " layers : found " << layerConfigs.size()
92  << " configuration(s)" + addonOutput);
93 
94  // Helper function to fill the layer
95  auto fillLayer = [&](const LayerSurfaceVector lSurfaces,
96  const LayerConfig& lCfg) -> void {
97  // Set binning by hand if nb0 > 0 and nb1 > 0
98  auto nb0 = std::get<int>(lCfg.binning0);
99  auto nb1 = std::get<int>(lCfg.binning1);
100  // Or use the binning type
101  auto nt0 = std::get<BinningType>(lCfg.binning0);
102  auto nt1 = std::get<BinningType>(lCfg.binning1);
103 
104  if (type == 0) {
105  ProtoLayer pl(gctx, lSurfaces);
106  ACTS_DEBUG("- creating CylinderLayer with "
107  << lSurfaces.size() << " surfaces at r = " << pl.medium(binR));
108  pl.envelope[Acts::binR] = {lCfg.envelope.first, lCfg.envelope.second};
109  pl.envelope[Acts::binZ] = {lCfg.envelope.second, lCfg.envelope.second};
110  if (nb0 > 0 and nb1 > 0) {
111  layers.push_back(
112  m_cfg.layerCreator->cylinderLayer(gctx, lSurfaces, nb0, nb1, pl));
113  } else {
114  layers.push_back(
115  m_cfg.layerCreator->cylinderLayer(gctx, lSurfaces, nt0, nt1, pl));
116  }
117  } else {
118  ProtoLayer pl(gctx, lSurfaces);
119  ACTS_DEBUG("- creating DiscLayer with "
120  << lSurfaces.size() << " surfaces at z = " << pl.medium(binZ));
121  pl.envelope[Acts::binR] = {lCfg.envelope.first, lCfg.envelope.second};
122  pl.envelope[Acts::binZ] = {lCfg.envelope.second, lCfg.envelope.second};
123  if (nb0 > 0 and nb1 > 0) {
124  layers.push_back(
125  m_cfg.layerCreator->discLayer(gctx, lSurfaces, nb0, nb1, pl));
126  } else {
127  layers.push_back(
128  m_cfg.layerCreator->discLayer(gctx, lSurfaces, nt0, nt1, pl));
129  }
130  }
131  };
132 
133  for (auto layerCfg : layerConfigs) {
134  ACTS_DEBUG("- layer configuration found for layer " << layerCfg.volumeName
135  << " with sensors ");
136  for (auto& sensor : layerCfg.sensorNames) {
137  ACTS_DEBUG(" - sensor: " << sensor);
138  }
139  if (not layerCfg.parseRanges.empty()) {
140  for (const auto& pRange : layerCfg.parseRanges) {
141  ACTS_DEBUG("- layer parsing restricted in "
142  << binningValueNames[pRange.first] << " to ["
143  << pRange.second.first << "/" << pRange.second.second
144  << "].");
145  }
146  }
147  if (not layerCfg.splitConfigs.empty()) {
148  for (const auto& sConfig : layerCfg.splitConfigs) {
149  ACTS_DEBUG("- layer splitting attempt in "
150  << binningValueNames[sConfig.first] << " with tolerance "
151  << sConfig.second << ".");
152  }
153  }
154 
155  // Either pick the configured volume or take the top level volume
156  TGeoVolume* tVolume =
157  gGeoManager->FindVolumeFast(layerCfg.volumeName.c_str());
158  if (tVolume == nullptr) {
159  tVolume = gGeoManager->GetTopVolume();
160  ACTS_DEBUG("- search volume is TGeo top volume");
161  } else {
162  ACTS_DEBUG("- setting search volume to " << tVolume->GetName());
163  }
164 
165  if (tVolume != nullptr) {
166  TGeoParser::Options tgpOptions;
167  tgpOptions.volumeNames = {layerCfg.volumeName};
168  tgpOptions.targetNames = layerCfg.sensorNames;
169  tgpOptions.parseRanges = layerCfg.parseRanges;
170  tgpOptions.unit = m_cfg.unit;
171  TGeoParser::State tgpState;
172  tgpState.volume = tVolume;
173 
174  ACTS_DEBUG("- applying " << layerCfg.parseRanges.size()
175  << " search restrictions.");
176  for (const auto& prange : layerCfg.parseRanges) {
177  ACTS_VERBOSE(" - range " << binningValueNames[prange.first]
178  << " within [ " << prange.second.first << ", "
179  << prange.second.second << "]");
180  }
181 
182  TGeoParser::select(tgpState, tgpOptions);
183 
184  ACTS_DEBUG("- number of selsected nodes found : "
185  << tgpState.selectedNodes.size());
186 
187  for (auto& snode : tgpState.selectedNodes) {
188  auto identifier =
189  m_cfg.identifierProvider != nullptr
190  ? m_cfg.identifierProvider->identify(gctx, *snode.node)
191  : Identifier();
192 
193  auto tgElement = std::make_shared<const Acts::TGeoDetectorElement>(
194  identifier, *snode.node, *snode.transform, layerCfg.localAxes,
195  m_cfg.unit);
196  m_elementStore.push_back(tgElement);
197  layerSurfaces.push_back(tgElement->surface().getSharedPtr());
198  }
199 
200  ACTS_DEBUG("- created TGeoDetectorElements : " << layerSurfaces.size());
201 
202  if (m_cfg.protoLayerHelper != nullptr and
203  not layerCfg.splitConfigs.empty()) {
204  auto protoLayers = m_cfg.protoLayerHelper->protoLayers(
205  gctx, unpack_shared_vector(layerSurfaces), layerCfg.splitConfigs);
206  ACTS_DEBUG("- splitting into " << protoLayers.size() << " layers.");
207  for (auto& pLayer : protoLayers) {
208  layerSurfaces.clear();
209  for (const auto& lsurface : pLayer.surfaces()) {
210  layerSurfaces.push_back(lsurface->getSharedPtr());
211  }
212  fillLayer(layerSurfaces, layerCfg);
213  }
214  } else {
215  fillLayer(layerSurfaces, layerCfg);
216  }
217  }
218  }
219  return;
220 }