File indexing completed on 2025-12-16 09:28:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "DD4hep/DetFactoryHelper.h"
0011 #include "DD4hep/Printout.h"
0012 #include "TMath.h"
0013 #include <XML/Helper.h>
0014
0015 using namespace std;
0016 using namespace dd4hep;
0017
0018 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0019
0020 using namespace ROOT::Math;
0021 xml_det_t x_det = e;
0022 string det_name = x_det.nameStr();
0023 int det_id = x_det.id();
0024 Material m_Vacuum = description.material("Vacuum");
0025 string vis_name = dd4hep::getAttrOrDefault<std::string>(x_det, _Unicode(vis), "BeamPipeVis");
0026
0027 sens.setType("tracker");
0028
0029 DetElement sdet(det_name, det_id);
0030 Assembly assembly(det_name + "_assembly");
0031
0032
0033 for (xml_coll_t slice_coll(x_det, _Unicode(slice)); slice_coll; slice_coll++) {
0034
0035 string grandmotherName = slice_coll.attr<string>(_Unicode(grandmother));
0036 string motherName = slice_coll.attr<string>(_Unicode(mother));
0037 bool detStart = getAttrOrDefault<bool>(slice_coll, _Unicode(end), true);
0038 int pipe_id = getAttrOrDefault<int>(slice_coll, _Unicode(pipe_id), 0);
0039 string slice_name = slice_coll.attr<string>(_Unicode(name));
0040 DetElement mother = description.detector(grandmotherName).child(motherName);
0041
0042
0043 Volume mother_vol = mother.volume();
0044
0045 double sensitive_thickness = 0.1 * mm;
0046 Solid sensitive_solid;
0047 Transform3D disk_transform;
0048
0049
0050 bool use_plane_xs = getAttrOrDefault<bool>(slice_coll, _Unicode(use_cross_section), false);
0051
0052 if (use_plane_xs) {
0053
0054
0055 double plane_x = getAttrOrDefault<double>(slice_coll, _Unicode(plane_x), 0.0);
0056 double plane_y = getAttrOrDefault<double>(slice_coll, _Unicode(plane_y), 0.0);
0057 double plane_z = getAttrOrDefault<double>(slice_coll, _Unicode(plane_z), 0.0);
0058 double plane_yrot = getAttrOrDefault<double>(slice_coll, _Unicode(plane_yrot), 0.0);
0059
0060
0061 auto mother_matrix = mother.nominal().worldTransformation();
0062 const Double_t* translation = mother_matrix.GetTranslation();
0063 const Double_t* rotation = mother_matrix.GetRotationMatrix();
0064
0065
0066 Transform3D mother_to_world(rotation[0], rotation[1], rotation[2], translation[0],
0067 rotation[3], rotation[4], rotation[5], translation[1],
0068 rotation[6], rotation[7], rotation[8], translation[2]);
0069
0070
0071 Position plane_pos_world(plane_x, plane_y, plane_z);
0072 RotationY plane_rot_world(plane_yrot);
0073 Transform3D plane_transform_world(plane_rot_world, plane_pos_world);
0074
0075
0076 disk_transform = mother_to_world.Inverse() * plane_transform_world;
0077
0078
0079 double max_dim = getAttrOrDefault<double>(slice_coll, _Unicode(max_dimension), 1.0 * m);
0080
0081
0082 Box cutting_box(max_dim, max_dim, sensitive_thickness / 2);
0083
0084
0085
0086 sensitive_solid =
0087 IntersectionSolid(cutting_box, mother_vol.solid(), disk_transform.Inverse());
0088
0089 } else {
0090
0091 ConeSegment mother_shape = mother_vol.solid();
0092
0093
0094 double rOuter1 = mother_shape.rMax1();
0095 double rOuter2 = mother_shape.rMax2();
0096 double length = 2 * mother_shape.dZ();
0097
0098
0099 double rEnd = rOuter2 - (rOuter2 - rOuter1) * sensitive_thickness / length;
0100 double zPos = length / 2.0 - sensitive_thickness / 2.0;
0101 if (detStart) {
0102 rEnd = rOuter1 - (rOuter1 - rOuter2) * sensitive_thickness / length;
0103 zPos = -length / 2.0 + sensitive_thickness / 2.0;
0104 }
0105
0106 sensitive_solid = ConeSegment(sensitive_thickness / 2, 0.0, rOuter2, 0.0, rEnd);
0107 disk_transform = Transform3D(Rotation3D(), Position(0.0, 0.0, zPos));
0108 }
0109
0110 Volume v_start_disk("v_start_disk_" + motherName, sensitive_solid, m_Vacuum);
0111 v_start_disk.setSensitiveDetector(sens);
0112
0113 auto disk_placement = mother_vol.placeVolume(v_start_disk, disk_transform);
0114 disk_placement.addPhysVolID("end", detStart);
0115 disk_placement.addPhysVolID("pipe", pipe_id);
0116 disk_placement.addPhysVolID("system", det_id);
0117
0118 DetElement slice_element(mother, slice_name, pipe_id);
0119
0120 slice_element.setPlacement(disk_placement);
0121 }
0122
0123 auto pv_assembly = description.worldVolume().placeVolume(assembly);
0124 pv_assembly.addPhysVolID("system", det_id);
0125 sdet.setPlacement(pv_assembly);
0126
0127 return sdet;
0128 }
0129
0130 DECLARE_DETELEMENT(BeamPipeTracking, create_detector)