Analysis Software
Documentation for sPHENIX simulation 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 
17 
18 #include <algorithm>
19 #include <array>
20 #include <limits>
21 #include <memory>
22 #include <ostream>
23 #include <stdexcept>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 
28 namespace Acts {
29 
30 class IVolumeMaterial;
31 class ISurfaceMaterial;
32 class ILayerBuilder;
33 class IConfinedTrackingVolumeBuilder;
34 
37  Undefined = 0,
38  Attaching = 1,
39  Inserting = 2,
40  Wrapping = 3,
44 };
45 
47 struct VolumeConfig {
48  bool present{false};
49  bool wrapping{false};
50  double rMin;
51  double rMax;
52  double zMin;
53  double zMax;
56 
59  : rMin(std::numeric_limits<double>::max()),
60  rMax(std::numeric_limits<double>::lowest()),
61  zMin(std::numeric_limits<double>::max()),
62  zMax(std::numeric_limits<double>::lowest()),
63  layers() {}
64 
69  void adaptZ(const VolumeConfig& lConfig) {
70  if (lConfig) {
71  zMin = std::min(zMin, lConfig.zMin);
72  zMax = std::max(zMax, lConfig.zMax);
73  }
74  }
75 
80  void adaptR(const VolumeConfig& lConfig) {
81  if (lConfig) {
82  rMin = std::min(rMin, lConfig.rMin);
83  rMax = std::max(rMax, lConfig.rMax);
84  }
85  }
86 
91  void adapt(const VolumeConfig& lConfig) {
92  adaptZ(lConfig);
93  adaptR(lConfig);
94  }
95 
102  void midPointAttachZ(VolumeConfig& lConfig) {
103  if (lConfig.zMin >= zMax) {
104  double zMid = 0.5 * (lConfig.zMin + zMax);
105  lConfig.zMin = zMid;
106  zMax = zMid;
107  } else {
108  double zMid = 0.5 * (zMin + lConfig.zMax);
109  lConfig.zMax = zMid;
110  zMin = zMid;
111  }
112  }
113 
118  void attachZ(const VolumeConfig& lConfig) {
119  if (lConfig.zMin >= zMax) {
120  zMax = lConfig.zMin;
121  } else {
122  zMin = lConfig.zMax;
123  }
124  }
125 
130  bool overlapsInR(const VolumeConfig& vConfig) const {
131  if (!present) {
132  return false;
133  }
134  return std::max(rMin, vConfig.rMin) <= std::min(rMax, vConfig.rMax);
135  }
136 
141  bool overlapsInZ(const VolumeConfig& vConfig) const {
142  if (!present) {
143  return false;
144  }
145  return std::max(zMin, vConfig.zMin) <= std::min(zMax, vConfig.zMax);
146  }
147 
152  bool wraps(const VolumeConfig& vConfig) const {
153  if ((zMax <= vConfig.zMin) || (zMin >= vConfig.zMax)) {
154  return true;
155  }
156  return containsInR(vConfig);
157  }
158 
162  bool contains(const VolumeConfig& vConfig) const {
163  return (containsInR(vConfig) && containsInZ(vConfig));
164  }
165 
169  bool containsInR(const VolumeConfig& vConfig) const {
170  return (rMin >= vConfig.rMax);
171  }
172 
176  bool containsInZ(const VolumeConfig& vConfig) const {
177  return (vConfig.zMin > zMin && vConfig.zMax < zMax);
178  }
179 
183  std::stringstream sl;
184  sl << rMin << ", " << rMax << " / " << zMin << ", " << zMax;
185  return sl.str();
186  }
187 
189  operator bool() const { return present; }
190 };
191 
194  public:
199 
202 
207 
211 
212  // WrappingCondition
214  std::string wConditionScreen = "[left untouched]";
215 
217  WrappingConfig() = default;
218 
221  // set the container to be present
223  std::string wConditionAddon = "";
224  // if we have more than one config present
228  wConditionScreen = "grouped to ";
229  }
230  // adapt the new volume config to the existing configs
231  if (nVolumeConfig) {
233  wConditionScreen += "[n]";
234  }
235  if (cVolumeConfig) {
237  wConditionScreen += "[c]";
238  }
239  if (pVolumeConfig) {
241  wConditionScreen += "[p]";
242  }
243  // adapt the external one
244  if (externalVolumeConfig) {
246  }
247  // attach the volume configs
248  if (nVolumeConfig && cVolumeConfig) {
250  }
251  if (cVolumeConfig && pVolumeConfig) {
253  }
254  // adapt r afterwards
255  // - easy if no existing volume
256  // - possible if no central volume
261  }
262  }
263 
266  // action is only needed if an existing volume
267  // is present
268  if (existingVolumeConfig) {
269  // 0 - simple attachment case
270  if (!cVolumeConfig) {
271  // check if it can be easily attached
274  // will attach the new volume(s)
276  wConditionScreen = "[n attached]";
277  }
280  // will attach the new volume(s)
282  wConditionScreen = "[p attached]";
283  }
284  // see if inner glue volumes are needed
288  } else {
289  fGapVolumeConfig.present = true;
290  // get the zMin/zMax boundaries
294  }
295  // see if outer glue volumes are needed
299  } else {
300  sGapVolumeConfig.present = true;
301  // get the zMin/zMax boundaries
305  }
306  } else {
307  // full wrapping or full insertion case
309  // Full wrapping case
310  // - set the rMin
314  // - set the rMax
318  // will wrap the new volume(s) around existing
320  wConditionScreen = "[fully wrapped]";
322  // full insertion case
323  // set the rMax
327  // set the rMin
331  // will insert the new volume(s) into existing
333  wConditionScreen = "[fully inserted]";
335  // central wrapping case
336  // set the rMax
340  // set the rMin
344  // set the Central Wrapping
346  wConditionScreen = "[centrally wrapped]";
348  // central insertion case
349  // set the rMax
353  // set the rMin
357  // set the Central Wrapping
359  wConditionScreen = "[centrally inserted]";
364  // The volumes are overlapping this shouldn't be happening return an
365  // error
366  throw std::invalid_argument(
367  "Volumes are overlapping, this shouldn't be happening. Please "
368  "check your geometry building.");
369  }
370 
371  // check if gaps are needed
372  //
373  // the gap reference is either the container for FULL wrapping,
374  // insertion
375  // or it is the centralVolume for central wrapping, insertion
376  VolumeConfig referenceVolume =
379  : cVolumeConfig;
380  // - at the negative sector
381  if (existingVolumeConfig.zMin > referenceVolume.zMin) {
382  fGapVolumeConfig.present = true;
384  fGapVolumeConfig.zMin = referenceVolume.zMin;
386  } else {
387  // adapt lower z boundary
388  if (nVolumeConfig) {
390  } else if (cVolumeConfig) {
392  }
393  }
394  // - at the positive sector
395  if (existingVolumeConfig.zMax < referenceVolume.zMax) {
396  sGapVolumeConfig.present = true;
399  sGapVolumeConfig.zMax = referenceVolume.zMax;
400  } else {
401  // adapt higher z boundary
402  if (pVolumeConfig) {
404  } else if (cVolumeConfig) {
406  }
407  }
408  }
409  }
410  return;
411  }
412 
415  // for screen output
416  std::stringstream sl;
417  if (containerVolumeConfig) {
418  sl << "New container built with configuration: "
419  << containerVolumeConfig.toString() << '\n';
420  }
421  // go through the new ones first
422  if (nVolumeConfig) {
423  sl << " - n: Negative Endcap, current configuration: "
424  << nVolumeConfig.toString() << '\n';
425  }
426  if (cVolumeConfig) {
427  sl << " - c: Barrel, current configuration: "
428  << cVolumeConfig.toString() << '\n';
429  }
430  if (pVolumeConfig) {
431  sl << " - p: Negative Endcap, current configuration: "
432  << pVolumeConfig.toString() << '\n';
433  }
434  if (existingVolumeConfig) {
435  sl << "Existing volume with configuration: "
436  << existingVolumeConfig.toString() << '\n';
437  if (fGapVolumeConfig) {
438  sl << " - g1: First gap volume, configuration : "
439  << fGapVolumeConfig.toString() << '\n';
440  }
441  if (sGapVolumeConfig) {
442  sl << " - g2: Second gap volume, configuration : "
443  << sGapVolumeConfig.toString() << '\n';
444  }
445  if (wCondition != Undefined) {
446  sl << "WrappingCondition = " << wCondition << '\n';
447  }
448  }
449  return sl.str();
450  }
451 };
452 
473  public:
476  struct Config {
478  std::shared_ptr<const ITrackingVolumeHelper> trackingVolumeHelper = nullptr;
482  std::shared_ptr<const IVolumeMaterial> volumeMaterial = nullptr;
484  bool buildToRadiusZero = false;
486  bool checkRingLayout = false;
490  std::shared_ptr<const ILayerBuilder> layerBuilder = nullptr;
492  std::shared_ptr<const IConfinedTrackingVolumeBuilder> ctVolumeBuilder =
493  nullptr;
495  std::pair<double, double> layerEnvelopeR = {1. * UnitConstants::mm,
496  1. * UnitConstants::mm};
499 
500  // The potential boundary material (MB) options - there are 6 at maximum
504  std::array<std::shared_ptr<const ISurfaceMaterial>, 6> boundaryMaterial{
505  nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
506 
508  int volumeSignature = -1;
509  };
510 
515  CylinderVolumeBuilder(const Config& cvbConfig,
516  std::unique_ptr<const Logger> logger = getDefaultLogger(
517  "CylinderVolumeBuilder", Logging::INFO));
518 
520  ~CylinderVolumeBuilder() override;
521 
532  const GeometryContext& gctx, TrackingVolumePtr existingVolume = nullptr,
533  VolumeBoundsPtr externalBounds = nullptr) const override;
534 
538  void setConfiguration(const Config& cvbConfig);
539 
543  Config getConfiguration() const;
544 
548  void setLogger(std::unique_ptr<const Logger> newLogger);
549 
558  const GeometryContext& gctx, const LayerVector& lVector,
559  const MutableTrackingVolumeVector& mtvVector) const;
560 
561  private:
564 
568  const Logger& logger() const { return *m_logger; }
569 
571  std::unique_ptr<const Logger> m_logger;
572 
586  VolumeConfig& layerConfig,
587  const VolumeConfig& insideConfig,
588  const VolumeConfig& volumeConfig, int sign) const;
589 };
590 
593  const {
594  return m_cfg;
595 }
596 
597 } // namespace Acts