17 #include "DD4hep/DetFactoryHelper.h"
18 #include "DD4hep/Printout.h"
22 using namespace dd4hep::detail;
25 typedef vector<PlacedVolume> Placements;
27 Material air = description.air();
28 int det_id = x_det.id();
29 string det_name = x_det.nameStr();
30 DetElement sdet(det_name, det_id);
31 Assembly assembly(det_name);
32 map<string, Volume> volumes;
33 map<string, Placements> sensitives;
36 sens.setType(
"tracker");
37 for (xml_coll_t mi(x_det, _U(module)); mi; ++mi) {
38 xml_comp_t x_mod = mi;
39 xml_comp_t m_env = x_mod.child(_U(module_envelope));
40 string m_nam = x_mod.nameStr();
41 Volume m_vol(m_nam, Box(m_env.width() / 2, m_env.length() / 2, m_env.thickness() / 2), air);
42 int ncomponents = 0, sensor_number = 1;
44 if (volumes.find(m_nam) != volumes.end()) {
45 printout(ERROR,
"SiTrackerBarrel",
"Logics error in building modules.");
46 throw runtime_error(
"Logics error in building modules.");
48 volumes[m_nam] = m_vol;
49 m_vol.setVisAttributes(description.visAttributes(x_mod.visStr()));
50 for (xml_coll_t ci(x_mod, _U(module_component)); ci; ++ci, ++ncomponents) {
51 xml_comp_t x_comp = ci;
52 xml_comp_t x_pos = x_comp.position(
false);
53 xml_comp_t x_rot = x_comp.rotation(
false);
54 string c_nam = _toString(ncomponents,
"component%d");
55 Box c_box(x_comp.width() / 2, x_comp.length() / 2, x_comp.thickness() / 2);
56 Volume c_vol(c_nam, c_box, description.material(x_comp.materialStr()));
59 Position c_pos(x_pos.x(0), x_pos.y(0), x_pos.z(0));
60 RotationZYX c_rot(x_rot.z(0), x_rot.y(0), x_rot.x(0));
61 pv = m_vol.placeVolume(c_vol, Transform3D(c_rot, c_pos));
63 pv = m_vol.placeVolume(c_vol, RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)));
65 pv = m_vol.placeVolume(c_vol, Position(x_pos.x(0), x_pos.y(0), x_pos.z(0)));
67 pv = m_vol.placeVolume(c_vol);
69 c_vol.setRegion(description, x_comp.regionStr());
70 c_vol.setLimitSet(description, x_comp.limitsStr());
71 c_vol.setVisAttributes(description, x_comp.visStr());
72 if (x_comp.isSensitive()) {
73 pv.addPhysVolID(_U(sensor), sensor_number++);
74 c_vol.setSensitiveDetector(sens);
75 sensitives[m_nam].push_back(pv);
79 for (xml_coll_t li(x_det, _U(layer)); li; ++li) {
80 xml_comp_t x_layer = li;
81 xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope));
82 xml_comp_t x_layout = x_layer.child(_U(rphi_layout));
83 xml_comp_t z_layout = x_layer.child(_U(z_layout));
84 int lay_id = x_layer.id();
85 string m_nam = x_layer.moduleStr();
86 string lay_nam = _toString(x_layer.id(),
"layer%d");
87 Tube lay_tub(x_barrel.inner_r(), x_barrel.outer_r(), x_barrel.z_length() / 2);
88 Volume lay_vol(lay_nam, lay_tub, air);
89 lay_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
90 double phi0 = x_layout.phi0();
91 double phi_tilt = x_layout.phi_tilt();
92 double rc = x_layout.rc();
93 int nphi = x_layout.nphi();
94 double rphi_dr = x_layout.dr();
95 double phi_incr = (M_PI * 2) / nphi;
97 double z0 = z_layout.z0();
98 double nz = z_layout.nz();
99 double z_dr = z_layout.dr();
100 Volume m_env = volumes[m_nam];
101 DetElement lay_elt(sdet, _toString(x_layer.id(),
"layer%d"), lay_id);
102 Placements& sensVols = sensitives[m_nam];
107 double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0;
109 double module_z = -z0;
113 for (
int ii = 0; ii < nphi; ii++) {
114 double dx = z_dr * std::cos(phic + phi_tilt);
115 double dy = z_dr * std::sin(phic + phi_tilt);
116 double x = rc * std::cos(phic);
117 double y = rc * std::sin(phic);
120 for (
int j = 0; j < nz; j++) {
121 string module_name = _toString(module,
"module%d");
122 DetElement mod_elt(lay_elt, module_name, module);
128 Transform3D tr(RotationZYX(0, ((M_PI / 2) - phic - phi_tilt), -M_PI / 2),
129 Position(x, y, module_z));
131 pv = lay_vol.placeVolume(m_env, tr);
132 pv.addPhysVolID(
"module", module);
133 mod_elt.setPlacement(pv);
134 for (
size_t ic = 0; ic < sensVols.size(); ++ic) {
135 PlacedVolume sens_pv = sensVols[ic];
136 DetElement comp_elt(mod_elt, sens_pv.volume().name(), module);
137 comp_elt.setPlacement(sens_pv);
157 pv = assembly.placeVolume(lay_vol);
158 pv.addPhysVolID(
"layer", lay_id);
159 lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(),
161 lay_elt.setPlacement(pv);
163 sdet.setAttributes(description, assembly, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
164 assembly.setVisAttributes(description.invisible());
165 pv = description.pickMotherVolume(sdet).placeVolume(assembly);
166 pv.addPhysVolID(
"system", det_id);
167 pv.addPhysVolID(
"barrel", 0);
168 sdet.setPlacement(pv);