File indexing completed on 2026-09-10 08:26:47
0001
0002
0003
0004
0005
0006
0007 #include "DD4hep/DetFactoryHelper.h"
0008 #include <XML/Helper.h>
0009 #include <XML/Utilities.h>
0010 #include <algorithm>
0011 #include <iostream>
0012 #include <tuple>
0013
0014 using namespace std;
0015 using namespace dd4hep;
0016
0017
0018 static tuple<Volume, Position> build_specHomoCAL_module(const Detector& description,
0019 const xml::Component& mod_x,
0020 SensitiveDetector& sens);
0021
0022
0023 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0024 sens.setType("calorimeter");
0025
0026 xml_det_t x_det = e;
0027 xml_comp_t x_mod = x_det.child(_Unicode(module));
0028 string det_name = x_det.nameStr();
0029 int det_ID = x_det.id();
0030
0031
0032 DetElement det(det_name, det_ID);
0033
0034
0035 Volume motherVol = description.pickMotherVolume(det);
0036
0037
0038 dd4hep::xml::setDetectorTypeFlag(x_det, det);
0039
0040
0041 Assembly assembly(det_name);
0042 assembly.setVisAttributes(description.invisible());
0043
0044
0045
0046 auto [modVol, modSize] = build_specHomoCAL_module(description, x_mod, sens);
0047 double detSizeXY = getAttrOrDefault(x_det, _Unicode(sizeXY), 20);
0048 int nxy = int(detSizeXY / modSize.x());
0049 double xypos0 = -nxy * modSize.x() / 2.0 + modSize.x() / 2.0;
0050
0051
0052
0053 for (xml_coll_t si(x_det, _Unicode(sector)); si; si++) {
0054
0055 xml_comp_t x_sector(si);
0056 int sector_id = x_sector.id();
0057 int mod_id = 0;
0058
0059 xml_comp_t x_pos = x_sector.position();
0060 xml_comp_t x_rot = x_sector.rotation();
0061
0062 for (int ix = 0; ix < nxy; ix++) {
0063 for (int iy = 0; iy < nxy; iy++) {
0064
0065 double mod_pos_x = x_pos.x() + xypos0 + ix * modSize.x();
0066 double mod_pos_y = x_pos.y() + xypos0 + iy * modSize.y();
0067 double mod_pos_z = x_pos.z() + 0.0 * cm;
0068
0069 PlacedVolume modPV =
0070 assembly.placeVolume(modVol, Transform3D(RotationZYX(x_rot.x(), x_rot.y(), x_rot.z()),
0071 Position(mod_pos_x, mod_pos_y, mod_pos_z)));
0072
0073 modPV.addPhysVolID("sector", sector_id).addPhysVolID("module", mod_id);
0074 mod_id++;
0075 }
0076 }
0077
0078 }
0079
0080
0081 PlacedVolume detPV = motherVol.placeVolume(assembly, Position(0.0, 0.0, 0.0));
0082 detPV.addPhysVolID("system", det_ID);
0083
0084
0085 det.setPlacement(detPV);
0086
0087 return det;
0088 }
0089
0090
0091
0092 static tuple<Volume, Position> build_specHomoCAL_module(const Detector& description,
0093 const xml::Component& mod_x,
0094 SensitiveDetector& sens) {
0095
0096 double sx = mod_x.attr<double>(_Unicode(sizex));
0097 double sy = mod_x.attr<double>(_Unicode(sizey));
0098 double sz = mod_x.attr<double>(_Unicode(sizez));
0099 double frame_size = mod_x.attr<double>(_Unicode(frameSize));
0100
0101 Box modShape((sx / 2.0 - frame_size), (sy / 2.0 - frame_size), sz / 2.0);
0102 auto modMat = description.material(mod_x.attr<std::string>(_Unicode(material)));
0103 Volume modVol("module_vol", modShape, modMat);
0104
0105 if (mod_x.hasAttr(_Unicode(vis))) {
0106 modVol.setVisAttributes(description.visAttributes(mod_x.attr<std::string>(_Unicode(vis))));
0107 }
0108
0109 modVol.setSensitiveDetector(sens);
0110 return make_tuple(modVol, Position{sx, sy, sz});
0111 }
0112
0113 DECLARE_DETELEMENT(LumiSpecHomoCAL, create_detector)