Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
detector.py
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file detector.py
1 import math
2 import acts, acts.examples
3 
4 
5 from acts import (
6  logging,
7  Binning,
8  Extent,
9  ProtoBinning,
10  LayerStructureBuilder,
11  VolumeBoundsType,
12  VolumeStructureBuilder,
13  DetectorVolumeBuilder,
14  DetectorBuilder,
15  CylindricalContainerBuilder,
16  Transform3,
17 )
18 
19 
20 def phiBinning(phiBins, extraBins=1):
21  """helper method to create phi binning
22 
23  :param phiBins: number of phi bins
24  :param extraBins: number of phi bins
25 
26  """
27  return ProtoBinning(
28  Binning.phi, Binning.closed, -math.pi, math.pi, phiBins, extraBins
29  )
30 
31 
33  def __init__(
34  self,
35  name,
36  extent,
37  provider=None,
38  binnings=None,
39  supports=[],
40  loglevel=logging.INFO,
41  ):
42  """Create a cylindrical, concentric volume builder
43 
44  :param name: name of the volume
45  :param extent: extent of the volume
46  :param provider: surface provider for the volume
47  :param binning: binning of surfces in this volume
48  :param support: support surface description
49  :param loglevel: logging level
50  """
51  self._name = name
52  self._extent = extent
53  self._provider = provider
54  self._binnings = binnings
55  self._supports = supports
56  self._loglevel = loglevel
57 
58  def builder(self):
59  "Return the associated builder"
60 
61  # Get r, z, phi range
62  rRange = self._extent.range(acts.Binning.r)
63  zRange = self._extent.range(acts.Binning.z)
64 
65  # Set up the shape builder: external builder
66  shapeConfig = VolumeStructureBuilder.Config()
67  shapeConfig.boundsType = VolumeBoundsType.Cylinder
68  shapeConfig.boundValues = [
69  rRange[0],
70  rRange[1],
71  0.5 * (zRange[1] - zRange[0]),
72  math.pi,
73  0,
74  ]
75  shapeConfig.transform = Transform3([0, 0, 0.5 * (zRange[1] + zRange[0])])
76  shapeConfig.auxiliary = "Shape[" + self._name + "]"
77 
78  # Set up the volume builder
79  volConfig = acts.DetectorVolumeBuilder.Config()
80  volConfig.name = self._name
81  volConfig.auxiliary = "Volume[" + self._name + "]"
82  volConfig.externalsBuilder = VolumeStructureBuilder(
83  shapeConfig, shapeConfig.auxiliary, self._loglevel
84  )
85  if self._provider is not None:
86  layerConfig = LayerStructureBuilder.Config()
87  layerConfig.surfacesProvider = self._provider
88  layerConfig.binnings = self._binnings
89  layerConfig.supports = self._supports
90  layerConfig.auxiliary = "Layer[" + self._name + "]"
91  volConfig.internalsBuilder = LayerStructureBuilder(
92  layerConfig, layerConfig.auxiliary, self._loglevel
93  )
94  # Return the builder
95  return DetectorVolumeBuilder(volConfig, self._name, self._loglevel)
96 
97  def prependName(self, parent):
98  """Allows to set the name from a parent"""
99  self._name = parent + "_" + self._name
100 
101  def extent(self):
102  """Return the extent of the volume in order to create gap volumes"""
103  return self._extent
104 
105 
107  def __init__(
108  self,
109  name,
110  extent,
111  volumes,
112  layers=None,
113  binning=[],
114  rootbuilder=None,
115  geoidgenerator=None,
116  reversegeoids=False,
117  loglevel=logging.INFO,
118  ):
119  """Create a cylindrical container builder from volumes or layer definitions
120 
121  :param name: name of the container
122  :param extent: extent of the container
123  :param volumes: list of volumes
124  :param layers: list of layers [ [extent, provider, binnings, supports], ... ]
125  :param binning: binning of surfces in this container
126  :param rootbuilder: root volume finder builder
127  :param geoidgenerator: geoid generator for setting geo ids
128  :param reversegeoids: reverse the geo id order
129  :param loglevel: logging level
130 
131  """
132  self._name = name
133  self._extent = extent
134  self._layers = layers
135  self._volumes = volumes
136  self._binning = binning
137  self._rootbuilder = rootbuilder
138  self._geoidgenerator = geoidgenerator
139  self._reversegeoids = reversegeoids
140  self._loglevel = loglevel
141 
142  def builder(self):
143  "Return the associated builder"
144  orthogonal = Binning.r if self._binning == Binning.r else Binning.z
145 
146  builders = []
147  # If the container is defined by volumes, just fill the builders
148  if self._volumes is not None:
149  builders = [volume.builder() for volume in self._volumes]
150  # Otherwise, build the container from the layers
151  else:
152  bReference = self._extent.range(self._binning)[0]
153  oRange = self._extent.range(orthogonal)
154  # Builders to be constructed
155  il = 0
156  # Sub layer loop
157  for layer in self._layers:
158  bRange = layer.extent().range(self._binning)
159  # Low gap volume insertion
160  if bReference < bRange[0]:
161  gExtent = Extent(
162  [[self._binning, [bReference, bRange[0]]], [orthogonal, oRange]]
163  )
164  builders += [
166  self._name + "_gap_" + str(il), gExtent
167  ).builder()
168  ]
169  # Layer volume insertion
170  layer.prependName(self._name)
171 
172  builders += [layer.builder()]
173  # Update reference and increment the counter
174  bReference = bRange[1]
175  il = il + 1
176 
177  # Last gap volume insertion
178  if bReference < self._extent.range(self._binning)[1]:
179  gExtent = Extent(
180  [
181  [
182  self._binning,
183  [bReference, self._extent.range(self._binning)[1]],
184  ],
185  [orthogonal, oRange],
186  ]
187  )
188  builders += [
190  self._name + "_gap_" + str(il), gExtent
191  ).builder()
192  ]
193 
194  # The container builder
195  containerConfig = CylindricalContainerBuilder.Config()
196  containerConfig.builders = builders
197  containerConfig.binning = [self._binning]
198  containerConfig.rootVolumeFinderBuilder = self._rootbuilder
199  containerConfig.geoIdGenerator = self._geoidgenerator
200  containerConfig.geoIdReverseGen = self._reversegeoids
201  containerConfig.auxiliary = "Container[" + self._name + "]"
202  return CylindricalContainerBuilder(containerConfig, self._name, self._loglevel)