9 #include "../DetUtils.h"
11 #include "DD4hep/DetFactoryHelper.h"
13 using dd4hep::DetElement;
14 using dd4hep::PlacedVolume;
16 using dd4hep::xml::Dimension;
20 dd4hep::Detector& lcdd, dd4hep::xml::Handle_t xmlElement,
21 dd4hep::SensitiveDetector sensDet) {
23 dd4hep::xml::DetElement xmlDet =
24 static_cast<dd4hep::xml::DetElement
>(xmlElement);
25 Dimension dimensions(xmlDet.dimensions());
27 dd4hep::xml::Dimension sdTyp = xmlElement.child(_Unicode(sensitive));
29 sensDet.setType(sdTyp.typeStr());
33 std::string detectorName = xmlDet.nameStr();
34 DetElement topDetElement(detectorName, xmlDet.id());
37 detWorldExt->addType(
"barrel",
"detector");
39 dd4hep::Tube topVolumeShape(dimensions.rmin(), dimensions.rmax(),
40 (dimensions.zmax() - dimensions.zmin()) * 0.5);
41 Volume topVolume(detectorName, topVolumeShape, lcdd.air());
42 topVolume.setVisAttributes(lcdd.invisible());
45 unsigned int layerCounter = 0;
46 double integratedModuleComponentThickness = 0;
49 dd4hep::xml::Component xLayers = xmlElement.child(_Unicode(layers));
50 for (dd4hep::xml::Collection_t xLayerColl(xLayers, _U(
layer));
51 nullptr != xLayerColl; ++xLayerColl) {
52 dd4hep::xml::Component xLayer =
53 static_cast<dd4hep::xml::Component
>(xLayerColl);
54 dd4hep::xml::Component xRods = xLayer.child(
"rods");
55 dd4hep::xml::Component xRodEven = xRods.child(
"rodOdd");
56 dd4hep::xml::Component xRodOdd = xRods.child(
"rodEven");
57 dd4hep::xml::Component xModulesEven = xRodEven.child(
"modules");
58 dd4hep::xml::Component xModulePropertiesOdd =
59 xRodOdd.child(
"moduleProperties");
60 dd4hep::xml::Component xModulesOdd = xRodOdd.child(
"modules");
61 dd4hep::Tube layerShape(xLayer.rmin(), xLayer.rmax(), dimensions.zmax());
62 Volume layerVolume(
"layer", layerShape, lcdd.material(
"Air"));
64 PlacedVolume placedLayerVolume = topVolume.placeVolume(layerVolume);
65 placedLayerVolume.addPhysVolID(
"layer", layerCounter);
66 DetElement lay_det(topDetElement,
"layer" +
std::to_string(layerCounter),
72 layerExtension->
addType(
"sensitive cylinder",
"layer");
73 layerExtension->
addType(
"axes",
"definitions",
"XzY");
75 lay_det.setPlacement(placedLayerVolume);
76 dd4hep::xml::Component xModuleComponentsOdd =
77 xModulePropertiesOdd.child(
"components");
78 integratedModuleComponentThickness = 0;
79 int moduleCounter = 0;
82 std::vector<std::pair<dd4hep::Material, double>> compMaterials;
84 for (dd4hep::xml::Collection_t xModuleComponentOddColl(xModuleComponentsOdd,
86 nullptr != xModuleComponentOddColl; ++xModuleComponentOddColl) {
87 dd4hep::xml::Component xModuleComponentOdd =
88 static_cast<dd4hep::xml::Component
>(xModuleComponentOddColl);
90 compMaterials.push_back(
91 std::make_pair(lcdd.material(xModuleComponentOdd.materialStr()),
92 xModuleComponentOdd.thickness()));
94 for (dd4hep::xml::Collection_t xModuleComponentOddColl(xModuleComponentsOdd,
96 nullptr != xModuleComponentOddColl; ++xModuleComponentOddColl) {
97 dd4hep::xml::Component xModuleComponentOdd =
98 static_cast<dd4hep::xml::Component
>(xModuleComponentOddColl);
99 auto moduleWidth = 0.5 * xModulePropertiesOdd.attr<
double>(
"modWidth");
100 auto moduleThickness = 0.5 * xModuleComponentOdd.thickness();
101 auto moduleLength = 0.5 * xModulePropertiesOdd.attr<
double>(
"modLength");
102 Volume moduleVolume = Volume(
103 "module",
dd4hep::Box(moduleWidth, moduleThickness, moduleLength),
104 lcdd.material(xModuleComponentOdd.materialStr()));
109 moduleWidth, moduleLength, moduleThickness, xLayer.X(), xLayer.Z());
111 moduleVolume.setVisAttributes(lcdd.invisible());
112 unsigned int nPhi = xRods.repeat();
113 dd4hep::xml::Handle_t currentComp;
114 for (
unsigned int phiIndex = 0; phiIndex < nPhi; ++phiIndex) {
118 if (0 == phiIndex % 2) {
119 phi = 2 *
M_PI *
static_cast<double>(phiIndex) /
120 static_cast<double>(nPhi);
121 currentComp = xModulesEven;
123 currentComp = xModulesOdd;
125 for (dd4hep::xml::Collection_t xModuleColl(currentComp, _U(module));
126 nullptr != xModuleColl; ++xModuleColl) {
127 dd4hep::xml::Component xModule =
128 static_cast<dd4hep::xml::Component
>(xModuleColl);
129 double currentPhi = atan2(xModule.Y(), xModule.X());
130 double componentOffset =
131 integratedModuleComponentThickness -
132 0.5 * xModulePropertiesOdd.attr<
double>(
"modThickness") +
133 0.5 * xModuleComponentOdd.thickness();
134 lX = xModule.X() + cos(currentPhi) * componentOffset;
135 lY = xModule.Y() + sin(currentPhi) * componentOffset;
139 dd4hep::RotationZ(atan2(lY, lX) + 0.5 *
M_PI), moduleOffset);
140 dd4hep::RotationZ lRotation(phi);
141 PlacedVolume placedModuleVolume =
142 layerVolume.placeVolume(moduleVolume, lRotation * lTrafo);
143 if (xModuleComponentOdd.isSensitive()) {
144 placedModuleVolume.addPhysVolID(
"module", moduleCounter);
145 moduleVolume.setSensitiveDetector(sensDet);
146 DetElement mod_det(lay_det,
153 mod_det.setPlacement(placedModuleVolume);
158 integratedModuleComponentThickness += xModuleComponentOdd.thickness();
162 Volume motherVol = lcdd.pickMotherVolume(topDetElement);
163 PlacedVolume placedGenericTrackerBarrel = motherVol.placeVolume(topVolume);
164 placedGenericTrackerBarrel.addPhysVolID(
"system", topDetElement.id());
165 topDetElement.setPlacement(placedGenericTrackerBarrel);
166 return topDetElement;