Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-24 08:26:30

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Whitney Armstrong
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/Layering.h>
0011 #include <XML/Utilities.h>
0012 //////////////////////////////////////////////////
0013 // Far Forward Ion Zero Degree Calorimeter - Hcal
0014 //////////////////////////////////////////////////
0015 
0016 using namespace std;
0017 using namespace dd4hep;
0018 
0019 static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) {
0020   xml_det_t x_det = e;
0021   string detName  = x_det.nameStr();
0022   int detID       = x_det.id();
0023 
0024   xml_dim_t dim = x_det.dimensions();
0025   double Width  = dim.x();
0026   // double     Length     = dim.z();
0027 
0028   xml_dim_t pos = x_det.position();
0029   double z      = pos.z();
0030   xml_dim_t rot = x_det.rotation();
0031 
0032   Material Vacuum = desc.material("Vacuum");
0033 
0034   double totWidth = Layering(x_det).totalThickness();
0035 
0036   Box envelope(Width / 2.0, Width / 2.0, totWidth / 2.0);
0037   Volume envelopeVol(detName + "_envelope", envelope, Vacuum);
0038   envelopeVol.setVisAttributes(desc.visAttributes(x_det.visStr()));
0039   PlacedVolume pv;
0040 
0041   int layer_num = 1;
0042   // Read layers
0043   for (xml_coll_t c(x_det, _U(layer)); c; ++c) {
0044     xml_comp_t x_layer = c;
0045     int repeat         = x_layer.repeat();
0046     double layerWidth  = 0;
0047 
0048     for (xml_coll_t l(x_layer, _U(slice)); l; ++l)
0049       layerWidth += xml_comp_t(l).thickness();
0050 
0051     // Loop over repeat#
0052     for (int i = 0; i < repeat; i++) {
0053       double zlayer     = z;
0054       string layer_name = detName + _toString(layer_num, "_layer%d");
0055       Volume layer_vol(layer_name, Box(Width / 2.0, Width / 2.0, layerWidth / 2.0), Vacuum);
0056 
0057       int slice_num = 1;
0058       // Loop over slices
0059       for (xml_coll_t l(x_layer, _U(slice)); l; ++l) {
0060         xml_comp_t x_slice = l;
0061         double w           = x_slice.thickness();
0062         string slice_name  = layer_name + _toString(slice_num, "slice%d");
0063         Material slice_mat = desc.material(x_slice.materialStr());
0064         Volume slice_vol(slice_name, Box(Width / 2.0, Width / 2.0, w / 2.0), slice_mat);
0065 
0066         if (x_slice.isSensitive()) {
0067           sens.setType("calorimeter");
0068           slice_vol.setSensitiveDetector(sens);
0069         }
0070 
0071         slice_vol.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
0072         pv = layer_vol.placeVolume(
0073             slice_vol, Transform3D(RotationZYX(0, 0, 0),
0074                                    Position(0.0, 0.0, z - zlayer - layerWidth / 2.0 + w / 2.0)));
0075         pv.addPhysVolID("slice", slice_num);
0076         z += w;
0077         ++slice_num;
0078       }
0079 
0080       string layer_vis =
0081           dd4hep::getAttrOrDefault<std::string>(x_layer, _Unicode(vis), "InvisibleWithDaughters");
0082       layer_vol.setAttributes(desc, x_layer.regionStr(), x_layer.limitsStr(), layer_vis);
0083       pv = envelopeVol.placeVolume(
0084           layer_vol,
0085           Transform3D(RotationZYX(0, 0, 0),
0086                       Position(0, 0, zlayer - pos.z() - totWidth / 2.0 + layerWidth / 2.0)));
0087       pv.addPhysVolID("layer", layer_num);
0088       ++layer_num;
0089     }
0090   }
0091 
0092   DetElement det(detName, detID);
0093 
0094   // apply any detector type flags set in XML
0095   dd4hep::xml::setDetectorTypeFlag(x_det, det);
0096 
0097   Volume motherVol = desc.pickMotherVolume(det);
0098   Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()),
0099                  Position(pos.x(), pos.y(), pos.z() + totWidth / 2.0));
0100   PlacedVolume phv = motherVol.placeVolume(envelopeVol, tr);
0101   phv.addPhysVolID("system", detID);
0102   det.setPlacement(phv);
0103 
0104   return det;
0105 }
0106 DECLARE_DETELEMENT(ZDC_Sampling, createDetector)