EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CylinderVolumeBuilder.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CylinderVolumeBuilder.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-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 
18 #include "Acts/Utilities/Units.hpp"
19 
20 #include <array>
21 #include <limits>
22 #include <string>
23 
24 namespace Acts {
25 
26 class TrackingVolume;
27 class VolumeBounds;
28 class IVolumeMaterial;
29 class ISurfaceMaterial;
30 
33  Undefined = 0,
34  Attaching = 1,
35  Inserting = 2,
36  Wrapping = 3,
40 };
41 
43 struct VolumeConfig {
44  bool present{false};
45  bool wrapping{false};
46  double rMin;
47  double rMax;
48  double zMin;
49  double zMax;
52 
55  : rMin(std::numeric_limits<double>::max()),
56  rMax(std::numeric_limits<double>::lowest()),
57  zMin(std::numeric_limits<double>::max()),
58  zMax(std::numeric_limits<double>::lowest()),
59  layers() {}
60 
65  void adaptZ(const VolumeConfig& lConfig) {
66  if (lConfig) {
67  zMin = std::min(zMin, lConfig.zMin);
68  zMax = std::max(zMax, lConfig.zMax);
69  }
70  }
71 
76  void adaptR(const VolumeConfig& lConfig) {
77  if (lConfig) {
78  rMin = std::min(rMin, lConfig.rMin);
79  rMax = std::max(rMax, lConfig.rMax);
80  }
81  }
82 
87  void adapt(const VolumeConfig& lConfig) {
88  adaptZ(lConfig);
89  adaptR(lConfig);
90  }
91 
98  void midPointAttachZ(VolumeConfig& lConfig) {
99  if (lConfig.zMin >= zMax) {
100  double zMid = 0.5 * (lConfig.zMin + zMax);
101  lConfig.zMin = zMid;
102  zMax = zMid;
103  } else {
104  double zMid = 0.5 * (zMin + lConfig.zMax);
105  lConfig.zMax = zMid;
106  zMin = zMid;
107  }
108  }
109 
114  void attachZ(const VolumeConfig& lConfig) {
115  if (lConfig.zMin >= zMax) {
116  zMax = lConfig.zMin;
117  } else {
118  zMin = lConfig.zMax;
119  }
120  }
121 
126  bool overlapsInR(const VolumeConfig& vConfig) const {
127  if (!present) {
128  return false;
129  }
130  return std::max(rMin, vConfig.rMin) <= std::min(rMax, vConfig.rMax);
131  }
132 
137  bool overlapsInZ(const VolumeConfig& vConfig) const {
138  if (!present) {
139  return false;
140  }
141  return std::max(zMin, vConfig.zMin) <= std::min(zMax, vConfig.zMax);
142  }
143 
148  bool wraps(const VolumeConfig& vConfig) const {
149  if ((zMax <= vConfig.zMin) || (zMin >= vConfig.zMax)) {
150  return true;
151  }
152  return containsInR(vConfig);
153  }
154 
158  bool contains(const VolumeConfig& vConfig) const {
159  return (containsInR(vConfig) && containsInZ(vConfig));
160  }
161 
165  bool containsInR(const VolumeConfig& vConfig) const {
166  return (rMin >= vConfig.rMax);
167  }
168 
172  bool containsInZ(const VolumeConfig& vConfig) const {
173  return (vConfig.zMin > zMin && vConfig.zMax < zMax);
174  }
175 
177  std::string toString() const {
179  std::stringstream sl;
180  sl << rMin << ", " << rMax << " / " << zMin << ", " << zMax;
181  return sl.str();
182  }
183 
185  operator bool() const { return present; }
186 };
187 
190  public:
195 
198 
203 
207 
208  // WrappingCondition
210  std::string wConditionScreen = "[left untouched]";
211 
213  WrappingConfig() = default;
214 
217  // set the container to be present
219  std::string wConditionAddon = "";
220  // if we have more than one config present
224  wConditionScreen = "grouped to ";
225  }
226  // adapt the new volume config to the existing configs
227  if (nVolumeConfig) {
229  wConditionScreen += "[n]";
230  }
231  if (cVolumeConfig) {
233  wConditionScreen += "[c]";
234  }
235  if (pVolumeConfig) {
237  wConditionScreen += "[p]";
238  }
239  // adapt the external one
240  if (externalVolumeConfig) {
242  }
243  // attach the volume configs
244  if (nVolumeConfig && cVolumeConfig) {
246  }
247  if (cVolumeConfig && pVolumeConfig) {
249  }
250  // adapt r afterwards
251  // - easy if no exisitng volume
252  // - possible if no central volume
257  }
258  }
259 
262  // action is only needed if an existing volume
263  // is present
264  if (existingVolumeConfig) {
265  // 0 - simple attachment case
266  if (!cVolumeConfig) {
267  // check if it can be easily attached
270  // will attach the new volume(s)
272  wConditionScreen = "[n attched]";
273  }
276  // will attach the new volume(s)
278  wConditionScreen = "[p attched]";
279  }
280  // see if inner glue volumes are needed
284  } else {
285  fGapVolumeConfig.present = true;
286  // get the zMin/zMax boundaries
290  }
291  // see if outer glue volumes are needed
295  } else {
296  sGapVolumeConfig.present = true;
297  // get the zMin/zMax boundaries
301  }
302  } else {
303  // full wrapping or full insertion case
305  // Full wrapping case
306  // - set the rMin
310  // - set the rMax
314  // will wrap the new volume(s) around existing
316  wConditionScreen = "[fully wrapped]";
318  // full insertion case
319  // set the rMax
323  // set the rMin
327  // will insert the new volume(s) into existing
329  wConditionScreen = "[fully inserted]";
331  // central wrapping case
332  // set the rMax
336  // set the rMin
340  // set the Central Wrapping
342  wConditionScreen = "[centrally wrapped]";
344  // central insertion case
345  // set the rMax
349  // set the rMin
353  // set the Central Wrapping
355  wConditionScreen = "[centrally inserted]";
356  }
357 
358  // check if gaps are needed
359  //
360  // the gap reference is either the container for FULL wrapping,
361  // insertion
362  // or it is the centralVolume for central wrapping, insertion
363  VolumeConfig referenceVolume =
366  : cVolumeConfig;
367  // - at the negative sector
368  if (existingVolumeConfig.zMin > referenceVolume.zMin) {
369  fGapVolumeConfig.present = true;
371  fGapVolumeConfig.zMin = referenceVolume.zMin;
373  } else {
374  // adapt lower z boundary
375  if (nVolumeConfig) {
377  } else if (cVolumeConfig) {
379  }
380  }
381  // - at the positive sector
382  if (existingVolumeConfig.zMax < referenceVolume.zMax) {
383  sGapVolumeConfig.present = true;
386  sGapVolumeConfig.zMax = referenceVolume.zMax;
387  } else {
388  // adapt higher z boundary
389  if (pVolumeConfig) {
391  } else if (cVolumeConfig) {
393  }
394  }
395  }
396  }
397  return;
398  }
399 
401  std::string toString() const {
402  // for screen output
403  std::stringstream sl;
404  if (containerVolumeConfig) {
405  sl << "New contaienr built with configuration: "
406  << containerVolumeConfig.toString() << '\n';
407  }
408  // go throug the new new ones first
409  if (nVolumeConfig) {
410  sl << " - n: Negative Endcap, current configuration: "
411  << nVolumeConfig.toString() << '\n';
412  }
413  if (cVolumeConfig) {
414  sl << " - c: Barrel, current configuration: "
415  << cVolumeConfig.toString() << '\n';
416  }
417  if (pVolumeConfig) {
418  sl << " - p: Negative Endcap, current configuration: "
419  << pVolumeConfig.toString() << '\n';
420  }
421  if (existingVolumeConfig) {
422  sl << "Existing volume with configuration: "
423  << existingVolumeConfig.toString() << '\n';
424  if (fGapVolumeConfig) {
425  sl << " - g1: First gap volume, configuration : "
426  << fGapVolumeConfig.toString() << '\n';
427  }
428  if (sGapVolumeConfig) {
429  sl << " - g2: Second gap volume, configuration : "
430  << sGapVolumeConfig.toString() << '\n';
431  }
432  if (wCondition != Undefined) {
433  sl << "WrappingCondition = " << wCondition << '\n';
434  }
435  }
436  return sl.str();
437  }
438 };
439 
460  public:
463  struct Config {
465  std::shared_ptr<const ITrackingVolumeHelper> trackingVolumeHelper = nullptr;
467  std::string volumeName = "";
469  std::shared_ptr<const IVolumeMaterial> volumeMaterial = nullptr;
471  bool buildToRadiusZero = false;
473  bool checkRingLayout = false;
477  std::shared_ptr<const ILayerBuilder> layerBuilder = nullptr;
479  std::shared_ptr<const IConfinedTrackingVolumeBuilder> ctVolumeBuilder =
480  nullptr;
482  std::pair<double, double> layerEnvelopeR = {1. * UnitConstants::mm,
483  1. * UnitConstants::mm};
486 
487  // The potential boundary material (MB) options - there are 6 at maximium
491  std::array<std::shared_ptr<const ISurfaceMaterial>, 6> boundaryMaterial{
492  nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
493 
495  int volumeSignature = -1;
496  };
497 
502  CylinderVolumeBuilder(const Config& cvbConfig,
503  std::unique_ptr<const Logger> logger = getDefaultLogger(
504  "CylinderVolumeBuilder", Logging::INFO));
505 
507  ~CylinderVolumeBuilder() override;
508 
519  const GeometryContext& gctx, TrackingVolumePtr existingVolume = nullptr,
520  VolumeBoundsPtr externalBounds = nullptr) const override;
521 
525  void setConfiguration(const Config& cvbConfig);
526 
530  Config getConfiguration() const;
531 
535  void setLogger(std::unique_ptr<const Logger> newLogger);
536 
544  const GeometryContext& gctx, const LayerVector& lVector,
545  const MutableTrackingVolumeVector& mtvVector) const;
546 
547  private:
550 
554  const Logger& logger() const { return *m_logger; }
555 
557  std::unique_ptr<const Logger> m_logger;
558 
572  VolumeConfig& layerConfig,
573  const VolumeConfig& insideConfig,
574  const VolumeConfig& volumeConfig, int sign) const;
575 };
576 
579  const {
580  return m_cfg;
581 }
582 
583 } // namespace Acts