12 #include "DD4hep/DetFactoryHelper.h"
17 using namespace dd4hep;
19 static Ref_t
create_element(Detector& oddd, xml_h xml, SensitiveDetector sens) {
20 xml_det_t x_det = xml;
21 string detName = x_det.nameStr();
24 DetElement barrelDetector(detName, x_det.id());
28 barrelExtension->addType(
"barrel",
"detector");
30 for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) {
31 xml_comp_t x_boundary_material = bmat;
38 dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
39 string barrelShapeName = x_det_dim.nameStr();
41 Tube barrelShape(x_det_dim.rmin(), x_det_dim.rmax(), x_det_dim.dz());
42 Volume barrelVolume(detName, barrelShape, oddd.air());
43 barrelVolume.setVisAttributes(oddd, x_det.visStr());
46 xml_comp_t x_stave = x_det.child(_U(stave));
47 Assembly staveAssembly(
"stave");
49 staveAssembly.setVisAttributes(oddd, x_stave.visStr());
51 DetElement staveElementTemplate(
"StaveElementTemplate", 0);
54 xml_comp_t x_module = x_det.child(_U(module));
60 double gap = x_stave.gap();
61 unsigned int nModules = x_stave.nmodules();
62 double ystep = length +
gap;
64 double staveHlength = ymin + 0.5 *
length;
67 for (
unsigned int moduleNum = 0; moduleNum < nModules; ++moduleNum) {
68 double positionY = -ymin + moduleNum * ystep;
70 if (x_stave.hasChild(_U(eltube))) {
72 xml_comp_t x_cable = x_stave.child(_U(eltube));
74 double rMin = x_cable.rmin();
75 double rMax = x_cable.rmax();
79 double rStep = (rMax - rMin) / (0.5 * nModules);
80 double rCable = rMin +
abs(moduleNum - 0.5 * nModules) * rStep;
82 Tube cable(0., rCable, 0.495 * ystep);
84 Volume cableVolume(
"Cable", cable, oddd.material(x_cable.materialStr()));
85 cableVolume.setVisAttributes(oddd, x_cable.visStr());
88 staveAssembly.placeVolume(
90 Position(x_cable.x_offset(), positionY,
91 x_cable.z_offset())));
95 PlacedVolume placedModule =
96 staveAssembly.placeVolume(module.first, Position(0., positionY, 0.));
97 placedModule.addPhysVolID(
"module", moduleNum);
99 string moduleName = _toString((
int)moduleNum,
"module%d");
101 auto moduleElement = module.second.clone(moduleName, moduleNum);
102 moduleElement.setPlacement(placedModule);
104 staveElementTemplate.add(moduleElement);
108 std::vector<double> layerR;
112 for (xml_coll_t lay(xml, _U(
layer)); lay; ++lay, ++layerNum) {
113 xml_comp_t x_layer = lay;
119 Tube(x_layer.rmin(), x_layer.rmax(), staveHlength + x_layer.outer_z()),
122 layerVolume.setVisAttributes(oddd, x_layer.visStr());
125 DetElement layerElement(barrelDetector, layerName, layerNum);
128 unsigned int nStaves = x_layer.nphi();
129 double phiStep = 2. *
M_PI / nStaves;
130 double phiTilt = x_layer.phi_tilt();
131 double phi0 = x_layer.phi0();
132 double r = x_layer.r();
136 for (
unsigned int staveNum = 0; staveNum < nStaves; ++staveNum) {
137 string staveName = _toString((
int)staveNum,
"stave%d");
139 double phi = phi0 + staveNum * phiStep;
140 double x = r *
cos(phi);
141 double y = r * sin(phi);
143 PlacedVolume placedStave = layerVolume.placeVolume(
146 RotationY(phi + phiTilt),
147 Position(x, y, 0.)));
148 placedStave.addPhysVolID(
"stave", staveNum);
151 DetElement staveElement = staveElementTemplate.clone(staveName, staveNum);
152 staveElement.setPlacement(placedStave);
154 layerElement.add(staveElement);
158 std::vector<double> dummyR;
164 layerExtension->
addType(
"sensitive cylinder",
"layer");
167 for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
168 xml_comp_t x_layer_material = lmat;
172 PlacedVolume placedLayer = barrelVolume.placeVolume(layerVolume);
173 placedLayer.addPhysVolID(
"layer", layerNum);
176 layerElement.setPlacement(placedLayer);
184 if (x_det.hasChild(_Unicode(services))) {
186 xml_comp_t x_services = x_det.child(_Unicode(services));
187 if (x_services.hasChild(_Unicode(cable_routing))) {
188 xml_comp_t x_cable_routing = x_services.child(_Unicode(cable_routing));
191 if (x_services.hasChild(_Unicode(cooling_routing))) {
192 xml_comp_t x_cooling_routing =
193 x_services.child(_Unicode(cooling_routing));
199 Volume motherVolume = oddd.pickMotherVolume(barrelDetector);
200 Position translation(0., 0., x_det_dim.z());
201 PlacedVolume placedBarrel =
202 motherVolume.placeVolume(barrelVolume, translation);
204 placedBarrel.addPhysVolID(
"system", barrelDetector.id());
205 barrelDetector.setPlacement(placedBarrel);
208 return barrelDetector;