11 #include "DD4hep/DetFactoryHelper.h"
16 using namespace dd4hep;
19 Assembly& staveAssembly,
double staveHlength,
21 unsigned int nModules = x_stave.nmodules();
24 if (x_stave.hasChild(_U(subtraction)) and x_stave.hasChild(_U(tube))) {
25 xml_comp_t x_sub = x_stave.child(_U(subtraction));
26 xml_comp_t x_trd = x_sub.child(_U(trd));
27 xml_comp_t x_tubs = x_sub.child(_U(tubs));
28 xml_comp_t x_pipe = x_stave.child(_U(tube));
31 Trapezoid foamShape(x_trd.x1(), x_trd.x2(), staveHlength + x_trd.dz(),
32 staveHlength + x_trd.dz(), x_trd.thickness());
34 Tube foamCutout(x_tubs.rmin(), x_tubs.rmax(), staveHlength + x_tubs.dz());
37 Volume foamVolume(
"CarbonFoam",
38 SubtractionSolid(foamShape, foamCutout,
40 oddd.material(x_sub.materialStr()));
41 foamVolume.setVisAttributes(oddd, x_sub.visStr());
43 staveAssembly.placeVolume(
45 Position(x_sub.x_offset(), x_sub.y_offset(), x_sub.z_offset()));
47 Tube coolingPipe(x_pipe.rmin(), x_pipe.rmax(), staveHlength + x_pipe.dz());
49 Volume pipeVolume(
"CoolingPipe", coolingPipe,
50 oddd.material(x_pipe.materialStr()));
51 pipeVolume.setVisAttributes(oddd, x_pipe.visStr());
54 staveAssembly.placeVolume(
56 Position(x_pipe.x_offset(), x_pipe.y_offset(),
59 xml_comp_t x_cable = x_stave.child(_U(eltube));
61 for (
unsigned int modCable = 0; modCable < 0.5 * nModules; ++modCable) {
62 double cableLength = staveHlength - modCable * ylength;
64 for (
int side = -1; side < 2; side += 2) {
65 Tube cable(x_cable.rmin(), x_cable.rmax(), 0.5 * cableLength);
67 Volume cableVolume(
"Cable", cable,
68 oddd.material(x_cable.materialStr()));
69 cableVolume.setVisAttributes(oddd, x_cable.visStr());
72 staveAssembly.placeVolume(
75 RotationX(0.5 *
M_PI),
77 x_cable.x_offset() + 2.05 * modCable * x_cable.rmax(),
78 side * (staveHlength - 0.5 * cableLength + x_cable.dz()),
79 x_cable.z_offset())));
86 xml_det_t x_det = xml;
87 string detName = x_det.nameStr();
90 DetElement barrelDetector(detName, x_det.id());
94 barrelExtension->addType(
"barrel",
"detector");
96 for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) {
97 xml_comp_t x_boundary_material = bmat;
104 dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
105 string barrelShapeName = x_det_dim.nameStr();
108 Tube barrelShape(x_det_dim.rmin(), x_det_dim.rmax(), x_det_dim.dz());
109 Volume barrelVolume(detName, barrelShape, oddd.air());
110 barrelVolume.setVisAttributes(oddd, x_det.visStr());
113 xml_comp_t x_stave = x_det.child(_U(stave));
114 Assembly staveAssembly(
"stave");
116 staveAssembly.setVisAttributes(oddd, x_stave.visStr());
118 DetElement staveElementTemplate(
"StaveElementTemplate", 0);
121 xml_comp_t x_module = x_det.child(_U(module));
127 double gap = x_stave.gap();
128 unsigned int nModules = x_stave.nmodules();
129 double ystep = ylength +
gap;
130 double ymin = (nModules * 0.5 - 0.5) * ylength;
131 double staveHlength = ymin + 0.5 * ylength;
134 for (
unsigned int moduleNum = 0; moduleNum < nModules; ++moduleNum) {
136 PlacedVolume placedModule = staveAssembly.placeVolume(
137 module.first, Position(0., -ymin + moduleNum * ystep, 0.));
138 placedModule.addPhysVolID(
"module", moduleNum);
140 string moduleName = _toString((
int)moduleNum,
"module%d");
142 auto moduleElement = module.second.clone(moduleName, moduleNum);
143 moduleElement.setPlacement(placedModule);
145 staveElementTemplate.add(moduleElement);
151 std::vector<double> layerR;
155 for (xml_coll_t lay(xml, _U(
layer)); lay; ++lay, ++layerNum) {
156 xml_comp_t x_layer = lay;
162 Tube(x_layer.rmin(), x_layer.rmax(), staveHlength + x_layer.outer_z()),
165 layerVolume.setVisAttributes(oddd, x_layer.visStr());
168 DetElement layerElement(barrelDetector, layerName, layerNum);
171 unsigned int nStaves = x_layer.nphi();
172 double phiStep = 2. *
M_PI / nStaves;
173 double phiTilt = x_layer.phi_tilt();
174 double phi0 = x_layer.phi0();
175 double r = x_layer.r();
179 for (
unsigned int staveNum = 0; staveNum < nStaves; ++staveNum) {
180 string staveName = _toString((
int)staveNum,
"stave%d");
182 double phi = phi0 + staveNum * phiStep;
183 double x = r * cos(phi);
184 double y = r * sin(phi);
186 PlacedVolume placedStave = layerVolume.placeVolume(
189 RotationY(phi + phiTilt),
190 Position(x, y, 0.)));
191 placedStave.addPhysVolID(
"stave", staveNum);
194 DetElement staveElement = staveElementTemplate.clone(staveName, staveNum);
195 staveElement.setPlacement(placedStave);
197 layerElement.add(staveElement);
211 for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
212 xml_comp_t x_layer_material = lmat;
216 layerExtension->
addType(
"sensitive cylinder",
"layer");
219 PlacedVolume placedLayer = barrelVolume.placeVolume(layerVolume);
220 placedLayer.addPhysVolID(
"layer", layerNum);
223 layerElement.setPlacement(placedLayer);
229 if (x_det.hasChild(_Unicode(services))) {
231 xml_comp_t x_services = x_det.child(_Unicode(services));
232 if (x_services.hasChild(_Unicode(cable_routing))) {
233 xml_comp_t x_cable_routing = x_services.child(_Unicode(cable_routing));
236 if (x_services.hasChild(_Unicode(cooling_routing))) {
237 xml_comp_t x_cooling_routing =
238 x_services.child(_Unicode(cooling_routing));
244 Volume motherVolume = oddd.pickMotherVolume(barrelDetector);
245 Position translation(0., 0., x_det_dim.z());
246 PlacedVolume placedBarrel =
247 motherVolume.placeVolume(barrelVolume, translation);
249 placedBarrel.addPhysVolID(
"system", barrelDetector.id());
250 barrelDetector.setPlacement(placedBarrel);
253 return barrelDetector;