File indexing completed on 2025-01-18 09:14:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include <DD4hep/DetFactoryHelper.h>
0040 #include <DD4hep/Printout.h>
0041
0042
0043 #include <iomanip>
0044
0045 using namespace std;
0046 using namespace dd4hep;
0047 using namespace dd4hep::detail;
0048
0049 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0050 constexpr double tol = 0.0;
0051 xml_det_t x_det = e;
0052
0053
0054 int det_id = x_det.id();
0055 string det_name = x_det.nameStr();
0056 Material air = description.air();
0057
0058
0059
0060 xml_comp_t x_dim = x_det.dimensions();
0061 double hthick = x_dim.thickness();
0062 double hzlength = x_dim.z_length()/2.;
0063
0064
0065 xml_comp_t fX_struct( x_det.child( _Unicode(structure) ) );
0066 xml_comp_t fX_absorb( fX_struct.child( _Unicode(absorb) ) );
0067 xml_comp_t fX_core1( fX_struct.child( _Unicode(core1) ) );
0068 xml_comp_t fX_core2( fX_struct.child( _Unicode(core2) ) );
0069 xml_comp_t fX_hole( fX_struct.child( _Unicode(hole) ) );
0070 xml_comp_t fX_phdet1( fX_struct.child( _Unicode(phdet1) ) );
0071 xml_comp_t fX_phdet2( fX_struct.child( _Unicode(phdet2) ) );
0072
0073 Material mat;
0074 Transform3D trafo;
0075 PlacedVolume pv;
0076 Solid sol;
0077
0078 sens.setType("calorimeter");
0079
0080
0081 sol = Tube(0., fX_core1.rmax(), hzlength);
0082 mat = description.material(fX_core1.materialStr());
0083 Volume fiber_scint_vol(fX_core1.nameStr(), sol, mat);
0084 fiber_scint_vol.setAttributes(description, fX_core1.regionStr(), fX_core1.limitsStr(), fX_core1.visStr());
0085 if ( fX_core1.isSensitive() ) {
0086 fiber_scint_vol.setSensitiveDetector(sens);
0087 }
0088 cout << setw(28) << left << fiber_scint_vol.name()
0089 << " mat: " << setw(15) << left << mat.name()
0090 << " vis: " << setw(15) << left<< fX_core1.visStr()
0091 << " solid: " << setw(20) << left << sol.type()
0092 << " sensitive: " << yes_no(fX_core1.isSensitive()) << endl;
0093
0094
0095 sol = Tube(0., fX_core2.rmax(), hzlength);
0096 mat = description.material(fX_core2.materialStr());
0097 Volume fiber_quartz_vol(fX_core2.nameStr(), sol, mat);
0098 fiber_quartz_vol.setAttributes(description, fX_core2.regionStr(), fX_core2.limitsStr(), fX_core2.visStr());
0099 if ( fX_core2.isSensitive() ) {
0100 fiber_quartz_vol.setSensitiveDetector(sens);
0101 }
0102 cout << setw(28) << left << fiber_quartz_vol.name()
0103 << " mat: " << setw(15) << left << mat.name()
0104 << " vis: " << setw(15) << left << fX_core2.visStr()
0105 << " solid: " << setw(20) << left << sol.type()
0106 << " sensitive: " << yes_no(fX_core2.isSensitive()) << endl;
0107
0108
0109 mat = description.material(fX_hole.materialStr());
0110 sol = Tube(0., fX_hole.rmax(), hzlength);
0111 Volume scint_hole_vol( fX_core1.nameStr()+"_hole", sol, mat);
0112 scint_hole_vol.setAttributes(description, fX_hole.regionStr(), fX_hole.limitsStr(), fX_hole.visStr());
0113 trafo = Transform3D(RotationZYX(0.,0.,0.),Position(0.,0.,0.));
0114 pv = scint_hole_vol.placeVolume(fiber_scint_vol, trafo);
0115 pv.addPhysVolID("type",1);
0116 cout << setw(28) << left << scint_hole_vol.name()
0117 << " mat: " << setw(15) << left << mat.name()
0118 << " vis: " << setw(15) << left << fX_hole.visStr()
0119 << " solid: " << setw(20) << left << sol.type()
0120 << " sensitive: " << yes_no(fX_hole.isSensitive()) << endl;
0121 if ( fX_hole.isSensitive() ) {
0122 scint_hole_vol.setSensitiveDetector(sens);
0123 }
0124
0125
0126 Volume quartz_hole_vol( fX_core2.nameStr()+"_hole", sol, mat);
0127 quartz_hole_vol.setAttributes(description, fX_hole.regionStr(), fX_hole.limitsStr(), fX_hole.visStr());
0128 pv = quartz_hole_vol.placeVolume(fiber_quartz_vol);
0129 pv.addPhysVolID("type",2);
0130 cout << setw(28) << left << quartz_hole_vol.name()
0131 << " mat: " << setw(15) << left << mat.name()
0132 << " vis: " << setw(15) << left << fX_hole.visStr()
0133 << " solid: " << setw(20) << left << sol.type()
0134 << " sensitive: " << yes_no(fX_hole.isSensitive()) << endl;
0135 if ( fX_hole.isSensitive() ) {
0136 quartz_hole_vol.setSensitiveDetector(sens);
0137 }
0138
0139
0140 mat = description.material(fX_absorb.materialStr());
0141 sol = Tube(0., hthick, hzlength);
0142 Volume scint_abs_vol( fX_core1.nameStr()+"_absorber", sol, mat);
0143 scint_abs_vol.setAttributes(description, fX_absorb.regionStr(), fX_absorb.limitsStr(), fX_absorb.visStr());
0144 pv = scint_abs_vol.placeVolume(scint_hole_vol);
0145 pv.addPhysVolID("hole",1);
0146 cout << setw(28) << left << scint_abs_vol.name()
0147 << " mat: " << setw(15) << left << mat.name()
0148 << " vis: " << setw(15) << left << fX_absorb.visStr()
0149 << " solid: " << setw(20) << left << sol.type()
0150 << " sensitive: " << yes_no(fX_absorb.isSensitive()) << endl;
0151 if ( fX_absorb.isSensitive() ) {
0152 scint_abs_vol.setSensitiveDetector(sens);
0153 }
0154
0155
0156 mat = description.material(fX_absorb.materialStr());
0157 Volume quartz_abs_vol(fX_core2.nameStr()+"_absorber", sol, mat);
0158 quartz_abs_vol.setAttributes(description, fX_absorb.regionStr(), fX_absorb.limitsStr(), fX_absorb.visStr());
0159 pv = quartz_abs_vol.placeVolume(quartz_hole_vol, trafo);
0160 pv.addPhysVolID("hole",2);
0161 cout << setw(28) << left << quartz_abs_vol.name()
0162 << " mat: " << setw(15) << left << mat.name()
0163 << " vis: " << setw(15) << left << fX_absorb.visStr()
0164 << " solid: " << setw(20) << left << sol.type()
0165 << " sensitive: " << yes_no(fX_absorb.isSensitive()) << endl;
0166 if ( fX_absorb.isSensitive() ) {
0167 quartz_abs_vol.setSensitiveDetector(sens);
0168 }
0169
0170
0171 int Ncount = x_dim.numsides();
0172 double hzph = x_dim.z1();
0173 double agap = x_dim.gap();
0174 double dx = 2*(Ncount + Ncount+1)/2e0 * (hthick+agap) + tol;
0175 double dy = hthick + tol;
0176 double dz = hzlength+hzph + tol;
0177 Box tube_row_box(dx, dy, dz);
0178 Volume tube_row_vol("layer", tube_row_box, air);
0179 tube_row_vol.setVisAttributes(description, x_det.visStr());
0180 tube_row_vol.setSensitiveDetector(sens);
0181 cout << tube_row_vol.name()
0182 << " dx: " << tube_row_box.x()
0183 << " dy: " << tube_row_box.y()
0184 << " dz: " << tube_row_box.z() << endl;
0185 tube_row_vol.setVisAttributes(description, "layerVis");
0186
0187 for (int ijk=-Ncount; ijk<Ncount+1; ijk++) {
0188 double mod_x_off = (ijk) * 2 * (hthick + agap);
0189 int towernum = Ncount + ijk + 1;
0190 pv = tube_row_vol.placeVolume((towernum%2 == 0) ? quartz_abs_vol : scint_abs_vol, Position(mod_x_off,0.,0.));
0191 pv.addPhysVolID("tube", towernum);
0192 cout << "Placing row " << setw(5) << right << ijk
0193 << " x-offset: " << setw(7) << right << mod_x_off
0194 << " volume of type " << pv.volume().name()
0195 << endl;
0196 }
0197
0198 dy = 2*(Ncount + Ncount+1)/2e0 * (hthick+agap) + tol;
0199 DetElement sdet(det_name, det_id);
0200 Box env_box(dx+tol, dy+tol, dz+tol);
0201 Volume envelopeVol(det_name, env_box, air);
0202 envelopeVol.setAttributes(description, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
0203 if ( x_dim.isSensitive() ) {
0204 envelopeVol.setSensitiveDetector(sens);
0205 }
0206
0207
0208 for (int ijk=-Ncount; ijk < Ncount+1; ijk++) {
0209 double mod_y_off = (ijk) * 2 * (tube_row_box.y() + agap);
0210 Transform3D tr(RotationZYX(0.,0.,0.), Position(0.,mod_y_off,0.));
0211 pv = envelopeVol.placeVolume(tube_row_vol, tr);
0212 pv.addPhysVolID("layer", Ncount+ijk+1);
0213
0214 DetElement de_layer(_toString(Ncount+ijk, "layer_%d"), det_id);
0215 de_layer.setPlacement(pv);
0216 sdet.add(de_layer);
0217 cout << "Placing " << setw(28) << left << de_layer.name()
0218 << " y-offset: " << setw(7) << right << mod_y_off
0219 << " volume of type " << pv.volume().name()
0220 << endl;
0221 }
0222
0223
0224 dz = x_dim.zmin()+hzlength+hzph+tol;
0225 Volume motherVol = description.pickMotherVolume(sdet);
0226 pv = motherVol.placeVolume(envelopeVol, Position(0, 0, dz));
0227 pv.addPhysVolID("system", det_id);
0228 sdet.setPlacement(pv);
0229 return sdet;
0230 }
0231
0232 DECLARE_DETELEMENT(DD4hep_FiberTubeCalorimeter,create_detector)