ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TKLayoutEndcap_geo.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TKLayoutEndcap_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 
21 static Ref_t create_element(Detector& lcdd, xml_h xml, SensitiveDetector sens) {
22  xml_det_t x_det = xml;
23  string det_name = x_det.nameStr();
24  // Make DetElement
25  DetElement cylinderVolume(det_name, x_det.id());
26  // add Extension to Detlement for the RecoGeometry
27  Acts::ActsExtension* detvolume = new Acts::ActsExtension();
28  detvolume->addType("endcap", "detector");
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  int module_num_num = 0;
38  size_t layer_num = 0;
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  // go trough possible modules
52  if (x_layer.hasChild(_U(module))) {
53  for (xml_coll_t i(x_layer, _U(module)); i; i++) {
54  xml_comp_t x_module = i;
55  int repeat = x_module.repeat();
56  double deltaphi = 2. * M_PI / repeat;
57  double radius = x_module.radius();
58  // Create the module volume
59  Volume mod_vol(
60  "module",
61  Trapezoid(x_module.x1(), x_module.x2(), x_module.thickness(),
62  x_module.thickness(), x_module.length()),
63  lcdd.material(x_module.materialStr()));
64  size_t module_num = 0;
65  // Place the Modules
66  for (int k = 0; k < repeat; k++) {
67  double slicedz = x_module.dz();
68  if (k % 2 == 0)
69  slicedz -= 10. * x_module.thickness();
70  string zname = _toString((int)k, "z%d");
71  // Visualization
72  mod_vol.setVisAttributes(lcdd, x_module.visStr());
73  double phi = deltaphi / dd4hep::rad * k;
74  string module_name =
75  zname + _toString((int)(repeat * module_num_num + module_num),
76  "module%d");
77  Position trans(radius * cos(phi), radius * sin(phi), slicedz);
78  // Create the module DetElement
79  DetElement mod_det(lay_det, module_name,
80  repeat * module_num_num + module_num);
81  // Create and attach the extension for DD4Hep/Acts conversion
82  Acts::ActsExtension* moduleExtension = new Acts::ActsExtension();
83  mod_det.addExtension<Acts::ActsExtension>(moduleExtension);
84  // Set Sensitive Volmes sensitive
85  if (x_module.isSensitive()) {
86  mod_vol.setSensitiveDetector(sens);
87  }
88  // Place Module Box Volumes in layer
89  PlacedVolume placedmodule = layer_vol.placeVolume(
90  mod_vol,
91  Transform3D(RotationX(0.5 * M_PI) * RotationY(phi + 0.5 * M_PI),
92  trans));
93  placedmodule.addPhysVolID("module",
94  repeat * module_num_num + module_num);
95  // assign module DetElement to the placed module volume
96  mod_det.setPlacement(placedmodule);
97  ++module_num;
98  }
99  ++module_num_num;
100  }
101  }
102  // set granularity of layer material mapping and where material should be
103  // mapped
104  // hand over modules to ACTS
105  Acts::ActsExtension* detlayer = new Acts::ActsExtension();
106  detlayer->addType("axes", "definitions", "XZy");
107  detlayer->addType("sensitive disk", "layer");
108  lay_det.addExtension<Acts::ActsExtension>(detlayer);
109  double layerZpos = x_layer.z();
110  // Placed Layer Volume
111  Position layer_pos(0., 0., layerZpos);
112  PlacedVolume placedLayer = tube_vol.placeVolume(layer_vol, layer_pos);
113  placedLayer.addPhysVolID("layer", layer_num);
114  lay_det.setPlacement(placedLayer);
115  ++layer_num;
116  }
117 
118  // if it is the negative endcap the normal vector needs to point into the
119  // Place Volume
120  Position endcap_translation(0., 0., x_det_dim.z());
121  Rotation3D rotation(1., 0., 0., 0., 1., 0., 0., 0., 1.);
122  if (x_det_dim.z() < 0.) {
123  rotation.SetComponents(1., 0., 0., 0., 1., 0., 0., 0., -1.);
124  }
125  Transform3D endcap_transform(rotation, endcap_translation);
126  Volume mother_vol = lcdd.pickMotherVolume(cylinderVolume);
127  PlacedVolume placedTube = mother_vol.placeVolume(tube_vol, endcap_transform);
128  placedTube.addPhysVolID("system", cylinderVolume.id());
129  cylinderVolume.setPlacement(placedTube);
130 
131  return cylinderVolume;
132 }
133 
134 DECLARE_DETELEMENT(ACTS_TKLayoutEndcap, create_element)