11 #include "DD4hep/DetFactoryHelper.h"
16 using namespace dd4hep;
19 xml_det_t x_det = xml;
20 string detName = x_det.nameStr();
23 DetElement endcapDetector(detName, x_det.id());
27 endcapExtension->addType(
"endcap",
"detector");
29 for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) {
30 xml_comp_t x_boundary_material = bmat;
36 dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
37 string endcapShapeName = x_det_dim.nameStr();
39 Tube endcapShape(x_det_dim.rmin(), x_det_dim.rmax(), x_det_dim.dz());
40 Volume endcapVolume(detName, endcapShape, oddd.air());
41 endcapVolume.setVisAttributes(oddd, x_det.visStr());
44 Volume motherVolume = oddd.pickMotherVolume(endcapDetector);
45 Position translation(0., 0., x_det_dim.z());
46 PlacedVolume placedEndcap =
47 motherVolume.placeVolume(endcapVolume, translation);
50 xml_comp_t x_module = x_det.child(_U(module));
55 Assembly diskAssembly(
"disk");
58 DetElement diskElementTemplate(
"DiskElementTemplate", 0);
62 for (xml_coll_t ring(xml, _U(ring)); ring; ++ring, ++ringNum) {
64 xml_comp_t x_ring = ring;
67 string ringName = _toString((
int)ringNum,
"ring%d");
68 Assembly ringAssembly(ringName);
69 ringAssembly.setVisAttributes(oddd, x_ring.visStr());
72 DetElement ringElement(ringName, ringNum);
74 double r = x_ring.r();
75 double phi0 = x_ring.phi0();
76 unsigned int nModules = x_ring.nphi();
77 double zgap = x_ring.gap();
78 double phiStep = 2. *
M_PI / nModules;
81 for (
unsigned int modNum = 0; modNum < nModules; ++modNum) {
83 string moduleName = _toString((
int)modNum,
"module%d");
84 bool odd = bool(modNum % 2);
86 double phi = phi0 + modNum * phiStep;
87 double z = odd ? -zgap : zgap;
88 Position trans(r * cos(phi), r * sin(phi), z);
90 double flip = x_det_dim.z() < 0. ?
M_PI : 0.;
94 PlacedVolume placedModule = ringAssembly.placeVolume(
97 placedModule.addPhysVolID(
"module", modNum);
99 auto moduleElement = module.second.clone(moduleName, modNum);
100 moduleElement.setPlacement(placedModule);
102 ringElement.add(moduleElement);
106 PlacedVolume placedRing = diskAssembly.placeVolume(
107 ringAssembly, Position(0., 0., x_ring.z_offset()));
108 placedRing.addPhysVolID(
"ring", ringNum);
109 ringElement.setPlacement(placedRing);
111 diskElementTemplate.add(ringElement);
114 xml_comp_t x_support = x_det.child(_Unicode(ring_support));
116 Tube supportShape(x_support.rmin(), x_support.rmax(), x_support.dz());
117 Volume supportVolume(
"DiskSupport", supportShape,
118 oddd.material(x_support.materialStr()));
119 supportVolume.setVisAttributes(oddd, x_support.visStr());
120 diskAssembly.placeVolume(supportVolume);
128 std::vector<double> endcapZ;
129 for (xml_coll_t lay(xml, _U(
layer)); lay; ++lay, ++layNum) {
131 xml_comp_t x_layer = lay;
135 Volume layerVolume(layerName,
136 Tube(x_layer.rmin(), x_layer.rmax(), x_layer.dz()),
139 layerVolume.setVisAttributes(oddd, x_layer.visStr());
141 string diskElName = _toString((
int)layNum,
"disk%d");
144 DetElement layerElement(layerName, layNum);
145 auto diskElement = diskElementTemplate.clone(diskElName, layNum);
148 PlacedVolume placedDisk = layerVolume.placeVolume(diskAssembly);
149 diskElement.setPlacement(placedDisk);
150 layerElement.add(diskElement);
153 double zeff = x_layer.z_offset() - x_det_dim.z();
154 endcapZ.push_back(zeff);
156 PlacedVolume placedLayer =
157 endcapVolume.placeVolume(layerVolume, Position(0., 0., zeff));
158 placedLayer.addPhysVolID(
"layer", layNum);
163 layerExtension->
addType(
"sensitive disk",
"layer");
166 for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
167 xml_comp_t x_layer_material = lmat;
171 layerElement.setPlacement(placedLayer);
172 endcapDetector.add(layerElement);
176 if (x_det.hasChild(_U(disk))) {
178 xml_comp_t x_endplate = x_det.child(_U(disk));
181 Tube endplateShape(x_endplate.rmin(), x_endplate.rmax(), x_endplate.dz());
182 Volume endplateVolume(
"Endplate", endplateShape,
183 oddd.material(x_endplate.materialStr()));
184 endplateVolume.setVisAttributes(oddd, x_endplate.visStr());
186 double zeff = x_endplate.z_offset() - x_det_dim.z();
187 endcapZ.push_back(zeff);
188 PlacedVolume placedEndplate =
189 endcapVolume.placeVolume(endplateVolume, Position(0., 0., zeff));
191 DetElement endplateElement(
"Endplate", 0);
196 endplateExtension->
addType(
"passive disk",
"layer");
199 for (xml_coll_t lmat(x_endplate, _Unicode(layer_material)); lmat; ++lmat) {
200 xml_comp_t x_layer_material = lmat;
205 endplateElement.setPlacement(placedEndplate);
206 endcapDetector.add(endplateElement);
209 if (x_det.hasChild(_Unicode(services))) {
211 xml_comp_t x_services = x_det.child(_Unicode(services));
212 if (x_services.hasChild(_Unicode(cable_routing))) {
213 xml_comp_t x_cable_routing = x_services.child(_Unicode(cable_routing));
216 if (x_services.hasChild(_Unicode(cooling_routing))) {
217 xml_comp_t x_cooling_routing =
218 x_services.child(_Unicode(cooling_routing));
224 std::vector<double> layerR;
228 placedEndcap.addPhysVolID(
"system", endcapDetector.id());
229 endcapDetector.setPlacement(placedEndcap);
232 return endcapDetector;