11 #include "../DetUtils.h"
12 #include "DD4hep/DetFactoryHelper.h"
14 using dd4hep::DetElement;
15 using dd4hep::PlacedVolume;
17 using dd4hep::xml::Dimension;
21 dd4hep::Detector& lcdd, dd4hep::xml::Handle_t xmlElement,
22 dd4hep::SensitiveDetector sensDet) {
24 dd4hep::xml::DetElement xmlDet =
25 static_cast<dd4hep::xml::DetElement
>(xmlElement);
26 Dimension dimensions(xmlDet.dimensions());
28 dd4hep::xml::Dimension sdTyp = xmlElement.child(_Unicode(sensitive));
30 sensDet.setType(sdTyp.typeStr());
34 std::string detectorName = xmlDet.nameStr();
35 DetElement topDetElement(detectorName, xmlDet.id());
38 detWorldExt->addType(
"barrel",
"detector");
40 dd4hep::Tube topVolumeShape(dimensions.rmin(), dimensions.rmax(),
41 (dimensions.zmax() - dimensions.zmin()) * 0.5);
42 Volume topVolume(detectorName, topVolumeShape, lcdd.air());
43 topVolume.setVisAttributes(lcdd.invisible());
46 unsigned int layerCounter = 0;
47 double integratedModuleComponentThickness = 0;
50 dd4hep::xml::Component xLayers = xmlElement.child(_Unicode(layers));
51 for (dd4hep::xml::Collection_t xLayerColl(xLayers, _U(
layer));
52 nullptr != xLayerColl; ++xLayerColl) {
53 dd4hep::xml::Component xLayer =
54 static_cast<dd4hep::xml::Component
>(xLayerColl);
55 dd4hep::xml::Component xRods = xLayer.child(
"rods");
56 dd4hep::xml::Component xRodEven = xRods.child(
"rodOdd");
57 dd4hep::xml::Component xRodOdd = xRods.child(
"rodEven");
58 dd4hep::xml::Component xModulesEven = xRodEven.child(
"modules");
59 dd4hep::xml::Component xModulePropertiesOdd =
60 xRodOdd.child(
"moduleProperties");
61 dd4hep::xml::Component xModulesOdd = xRodOdd.child(
"modules");
62 dd4hep::Tube layerShape(xLayer.rmin(), xLayer.rmax(), dimensions.zmax());
63 Volume layerVolume(
"layer", layerShape, lcdd.material(
"Air"));
65 PlacedVolume placedLayerVolume = topVolume.placeVolume(layerVolume);
66 placedLayerVolume.addPhysVolID(
"layer", layerCounter);
67 DetElement lay_det(topDetElement,
"layer" +
std::to_string(layerCounter),
73 layerExtension->
addType(
"sensitive cylinder",
"layer");
74 layerExtension->
addType(
"axes",
"definitions",
"XzY");
76 lay_det.setPlacement(placedLayerVolume);
77 dd4hep::xml::Component xModuleComponentsOdd =
78 xModulePropertiesOdd.child(
"components");
79 integratedModuleComponentThickness = 0;
80 int moduleCounter = 0;
83 std::vector<std::pair<dd4hep::Material, double>> compMaterials;
85 for (dd4hep::xml::Collection_t xModuleComponentOddColl(xModuleComponentsOdd,
87 nullptr != xModuleComponentOddColl; ++xModuleComponentOddColl) {
88 dd4hep::xml::Component xModuleComponentOdd =
89 static_cast<dd4hep::xml::Component
>(xModuleComponentOddColl);
91 compMaterials.push_back(
92 std::make_pair(lcdd.material(xModuleComponentOdd.materialStr()),
93 xModuleComponentOdd.thickness()));
95 for (dd4hep::xml::Collection_t xModuleComponentOddColl(xModuleComponentsOdd,
97 nullptr != xModuleComponentOddColl; ++xModuleComponentOddColl) {
98 dd4hep::xml::Component xModuleComponentOdd =
99 static_cast<dd4hep::xml::Component
>(xModuleComponentOddColl);
100 auto moduleWidth = 0.5 * xModulePropertiesOdd.attr<
double>(
"modWidth");
101 auto moduleThickness = 0.5 * xModuleComponentOdd.thickness();
102 auto moduleLength = 0.5 * xModulePropertiesOdd.attr<
double>(
"modLength");
103 Volume moduleVolume = Volume(
104 "module",
dd4hep::Box(moduleWidth, moduleThickness, moduleLength),
105 lcdd.material(xModuleComponentOdd.materialStr()));
110 moduleWidth, moduleLength, moduleThickness, xLayer.X(), xLayer.Z());
112 moduleVolume.setVisAttributes(lcdd.invisible());
113 unsigned int nPhi = xRods.repeat();
114 dd4hep::xml::Handle_t currentComp;
115 for (
unsigned int phiIndex = 0; phiIndex < nPhi; ++phiIndex) {
119 if (0 == phiIndex % 2) {
120 phi = 2 *
M_PI *
static_cast<double>(phiIndex) /
121 static_cast<double>(nPhi);
122 currentComp = xModulesEven;
124 currentComp = xModulesOdd;
126 for (dd4hep::xml::Collection_t xModuleColl(currentComp, _U(module));
127 nullptr != xModuleColl; ++xModuleColl) {
128 dd4hep::xml::Component xModule =
129 static_cast<dd4hep::xml::Component
>(xModuleColl);
130 double currentPhi = atan2(xModule.Y(), xModule.X());
131 double componentOffset =
132 integratedModuleComponentThickness -
133 0.5 * xModulePropertiesOdd.attr<
double>(
"modThickness") +
134 0.5 * xModuleComponentOdd.thickness();
135 lX = xModule.X() +
cos(currentPhi) * componentOffset;
136 lY = xModule.Y() + sin(currentPhi) * componentOffset;
140 dd4hep::RotationZ(atan2(lY, lX) + 0.5 *
M_PI), moduleOffset);
141 dd4hep::RotationZ lRotation(phi);
142 PlacedVolume placedModuleVolume =
143 layerVolume.placeVolume(moduleVolume, lRotation * lTrafo);
144 if (xModuleComponentOdd.isSensitive()) {
145 placedModuleVolume.addPhysVolID(
"module", moduleCounter);
146 moduleVolume.setSensitiveDetector(sensDet);
147 DetElement mod_det(lay_det,
154 mod_det.setPlacement(placedModuleVolume);
159 integratedModuleComponentThickness += xModuleComponentOdd.thickness();
163 Volume motherVol = lcdd.pickMotherVolume(topDetElement);
164 PlacedVolume placedGenericTrackerBarrel = motherVol.placeVolume(topVolume);
165 placedGenericTrackerBarrel.addPhysVolID(
"system", topDetElement.id());
166 topDetElement.setPlacement(placedGenericTrackerBarrel);
167 return topDetElement;