Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:16:00

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2023 Sebouh J. Paul
0003 
0004 //==========================================================================
0005 //  Implementation of SiPM-on-tile Zero-Degree Calorimeter
0006 //--------------------------------------------------------------------------
0007 //  Author: Sebouh J. Paul (UCR)
0008 //==========================================================================
0009 
0010 #include "DD4hep/DetFactoryHelper.h"
0011 #include <XML/Helper.h>
0012 #include <XML/Layering.h>
0013 
0014 using namespace dd4hep;
0015 
0016 static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens) {
0017   xml_det_t detElem   = handle;
0018   std::string detName = detElem.nameStr();
0019   int detID           = detElem.id();
0020 
0021   xml_dim_t dim = detElem.dimensions();
0022   double width  = dim.x(); // Size along x-axis
0023   double height = dim.y(); // Size along y-axis
0024   double length = dim.z(); // Size along z-axis
0025 
0026   xml_dim_t pos = detElem.position(); // Position in global coordinates
0027   xml_dim_t rot = detElem.rotation();
0028 
0029   Material air = desc.material("Air");
0030 
0031   // Defining envelope
0032   Box envelope(width / 2.0, height / 2.0, length / 2.0);
0033 
0034   // Defining envelope volume
0035   Volume envelopeVol(detName, envelope, air);
0036   // Setting envelope attributes
0037   envelopeVol.setAttributes(desc, detElem.regionStr(), detElem.limitsStr(), detElem.visStr());
0038 
0039   PlacedVolume pv;
0040 
0041   double z_distance_traversed = 0.;
0042 
0043   int layer_num = 1;
0044 
0045   // Looping through all the different layer sections
0046   for (xml_coll_t c(detElem, _U(layer)); c; ++c) {
0047     xml_comp_t x_layer     = c;
0048     int repeat             = x_layer.repeat();
0049     double layer_thickness = x_layer.thickness();
0050 
0051     // Looping through the number of repeated layers in each section
0052     for (int i = 0; i < repeat; i++) {
0053       std::string layer_name = detName + _toString(layer_num, "_layer%d");
0054 
0055       Box layer(width / 2., height / 2., layer_thickness / 2.);
0056 
0057       Volume layer_vol(layer_name, layer, air);
0058 
0059       int slice_num  = 1;
0060       double slice_z = -layer_thickness / 2.; // Keeps track of slices' z locations in each layer
0061 
0062       // Looping over each layer's slices
0063       for (xml_coll_t l(x_layer, _U(slice)); l; ++l) {
0064         xml_comp_t x_slice     = l;
0065         double slice_thickness = x_slice.thickness();
0066         std::string slice_name = layer_name + _toString(slice_num, "slice%d");
0067         Material slice_mat     = desc.material(x_slice.materialStr());
0068         slice_z += slice_thickness / 2.; // Going to slice halfway point
0069 
0070         Box slice(width / 2., height / 2., slice_thickness / 2.);
0071 
0072         Volume slice_vol(slice_name, slice, slice_mat);
0073 
0074         // Setting appropriate slices as sensitive
0075         if (x_slice.isSensitive()) {
0076           sens.setType("calorimeter");
0077           slice_vol.setSensitiveDetector(sens);
0078         }
0079 
0080         // Setting slice attributes
0081         slice_vol.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
0082 
0083         // Placing slice within layer
0084         pv = layer_vol.placeVolume(slice_vol,
0085                                    Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z)));
0086         pv.addPhysVolID("slice", slice_num);
0087         slice_z += slice_thickness / 2.;
0088         z_distance_traversed += slice_thickness;
0089         ++slice_num;
0090       }
0091 
0092       // Setting layer attributes
0093       layer_vol.setAttributes(desc, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
0094       // Placing each layer inside the envelope volume
0095       // -length/2. is front of detector in global coordinate system
0096       // + (z_distance_traversed - layer_thickness) goes to the front of each layer
0097       // + layer_thickness/2. places layer in correct spot
0098       // Example: After placement of slices in first layer, z_distance_traversed = layer_thickness
0099       //          Subtracting layer_thickness goes back to the front of the first slice (Now, z = -length/2)
0100       //          Adding layer_thickness/2. goes to half the first layer thickness (proper place to put layer)
0101       //          Each loop over repeat will increases z_distance_traversed by layer_thickness
0102       pv = envelopeVol.placeVolume(
0103           layer_vol, Transform3D(RotationZYX(0, 0, 0),
0104                                  Position(0., 0.,
0105                                           -length / 2. + (z_distance_traversed - layer_thickness) +
0106                                               layer_thickness / 2.)));
0107       pv.addPhysVolID("layer", layer_num);
0108       layer_num++;
0109     }
0110   }
0111 
0112   DetElement det(detName, detID);
0113   Volume motherVol = desc.pickMotherVolume(det);
0114 
0115   // Placing ZDC in world volume
0116   auto tr =
0117       Transform3D(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z()));
0118   PlacedVolume phv = motherVol.placeVolume(envelopeVol, tr);
0119   phv.addPhysVolID("system", detID);
0120   det.setPlacement(phv);
0121 
0122   return det;
0123 }
0124 DECLARE_DETELEMENT(ZeroDegreeCalorimeterSiPMonTile, createDetector)