EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TGeoDetectorOptions.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TGeoDetectorOptions.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 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 
9 #pragma once
10 
12 #include "Acts/Utilities/Units.hpp"
14 
15 #include <cstdlib>
16 #include <iostream>
17 #include <sstream>
18 #include <utility>
19 
20 #include <boost/program_options.hpp>
21 
22 namespace po = boost::program_options;
23 
24 namespace ActsExamples {
25 
26 namespace Options {
27 
33 template <typename options_t>
34 void addTGeoGeometryOptions(options_t& opt) {
35  opt.add_options()("geo-tgeo-filename",
36  po::value<std::string>()->default_value(""),
37  "Root file name.")(
38  "geo-tgeo-worldvolume", po::value<std::string>()->default_value(""),
39  "Root world volume to start search from.")(
40  "geo-tgeo-unit-scalor", po::value<double>()->default_value(10.),
41  "Unit scalor from ROOT to Acts.")(
42  "geo-tgeo-bp-parameters",
43 
44  po::value<read_range>()->multitoken()->default_value({}),
45 
46 
47  "Potential beam pipe parameters {r, z, t} in [mm].")(
48  "geo-tgeo-nlayers", po::value<read_series>()->default_value({}),
49  "Number of layers on the negative side.")(
50  "geo-tgeo-clayers", po::value<read_series>()->default_value({}),
51  "Number of layers in the barrel.")(
52  "geo-tgeo-players", po::value<read_series>()->default_value({}),
53  "Number of layers on the positive side.")(
54  "geo-tgeo-ringlayout", po::value<read_series>()->default_value({}),
55  "Indicator if ring layout is present.")(
56  "geo-tgeo-ringtolerance", po::value<read_range>()->default_value({}),
57  "Tolerance for ring layout detection in [mm].")(
58  "geo-tgeo-nvolume-name", po::value<read_strings>()->default_value({}),
59  "Name identifier of the volume for searching negative layers.")(
60  "geo-tgeo-cvolume-name", po::value<read_strings>()->default_value({}),
61  "Name identifier of the volume for searching central layers.")(
62  "geo-tgeo-pvolume-name", po::value<read_strings>()->default_value({}),
63  "Name identifier of the volume for searching positive layers.")(
64  "geo-tgeo-nmodule-name", po::value<read_strings>()->default_value({}),
65  "Name identifier for negative sensitive objects, odered along the "
66  "series.")("geo-tgeo-cmodule-name",
67  po::value<read_strings>()->default_value({}),
68  "Name identifier for central sensitive objects, odered "
69  "along the series.")(
70  "geo-tgeo-pmodule-name", po::value<read_strings>()->default_value({}),
71  "Name identifier for positive sensitive objects, odered along the "
72  "series.")("geo-tgeo-nlayer-r-range",
73  po::value<std::vector<Interval>>()->default_value({}),
74  "Radial range(s) for negative layers "
75  "to restrict the module parsing (optional).")(
76  "geo-tgeo-clayer-r-range",
77  po::value<std::vector<Interval>>()->default_value({}),
78  "Radial range(s) for central layers "
79  "to restrict the module parsing (optional).")(
80  "geo-tgeo-player-r-range",
81  po::value<std::vector<Interval>>()->default_value({}),
82  "Radial range(s) for positive layers "
83  "to restrict the module parsing (optional).")(
84  "geo-tgeo-nlayer-z-range",
85  po::value<std::vector<Interval>>()->default_value({}),
86  "Longitudinal range(s) for negative layers "
87  "to restrict the module parsing (optional).")(
88  "geo-tgeo-clayer-z-range",
89  po::value<std::vector<Interval>>()->default_value({}),
90  "Longitudinal range(s) for central layers "
91  "to restrict the module parsing (optional).")(
92  "geo-tgeo-player-z-range",
93  po::value<std::vector<Interval>>()->default_value({}),
94  "Longitudinal range(s) for positive layers "
95  "to restrict the module parsing (optional).")(
96  "geo-tgeo-nlayer-r-split", po::value<read_range>()->default_value({}),
97  "R-tolerances (if > 0.) that triggers splitting "
98  " of collected surfaces into different negative layers.")(
99  "geo-tgeo-nlayer-z-split", po::value<read_range>()->default_value({}),
100  "Z-tolerances (if > 0.) that triggers splitting "
101  " of collected surfaces into different negative layers.")(
102  "geo-tgeo-clayer-r-split", po::value<read_range>()->default_value({}),
103  "R-tolerances (if > 0.) that triggers splitting "
104  " of collected surfaces into different central layers.")(
105  "geo-tgeo-clayer-z-split", po::value<read_range>()->default_value({}),
106  "Z-tolerances (if > 0.) that triggers splitting "
107  " of collected surfaces into different central layers.")(
108  "geo-tgeo-player-r-split", po::value<read_range>()->default_value({}),
109  "R-tolerances (if > 0.) that triggers splitting "
110  " of collected surfaces into different positive layers.")(
111  "geo-tgeo-sfbin-z-tolerance",
112  po::value<std::vector<Interval>>()->default_value({}),
113  "Tolerance interval in z [mm] for automated surface binning.")(
114  "geo-tgeo-sfbin-r-tolerance",
115  po::value<std::vector<Interval>>()->default_value({}),
116  "Tolerance interval in r [mm] for automated surface binninng.")(
117  "geo-tgeo-sfbin-phi-tolerance",
118  po::value<std::vector<Interval>>()->default_value({}),
119  "Tolerance interval in phi [rad] for automated surface binning.")(
120  "geo-tgeo-nmodule-axes", po::value<read_strings>()->default_value({}),
121  "Axes definition for negative sensitive objects, odered "
122  "along the series.")(
123  "geo-tgeo-player-z-split", po::value<read_range>()->default_value({}),
124  "Z-tolerances (if > 0.) that triggers splitting "
125  " of collected surfaces into different positive layers.")(
126  "geo-tgeo-cmodule-axes", po::value<read_strings>()->default_value({}),
127 
128  "Axes definition for central sensitive objects, odered along the "
129  "series.")("geo-tgeo-pmodule-axes",
130  po::value<read_strings>()->default_value({}),
131  "Axes definition for positive sensitive objects, odered "
132  "along the series.");
133 }
134 
143 template <typename variable_map_t>
144 std::vector<Acts::TGeoLayerBuilder::Config> readTGeoLayerBuilderConfigs(
145  const variable_map_t& vm) {
146  std::vector<Acts::TGeoLayerBuilder::Config> detLayerConfigs;
147 
148  // General: subdetector naming
149  read_strings subDetectors =
150  vm["geo-detector-volume"].template as<read_strings>();
151  double unitScalor = vm["geo-tgeo-unit-scalor"].template as<double>();
152 
153  // The number of layers, can be set 1 with splitting detection
154  read_series nLayers = vm["geo-tgeo-nlayers"].template as<read_series>();
155  read_series cLayers = vm["geo-tgeo-clayers"].template as<read_series>();
156  read_series pLayers = vm["geo-tgeo-players"].template as<read_series>();
157 
158  std::array<read_series, 3> layers = {nLayers, cLayers, pLayers};
159 
160  std::array<size_t, 3> seriesSize = {nLayers.size(), cLayers.size(),
161  pLayers.size()};
162 
163  read_series ringLayout = vm["geo-tgeo-ringlayout"].template as<read_series>();
164 
165  read_range ringTolerance =
166  vm["geo-tgeo-ringtolerance"].template as<read_range>();
167 
168 
169 
170  // The layer names to parse for in the TGeo
171 
172  read_strings nVolumeName =
173  vm["geo-tgeo-nvolume-name"].template as<read_strings>();
174  read_strings cVolumeName =
175  vm["geo-tgeo-cvolume-name"].template as<read_strings>();
176  read_strings pVolumeName =
177  vm["geo-tgeo-pvolume-name"].template as<read_strings>();
178 
179  std::array<read_strings, 3> volumeName = {nVolumeName, cVolumeName,
180  pVolumeName};
181 
182  read_strings nSensitiveNames =
183  vm["geo-tgeo-nmodule-name"].template as<read_strings>();
184  read_strings cSensitiveNames =
185  vm["geo-tgeo-cmodule-name"].template as<read_strings>();
186  read_strings pSensitiveNames =
187  vm["geo-tgeo-pmodule-name"].template as<read_strings>();
188 
189  // The sensitive names to parse for in the TGeo
190  std::array<read_strings, 3> sensitiveNames = {
191  nSensitiveNames, cSensitiveNames, pSensitiveNames};
192 
193  read_strings nSensitiveAxes =
194  vm["geo-tgeo-nmodule-axes"].template as<read_strings>();
195  read_strings cSensitiveAxes =
196  vm["geo-tgeo-cmodule-axes"].template as<read_strings>();
197  read_strings pSensitiveAxes =
198  vm["geo-tgeo-pmodule-axes"].template as<read_strings>();
199 
200  std::array<read_strings, 3> sensitiveAxes = {nSensitiveAxes, cSensitiveAxes,
201  pSensitiveAxes};
202 
203  // The parse radii in r
204  std::vector<Interval> nRrange =
205  vm["geo-tgeo-nlayer-r-range"].template as<std::vector<Interval>>();
206  std::vector<Interval> cRrange =
207  vm["geo-tgeo-clayer-r-range"].template as<std::vector<Interval>>();
208  std::vector<Interval> pRrange =
209  vm["geo-tgeo-player-r-range"].template as<std::vector<Interval>>();
210  std::array<std::vector<Interval>, 3> rRange = {nRrange, cRrange, pRrange};
211 
212  // The parse ranges in z
213  std::vector<Interval> nZrange =
214  vm["geo-tgeo-nlayer-z-range"].template as<std::vector<Interval>>();
215  std::vector<Interval> cZrange =
216  vm["geo-tgeo-clayer-z-range"].template as<std::vector<Interval>>();
217  std::vector<Interval> pZrange =
218  vm["geo-tgeo-player-z-range"].template as<std::vector<Interval>>();
219  std::array<std::vector<Interval>, 3> zRange = {nZrange, cZrange, pZrange};
220 
221  // The split tolerances in r and z
222  read_range nLayerSplitR =
223  vm["geo-tgeo-nlayer-r-split"].template as<read_range>();
224  read_range nLayerSplitZ =
225  vm["geo-tgeo-nlayer-z-split"].template as<read_range>();
226  read_range cLayerSplitR =
227  vm["geo-tgeo-clayer-r-split"].template as<read_range>();
228  read_range cLayerSplitZ =
229  vm["geo-tgeo-clayer-z-split"].template as<read_range>();
230  read_range pLayerSplitR =
231  vm["geo-tgeo-player-r-split"].template as<read_range>();
232  read_range pLayerSplitZ =
233  vm["geo-tgeo-player-z-split"].template as<read_range>();
234 
235  std::array<read_range, 3> splitTolR = {nLayerSplitR, cLayerSplitR,
236  pLayerSplitR};
237 
238  std::array<read_range, 3> splitTolZ = {nLayerSplitZ, cLayerSplitZ,
239  pLayerSplitZ};
240 
241  // Automated binning configuration
242  std::vector<Interval> binToleranceR =
243  vm["geo-tgeo-sfbin-r-tolerance"].template as<std::vector<Interval>>();
244  std::vector<Interval> binToleranceZ =
245  vm["geo-tgeo-sfbin-z-tolerance"].template as<std::vector<Interval>>();
246  std::vector<Interval> binTolerancePhi =
247  vm["geo-tgeo-sfbin-phi-tolerance"].template as<std::vector<Interval>>();
248 
249  // The maximum series and total counter for access of nonsplit layers
250  size_t max_series = *std::max_element(seriesSize.begin(), seriesSize.end());
251  std::array<size_t, 3> ti = {0, 0, 0};
252 
253  // If a beam pipe is present, shift the sub detector names by one
254  // Create a beam pipe if configured to do so
255  int idetaddon = 0;
256  auto beamPipeParameters =
257  vm["geo-tgeo-bp-parameters"].template as<read_range>();
258  if (beamPipeParameters.size() > 2) {
259  ++idetaddon;
260  }
261 
262  // Split the sensor names if there are mulitple ones
263  auto splitAtOr =
264  [](const std::string& sensorNames) -> std::vector<std::string> {
265  std::vector<std::string> sensors;
266  std::istringstream feed(sensorNames);
267  std::string split;
268  while (getline(feed, split, '|')) {
269  sensors.push_back(split);
270  }
271  return sensors;
272  };
273 
274  // Prepare the TGeoLayerBuilder::Configs
275  for (size_t idet = 0; idet < max_series; ++idet) {
276  // Each detector needs a layer builder
277  Acts::TGeoLayerBuilder::Config layerBuilderConfig;
278 
279  // Configuration of AutoBinning
280  if (binTolerancePhi.size() == binToleranceZ.size() and
281  binToleranceR.size() == binToleranceZ.size()) {
282  layerBuilderConfig.autoSurfaceBinning = true;
283 
284  auto tolR = binToleranceR[idet];
285  std::vector<std::pair<double, double>> binTolerances{(int)Acts::binValues,
286  {0., 0.}};
287  binTolerances[Acts::binR] = {tolR.lower.value_or(0.),
288  tolR.upper.value_or(0.)};
289 
290  auto tolZ = binToleranceZ[idet];
291  binTolerances[Acts::binZ] = {tolZ.lower.value_or(0.),
292  tolZ.upper.value_or(0.)};
293  auto tolPhi = binTolerancePhi[idet];
294  binTolerances[Acts::binPhi] = {tolPhi.lower.value_or(0.),
295  tolPhi.upper.value_or(0.)};
296 
297  layerBuilderConfig.surfaceBinMatcher =
298  Acts::SurfaceBinningMatcher(binTolerances);
299  }
300 
301  // Loop over the | n | c | p | configuration
302  for (unsigned int ncp = 0; ncp < 3; ++ncp) {
303  // number of layers of this configuration
304  unsigned int nl = layers[ncp].size() > idet ? layers[ncp][idet] : 0;
305  for (unsigned int in = 0; in < nl; ++in, ++ti[ncp]) {
306  // Create the layer config object and fill it
308  lConfig.volumeName = volumeName[ncp][ti[ncp]];
309  lConfig.sensorNames = splitAtOr(sensitiveNames[ncp][ti[ncp]]);
310  lConfig.localAxes = sensitiveAxes[ncp][ti[ncp]];
311 
312  // Fill the parsing restrictions in r
313  auto rR = rRange[ncp];
314  if (rR.size() > ti[ncp]) {
315  double rMin = rR[ti[ncp]].lower.value_or(0.);
316  double rMax =
317  rR[ti[ncp]].upper.value_or(std::numeric_limits<double>::max());
318  lConfig.parseRanges.push_back({Acts::binR, {rMin, rMax}});
319  }
320  // Fill the layer splitting parameters in r
321  if (splitTolR[ncp].size() > ti[ncp]) {
322  double rsp = splitTolR[ncp][ti[ncp]];
323  if (rsp > 0.) {
324  lConfig.splitConfigs.push_back({Acts::binR, rsp});
325  }
326  }
327  // Fill the parsing restrictions in z
328  auto zR = zRange[ncp];
329  if (zR.size() > ti[ncp]) {
330  double zMin =
331  zR[ti[ncp]].lower.value_or(-std::numeric_limits<double>::max());
332  double zMax =
333  zR[ti[ncp]].upper.value_or(std::numeric_limits<double>::max());
334  lConfig.parseRanges.push_back({Acts::binZ, {zMin, zMax}});
335  }
336  // Fill the layer splitting parameters in z
337  if (splitTolZ[ncp].size() > ti[ncp]) {
338  double zsp = splitTolZ[ncp][ti[ncp]];
339  if (zsp > 0.) {
340  lConfig.splitConfigs.push_back({Acts::binZ, zsp});
341  }
342  }
343  layerBuilderConfig.layerConfigurations[ncp].push_back(lConfig);
344  }
345  }
346 
347  // Set the scale and the layer creator
348  layerBuilderConfig.configurationName = subDetectors[idet + idetaddon];
349  layerBuilderConfig.unit = unitScalor;
350 
351  // Now add it to the configs
352  detLayerConfigs.push_back(layerBuilderConfig);
353  }
354  return detLayerConfigs;
355 }
356 
357 } // namespace Options
358 } // namespace ActsExamples