12 #include "DD4hep/DetFactoryHelper.h"
17 using namespace dd4hep;
20 Assembly& staveAssembly,
double staveHlength,
22 unsigned int nModules = x_stave.nmodules();
25 if (x_stave.hasChild(_U(subtraction)) and x_stave.hasChild(_U(tube))) {
26 xml_comp_t x_sub = x_stave.child(_U(subtraction));
27 xml_comp_t x_trd = x_sub.child(_U(trd));
28 xml_comp_t x_tubs = x_sub.child(_U(tubs));
29 xml_comp_t x_pipe = x_stave.child(_U(tube));
32 Trapezoid foamShape(x_trd.x1(), x_trd.x2(), staveHlength + x_trd.dz(),
33 staveHlength + x_trd.dz(), x_trd.thickness());
35 Tube foamCutout(x_tubs.rmin(), x_tubs.rmax(), staveHlength + x_tubs.dz());
38 Volume foamVolume(
"CarbonFoam",
39 SubtractionSolid(foamShape, foamCutout,
41 oddd.material(x_sub.materialStr()));
42 foamVolume.setVisAttributes(oddd, x_sub.visStr());
44 staveAssembly.placeVolume(
46 Position(x_sub.x_offset(), x_sub.y_offset(), x_sub.z_offset()));
48 Tube coolingPipe(x_pipe.rmin(), x_pipe.rmax(), staveHlength + x_pipe.dz());
50 Volume pipeVolume(
"CoolingPipe", coolingPipe,
51 oddd.material(x_pipe.materialStr()));
52 pipeVolume.setVisAttributes(oddd, x_pipe.visStr());
55 staveAssembly.placeVolume(
57 Position(x_pipe.x_offset(), x_pipe.y_offset(),
60 xml_comp_t x_cable = x_stave.child(_U(eltube));
62 for (
unsigned int modCable = 0; modCable < 0.5 * nModules; ++modCable) {
63 double cableLength = staveHlength - modCable * ylength;
65 for (
int side = -1; side < 2; side += 2) {
66 Tube cable(x_cable.rmin(), x_cable.rmax(), 0.5 * cableLength);
68 Volume cableVolume(
"Cable", cable,
69 oddd.material(x_cable.materialStr()));
70 cableVolume.setVisAttributes(oddd, x_cable.visStr());
73 staveAssembly.placeVolume(
76 RotationX(0.5 *
M_PI),
78 x_cable.x_offset() + 2.05 * modCable * x_cable.rmax(),
79 side * (staveHlength - 0.5 * cableLength + x_cable.dz()),
80 x_cable.z_offset())));
86 static Ref_t
create_element(Detector& oddd, xml_h xml, SensitiveDetector sens) {
87 xml_det_t x_det = xml;
88 string detName = x_det.nameStr();
91 DetElement barrelDetector(detName, x_det.id());
95 barrelExtension->addType(
"barrel",
"detector");
97 for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) {
98 xml_comp_t x_boundary_material = bmat;
100 "boundary_material");
105 dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
106 string barrelShapeName = x_det_dim.nameStr();
109 Tube barrelShape(x_det_dim.rmin(), x_det_dim.rmax(), x_det_dim.dz());
110 Volume barrelVolume(detName, barrelShape, oddd.air());
111 barrelVolume.setVisAttributes(oddd, x_det.visStr());
114 xml_comp_t x_stave = x_det.child(_U(stave));
115 Assembly staveAssembly(
"stave");
117 staveAssembly.setVisAttributes(oddd, x_stave.visStr());
119 DetElement staveElementTemplate(
"StaveElementTemplate", 0);
122 xml_comp_t x_module = x_det.child(_U(module));
128 double gap = x_stave.gap();
129 unsigned int nModules = x_stave.nmodules();
130 double ystep = ylength +
gap;
131 double ymin = (nModules * 0.5 - 0.5) * ylength;
132 double staveHlength = ymin + 0.5 * ylength;
135 for (
unsigned int moduleNum = 0; moduleNum < nModules; ++moduleNum) {
137 PlacedVolume placedModule = staveAssembly.placeVolume(
138 module.first, Position(0., -ymin + moduleNum * ystep, 0.));
139 placedModule.addPhysVolID(
"module", moduleNum);
141 string moduleName = _toString((
int)moduleNum,
"module%d");
143 auto moduleElement = module.second.clone(moduleName, moduleNum);
144 moduleElement.setPlacement(placedModule);
146 staveElementTemplate.add(moduleElement);
152 std::vector<double> layerR;
156 for (xml_coll_t lay(xml, _U(
layer)); lay; ++lay, ++layerNum) {
157 xml_comp_t x_layer = lay;
163 Tube(x_layer.rmin(), x_layer.rmax(), staveHlength + x_layer.outer_z()),
166 layerVolume.setVisAttributes(oddd, x_layer.visStr());
169 DetElement layerElement(barrelDetector, layerName, layerNum);
172 unsigned int nStaves = x_layer.nphi();
173 double phiStep = 2. *
M_PI / nStaves;
174 double phiTilt = x_layer.phi_tilt();
175 double phi0 = x_layer.phi0();
176 double r = x_layer.r();
180 for (
unsigned int staveNum = 0; staveNum < nStaves; ++staveNum) {
181 string staveName = _toString((
int)staveNum,
"stave%d");
183 double phi = phi0 + staveNum * phiStep;
184 double x = r *
cos(phi);
185 double y = r * sin(phi);
187 PlacedVolume placedStave = layerVolume.placeVolume(
190 RotationY(phi + phiTilt),
191 Position(x, y, 0.)));
192 placedStave.addPhysVolID(
"stave", staveNum);
195 DetElement staveElement = staveElementTemplate.clone(staveName, staveNum);
196 staveElement.setPlacement(placedStave);
198 layerElement.add(staveElement);
212 for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
213 xml_comp_t x_layer_material = lmat;
217 layerExtension->
addType(
"sensitive cylinder",
"layer");
220 PlacedVolume placedLayer = barrelVolume.placeVolume(layerVolume);
221 placedLayer.addPhysVolID(
"layer", layerNum);
224 layerElement.setPlacement(placedLayer);
230 if (x_det.hasChild(_Unicode(services))) {
232 xml_comp_t x_services = x_det.child(_Unicode(services));
233 if (x_services.hasChild(_Unicode(cable_routing))) {
234 xml_comp_t x_cable_routing = x_services.child(_Unicode(cable_routing));
237 if (x_services.hasChild(_Unicode(cooling_routing))) {
238 xml_comp_t x_cooling_routing =
239 x_services.child(_Unicode(cooling_routing));
245 Volume motherVolume = oddd.pickMotherVolume(barrelDetector);
246 Position translation(0., 0., x_det_dim.z());
247 PlacedVolume placedBarrel =
248 motherVolume.placeVolume(barrelVolume, translation);
250 placedBarrel.addPhysVolID(
"system", barrelDetector.id());
251 barrelDetector.setPlacement(placedBarrel);
254 return barrelDetector;