EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DemonstratorBarrel_geo.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DemonstratorBarrel_geo.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 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 
11 
12 #include <string>
13 #include <vector>
14 
15 #include "DD4hep/DetFactoryHelper.h"
16 
17 using namespace dd4hep;
18 
24 static Ref_t create_element(Detector& lcdd, xml_h xml,
25  dd4hep::SensitiveDetector sens) {
26  xml_det_t x_det = xml;
27  std::string barrelName = x_det.nameStr();
28  // Make dd4hep::DetElement
29  dd4hep::DetElement barrelDetector(barrelName, x_det.id());
30  // add Extension to Detlement for the RecoGeometry
31  Acts::ActsExtension* barrelExtension = new Acts::ActsExtension();
32  barrelExtension->addType("barrel", "detector");
33  barrelDetector.addExtension<Acts::ActsExtension>(barrelExtension);
34 
35  // Make Volume
36  dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
37  dd4hep::Tube barrelShape(x_det_dim.rmin(), x_det_dim.rmax(), x_det_dim.dz());
38  dd4hep::Volume barrelVolume(barrelName, barrelShape,
39  lcdd.air()); // air at the moment change later
40  barrelVolume.setVisAttributes(lcdd, x_det.visStr());
41 
42  // Loop over the layers and build them
43  for (xml_coll_t j(xml, _U(layer)); j; ++j) {
44  // Get the layer xml configuration
45  xml_comp_t x_layer = j;
46  double rmin = x_layer.rmin();
47  double rmax = x_layer.rmax();
48  unsigned int layerNum = x_layer.id();
49  // Create Volume for Layer
50  std::string layerName = barrelName + _toString((int)layerNum, "layer%d");
51  dd4hep::Volume layerVolume(layerName, Tube(rmin, rmax, x_layer.dz()),
52  lcdd.material(x_layer.materialStr()));
53  dd4hep::DetElement layerElement(barrelDetector, layerName, layerNum);
54  // Visualization
55  layerVolume.setVisAttributes(lcdd, x_layer.visStr());
56 
57  unsigned int supportNum = 0;
58  // Place the support cylinder
59  if (x_layer.hasChild(_U(support))) {
60  xml_comp_t x_support = x_layer.child(_U(support));
61 
62  // Create the volume of the support structure
63  dd4hep::Volume supportVolume(
64  "SupportStructure",
65  Tube(x_support.rmin(), x_support.rmax(), x_support.dz()),
66  lcdd.material(x_support.materialStr()));
67  supportVolume.setVisAttributes(lcdd, x_support.visStr());
68  // Place the support structure
69  dd4hep::PlacedVolume placedSupport =
70  layerVolume.placeVolume(supportVolume);
71  placedSupport.addPhysVolID("support", supportNum++);
72  }
73 
74  // Construct the volume
75  if (x_layer.hasChild(_U(module))) {
76  xml_comp_t x_module = x_layer.child(_U(module));
77  // create the module volume and its corresponing component volumes first
78  dd4hep::Assembly moduleAssembly("module");
79  // Visualization
80  moduleAssembly.setVisAttributes(lcdd, x_module.visStr());
81  if (x_module.isSensitive()) {
82  moduleAssembly.setSensitiveDetector(sens);
83  }
84 
85  xml_comp_t x_mod_placement = x_module.child(_Unicode(placements));
86  unsigned int nphi = x_mod_placement.nphi();
87  double phi0 = x_mod_placement.phi0();
88  double phiTilt = x_mod_placement.phi_tilt();
89  double r = x_mod_placement.r();
90  double deltaPhi = 2 * M_PI / nphi;
91 
92  // Place the components inside the module
93  unsigned int compNum = 1;
94 
95  std::vector<PlacedVolume> sensComponents;
96 
97  for (xml_coll_t comp(x_module, _U(module_component)); comp;
98  ++comp, ++compNum) {
99  xml_comp_t x_comp = comp;
100  // Component volume
101  std::string componentName = _toString((int)compNum, "component%d");
102  dd4hep::Volume componentVolume(
103  componentName,
104  Box(0.5 * x_comp.dx(), 0.5 * x_comp.dy(), 0.5 * x_comp.dz()),
105  lcdd.material(x_comp.materialStr()));
106  if (x_comp.isSensitive()) {
107  componentVolume.setSensitiveDetector(sens);
108  }
109 
110  // Visualization
111  componentVolume.setVisAttributes(lcdd, x_comp.visStr());
112  // Place Module Box Volumes in layer
113  dd4hep::PlacedVolume placedComponent = moduleAssembly.placeVolume(
114  componentVolume,
115  Position(x_comp.x_offset(), x_comp.y_offset(), x_comp.z_offset()));
116  placedComponent.addPhysVolID("component", compNum);
117  // Remember the sensitive components of this module
118  if (x_comp.isSensitive()) {
119  sensComponents.push_back(placedComponent);
120  }
121  }
122 
123  // Add cooling pipe
124  if (x_module.hasChild(_U(tubs))) {
125  xml_comp_t x_tubs = x_module.child(_U(tubs));
126  dd4hep::Volume pipeVolume(
127  "CoolingPipe", Tube(x_tubs.rmin(), x_tubs.rmax(), x_tubs.length()),
128  lcdd.material(x_tubs.materialStr()));
129  pipeVolume.setVisAttributes(lcdd, x_tubs.visStr());
130  // Place the cooling pipe into the module
131  dd4hep::PlacedVolume placedPipe = moduleAssembly.placeVolume(
132  pipeVolume,
133  Transform3D(RotationX(0.5 * M_PI) * RotationY(0.5 * M_PI),
134  Position(x_tubs.x_offset(), x_tubs.y_offset(),
135  x_tubs.z_offset())));
136  placedPipe.addPhysVolID("support", supportNum++);
137  }
138 
139  // Add mount
140  if (x_module.hasChild(_U(anchor))) {
141  xml_comp_t x_trd = x_module.child(_U(anchor));
142  // create the two shapes first
143  dd4hep::Trapezoid mountShape(x_trd.x1(), x_trd.x2(), x_trd.length(),
144  x_trd.length(), x_trd.dz());
145 
146  dd4hep::Volume mountVolume("ModuleMount", mountShape,
147  lcdd.material(x_trd.materialStr()));
148 
149  // Place the mount onto the module
150  dd4hep::PlacedVolume placedMount = moduleAssembly.placeVolume(
151  mountVolume,
152  Transform3D(RotationZ(0.5 * M_PI),
153  Position(x_trd.x_offset(), x_trd.y_offset(),
154  x_trd.z_offset())));
155  placedMount.addPhysVolID("support", supportNum++);
156  }
157 
158  // Add cable
159  if (x_module.hasChild(_U(box))) {
160  xml_comp_t x_cab = x_module.child(_U(box));
161  dd4hep::Volume cableVolume(
162  "Cable", Box(0.5 * x_cab.dx(), 0.5 * x_cab.dy(), 0.5 * x_cab.dz()),
163  lcdd.material(x_cab.materialStr()));
164  // Visualization
165  cableVolume.setVisAttributes(lcdd, x_cab.visStr());
166  // Place Module Box Volumes in layer
167  dd4hep::PlacedVolume placedCable = moduleAssembly.placeVolume(
168  cableVolume,
169  Transform3D(RotationX(x_cab.alpha()),
170  Position(x_cab.x_offset(), x_cab.y_offset(),
171  x_cab.z_offset())));
172  placedCable.addPhysVolID("support", supportNum++);
173  }
174 
175  // Place the modules
176  for (unsigned int iphi = 0; iphi < nphi; ++iphi) {
177  double phi = phi0 + iphi * deltaPhi;
178  std::string moduleName = layerName + _toString((int)iphi, "module%d");
179  Position trans(r * cos(phi), r * sin(phi), 0.);
180  // Create detector element
181  dd4hep::DetElement moduleElement(layerElement, moduleName, iphi);
182  // Place the sensitive inside here
183  unsigned int ccomp = 1;
184  for (auto& sensComp : sensComponents) {
185  dd4hep::DetElement componentElement(moduleElement, "component",
186  ccomp++);
187  componentElement.setPlacement(sensComp);
188  // Add the sensor extension
189  Acts::ActsExtension* sensorExtension = new Acts::ActsExtension();
190  sensorExtension->addType("sensor", "detector");
191  // Set the extension
192  componentElement.addExtension<Acts::ActsExtension>(sensorExtension);
193  }
194 
195  // Place Module Box Volumes in layer
196  dd4hep::PlacedVolume placedModule = layerVolume.placeVolume(
197  moduleAssembly,
198  Transform3D(RotationY(0.5 * M_PI) * RotationX(-phi - phiTilt),
199  trans));
200  placedModule.addPhysVolID("module", iphi + 1);
201 
202  // Assign module dd4hep::DetElement to the placed module volume
203  moduleElement.setPlacement(placedModule);
204  }
205  }
206 
207  // Configure the ACTS extension
208  Acts::ActsExtension* layerExtension = new Acts::ActsExtension();
209  layerExtension->addType("barrel", "layer");
210  // Add the proto layer material
211  for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
212  xml_comp_t x_layer_material = lmat;
213  xmlToProtoSurfaceMaterial(x_layer_material, *layerExtension,
214  "layer_material");
215  }
216  layerElement.addExtension<Acts::ActsExtension>(layerExtension);
217 
218  // Place layer volume
219  dd4hep::PlacedVolume placedLayer = barrelVolume.placeVolume(layerVolume);
220  placedLayer.addPhysVolID("layer", layerNum);
221  // Assign layer dd4hep::DetElement to layer volume
222  layerElement.setPlacement(placedLayer);
223  }
224 
225  // Place Volume
226  dd4hep::Volume motherVolume = lcdd.pickMotherVolume(barrelDetector);
227  dd4hep::PlacedVolume placedBarrel = motherVolume.placeVolume(barrelVolume);
228  // "system" is hard coded in the DD4Hep::VolumeManager
229  placedBarrel.addPhysVolID("system", barrelDetector.id());
230  barrelDetector.setPlacement(placedBarrel);
231 
232  return barrelDetector;
233 }
234 
235 DECLARE_DETELEMENT(DemonstratorBarrel, create_element)