File indexing completed on 2025-01-18 09:14:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "DD4hep/DetFactoryHelper.h"
0018 #include "DD4hep/Printout.h"
0019
0020 using namespace std;
0021 using namespace dd4hep;
0022 using namespace dd4hep::detail;
0023
0024 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0025 typedef vector<PlacedVolume> Placements;
0026 xml_det_t x_det = e;
0027 Material air = description.air();
0028 int det_id = x_det.id();
0029 string det_name = x_det.nameStr();
0030 DetElement sdet (det_name,det_id);
0031 Assembly assembly (det_name);
0032 map<string, Volume> volumes;
0033 map<string, Placements> sensitives;
0034 PlacedVolume pv;
0035
0036 sens.setType("tracker");
0037 for(xml_coll_t mi(x_det,_U(module)); mi; ++mi) {
0038 xml_comp_t x_mod = mi;
0039 xml_comp_t m_env = x_mod.child(_U(module_envelope));
0040 string m_nam = x_mod.nameStr();
0041 Volume m_vol(m_nam,Box(m_env.width()/2,m_env.length()/2,m_env.thickness()/2),air);
0042 int ncomponents = 0, sensor_number = 1;
0043
0044 if ( volumes.find(m_nam) != volumes.end() ) {
0045 printout(ERROR,"SiTrackerBarrel","Logics error in building modules.");
0046 throw runtime_error("Logics error in building modules.");
0047 }
0048 volumes[m_nam] = m_vol;
0049 m_vol.setVisAttributes(description.visAttributes(x_mod.visStr()));
0050 for(xml_coll_t ci(x_mod,_U(module_component)); ci; ++ci, ++ncomponents) {
0051 xml_comp_t x_comp = ci;
0052 xml_comp_t x_pos = x_comp.position(false);
0053 xml_comp_t x_rot = x_comp.rotation(false);
0054 string c_nam = _toString(ncomponents,"component%d");
0055 Box c_box(x_comp.width()/2,x_comp.length()/2,x_comp.thickness()/2);
0056 Volume c_vol(c_nam,c_box,description.material(x_comp.materialStr()));
0057
0058 if ( x_pos && x_rot ) {
0059 Position c_pos(x_pos.x(0),x_pos.y(0),x_pos.z(0));
0060 RotationZYX c_rot(x_rot.z(0),x_rot.y(0),x_rot.x(0));
0061 pv = m_vol.placeVolume(c_vol, Transform3D(c_rot,c_pos));
0062 }
0063 else if ( x_rot ) {
0064 pv = m_vol.placeVolume(c_vol,RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0)));
0065 }
0066 else if ( x_pos ) {
0067 pv = m_vol.placeVolume(c_vol,Position(x_pos.x(0),x_pos.y(0),x_pos.z(0)));
0068 }
0069 else {
0070 pv = m_vol.placeVolume(c_vol);
0071 }
0072 c_vol.setRegion(description, x_comp.regionStr());
0073 c_vol.setLimitSet(description, x_comp.limitsStr());
0074 c_vol.setVisAttributes(description, x_comp.visStr());
0075 if ( x_comp.isSensitive() ) {
0076 pv.addPhysVolID(_U(sensor),sensor_number++);
0077 c_vol.setSensitiveDetector(sens);
0078 sensitives[m_nam].push_back(pv);
0079 }
0080 }
0081 }
0082 for(xml_coll_t li(x_det,_U(layer)); li; ++li) {
0083 xml_comp_t x_layer = li;
0084 xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope));
0085 xml_comp_t x_layout = x_layer.child(_U(rphi_layout));
0086 xml_comp_t z_layout = x_layer.child(_U(z_layout));
0087 int lay_id = x_layer.id();
0088 string m_nam = x_layer.moduleStr();
0089 string lay_nam = _toString(x_layer.id(),"layer%d");
0090 Tube lay_tub (x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length()/2);
0091 Volume lay_vol (lay_nam,lay_tub,air);
0092 double phi0 = x_layout.phi0();
0093 double phi_tilt = x_layout.phi_tilt();
0094 double rc = x_layout.rc();
0095 int nphi = x_layout.nphi();
0096 double rphi_dr = x_layout.dr();
0097 double phi_incr = (M_PI * 2) / nphi;
0098 double phic = phi0;
0099 double z0 = z_layout.z0();
0100 double nz = z_layout.nz();
0101 double z_dr = z_layout.dr();
0102 Volume m_env = volumes[m_nam];
0103 DetElement lay_elt(sdet,_toString(x_layer.id(),"layer%d"),lay_id);
0104 Placements& sensVols = sensitives[m_nam];
0105
0106
0107
0108
0109 double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0;
0110
0111 double module_z = -z0;
0112 int module = 1;
0113
0114
0115 for (int ii = 0; ii < nphi; ii++) {
0116 double dx = z_dr * std::cos(phic + phi_tilt);
0117 double dy = z_dr * std::sin(phic + phi_tilt);
0118 double x = rc * std::cos(phic);
0119 double y = rc * std::sin(phic);
0120
0121
0122 for (int j = 0; j < nz; j++) {
0123 string module_name = _toString(module,"module%d");
0124 DetElement mod_elt(lay_elt,module_name,module);
0125
0126
0127
0128 Transform3D tr(RotationZYX(0,((M_PI/2)-phic-phi_tilt),-M_PI/2),Position(x,y,module_z));
0129
0130 pv = lay_vol.placeVolume(m_env,tr);
0131 pv.addPhysVolID("module", module);
0132 mod_elt.setPlacement(pv);
0133 for(size_t ic=0; ic<sensVols.size(); ++ic) {
0134 PlacedVolume sens_pv = sensVols[ic];
0135 DetElement comp_elt(mod_elt,sens_pv.volume().name(),module);
0136 comp_elt.setPlacement(sens_pv);
0137 }
0138
0139
0140 module++;
0141
0142 x += dx;
0143 y += dy;
0144
0145 dx *= -1;
0146 dy *= -1;
0147
0148 module_z += z_incr;
0149 }
0150 phic += phi_incr;
0151 rc += rphi_dr;
0152 rphi_dr *= -1;
0153 module_z = -z0;
0154 }
0155
0156 pv = assembly.placeVolume(lay_vol);
0157 pv.addPhysVolID("layer", lay_id);
0158 lay_elt.setAttributes(description,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
0159 lay_elt.setPlacement(pv);
0160 }
0161 sdet.setAttributes(description,assembly,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
0162 assembly.setVisAttributes(description.invisible());
0163 pv = description.pickMotherVolume(sdet).placeVolume(assembly);
0164 pv.addPhysVolID("system", det_id);
0165 pv.addPhysVolID("barrel", 0);
0166 sdet.setPlacement(pv);
0167 return sdet;
0168 }
0169
0170 DECLARE_DETELEMENT(DD4hep_SiTrackerBarrel,create_detector)
0171