EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ODDModuleHelper.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ODDModuleHelper.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 "ODDModuleHelper.hpp"
10 
12 
13 using namespace std;
14 using namespace dd4hep;
15 
16 std::pair<Assembly, DetElement> ODDModuleHelper::assembleTrapezoidalModule(
17  Detector& oddd, SensitiveDetector& sens, const xml_comp_t& x_module) {
18  // The Module envelope volume
19  Assembly moduleAssembly("module");
20  // Visualization
21  moduleAssembly.setVisAttributes(oddd, x_module.visStr());
22 
23  // The module detector element
24  DetElement moduleElement("ModuleElementTemplate", 0);
25 
26  // Place the components inside the module
27  unsigned int compNum = 0;
28  unsigned int sensorNum = 0;
29 
30  for (xml_coll_t comp(x_module, _U(module_component)); comp;
31  ++comp, ++compNum) {
32  xml_comp_t x_comp = comp;
33 
34  // create the component volume
35  string compName =
36  _toString((int)compNum, "component%d") + x_comp.materialStr();
37 
38  Trapezoid trapShape(x_comp.x1(), x_comp.x2(), 0.5 * x_comp.thickness(),
39  0.5 * x_comp.thickness(), x_comp.length());
40 
41  Volume componentVolume(compName, trapShape,
42  oddd.material(x_comp.materialStr()));
43  componentVolume.setVisAttributes(oddd, x_comp.visStr());
44 
45  // overwrite if you have a subtraction
46  if (x_comp.hasChild(_U(subtraction))) {
47  xml_comp_t x_sub = x_comp.child(_U(subtraction));
48  Tube tubeCutout(x_sub.rmin(), x_sub.rmax(), 1.1 * x_comp.length());
49 
50  // Create the subtraction
51  componentVolume = Volume(
52  compName,
53  SubtractionSolid(
54  trapShape, tubeCutout,
55  Position(x_sub.x_offset(), x_sub.y_offset(), x_sub.z_offset())),
56  oddd.material(x_comp.materialStr()));
57 
58  // place a fitting pipe if available
59  if (x_comp.hasChild(_U(tube))) {
60  xml_comp_t x_pipe = x_comp.child(_U(tube));
61  Tube coolingPipe(x_pipe.rmin(), x_pipe.rmax(), x_comp.length());
62  // Create the subtraction
63  Volume pipeVolume("CoolingPipe", coolingPipe,
64  oddd.material(x_pipe.materialStr()));
65  pipeVolume.setVisAttributes(oddd, x_pipe.visStr());
66 
67  componentVolume.placeVolume(
68  pipeVolume,
69  Position(x_pipe.x_offset(), x_pipe.y_offset(), x_pipe.z_offset()));
70  }
71  }
72 
73  // Place the component
74  double stereoAlpha = x_comp.alpha();
75  PlacedVolume placedComponent = moduleAssembly.placeVolume(
76  componentVolume,
78  RotationY(stereoAlpha),
79  Position(x_comp.x_offset(), x_comp.y_offset(), x_comp.z_offset())));
80 
81  // Deal with the sensitive sensor
82  if (x_comp.isSensitive()) {
83  componentVolume.setSensitiveDetector(sens);
84  placedComponent.addPhysVolID("sensor", sensorNum++);
85 
86  // Create the sensor element and place it
87  string sensorName = _toString((int)sensorNum, "sensor%d");
88  DetElement sensorElement(moduleElement, sensorName, sensorNum);
89  sensorElement.setPlacement(placedComponent);
90 
91  // Add the sensor extension
92  Acts::ActsExtension* sensorExtension = new Acts::ActsExtension();
93  sensorExtension->addType("sensor", "detector");
94  sensorExtension->addType("axes", "definitions", "XZY");
95  // Set the extension
96  sensorElement.addExtension<Acts::ActsExtension>(sensorExtension);
97  }
98  }
99 
100  // return the module assembly
101  return std::pair<Assembly, DetElement>(moduleAssembly, moduleElement);
102 }
103 
104 std::pair<Assembly, DetElement> ODDModuleHelper::assembleRectangularModule(
105  Detector& oddd, SensitiveDetector& sens, const xml_comp_t& x_module,
106  double& ylength) {
107  // The Module envelope volume
108  Assembly moduleAssembly("module");
109  // Visualization
110  moduleAssembly.setVisAttributes(oddd, x_module.visStr());
111 
112  // The module detector element
113  DetElement moduleElement("ModuleElementTemplate", 0);
114 
115  // Place the components inside the module
116  unsigned int compNum = 0;
117  unsigned int sensorNum = 0;
118 
119  for (xml_coll_t comp(x_module, _U(module_component)); comp;
120  ++comp, ++compNum) {
121  xml_comp_t x_comp = comp;
122 
123  // Component volume
124  string componentName = _toString((int)compNum, "component%d");
125  Box boxShape(0.5 * x_comp.dx(), 0.5 * x_comp.dy(), 0.5 * x_comp.dz());
126  // Standard component volume without cutout
127  Volume componentVolume(componentName, boxShape,
128  oddd.material(x_comp.materialStr()));
129 
130  // overwrite if you have a subtraction
131  if (x_comp.hasChild(_U(subtraction))) {
132  xml_comp_t x_sub = x_comp.child(_U(subtraction));
133  Tube tubeCutout(x_sub.rmin(), x_sub.rmax(), x_comp.dy());
134 
135  // Create the subtraction
136  componentVolume =
137  Volume(componentName,
138  SubtractionSolid(
139  boxShape, tubeCutout,
140  Transform3D(RotationX(0.5 * M_PI),
141  Position(x_sub.x_offset(), x_sub.y_offset(),
142  x_sub.z_offset()))),
143  oddd.material(x_comp.materialStr()));
144 
145  // place a fitting pipe if available
146  if (x_comp.hasChild(_U(tube))) {
147  xml_comp_t x_pipe = x_comp.child(_U(tube));
148  Tube coolingPipe(x_pipe.rmin(), x_pipe.rmax(), 0.5 * x_comp.dy());
149  // Create the subtraction
150  Volume pipeVolume("CoolingPipe", coolingPipe,
151  oddd.material(x_pipe.materialStr()));
152  pipeVolume.setVisAttributes(oddd, x_pipe.visStr());
153 
154  componentVolume.placeVolume(
155  pipeVolume,
156  Transform3D(RotationX(0.5 * M_PI),
157  Position(x_pipe.x_offset(), x_pipe.y_offset(),
158  x_pipe.z_offset())));
159  }
160  }
161  componentVolume.setVisAttributes(oddd, x_comp.visStr());
162 
163  // Calculate the module dimension
164  double cylength =
165  2. * abs(std::copysign(0.5 * x_comp.dy(), x_comp.y_offset()) +
166  x_comp.y_offset());
167  ylength = cylength > ylength ? cylength : ylength;
168 
169  // Visualization
170  componentVolume.setVisAttributes(oddd, x_comp.visStr());
171  // Place Module Box Volumes in layer
172  double stereoAlpha = x_comp.alpha();
173  PlacedVolume placedComponent = moduleAssembly.placeVolume(
174  componentVolume,
175  Transform3D(
176  RotationZ(stereoAlpha),
177  Position(x_comp.x_offset(), x_comp.y_offset(), x_comp.z_offset())));
178 
179  // Deal with the sensitive sensor
180  if (x_comp.isSensitive()) {
181  componentVolume.setSensitiveDetector(sens);
182  placedComponent.addPhysVolID("sensor", sensorNum++);
183 
184  // Create the sensor element and place it
185  string sensorName = _toString((int)sensorNum, "sensor%d");
186  DetElement sensorElement(moduleElement, sensorName, sensorNum);
187  sensorElement.setPlacement(placedComponent);
188 
189  // Add the sensor extension
190  Acts::ActsExtension* sensorExtension = new Acts::ActsExtension();
191  sensorExtension->addType("sensor", "detector");
192  sensorExtension->addType("axes", "definitions", "XYZ");
193  // Set the extension
194  sensorElement.addExtension<Acts::ActsExtension>(sensorExtension);
195  }
196  }
197 
198  // return the module assembly
199  return std::pair<Assembly, DetElement>(moduleAssembly, moduleElement);
200 }