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 endcapDetector(detName, x_det.id());
28 endcapExtension->addType(
"endcap",
"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 endcapShapeName = x_det_dim.nameStr();
41 Tube endcapShape(x_det_dim.rmin(), x_det_dim.rmax(), x_det_dim.dz());
42 Volume endcapVolume(detName, endcapShape, oddd.air());
43 endcapVolume.setVisAttributes(oddd, x_det.visStr());
45 Assembly diskAssembly(
"Disk");
48 DetElement diskElementTemplate(
"DiskElementTemplate", 0);
52 for (xml_coll_t ring(x_det, _U(ring)); ring; ++ring, ++ringNum) {
53 xml_comp_t x_ring = ring;
56 Assembly ringAssembly(ringName);
59 DetElement ringElement(ringName, ringNum);
61 if (x_ring.hasChild(_U(module))) {
62 xml_comp_t x_module = x_ring.child(_U(module));
67 unsigned int nPhi = x_ring.nphi();
68 double phiStep = 2 *
M_PI / nPhi;
69 double phi0 = x_ring.phi0();
70 double r = x_ring.r();
71 double zgap = x_ring.gap();
73 for (
unsigned int modNum = 0; modNum < nPhi; ++modNum) {
75 string moduleName = _toString((
int)modNum,
"module%d");
77 bool odd = bool(modNum % 2);
80 double phi = phi0 + modNum * phiStep;
81 double x = r *
cos(phi);
82 double y = r * sin(phi);
83 double z = odd ? -zgap : zgap;
86 Position trans(x, y, z);
87 double flip = odd ?
M_PI : 0.;
89 double angX = 0.5 *
M_PI + flip;
90 double angY = odd ? 0.5 *
M_PI - phi : 0.5 *
M_PI +
phi;
92 PlacedVolume placedModule = ringAssembly.placeVolume(
95 RotationX(angX) * RotationY(angY),
97 placedModule.addPhysVolID(
"module", modNum);
99 auto moduleElement = module.second.clone(moduleName, modNum);
100 moduleElement.setPlacement(placedModule);
102 ringElement.add(moduleElement);
106 diskElementTemplate.add(ringElement);
108 size_t supportNum = 0;
109 for (xml_coll_t sup(x_ring, _U(support)); sup; ++sup, ++supportNum) {
110 xml_comp_t x_support = sup;
112 string supportName = _toString((
int)supportNum,
"RingSupport%d");
113 Volume supportVolume(
115 Tube(x_support.rmin(), x_support.rmax(), x_support.dz()),
116 oddd.material(x_support.materialStr()));
117 supportVolume.setVisAttributes(oddd, x_support.visStr());
119 ringAssembly.placeVolume(supportVolume,
120 Position(0., 0., x_support.z_offset()));
126 PlacedVolume placedRing = diskAssembly.placeVolume(
127 ringAssembly, Position(0., 0., x_ring.z_offset()));
129 placedRing.addPhysVolID(
"ring", ringNum);
130 ringElement.setPlacement(placedRing);
135 std::vector<double> endcapZ;
137 for (xml_coll_t lay(xml, _U(
layer)); lay; ++lay, ++layNum) {
138 xml_comp_t x_layer = lay;
141 Volume layerVolume(layerName,
142 Tube(x_layer.rmin(), x_layer.rmax(), x_layer.dz()),
145 layerVolume.setVisAttributes(oddd, x_layer.visStr());
147 string diskElName = _toString((
int)layNum,
"disk%d");
150 DetElement layerElement(layerName, layNum);
151 auto diskElement = diskElementTemplate.clone(diskElName, layNum);
154 PlacedVolume placedDisk = layerVolume.placeVolume(diskAssembly);
155 diskElement.setPlacement(placedDisk);
156 layerElement.add(diskElement);
159 double zeff = x_layer.z_offset() - x_det_dim.z();
160 PlacedVolume placedLayer =
161 endcapVolume.placeVolume(layerVolume, Position(0., 0., zeff));
162 placedLayer.addPhysVolID(
"layer", layNum);
163 endcapZ.push_back(zeff);
168 layerExtension->
addType(
"sensitive disk",
"layer");
171 for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
172 xml_comp_t x_layer_material = lmat;
177 layerElement.setPlacement(placedLayer);
178 endcapDetector.add(layerElement);
181 if (x_det.hasChild(_Unicode(services))) {
183 xml_comp_t x_services = x_det.child(_Unicode(services));
184 for (xml_coll_t crout(x_services, _Unicode(cable_routing)); crout;
186 xml_comp_t x_cable_routing = crout;
190 for (xml_coll_t crout(x_services, _Unicode(cooling_routing)); crout;
192 xml_comp_t x_cooling_routing = crout;
198 Volume motherVolume = oddd.pickMotherVolume(endcapDetector);
199 Position translation(0., 0., x_det_dim.z());
200 PlacedVolume placedEndcap =
201 motherVolume.placeVolume(endcapVolume, translation);
203 placedEndcap.addPhysVolID(
"system", endcapDetector.id());
204 endcapDetector.setPlacement(placedEndcap);
207 return endcapDetector;