File indexing completed on 2025-01-18 09:15:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "DD4hep/DetFactoryHelper.h"
0011 #include <XML/Helper.h>
0012 #include <XML/Layering.h>
0013
0014 using namespace dd4hep;
0015
0016 static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens) {
0017 xml_det_t detElem = handle;
0018 std::string detName = detElem.nameStr();
0019 int detID = detElem.id();
0020
0021 xml_dim_t dim = detElem.dimensions();
0022 double rmin = dim.rmin();
0023 double rmax = dim.rmax();
0024 double length = dim.z();
0025
0026 xml_dim_t pos = detElem.position();
0027
0028 Material air = desc.material("Air");
0029
0030
0031 const xml::Component& insert_xml = detElem.child(_Unicode(insert));
0032 xml_dim_t insert_dim = insert_xml.dimensions();
0033 xml_dim_t insert_local_pos = insert_xml.position();
0034
0035
0036 Tube envelope(rmin, rmax, length / 2.0);
0037
0038
0039 Box insert(insert_dim.x() / 2., insert_dim.y() / 2., length / 2.);
0040 SubtractionSolid envelope_with_inserthole(
0041 envelope, insert, Position(insert_local_pos.x(), insert_local_pos.y(), 0.));
0042 Volume envelopeVol(detName, envelope_with_inserthole, air);
0043
0044 envelopeVol.setAttributes(desc, detElem.regionStr(), detElem.limitsStr(), detElem.visStr());
0045 PlacedVolume pv;
0046
0047 int layer_num = 1;
0048 double layer_z = -length / 2.;
0049
0050 for (xml_coll_t c(detElem, _U(layer)); c; ++c) {
0051 xml_comp_t x_layer = c;
0052 int repeat = x_layer.repeat();
0053 double layer_thickness = x_layer.thickness();
0054
0055
0056 for (int i = 0; i < repeat; i++) {
0057 layer_z += layer_thickness / 2.;
0058
0059 std::string layer_name = detName + _toString(layer_num, "_layer%d");
0060 Tube layer(rmin, rmax, layer_thickness / 2.);
0061
0062
0063 Box layer_insert(insert_dim.x() / 2., insert_dim.y() / 2., layer_thickness / 2.);
0064 SubtractionSolid layer_with_inserthole(
0065 layer, layer_insert, Position(insert_local_pos.x(), insert_local_pos.y(), 0.));
0066 Volume layer_vol(layer_name, layer_with_inserthole, air);
0067
0068 int slice_num = 1;
0069 double slice_z = -layer_thickness / 2.;
0070
0071
0072 for (xml_coll_t l(x_layer, _U(slice)); l; ++l) {
0073 xml_comp_t x_slice = l;
0074 double slice_thickness = x_slice.thickness();
0075 std::string slice_name = layer_name + _toString(slice_num, "slice%d");
0076 Material slice_mat = desc.material(x_slice.materialStr());
0077 slice_z += slice_thickness / 2.;
0078
0079 Tube slice(rmin, rmax, slice_thickness / 2.);
0080
0081
0082 Box slice_insert(insert_dim.x() / 2., insert_dim.y() / 2., slice_thickness / 2.0);
0083 SubtractionSolid slice_with_inserthole(
0084 slice, slice_insert, Position(insert_local_pos.x(), insert_local_pos.y(), 0.));
0085 Volume slice_vol(slice_name, slice_with_inserthole, slice_mat);
0086
0087
0088 if (x_slice.isSensitive()) {
0089 sens.setType("calorimeter");
0090 slice_vol.setSensitiveDetector(sens);
0091 }
0092
0093
0094 slice_vol.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
0095
0096
0097 pv = layer_vol.placeVolume(slice_vol,
0098 Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z)));
0099 pv.addPhysVolID("slice", slice_num);
0100 slice_z += slice_thickness / 2.;
0101 ++slice_num;
0102 }
0103
0104
0105 layer_vol.setAttributes(desc, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
0106
0107
0108
0109
0110
0111
0112 pv = envelopeVol.placeVolume(layer_vol,
0113 Transform3D(RotationZYX(0, 0, 0), Position(0., 0., layer_z)));
0114 pv.addPhysVolID("layer", layer_num);
0115 layer_num++;
0116 layer_z += layer_thickness / 2.;
0117 }
0118 }
0119
0120 DetElement det(detName, detID);
0121 Volume motherVol = desc.pickMotherVolume(det);
0122
0123
0124 auto tr = Transform3D(Position(pos.x(), pos.y(), pos.z() + length / 2.));
0125
0126 PlacedVolume phv = motherVol.placeVolume(envelopeVol, tr);
0127 phv.addPhysVolID("system", detID);
0128 det.setPlacement(phv);
0129
0130 return det;
0131 }
0132 DECLARE_DETELEMENT(epic_EndcapCalorimeterWithInsertCutout, createDetector)