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