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;
37 dd4hep::xml::Dimension x_det_dim(x_det.dimensions());
38 string endcapShapeName = x_det_dim.nameStr();
40 Tube endcapShape(x_det_dim.rmin(), x_det_dim.rmax(), x_det_dim.dz());
41 Volume endcapVolume(detName, endcapShape, oddd.air());
42 endcapVolume.setVisAttributes(oddd, x_det.visStr());
44 Assembly diskAssembly(
"Disk");
47 DetElement diskElementTemplate(
"DiskElementTemplate", 0);
51 for (xml_coll_t ring(x_det, _U(ring)); ring; ++ring, ++ringNum) {
52 xml_comp_t x_ring = ring;
55 Assembly ringAssembly(ringName);
58 DetElement ringElement(ringName, ringNum);
60 if (x_ring.hasChild(_U(module))) {
61 xml_comp_t x_module = x_ring.child(_U(module));
66 unsigned int nPhi = x_ring.nphi();
67 double phiStep = 2 *
M_PI / nPhi;
68 double phi0 = x_ring.phi0();
69 double r = x_ring.r();
70 double zgap = x_ring.gap();
72 for (
unsigned int modNum = 0; modNum < nPhi; ++modNum) {
74 string moduleName = _toString((
int)modNum,
"module%d");
76 bool odd = bool(modNum % 2);
79 double phi = phi0 + modNum * phiStep;
80 double x = r * cos(phi);
81 double y = r * sin(phi);
82 double z = odd ? -zgap : zgap;
85 Position trans(x, y, z);
86 double flip = odd ?
M_PI : 0.;
88 double angX = 0.5 *
M_PI + flip;
89 double angY = odd ? 0.5 *
M_PI - phi : 0.5 *
M_PI +
phi;
91 PlacedVolume placedModule = ringAssembly.placeVolume(
94 RotationX(angX) * RotationY(angY),
96 placedModule.addPhysVolID(
"module", modNum);
98 auto moduleElement = module.second.clone(moduleName, modNum);
99 moduleElement.setPlacement(placedModule);
101 ringElement.add(moduleElement);
105 diskElementTemplate.add(ringElement);
107 size_t supportNum = 0;
108 for (xml_coll_t sup(x_ring, _U(support)); sup; ++sup, ++supportNum) {
109 xml_comp_t x_support = sup;
111 string supportName = _toString((
int)supportNum,
"RingSupport%d");
112 Volume supportVolume(
114 Tube(x_support.rmin(), x_support.rmax(), x_support.dz()),
115 oddd.material(x_support.materialStr()));
116 supportVolume.setVisAttributes(oddd, x_support.visStr());
118 ringAssembly.placeVolume(supportVolume,
119 Position(0., 0., x_support.z_offset()));
125 PlacedVolume placedRing = diskAssembly.placeVolume(
126 ringAssembly, Position(0., 0., x_ring.z_offset()));
128 placedRing.addPhysVolID(
"ring", ringNum);
129 ringElement.setPlacement(placedRing);
134 std::vector<double> endcapZ;
136 for (xml_coll_t lay(xml, _U(
layer)); lay; ++lay, ++layNum) {
137 xml_comp_t x_layer = lay;
140 Volume layerVolume(layerName,
141 Tube(x_layer.rmin(), x_layer.rmax(), x_layer.dz()),
144 layerVolume.setVisAttributes(oddd, x_layer.visStr());
146 string diskElName = _toString((
int)layNum,
"disk%d");
149 DetElement layerElement(layerName, layNum);
150 auto diskElement = diskElementTemplate.clone(diskElName, layNum);
153 PlacedVolume placedDisk = layerVolume.placeVolume(diskAssembly);
154 diskElement.setPlacement(placedDisk);
155 layerElement.add(diskElement);
158 double zeff = x_layer.z_offset() - x_det_dim.z();
159 PlacedVolume placedLayer =
160 endcapVolume.placeVolume(layerVolume, Position(0., 0., zeff));
161 placedLayer.addPhysVolID(
"layer", layNum);
162 endcapZ.push_back(zeff);
167 layerExtension->
addType(
"sensitive disk",
"layer");
170 for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
171 xml_comp_t x_layer_material = lmat;
176 layerElement.setPlacement(placedLayer);
177 endcapDetector.add(layerElement);
180 if (x_det.hasChild(_Unicode(services))) {
182 xml_comp_t x_services = x_det.child(_Unicode(services));
183 for (xml_coll_t crout(x_services, _Unicode(cable_routing)); crout;
185 xml_comp_t x_cable_routing = crout;
189 for (xml_coll_t crout(x_services, _Unicode(cooling_routing)); crout;
191 xml_comp_t x_cooling_routing = crout;
197 Volume motherVolume = oddd.pickMotherVolume(endcapDetector);
198 Position translation(0., 0., x_det_dim.z());
199 PlacedVolume placedEndcap =
200 motherVolume.placeVolume(endcapVolume, translation);
202 placedEndcap.addPhysVolID(
"system", endcapDetector.id());
203 endcapDetector.setPlacement(placedEndcap);
206 return endcapDetector;