Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:15:55

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Ryan Milton
0003 
0004 //==========================================================================
0005 //  Implementation of forward calorimeter with the insert shape cut out
0006 //--------------------------------------------------------------------------
0007 //  Author: Ryan Milton (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 rmin   = dim.rmin(); // Dummy variable. Set to 0 since cutting out insert
0023   double rmax   = dim.rmax(); // Max radius of endcap
0024   double length = dim.z();    // Size along z-axis
0025 
0026   xml_dim_t pos = detElem.position();
0027 
0028   Material air = desc.material("Air");
0029 
0030   // Getting insert dimensions
0031   const xml::Component& insert_xml = detElem.child(_Unicode(insert));
0032   xml_dim_t insert_dim             = insert_xml.dimensions();
0033   xml_dim_t insert_local_pos       = insert_xml.position();
0034 
0035   // Defining envelope
0036   Tube envelope(rmin, rmax, length / 2.0);
0037 
0038   // Removing insert shape from envelope
0039   Box insert(insert_dim.x() / 2., insert_dim.y() / 2., length / 2.);
0040   SubtractionSolid envelope_with_inserthole(
0041       envelope, insert, Position(insert_local_pos.x(), insert_local_pos.y(), 0.));
0042   Volume envelopeVol(detName, envelope_with_inserthole, air);
0043   // Setting envelope attributes
0044   envelopeVol.setAttributes(desc, detElem.regionStr(), detElem.limitsStr(), detElem.visStr());
0045   PlacedVolume pv;
0046 
0047   int layer_num  = 1;
0048   double layer_z = -length / 2.; // Keeps track of layers' local z locations
0049   // Looping through all the different layer sections
0050   for (xml_coll_t c(detElem, _U(layer)); c; ++c) {
0051     xml_comp_t x_layer     = c;
0052     int repeat             = x_layer.repeat();
0053     double layer_thickness = x_layer.thickness();
0054 
0055     // Looping through the number of repeated layers in each section
0056     for (int i = 0; i < repeat; i++) {
0057       layer_z += layer_thickness / 2.; // Going to halfway point in layer
0058 
0059       std::string layer_name = detName + _toString(layer_num, "_layer%d");
0060       Tube layer(rmin, rmax, layer_thickness / 2.);
0061 
0062       // Removing insert shape from each layer
0063       Box layer_insert(insert_dim.x() / 2., insert_dim.y() / 2., layer_thickness / 2.);
0064       SubtractionSolid layer_with_inserthole(
0065           layer, layer_insert, Position(insert_local_pos.x(), insert_local_pos.y(), 0.));
0066       Volume layer_vol(layer_name, layer_with_inserthole, air);
0067 
0068       int slice_num  = 1;
0069       double slice_z = -layer_thickness / 2.; // Keeps track of slices' z locations in each layer
0070 
0071       // Looping over each layer's slices
0072       for (xml_coll_t l(x_layer, _U(slice)); l; ++l) {
0073         xml_comp_t x_slice     = l;
0074         double slice_thickness = x_slice.thickness();
0075         std::string slice_name = layer_name + _toString(slice_num, "slice%d");
0076         Material slice_mat     = desc.material(x_slice.materialStr());
0077         slice_z += slice_thickness / 2.; // Going to slice halfway point
0078 
0079         Tube slice(rmin, rmax, slice_thickness / 2.);
0080 
0081         // Removing insert shape from each slice
0082         Box slice_insert(insert_dim.x() / 2., insert_dim.y() / 2., slice_thickness / 2.0);
0083         SubtractionSolid slice_with_inserthole(
0084             slice, slice_insert, Position(insert_local_pos.x(), insert_local_pos.y(), 0.));
0085         Volume slice_vol(slice_name, slice_with_inserthole, slice_mat);
0086 
0087         // Setting appropriate slices as sensitive
0088         if (x_slice.isSensitive()) {
0089           sens.setType("calorimeter");
0090           slice_vol.setSensitiveDetector(sens);
0091         }
0092 
0093         // Setting slice attributes
0094         slice_vol.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
0095 
0096         // Placing slice within layer
0097         pv = layer_vol.placeVolume(slice_vol,
0098                                    Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z)));
0099         pv.addPhysVolID("slice", slice_num);
0100         slice_z += slice_thickness / 2.; // Going to end of slice
0101         ++slice_num;
0102       }
0103 
0104       // Setting layer attributes
0105       layer_vol.setAttributes(desc, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
0106 
0107       // Placing each layer inside the envelope volume
0108       // layer_z starts as -length/2 (front of endcap)
0109       // layer_z is increased by layer_thickness/2 at the start of the layer loop
0110       // This moves to the middle of the layer (location of placement)
0111       // It's then increased by layer_thickness/2 again to move to end of layer
0112       pv = envelopeVol.placeVolume(layer_vol,
0113                                    Transform3D(RotationZYX(0, 0, 0), Position(0., 0., layer_z)));
0114       pv.addPhysVolID("layer", layer_num);
0115       layer_num++;
0116       layer_z += layer_thickness / 2.;
0117     }
0118   }
0119 
0120   DetElement det(detName, detID);
0121   Volume motherVol = desc.pickMotherVolume(det);
0122 
0123   // Placing endcap in world volume
0124   auto tr = Transform3D(Position(pos.x(), pos.y(), pos.z() + length / 2.));
0125 
0126   PlacedVolume phv = motherVol.placeVolume(envelopeVol, tr);
0127   phv.addPhysVolID("system", detID);
0128   det.setPlacement(phv);
0129 
0130   return det;
0131 }
0132 DECLARE_DETELEMENT(epic_EndcapCalorimeterWithInsertCutout, createDetector)