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 width = dim.x();
0031 auto length = dim.z();
0032 xml_dim_t pos = detElem.position();
0033 xml_dim_t rot = detElem.rotation();
0034
0035
0036 Box envShape(width * 0.5, width * 0.5, length * 0.5);
0037 Volume env(detName + "_envelope", envShape, desc.material("Air"));
0038 env.setVisAttributes(desc.visAttributes(detElem.visStr()));
0039
0040
0041 xml_comp_t mod_x = detElem.child(_Unicode(module));
0042 auto sx = mod_x.attr<double>(_Unicode(sizex));
0043 auto sy = mod_x.attr<double>(_Unicode(sizey));
0044 auto sz = mod_x.attr<double>(_Unicode(sizez));
0045
0046 Box modShape(sx / 2., sy / 2., sz / 2.);
0047 auto modMat = desc.material(mod_x.attr<std::string>(_Unicode(material)));
0048 Volume modVol("module_vol", modShape, modMat);
0049 modVol.setVisAttributes(desc.visAttributes(mod_x.visStr()));
0050
0051
0052 if (mod_x.hasChild(_Unicode(fiber))) {
0053 auto fiber_x = mod_x.child(_Unicode(fiber));
0054 auto fr = fiber_x.attr<double>(_Unicode(radius));
0055 auto fsx = fiber_x.attr<double>(_Unicode(spacex));
0056 auto fsy = fiber_x.attr<double>(_Unicode(spacey));
0057 auto foff = dd4hep::getAttrOrDefault<double>(fiber_x, _Unicode(offset), 0.5 * mm);
0058 auto fiberMat = desc.material(fiber_x.attr<std::string>(_Unicode(material)));
0059 Tube fiberShape(0., fr, sz / 2. - 1. * mm);
0060 Volume fiberVol("fiber_vol", fiberShape, fiberMat);
0061 fiberVol.setSensitiveDetector(sens);
0062
0063
0064
0065
0066 double fside = 2. / std::sqrt(3.) * fr;
0067 double fdistx = 2. * fside + fsx;
0068 double fdisty = 2. * fr + fsy;
0069
0070
0071 int nx = int(sx / (2. * fr)) + 1;
0072 int ny = int(sy / (2. * fr)) + 1;
0073
0074
0075 double y0 = (foff + fside);
0076 int nfibers = 0;
0077 for (int iy = 0; iy < ny; ++iy) {
0078 double y = y0 + fdisty * iy;
0079
0080 if ((sy - y) < y0) {
0081 break;
0082 }
0083 double x0 = (iy % 2) ? (foff + fside) : (foff + fside + fdistx / 2.);
0084 for (int ix = 0; ix < nx; ++ix) {
0085 double x = x0 + fdistx * ix;
0086
0087 if ((sx - x) < x0) {
0088 break;
0089 }
0090 auto fiberPV =
0091 modVol.placeVolume(fiberVol, nfibers++, Position{x - sx / 2., y - sy / 2., 0});
0092 fiberPV.addPhysVolID("fiber_x", ix + 1).addPhysVolID("fiber_y", iy + 1);
0093 }
0094 }
0095
0096 } else {
0097 modVol.setSensitiveDetector(sens);
0098 }
0099
0100
0101 double mod_x_pos = 0.0;
0102 double mod_y_pos = 0.0;
0103 double mod_z_pos = 0.0 * mm;
0104 double mgap = 0.000001 * mm;
0105 int mNTowers = floor(width / (sx + mgap));
0106
0107
0108 int k = 0;
0109
0110 for (int j = 0; j < mNTowers; j++) {
0111 if (j == 0)
0112 mod_y_pos = width * 0.5 - (sy + mgap) * 0.5;
0113 else
0114 mod_y_pos -= (sy + mgap);
0115
0116 for (int i = 0; i < mNTowers; i++) {
0117 if (i == 0)
0118 mod_x_pos = width * 0.5 - (sx + mgap) * 0.5;
0119 else
0120 mod_x_pos -= (sx + mgap);
0121
0122 PlacedVolume pv_mod = env.placeVolume(modVol, Position(mod_x_pos, mod_y_pos, mod_z_pos));
0123 pv_mod.addPhysVolID("module", k++);
0124
0125
0126 }
0127 }
0128
0129
0130 Volume motherVol = desc.pickMotherVolume(det);
0131 Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z()));
0132 PlacedVolume envPV = motherVol.placeVolume(env, tr);
0133 envPV.addPhysVolID("system", detID);
0134 det.setPlacement(envPV);
0135 return det;
0136 }
0137
0138 DECLARE_DETELEMENT(ZDCEcalScFiCalorimeter, create_detector)