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