18 #include "DD4hep/DetFactoryHelper.h"
19 #include "XML/Layering.h"
25 static double tolerance = 0e0;
26 Layering layering (e);
28 Material air = lcdd.air();
29 int det_id = x_det.id();
30 string det_name = x_det.nameStr();
31 xml_comp_t x_staves = x_det.staves();
32 xml_comp_t x_dim = x_det.dimensions();
33 int nsides = x_dim.numsides();
34 double inner_r = x_dim.rmin();
35 double dphi = (2*M_PI/nsides);
37 double mod_z = layering.totalThickness();
38 double outer_r = inner_r + mod_z;
39 double totThick = mod_z;
40 DetElement sdet (det_name,det_id);
41 Volume motherVol = lcdd.pickMotherVolume(sdet);
42 PolyhedraRegular hedra (nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z());
43 Volume envelope (det_name,hedra,air);
44 PlacedVolume env_phv = motherVol.placeVolume(envelope,RotationZYX(0,0,M_PI/nsides));
46 env_phv.addPhysVolID(
"system",det_id);
47 env_phv.addPhysVolID(
"barrel",0);
48 sdet.setPlacement(env_phv);
50 DetElement stave_det(
"stave0",det_id);
54 double trd_x2 = (2 * std::tan(hphi) * outer_r - dx)/2 - tolerance;
55 double trd_x1 = (2 * std::tan(hphi) * inner_r + dx)/2 - tolerance;
56 double trd_y1 = x_dim.z()/2 - tolerance;
57 double trd_y2 = trd_y1;
58 double trd_z = mod_z/2 - tolerance;
67 Volume mod_vol(
"stave",trd,air);
69 sens.setType(
"calorimeter");
72 double stave_z = trd_y1/2;
73 double l_dim_x = trd_x1/2;
74 double adj = (l_dim_x-trd_x2/2)/2;
75 double hyp = std::sqrt(trd_z*trd_z/4 + adj*adj);
76 double beta = std::acos(adj / hyp);
77 double tan_beta = std::tan(beta);
78 double l_pos_z = -(layering.totalThickness() / 2);
82 for(xml_coll_t li(x_det,_U(layer)); li; ++li) {
83 xml_comp_t x_layer = li;
84 int repeat = x_layer.repeat();
86 for (
int j=0; j<repeat; j++) {
87 string l_name = _toString(l_num,
"layer%d");
88 double l_thickness = layering.layer(l_num-1)->thickness();
89 double xcut = (l_thickness / tan_beta);
92 Position l_pos(0,0,l_pos_z+l_thickness/2);
93 Box l_box(l_dim_x*2-tolerance,stave_z*2-tolerance,l_thickness-tolerance);
94 Volume l_vol(l_name,l_box,air);
95 DetElement layer(stave_det, l_name, det_id);
99 double s_pos_z = -(l_thickness / 2);
100 for(xml_coll_t si(x_layer,_U(slice)); si; ++si) {
101 xml_comp_t x_slice = si;
102 string s_name = _toString(s_num,
"slice%d");
103 double s_thick = x_slice.thickness();
104 Box s_box(l_dim_x*2-tolerance,stave_z*2-tolerance,s_thick-tolerance);
105 Volume s_vol(s_name,s_box,lcdd.material(x_slice.materialStr()));
106 DetElement slice(layer,s_name,det_id);
108 if ( x_slice.isSensitive() ) {
109 s_vol.setSensitiveDetector(sens);
111 slice.setAttributes(lcdd,s_vol,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
114 PlacedVolume slice_phv = l_vol.placeVolume(s_vol,Position(0,0,s_pos_z+s_thick/2));
115 slice_phv.addPhysVolID(
"slice", s_num);
116 slice.setPlacement(slice_phv);
125 layer.setAttributes(lcdd,l_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
127 PlacedVolume layer_phv = mod_vol.placeVolume(l_vol,l_pos);
128 layer_phv.addPhysVolID(
"layer", l_num);
129 layer.setPlacement(layer_phv);
131 l_pos_z += l_thickness;
139 mod_vol.setVisAttributes(lcdd.visAttributes(x_staves.visStr()));
142 double phi = M_PI / nsides;
143 double mod_x_off = dx / 2;
144 double mod_y_off = inner_r + mod_z/2;
147 for (
int i = 0; i < nsides; i++, phi -= dphi) {
149 double m_pos_x = mod_x_off * std::cos(phi) - mod_y_off * std::sin(phi);
150 double m_pos_y = mod_x_off * std::sin(phi) + mod_y_off * std::cos(phi);
151 Transform3D tr(RotationZYX(0,phi,M_PI*0.5),Translation3D(-m_pos_x,-m_pos_y,0));
152 PlacedVolume pv = envelope.placeVolume(mod_vol,tr);
153 pv.addPhysVolID(
"system",det_id);
154 pv.addPhysVolID(
"barrel",0);
155 pv.addPhysVolID(
"module",i+1);
156 DetElement sd = i==0 ? stave_det : stave_det.clone(_toString(i,
"stave%d"));
162 envelope.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());