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;
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());
45 Volume motherVolume = oddd.pickMotherVolume(endcapDetector);
46 Position translation(0., 0., x_det_dim.z());
47 PlacedVolume placedEndcap =
48 motherVolume.placeVolume(endcapVolume, translation);
51 xml_comp_t x_module = x_det.child(_U(module));
56 Assembly diskAssembly(
"disk");
59 DetElement diskElementTemplate(
"DiskElementTemplate", 0);
63 for (xml_coll_t ring(xml, _U(ring)); ring; ++ring, ++ringNum) {
65 xml_comp_t x_ring = ring;
68 string ringName = _toString((
int)ringNum,
"ring%d");
69 Assembly ringAssembly(ringName);
70 ringAssembly.setVisAttributes(oddd, x_ring.visStr());
73 DetElement ringElement(ringName, ringNum);
75 double r = x_ring.r();
76 double phi0 = x_ring.phi0();
77 unsigned int nModules = x_ring.nphi();
78 double zgap = x_ring.gap();
79 double phiStep = 2. *
M_PI / nModules;
82 for (
unsigned int modNum = 0; modNum < nModules; ++modNum) {
84 string moduleName = _toString((
int)modNum,
"module%d");
85 bool odd = bool(modNum % 2);
87 double phi = phi0 + modNum * phiStep;
88 double z = odd ? -zgap : zgap;
89 Position trans(r *
cos(phi), r * sin(phi), z);
91 double flip = x_det_dim.z() < 0. ?
M_PI : 0.;
95 PlacedVolume placedModule = ringAssembly.placeVolume(
98 placedModule.addPhysVolID(
"module", modNum);
100 auto moduleElement = module.second.clone(moduleName, modNum);
101 moduleElement.setPlacement(placedModule);
103 ringElement.add(moduleElement);
107 PlacedVolume placedRing = diskAssembly.placeVolume(
108 ringAssembly, Position(0., 0., x_ring.z_offset()));
109 placedRing.addPhysVolID(
"ring", ringNum);
110 ringElement.setPlacement(placedRing);
112 diskElementTemplate.add(ringElement);
115 xml_comp_t x_support = x_det.child(_Unicode(ring_support));
117 Tube supportShape(x_support.rmin(), x_support.rmax(), x_support.dz());
118 Volume supportVolume(
"DiskSupport", supportShape,
119 oddd.material(x_support.materialStr()));
120 supportVolume.setVisAttributes(oddd, x_support.visStr());
121 diskAssembly.placeVolume(supportVolume);
129 std::vector<double> endcapZ;
130 for (xml_coll_t lay(xml, _U(
layer)); lay; ++lay, ++layNum) {
132 xml_comp_t x_layer = lay;
136 Volume layerVolume(layerName,
137 Tube(x_layer.rmin(), x_layer.rmax(), x_layer.dz()),
140 layerVolume.setVisAttributes(oddd, x_layer.visStr());
142 string diskElName = _toString((
int)layNum,
"disk%d");
145 DetElement layerElement(layerName, layNum);
146 auto diskElement = diskElementTemplate.clone(diskElName, layNum);
149 PlacedVolume placedDisk = layerVolume.placeVolume(diskAssembly);
150 diskElement.setPlacement(placedDisk);
151 layerElement.add(diskElement);
154 double zeff = x_layer.z_offset() - x_det_dim.z();
155 endcapZ.push_back(zeff);
157 PlacedVolume placedLayer =
158 endcapVolume.placeVolume(layerVolume, Position(0., 0., zeff));
159 placedLayer.addPhysVolID(
"layer", layNum);
164 layerExtension->
addType(
"sensitive disk",
"layer");
167 for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) {
168 xml_comp_t x_layer_material = lmat;
172 layerElement.setPlacement(placedLayer);
173 endcapDetector.add(layerElement);
177 if (x_det.hasChild(_U(disk))) {
179 xml_comp_t x_endplate = x_det.child(_U(disk));
182 Tube endplateShape(x_endplate.rmin(), x_endplate.rmax(), x_endplate.dz());
183 Volume endplateVolume(
"Endplate", endplateShape,
184 oddd.material(x_endplate.materialStr()));
185 endplateVolume.setVisAttributes(oddd, x_endplate.visStr());
187 double zeff = x_endplate.z_offset() - x_det_dim.z();
188 endcapZ.push_back(zeff);
189 PlacedVolume placedEndplate =
190 endcapVolume.placeVolume(endplateVolume, Position(0., 0., zeff));
192 DetElement endplateElement(
"Endplate", 0);
197 endplateExtension->
addType(
"passive disk",
"layer");
200 for (xml_coll_t lmat(x_endplate, _Unicode(layer_material)); lmat; ++lmat) {
201 xml_comp_t x_layer_material = lmat;
206 endplateElement.setPlacement(placedEndplate);
207 endcapDetector.add(endplateElement);
210 if (x_det.hasChild(_Unicode(services))) {
212 xml_comp_t x_services = x_det.child(_Unicode(services));
213 if (x_services.hasChild(_Unicode(cable_routing))) {
214 xml_comp_t x_cable_routing = x_services.child(_Unicode(cable_routing));
217 if (x_services.hasChild(_Unicode(cooling_routing))) {
218 xml_comp_t x_cooling_routing =
219 x_services.child(_Unicode(cooling_routing));
225 std::vector<double> layerR;
229 placedEndcap.addPhysVolID(
"system", endcapDetector.id());
230 endcapDetector.setPlacement(placedEndcap);
233 return endcapDetector;