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