File indexing completed on 2025-01-18 09:14:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include "DD4hep/DetFactoryHelper.h"
0020 #include "DDRec/Surface.h"
0021 #include "DDRec/DetectorData.h"
0022 #include <exception>
0023
0024 #include "DD4hep/Printout.h"
0025
0026 using namespace std;
0027 using namespace dd4hep;
0028 using namespace dd4hep::detail;
0029 using namespace dd4hep::rec;
0030
0031
0032
0033
0034 static double computeDpt( double ra, double rb, double theta ) {
0035 double dpt_sin = std::pow(ra * std::sin(theta), 2.0);
0036 double dpt_cos = std::pow(rb * std::cos(theta), 2.0);
0037 double dp = std::sqrt(dpt_sin + dpt_cos);
0038 return dp;
0039 }
0040
0041 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0042 xml_det_t x_det = e;
0043 Material air = description.air();
0044 int det_id = x_det.id();
0045 string det_name = x_det.nameStr();
0046 DetElement sdet (det_name,det_id);
0047 Assembly assembly (det_name+"_assembly");
0048 map<string, Volume> volumes;
0049 PlacedVolume pv;
0050
0051 double mod_width = 0.0;
0052 mod_width = 1.;
0053
0054 sens.setType("tracker");
0055 for(xml_coll_t mi(x_det,_U(module)); mi; ++mi) {
0056 xml_comp_t x_mod = mi;
0057 xml_comp_t m_env = x_mod.child(_U(module_envelope));
0058 string m_nam = x_mod.nameStr();
0059
0060 mod_width = m_env.width();
0061
0062 Volume m_vol(det_name+"_"+m_nam,Box(m_env.width()/2,m_env.length()/2,m_env.thickness()/2),air);
0063 int ncomponents = 0, sensor_number = 1;
0064
0065 if ( volumes.find(m_nam) != volumes.end() ) {
0066 printout(ERROR,"SiTrackerBarrel","Logics error in building modules.");
0067 throw runtime_error("Logics error in building modules.");
0068 }
0069 volumes[m_nam] = m_vol;
0070
0071 for(xml_coll_t ci(x_mod,_U(module_component)); ci; ++ci, ++ncomponents) {
0072 xml_comp_t x_comp = ci;
0073 xml_comp_t x_pos = x_comp.position(false);
0074 xml_comp_t x_rot = x_comp.rotation(false);
0075 string c_nam = det_name+"_"+m_nam+_toString(ncomponents,"_component%d");
0076 Box c_box(x_comp.width()/2,x_comp.length()/2,x_comp.thickness()/2);
0077 Volume c_vol(c_nam,c_box,description.material(x_comp.materialStr()));
0078
0079 if ( x_pos && x_rot ) {
0080 Position c_pos(x_pos.x(0),x_pos.y(0),x_pos.z(0));
0081 RotationZYX c_rot(x_rot.z(0),x_rot.y(0),x_rot.x(0));
0082 pv = m_vol.placeVolume(c_vol, Transform3D(c_rot,c_pos));
0083 }
0084 else if ( x_rot ) {
0085 pv = m_vol.placeVolume(c_vol,RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0)));
0086 }
0087 else if ( x_pos ) {
0088 pv = m_vol.placeVolume(c_vol,Position(x_pos.x(0),x_pos.y(0),x_pos.z(0)));
0089 }
0090 else {
0091 pv = m_vol.placeVolume(c_vol);
0092 }
0093 c_vol.setRegion(description, x_comp.regionStr());
0094 c_vol.setLimitSet(description, x_comp.limitsStr());
0095 c_vol.setVisAttributes(description, x_comp.visStr());
0096 if ( x_comp.isSensitive() ) {
0097 pv.addPhysVolID(_U(sensor),sensor_number++);
0098 c_vol.setSensitiveDetector(sens);
0099 }
0100 }
0101 m_vol.setVisAttributes(description.visAttributes(x_mod.visStr()));
0102 }
0103
0104 for(xml_coll_t li(x_det,_U(layer)); li; ++li) {
0105 xml_comp_t x_layer = li;
0106 xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope));
0107 xml_comp_t x_layout = x_layer.child(_U(rphi_layout));
0108 xml_comp_t z_layout = x_layer.child(_U(z_layout));
0109 int lay_id = x_layer.id();
0110 string m_nam = x_layer.moduleStr();
0111 Volume m_env = volumes[m_nam];
0112 string lay_nam = det_name+"_"+m_nam+_toString(x_layer.id(),"_layer%d");
0113
0114 double phi0 = x_layout.phi0();
0115 double phi_tilt = x_layout.phi_tilt();
0116 double rc = x_layout.rc();
0117 double rphi_dr = x_layout.dr();
0118 double phic = phi0;
0119 double z0 = z_layout.z0();
0120 double nz = z_layout.nz();
0121 double z_dr = z_layout.dr();
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0;
0132
0133 double module_z = -z0;
0134 int module = 1;
0135
0136
0137 double c0;
0138 if (x_layer.id() <=1 ) c0 = 2.;
0139 else if (x_layer.id() == 2 ) c0 = 1.9;
0140 else if (x_layer.id() == 3 ) c0 = 1.45;
0141 else c0 = 1.23;
0142
0143
0144 double env_rmin = x_barrel.inner_r();
0145 double env_rmax = x_barrel.outer_r();
0146 double env_z = x_barrel.z_length();
0147
0148 EllipticalTube envElTubeOut(c0*env_rmax,env_rmax, env_z);
0149 EllipticalTube envElTubeInn(c0*env_rmin,env_rmin, env_z+0.01);
0150 SubtractionSolid envElTube(envElTubeOut,envElTubeInn);
0151
0152 Tube envTube1(env_rmin, env_rmax, env_z+0.01, 3*M_PI/2, M_PI/2);
0153 UnionSolid lay_tub1(envElTube,envTube1);
0154
0155 Tube envTube2(env_rmax, c0*env_rmax, env_z+0.01, 3*M_PI/2, M_PI/2);
0156 SubtractionSolid lay_tub(lay_tub1,envTube2);
0157 Volume lay_vol (lay_nam,lay_tub,air);
0158
0159
0160
0161
0162
0163
0164 double a = c0 * rc;
0165 double b = rc;
0166 double theta = 0.;
0167 double thetaMin = M_PI / 2.;
0168 double thetaMax = M_PI * 3. / 2.;
0169 double deltaTheta = 0.0001;
0170 double numIntegrals = (thetaMax-thetaMin) / deltaTheta;
0171 double cell = 0.;
0172
0173
0174 for( int i=0; i < numIntegrals; i++ ) {
0175 if (i==0) theta = thetaMin;
0176 else theta += deltaTheta;
0177 cell += computeDpt( a, b, theta);
0178 }
0179
0180
0181 int n_ell = (cell * deltaTheta / mod_width);
0182 int nextPoint = 0;
0183 double run = 0.;
0184 theta = 0.;
0185
0186 for( int i=0; i < numIntegrals; i++ ) {
0187 if (i==0) theta = thetaMin;
0188 else theta += deltaTheta;
0189 double subIntegral = n_ell*run/cell;
0190 if( (int) subIntegral >= nextPoint ) {
0191 double x = a * std::cos(theta);
0192 double y = b * std::sin(theta);
0193
0194 for (int j = 0; j < nz; j++) {
0195
0196 Transform3D tr(RotationZYX(0,M_PI/2-theta,-M_PI/2),Position(x,y,module_z));
0197 pv = lay_vol.placeVolume(m_env,tr);
0198 pv.addPhysVolID("module", module++);
0199
0200 module_z += z_incr;
0201 }
0202 nextPoint++;
0203 }
0204 run += computeDpt(a, b, theta);
0205 }
0206
0207
0208
0209
0210
0211
0212
0213 double c_circ = 2 * M_PI * rc;
0214 int n_circ = c_circ / mod_width / 2;
0215 double phi_incr = (M_PI) / n_circ;
0216
0217
0218
0219 for (int ii = 0; ii < n_circ; ii++) {
0220
0221 double dx = z_dr * std::cos(phic + phi_tilt);
0222 double dy = z_dr * std::sin(phic + phi_tilt);
0223 double x = rc * std::cos(phic);
0224 double y = rc * std::sin(phic);
0225
0226
0227 for (int j = 0; j < nz; j++) {
0228
0229
0230
0231 Transform3D tr(RotationZYX(0,((M_PI/2)-phic-phi_tilt),-M_PI/2),Position(x,y,module_z));
0232 pv = lay_vol.placeVolume(m_env,tr);
0233 pv.addPhysVolID("module", module++);
0234
0235 x += dx;
0236 y += dy;
0237
0238 dx *= -1;
0239 dy *= -1;
0240
0241 module_z += z_incr;
0242 }
0243 phic += phi_incr;
0244 rc += rphi_dr;
0245 rphi_dr *= -1;
0246 module_z = -z0;
0247 }
0248
0249
0250 assembly.setVisAttributes(description.invisible());
0251 pv = assembly.placeVolume(lay_vol);
0252 pv.addPhysVolID("layer", lay_id);
0253 DetElement m_elt(sdet,lay_nam,lay_id);
0254 m_elt.setAttributes(description,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
0255 m_elt.setPlacement(pv);
0256 }
0257
0258 pv = description.pickMotherVolume(sdet).placeVolume(assembly);
0259 pv.addPhysVolID("system", det_id);
0260 pv.addPhysVolID("barrel", 0);
0261 sdet.setPlacement(pv);
0262 return sdet;
0263 }
0264
0265 DECLARE_DETELEMENT(Lhe_BP_SiVertexBarrel,create_detector)