File indexing completed on 2025-01-18 09:14:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "DD4hep/DetFactoryHelper.h"
0016 #include "DD4hep/Printout.h"
0017 #include "DD4hep/Detector.h"
0018
0019
0020 #include <iostream>
0021 #include <map>
0022
0023 using namespace dd4hep;
0024
0025 namespace {
0026
0027 struct MyDetExtension {
0028 int idD, Ni, Nj;
0029 double dimDX, dimDY, dimDZ;
0030 double pixelX, pixelY, pixelZ;
0031 DetElement detector;
0032
0033 MyDetExtension(DetElement e) : idD(0), Ni(0), Nj(0),
0034 dimDX(0.0), dimDY(0.0), dimDZ(0.0),
0035 pixelX(0.0), pixelY(0.0), pixelZ(0.0), detector(e) {}
0036 MyDetExtension(const MyDetExtension& e, DetElement d)
0037 : idD(e.idD), Ni(e.Ni), Nj(e.Nj),
0038 dimDX(e.dimDX), dimDY(e.dimDY), dimDZ(e.dimDZ),
0039 pixelX(e.pixelX), pixelY(e.pixelY), pixelZ(e.pixelZ),
0040 detector(d)
0041 {
0042 }
0043 };
0044 }
0045 typedef MyDetExtension DetectorExtension;
0046
0047 static Ref_t create_detector(Detector &description, xml_h e, SensitiveDetector sens) {
0048 xml_det_t x_det = e;
0049 xml_comp_t det_dim = x_det.child(_U(dimensions));
0050 xml_comp_t det_mod = x_det.child(_U(module));
0051 std::string det_name = x_det.nameStr();
0052 Assembly assembly (det_name);
0053 DetElement sdet(det_name,x_det.id());
0054 Volume motherVol = description.pickMotherVolume(sdet);
0055 Material mat = description.material("Silicon");
0056
0057 DetectorExtension* ext = new MyDetExtension(sdet);
0058 sdet.addExtension<MyDetExtension>(ext);
0059 ext->idD = x_det.id();
0060 ext->dimDX = det_dim.x();
0061 ext->dimDY = det_dim.y();
0062 ext->dimDZ = det_dim.z();
0063 ext->pixelX = det_mod.x();
0064 ext->pixelY = det_mod.y();
0065 ext->pixelZ = det_mod.z();
0066 ext->Ni = int(det_dim.x()/det_mod.x());
0067 ext->Nj = int(det_dim.y()/det_mod.y());
0068
0069 assembly.setVisAttributes(description.visAttributes(x_det.visStr()));
0070
0071 Box sensor_box(Box(det_dim.x(),det_dim.y(),det_dim.z()));
0072 Volume sensor_vol(det_name, sensor_box, mat);
0073 sensor_vol.setVisAttributes(description.visAttributes(det_mod.visStr()));
0074 sensor_vol.setLimitSet(description, x_det.limitsStr());
0075 sensor_vol.setRegion(description, x_det.regionStr());
0076 sensor_vol.setSensitiveDetector(sens);
0077 if ( x_det.isSensitive() ) {
0078 sens.setType("tracker");
0079 }
0080 PlacedVolume pv;
0081 DetElement side_det;
0082 double epsilon = 1e-10;
0083 Position side_pos(0,0,30*dd4hep::mm);
0084 Position env_dim_min(sensor_box.x()+epsilon, sensor_box.y()+epsilon, +100000.0);
0085 Position env_dim_max(sensor_box.x()+epsilon, sensor_box.y()+epsilon, -100000.0);
0086
0087 for( xml_coll_t mod(x_det, _U(module_position)); mod; mod++ ) {
0088 xml_comp_t x_pos = mod;
0089 if ( x_pos.z() > env_dim_max.z() ) {
0090 env_dim_max.SetZ(x_pos.z());
0091 printout(DEBUG,"MiniTel","Envelope z_max = %f",x_pos.z());
0092 }
0093 if ( x_pos.z() < env_dim_min.z() ) {
0094 env_dim_min.SetZ(x_pos.z());
0095 printout(DEBUG,"MiniTel","Envelope z_min = %f",x_pos.z());
0096 }
0097 }
0098
0099 Volume side_vol;
0100 if ( x_det.hasChild(_U(assembly)) ) {
0101 side_vol = Assembly("side_0");
0102 printout(DEBUG,"MiniTel","Using assembly envelope");
0103 }
0104 else {
0105 Box side_box(env_dim_max.x(), env_dim_max.y(), (env_dim_max.z()-env_dim_min.z())/2.0+sensor_box.z() + epsilon);
0106 side_vol = Volume("side_0", side_box, description.air());
0107 printout(DEBUG,"MiniTel","Envelope Box = %f",side_box.z());
0108 }
0109 side_det = DetElement(sdet,"side_0", x_det.id());
0110 if ( x_det.hasChild(_U(side_position)) ) {
0111 xml_comp_t x_pos = x_det.child(_U(side_position));
0112 side_pos = Position(x_pos.x(0), x_pos.y(0), x_pos.z(3*dd4hep::cm));
0113 printout(ALWAYS,"","side_pos = %f",side_pos.z());
0114 }
0115
0116 Unicode tag("missing_module_placements");
0117 xml_dim_t miss = x_det.child(tag, false);
0118 int missing_placement = miss ? miss.number() : 0;
0119 pv = assembly.placeVolume(side_vol, side_pos);
0120 pv.addPhysVolID("side",0);
0121 side_det.setPlacement(pv);
0122 int count = 0;
0123 for( xml_coll_t mpos(x_det, _U(module_position)); mpos; mpos++ ) {
0124 xml_comp_t x_pos = mpos;
0125 DetElement module(side_det, _toString(count, "module_%d"), count);
0126 pv = side_vol.placeVolume(sensor_vol,Transform3D(Position(x_pos.x(),x_pos.y(),x_pos.z())));
0127 pv.addPhysVolID("module", ++count);
0128 if ( missing_placement > 0 && count%missing_placement == 0 ) {
0129 printout(WARNING,"","Drop placement of DetElement: %s", module.path().c_str());
0130 continue;
0131 }
0132 module.setPlacement(pv);
0133 }
0134
0135 if ( x_det.hasChild(_U(reflect)) ) {
0136 xml_comp_t x_pos = x_det.child(_U(reflect));
0137 side_pos = Position(x_pos.x(-side_pos.x()), x_pos.y(-side_pos.y()), x_pos.z(-side_pos.z()));
0138 auto [det, vol] = side_det.reflect("side_1", x_det.id(), sens);
0139 pv = assembly.placeVolume(vol, Transform3D(RotationZ(M_PI),side_pos));
0140 pv.addPhysVolID("side",1);
0141 det.setPlacement(pv);
0142 sdet.add(det);
0143 }
0144
0145 pv = motherVol.placeVolume(assembly);
0146 pv.addPhysVolID("system", x_det.id());
0147 sdet.setPlacement(pv);
0148 return sdet;
0149 }
0150
0151 DECLARE_DETELEMENT(MiniTelPixel,create_detector)