24 #include "DD4hep/DetFactoryHelper.h"
28 using namespace dd4hep;
37 std::string
name = x_det.nameStr();
42 Assembly assembly(name +
"_assembly");
44 DetElement tracker(name, x_det.id());
48 detvolume->addType(
"barrel",
"detector");
56 double minZhalf = 1e99;
58 bool isStripDetector =
false;
60 isStripDetector = x_det.attr<
bool>(_Unicode(isStripDetector));
62 }
catch (std::runtime_error) {
68 for (xml_coll_t
c(e, _U(
layer));
c; ++
c) {
69 xml_comp_t x_layer(
c);
72 xml_comp_t x_sensitive(x_layer.child(_U(sensitive)));
73 xml_comp_t x_ladder(x_layer.child(_U(ladder)));
75 int layer_id = x_layer.id();
76 int nLadders = x_layer.attr<
double>(_Unicode(nLadders));
78 double dphi = 2. *
M_PI / double(nLadders);
80 std::string layername = name + _toString(layer_id,
"_layer%d");
84 Assembly layer_assembly(
"layer_assembly" + _toString(layer_id,
"_%d"));
86 DetElement layerDE(tracker, _toString(layer_id,
"layer_%d"), x_det.id());
92 detlayer->addType(
"sensitive plane",
"layer");
95 pv = assembly.placeVolume(layer_assembly);
97 pv.addPhysVolID(
"layer", layer_id);
99 layerDE.setPlacement(pv);
103 double supp_zhalf = x_ladder.length();
104 double supp_offset = x_ladder.offset();
105 double supp_distance = x_ladder.distance();
106 double supp_thickness = x_ladder.thickness();
107 double supp_width = x_ladder.width();
109 std::string supp_vis = x_ladder.visStr();
110 std::string supp_matS = x_ladder.materialStr();
112 double sens_zhalf = x_sensitive.length();
113 double sens_offset = x_sensitive.offset();
114 double sens_distance = x_sensitive.distance();
115 double sens_thickness = x_sensitive.thickness();
116 double sens_width = x_sensitive.width();
118 std::string sens_vis = x_sensitive.visStr();
119 std::string sens_matS = x_sensitive.materialStr();
121 double phi0 = x_layer.phi0();
123 if (sens_distance < minRadius)
124 minRadius = sens_distance;
125 if (supp_distance < minRadius)
126 minRadius = supp_distance;
127 if (sens_zhalf < minZhalf)
128 minZhalf = sens_zhalf;
129 if (supp_zhalf < minZhalf)
130 minZhalf = supp_zhalf;
157 Material supp_mat = lcdd.material(supp_matS);
158 Material sens_mat = lcdd.material(sens_matS);
161 Box sens_box(sens_thickness / 2., sens_width / 2., sens_zhalf);
162 Box supp_box(supp_thickness / 2., supp_width / 2., supp_zhalf);
164 Volume supp_vol(layername +
"_supp", supp_box, supp_mat);
165 Volume sens_vol(layername +
"_sens", sens_box, sens_mat);
198 sens.setType(
"tracker");
199 sens_vol.setSensitiveDetector(sens);
201 sens_vol.setAttributes(lcdd, x_det.regionStr(), x_det.limitsStr(),
203 supp_vol.setAttributes(lcdd, x_det.regionStr(), x_det.limitsStr(),
208 for (
int j = 0; j < nLadders; ++j) {
209 double phi = phi0 + j * dphi;
211 std::string laddername = layername + _toString(j,
"_ladder%d");
213 RotationZYX rot(phi, 0, 0);
216 double lthick = supp_thickness;
217 double radius = supp_distance;
218 double offset = supp_offset;
220 layer_assembly.placeVolume(
224 Position((radius + lthick / 2.) * cos(phi) - offset * sin(phi),
225 (radius + lthick / 2.) * sin(phi) + offset * cos(phi),
229 lthick = sens_thickness;
230 radius = sens_distance;
231 offset = sens_offset;
233 pv = layer_assembly.placeVolume(
237 Position((radius + lthick / 2.0) * cos(phi) - offset * sin(phi),
238 (radius + lthick / 2.0) * sin(phi) + offset * cos(phi),
243 pv.addPhysVolID(
"module", j).addPhysVolID(
"sensor", 0);
245 DetElement ladderDE(layerDE, laddername, x_det.id());
246 ladderDE.setPlacement(pv);
254 layer_assembly->GetShape()->ComputeBBox();
257 #if 0 //-------- add an inscribing cylinder of air for tracking purposes
278 #endif //----------------------------------------------------------------------------------
282 Volume mother = lcdd.pickMotherVolume(tracker);
284 pv = mother.placeVolume(assembly);
286 pv.addPhysVolID(
"system", x_det.id()).addPhysVolID(
"side", 0);
288 tracker.setPlacement(pv);
290 assembly->GetShape()->ComputeBBox();