File indexing completed on 2026-09-13 08:27:20
0001
0002
0003
0004 #include "DD4hep/DetFactoryHelper.h"
0005 #include "DD4hep/OpticalSurfaces.h"
0006 #include "DD4hep/Printout.h"
0007 #include "DDRec/DetectorData.h"
0008 #include "DDRec/Surface.h"
0009 #include <XML/Helper.h>
0010 #include <XML/Utilities.h>
0011 #include <algorithm>
0012 #include <iostream>
0013 #include <math.h>
0014 #include <tuple>
0015
0016
0017
0018
0019
0020 using namespace std;
0021 using namespace dd4hep;
0022
0023
0024 static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) {
0025 xml::DetElement detElem = handle;
0026 std::string detName = detElem.nameStr();
0027 int detID = detElem.id();
0028 DetElement det(detName, detID);
0029 sens.setType("calorimeter");
0030 auto dim = detElem.dimensions();
0031 auto xwidth = dim.x();
0032 auto ywidth = dim.y();
0033 auto length = dim.z();
0034 xml_dim_t pos = detElem.position();
0035 xml_dim_t rot = detElem.rotation();
0036
0037
0038 dd4hep::xml::setDetectorTypeFlag(detElem, det);
0039
0040
0041 Box envShape(xwidth * 0.5, ywidth * 0.5, length * 0.5);
0042 Volume env(detName + "_envelope", envShape, desc.material("Air"));
0043 env.setVisAttributes(desc.visAttributes(detElem.visStr()));
0044
0045
0046 xml_comp_t fr = detElem.child(_Unicode(support));
0047 auto fx = xwidth;
0048 auto fy = ywidth;
0049 auto fz = fr.attr<double>(_Unicode(sizez));
0050 auto fthickness = fr.attr<double>(_Unicode(thickness));
0051
0052 Box frShape(fx / 2., fy / 2., fz / 2.);
0053 auto frMat = desc.material(fr.attr<std::string>(_Unicode(material)));
0054 Volume frVol("frame_vol", frShape, frMat);
0055 frVol.setVisAttributes(desc.visAttributes(fr.visStr()));
0056
0057 xml_comp_t mod_x = detElem.child(_Unicode(module));
0058 auto nx = mod_x.attr<int>(_Unicode(nx));
0059 auto ny = mod_x.attr<int>(_Unicode(ny));
0060
0061
0062 xml_comp_t twr = mod_x.child(_Unicode(tower));
0063 double tsx = twr.attr<double>(_Unicode(cellx));
0064 double tsy = twr.attr<double>(_Unicode(celly));
0065 double tsz = twr.thickness();
0066 Material t_mat = desc.material(twr.materialStr());
0067 string t_name = twr.nameStr();
0068
0069 Box t_Shape(tsx / 2., tsy / 2., tsz / 2.);
0070 Volume t_Vol("tower_vol", t_Shape, t_mat);
0071 t_Vol.setVisAttributes(desc.visAttributes(twr.visStr()));
0072 if (twr.isSensitive())
0073 t_Vol.setSensitiveDetector(sens);
0074
0075
0076 xml_comp_t sct = mod_x.child(_Unicode(socket));
0077 double ssx = sct.attr<double>(_Unicode(cellx));
0078 double ssy = sct.attr<double>(_Unicode(celly));
0079 double ssz = sct.thickness();
0080 Material s_mat = desc.material(sct.materialStr());
0081 string s_name = sct.nameStr();
0082
0083 Box s_Shape(ssx / 2., ssy / 2., ssz / 2.);
0084 Volume s_Vol("socket_vol", s_Shape, s_mat);
0085 s_Vol.setVisAttributes(desc.visAttributes(sct.visStr()));
0086
0087 PlacedVolume pv;
0088 double x_pos_0 = -(nx * tsx + (nx - 1) * fthickness) / 2.;
0089 double y_pos_0 = -(ny * tsy + (ny - 1) * fthickness) / 2.;
0090 double twr_z_pos_in_fr = -fz / 2. + tsz / 2.;
0091 double sct_z_pos_in_env = -length / 2. + tsz + ssz / 2.;
0092 int mod_i = 0;
0093 for (int ix = 0; ix < nx; ix++) {
0094 double x_pos = x_pos_0 + ix * (tsx + fthickness) + tsx / 2.;
0095
0096 for (int iy = 0; iy < ny; iy++) {
0097 double y_pos = y_pos_0 + iy * (tsy + fthickness) + tsy / 2.;
0098
0099 mod_i++;
0100
0101 Position twr_pos(x_pos, y_pos, twr_z_pos_in_fr);
0102 pv = frVol.placeVolume(t_Vol, twr_pos);
0103 pv.addPhysVolID(t_name, mod_i);
0104
0105 Position sct_pos(x_pos, y_pos, sct_z_pos_in_env);
0106 pv = env.placeVolume(s_Vol, sct_pos);
0107 }
0108 }
0109
0110 double f_zpos = -length / 2. + fz / 2.;
0111 Position fr_pos(0, 0, f_zpos);
0112 pv = env.placeVolume(frVol, fr_pos);
0113
0114
0115 Volume motherVol = desc.pickMotherVolume(det);
0116 Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z()));
0117 PlacedVolume envPV = motherVol.placeVolume(env, tr);
0118 envPV.addPhysVolID("system", detID);
0119 det.setPlacement(envPV);
0120 return det;
0121 }
0122
0123 DECLARE_DETELEMENT(ZDC_Crystal, create_detector)