ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IBLSimpleBarrel_geo.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file IBLSimpleBarrel_geo.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017 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 
10 #include "DD4hep/DetFactoryHelper.h"
11 
12 using namespace std;
13 using namespace dd4hep;
14 
20 static Ref_t create_element(Detector& lcdd, xml_h xml, SensitiveDetector sens) {
21  xml_det_t x_det = xml;
22  string det_name = x_det.nameStr();
23  // Make DetElement
24  DetElement cylinderVolume(det_name, x_det.id());
25  // add Extension to Detlement for the RecoGeometry
26  Acts::ActsExtension* barrelExtension = new Acts::ActsExtension();
27  barrelExtension->addType("barrel", "detector");
28  cylinderVolume.addExtension<Acts::ActsExtension>(barrelExtension);
29  // make Volume
30  dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
31  Tube tube_shape(x_det_dim.rmin(), x_det_dim.rmax(), x_det_dim.dz());
32  Volume tube_vol(det_name, tube_shape,
33  lcdd.air()); // air at the moment change later
34  tube_vol.setVisAttributes(lcdd, x_det_dim.visStr());
35  // go trough possible layers
36  size_t layer_num = 0;
37 
38  for (xml_coll_t j(xml, _U(layer)); j; ++j) {
39  xml_comp_t x_layer = j;
40  double l_rmin = x_layer.inner_r();
41  double l_rmax = x_layer.outer_r();
42  // Create Volume for Layer
43  string layer_name = det_name + _toString((int)layer_num, "layer%d");
44  Volume layer_vol(layer_name, Tube(l_rmin, l_rmax, x_layer.z()),
45  lcdd.material(x_layer.materialStr()));
46  DetElement lay_det(cylinderVolume, layer_name, layer_num);
47  // Visualization
48  layer_vol.setVisAttributes(lcdd, x_layer.visStr());
49 
50  // go trough possible modules
51  if (x_layer.hasChild(_U(module))) {
52  xml_comp_t x_module = x_layer.child(_U(module));
53  int repeat = x_module.repeat();
54  double deltaphi = 2. * M_PI / repeat;
55  // slices in z
56  xml_comp_t x_slice = x_layer.child(_U(slice));
57  int zrepeat = x_slice.repeat();
58  double dz = x_slice.z();
59  double dr = x_slice.dr();
60 
61  // Place the Modules in z
62  size_t module_num = 0;
63  // create the module volume and its corresponing component volumes first
64  Volume mod_vol(
65  "module",
66  Box(x_module.length(), x_module.width(), x_module.thickness()),
67  lcdd.material(x_module.materialStr()));
68  // Visualization
69  mod_vol.setVisAttributes(lcdd, x_module.visStr());
70  // the sensitive placed components to be used later to create the
71  // DetElements
72  std::vector<PlacedVolume> sensComponents;
73  int comp_num = 0;
74  // go through module components
75  for (xml_coll_t comp(x_module, _U(module_component)); comp; ++comp) {
76  string component_name = _toString((int)comp_num, "component%d");
77  xml_comp_t x_component = comp;
78  Volume comp_vol(component_name,
79  Box(x_component.length(), x_component.width(),
80  x_component.thickness()),
81  lcdd.material(x_component.materialStr()));
82  comp_vol.setVisAttributes(lcdd, x_component.visStr());
83 
84  // make sensitive components sensitive
85  if (x_component.isSensitive())
86  comp_vol.setSensitiveDetector(sens);
87 
88  // Place Component in Module
89  Position trans(x_component.x(), 0., x_component.z());
90  PlacedVolume placedcomponent = mod_vol.placeVolume(comp_vol, trans);
91  placedcomponent.addPhysVolID("component", comp_num);
92  if (x_component.isSensitive())
93  sensComponents.push_back(placedcomponent);
94  comp_num++;
95  }
96  // add possible trapezoidal shape with hole for cooling pipe
97  if (x_module.hasChild(_U(subtraction))) {
98  xml_comp_t x_sub = x_module.child(_U(subtraction));
99  xml_comp_t x_trd = x_sub.child(_U(trd));
100  xml_comp_t x_tubs = x_sub.child(_U(tubs));
101  string component_name = _toString((int)comp_num, "component%d");
102  // create the two shapes first
103  Trapezoid trap_shape(x_trd.x1(), x_trd.x2(), x_trd.length(),
104  x_trd.length(), x_trd.thickness());
105  Tube tubs_shape(x_tubs.rmin(), x_tubs.rmax(), x_tubs.dz());
106  // create the subtraction
107  Volume sub_vol("subtraction_components",
108  SubtractionSolid(trap_shape, tubs_shape,
109  Transform3D(RotationX(0.5 * M_PI))),
110  lcdd.material(x_sub.materialStr()));
111  sub_vol.setVisAttributes(lcdd, x_sub.visStr());
112  // Place the volume in the module
113  PlacedVolume placedSub = mod_vol.placeVolume(
114  sub_vol, Transform3D(RotationZ(0.5 * M_PI) * RotationY(M_PI),
115  Position(0., 0., x_sub.z())));
116  placedSub.addPhysVolID("component", comp_num);
117  comp_num++;
118  }
119  // add posibble cooling pipe
120  if (x_module.hasChild(_U(tubs))) {
121  xml_comp_t x_tubs = x_module.child(_U(tubs));
122  string component_name = _toString((int)comp_num, "component%d");
123  Volume pipe_vol("CoolingPipe",
124  Tube(x_tubs.rmin(), x_tubs.rmax(), x_tubs.dz()),
125  lcdd.material(x_tubs.materialStr()));
126  pipe_vol.setVisAttributes(lcdd, x_tubs.visStr());
127  // Place the cooling pipe into the module
128  PlacedVolume placedPipe = mod_vol.placeVolume(
129  pipe_vol, Transform3D(RotationX(0.5 * M_PI) * RotationY(0.5 * M_PI),
130  Position(0., 0., x_tubs.z())));
131  placedPipe.addPhysVolID("component", comp_num);
132  comp_num++;
133  }
134  // Now place the module
135  for (int k = -zrepeat; k <= zrepeat; k++) {
136  double r = (l_rmax + l_rmin) * 0.5;
137  if (k % 2 == 0)
138  r += dr;
139  // Place the modules in phi
140  for (int i = 0; i < repeat; ++i) {
141  double phi = deltaphi / dd4hep::rad * i;
142  string module_name =
143  layer_name + _toString((int)module_num, "module%d");
144  Position trans(r * cos(phi), r * sin(phi), k * dz);
145  // create detector element
146  DetElement mod_det(lay_det, module_name, module_num);
147  // Set Sensitive Volumes sensitive
148  if (x_module.isSensitive()) {
149  mod_vol.setSensitiveDetector(sens);
150  }
151  int sens_comp_num = 0;
152  for (auto& sensComp : sensComponents) {
153  DetElement component_det(mod_det, "component", sens_comp_num);
154  component_det.setPlacement(sensComp);
155  sens_comp_num++;
156  }
157  // Place Module Box Volumes in layer
158  PlacedVolume placedmodule = layer_vol.placeVolume(
159  mod_vol,
160  Transform3D(RotationX(-0.5 * M_PI) * RotationZ(-0.5 * M_PI) *
161  RotationX(phi - 0.6 * M_PI),
162  trans));
163  placedmodule.addPhysVolID("module", module_num);
164  // assign module DetElement to the placed module volume
165  mod_det.setPlacement(placedmodule);
166  ++module_num;
167  }
168  }
169  }
170 
171  if (x_layer.hasChild(_U(tubs))) {
172  xml_comp_t x_support = x_layer.child(_U(tubs));
173  double srmin = l_rmin + x_support.offset();
174  double srmax = srmin + x_support.thickness();
175  // create the volume of the support structure
176  Volume support_vol("SupportStructure", Tube(srmin, srmax, x_support.dz()),
177  lcdd.material(x_support.materialStr()));
178  support_vol.setVisAttributes(lcdd, x_support.visStr());
179  // place the support structure
180  PlacedVolume placedSupport = layer_vol.placeVolume(support_vol);
181  placedSupport.addPhysVolID("support", 1);
182  }
183 
184  // set granularity of layer material mapping and where material should be
185  // mapped hand over modules to ACTS
186 
187  Acts::ActsExtension* layerExtension = new Acts::ActsExtension();
188  layerExtension->addType("sensitive cylinder", "layer");
189  lay_det.addExtension<Acts::ActsExtension>(layerExtension);
190  // Place layer volume
191  PlacedVolume placedLayer = tube_vol.placeVolume(layer_vol);
192  placedLayer.addPhysVolID("layer", layer_num);
193  // Assign layer DetElement to layer volume
194  lay_det.setPlacement(placedLayer);
195  ++layer_num;
196  }
197  // Place Volume
198  Volume mother_vol = lcdd.pickMotherVolume(cylinderVolume);
199  PlacedVolume placedTube = mother_vol.placeVolume(tube_vol);
200  placedTube.addPhysVolID("system", cylinderVolume.id());
201  cylinderVolume.setPlacement(placedTube);
202 
203  return cylinderVolume;
204 }
205 
206 DECLARE_DETELEMENT(ACTS_IBLSimpleBarrel, create_element)