ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Endcap_geo.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Endcap_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 
11 #include "DD4hep/DetFactoryHelper.h"
12 
13 using namespace std;
14 using namespace dd4hep;
15 
22 static Ref_t create_element(Detector& lcdd, xml_h xml, SensitiveDetector sens) {
23  xml_det_t x_det = xml;
24  string det_name = x_det.nameStr();
25  // Make DetElement
26  DetElement cylinderVolume(det_name, x_det.id());
27  // add Extension to Detlement for the RecoGeometry
28  Acts::ActsExtension* detvolume = new Acts::ActsExtension();
29  cylinderVolume.addExtension<Acts::ActsExtension>(detvolume);
30  // make Volume
31  dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
32  Tube tube_shape(x_det_dim.rmin(), x_det_dim.rmax(), x_det_dim.dz());
33  Volume tube_vol(det_name, tube_shape,
34  lcdd.air()); // air at the moment change later
35  tube_vol.setVisAttributes(lcdd, x_det_dim.visStr());
36  // go trough possible layers
37  size_t layer_num = 0;
38  // if it is the positive or negative endcap
39  for (xml_coll_t j(xml, _U(layer)); j; ++j) {
40  xml_comp_t x_layer = j;
41  double l_rmin = x_layer.inner_r();
42  double l_rmax = x_layer.outer_r();
43  double l_length = x_layer.dz();
44  // Create Volume and DetElement for Layer
45  string layer_name = det_name + _toString((int)layer_num, "layer%d");
46  Volume layer_vol(layer_name, Tube(l_rmin, l_rmax, l_length),
47  lcdd.material(x_layer.materialStr()));
48  DetElement lay_det(cylinderVolume, layer_name, layer_num);
49  // Visualization
50  layer_vol.setVisAttributes(lcdd, x_layer.visStr());
51  int module_num_num = 0;
52  // go trough possible modules
53  if (x_layer.hasChild(_U(module))) {
54  for (xml_coll_t i(x_layer, _U(module)); i; i++) {
55  xml_comp_t x_module = i;
56  int repeat = x_module.repeat();
57  double deltaphi = 2. * M_PI / repeat;
58  double radius = x_module.radius();
59  double slicedz = x_module.dz();
60 
61  size_t module_num = 0;
62 
63  // Create the module volume
64  Volume mod_vol(
65  "module",
66  Trapezoid(x_module.x1(), x_module.x2(), x_module.thickness(),
67  x_module.thickness(), x_module.length()),
68  lcdd.material(x_module.materialStr()));
69  mod_vol.setVisAttributes(lcdd, x_module.visStr());
70 
71  // create the Acts::DigitizationModule (needed to do geometric
72  // digitization) for all modules which have digitization module
73  auto digiModule =
75  x_module.x1(), x_module.x2(), x_module.length(),
76  x_module.thickness(), sens.readout().segmentation());
77 
78  // the sensitive placed components to be used later to create the
79  // DetElements
80  std::vector<PlacedVolume> sensComponents;
81  // the possible digitization module
82  std::shared_ptr<const Acts::DigitizationModule> digiComponent = nullptr;
83  // go through possible components
84  int comp_num = 0;
85  for (xml_coll_t comp(x_module, _U(module_component)); comp; comp++) {
86  xml_comp_t x_comp = comp;
87  // create the component volume
88  string comp_name =
89  _toString((int)comp_num, "component%d") + x_comp.materialStr();
90  Volume comp_vol(
91  comp_name,
92  Trapezoid(x_comp.x1(), x_comp.x2(), x_comp.thickness(),
93  x_comp.thickness(), x_comp.length()),
94  lcdd.material(x_comp.materialStr()));
95  comp_vol.setVisAttributes(lcdd, x_comp.visStr());
96 
97  // create the Acts::DigitizationModule (needed to do geometric
98  // digitization) for all modules which have the sdigitization
99  // compoenent
100  digiComponent =
102  x_comp.x1(), x_comp.x2(), x_comp.length(), x_comp.thickness(),
103  sens.readout().segmentation());
104 
105  // Set Sensitive Volumes sensitive
106  if (x_comp.isSensitive())
107  comp_vol.setSensitiveDetector(sens);
108 
109  // place component in module
110  Position translation(0., x_comp.z(), 0.);
111  PlacedVolume placed_comp = mod_vol.placeVolume(comp_vol, translation);
112  if (x_comp.isSensitive())
113  sensComponents.push_back(placed_comp);
114  placed_comp.addPhysVolID("component", module_num);
115  ++comp_num;
116  }
117 
118  // Place the Modules
119  for (int k = 0; k < repeat; k++) {
120  string zname = _toString((int)k, "z%d");
121 
122  double phi = deltaphi / dd4hep::rad * k;
123  string module_name =
124  zname + _toString((int)(repeat * module_num_num + module_num),
125  "module%d");
126  Position trans(radius * cos(phi), radius * sin(phi), slicedz);
127  // Create the module DetElement
128  DetElement mod_det(lay_det, module_name,
129  repeat * module_num_num + module_num);
130  // Set Sensitive Volumes sensitive
131  if (x_module.isSensitive()) {
132  mod_vol.setSensitiveDetector(sens);
133  // Create and attach the extension for DD4Hep/Acts conversion
134  Acts::ActsExtension* moduleExtension = new Acts::ActsExtension();
135  mod_det.addExtension<Acts::ActsExtension>(moduleExtension);
136  }
137 
138  int scomp_num = 0;
139  for (auto& sensComp : sensComponents) {
140  // Create DetElement
141  DetElement comp_det(mod_det, "component", scomp_num);
142  // Create and attach the extension
143  Acts::ActsExtension* moduleExtension = new Acts::ActsExtension();
144  comp_det.addExtension<Acts::ActsExtension>(moduleExtension);
145  comp_det.setPlacement(sensComp);
146  scomp_num++;
147  }
148  Rotation3D rotation1(1., 0., 0., 0., 1., 0., 0., 0., 1.);
149  // Place Module Box Volumes in layer
150  Transform3D transf1(RotationX(0.5 * M_PI) *
151  RotationY(phi + 0.5 * M_PI) *
152  RotationZ(0.1 * M_PI),
153  trans);
154  PlacedVolume placedmodule =
155  layer_vol.placeVolume(mod_vol, rotation1 * transf1);
156  placedmodule.addPhysVolID("module",
157  repeat * module_num_num + module_num);
158  // assign module DetElement to the placed module volume
159  mod_det.setPlacement(placedmodule);
160  ++module_num;
161  }
162  ++module_num_num;
163  }
164  }
165 
166  // Place the layer with appropriate Acts::Extension
167  // Configure the ACTS extension
168  Acts::ActsExtension* layerExtension = new Acts::ActsExtension();
169  layerExtension->addType("sensitive disk", "layer");
170  lay_det.addExtension<Acts::ActsExtension>(layerExtension);
171 
172  // Placed Layer Volume
173  Position layer_pos(0., 0., x_layer.z());
174  PlacedVolume placedLayer = tube_vol.placeVolume(layer_vol, layer_pos);
175  placedLayer.addPhysVolID("layer", layer_num);
176  lay_det.setPlacement(placedLayer);
177  ++layer_num;
178  }
179  // Place Volume
180  // if it is the negative endcap the normal vector needs to point into the
181  // outside
182  Position endcap_translation(0., 0., x_det_dim.z());
183  Rotation3D rotation(1., 0., 0., 0., 1., 0., 0., 0., 1.);
184  if (x_det_dim.z() < 0.) {
185  rotation.SetComponents(1., 0., 0., 0., -1., 0., 0., 0., -1.);
186  }
187  Transform3D endcap_transform(rotation, endcap_translation);
188  Volume mother_vol = lcdd.pickMotherVolume(cylinderVolume);
189  PlacedVolume placedTube = mother_vol.placeVolume(tube_vol, endcap_transform);
190  placedTube.addPhysVolID("system", cylinderVolume.id());
191  cylinderVolume.setPlacement(placedTube);
192 
193  return cylinderVolume;
194 }
195 
196 DECLARE_DETELEMENT(ACTS_Endcap, create_element)