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