Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Whitney Armstrong
0003 
0004 //==========================================================================
0005 //  AIDA Detector description implementation
0006 //--------------------------------------------------------------------------
0007 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0008 // All rights reserved.
0009 //
0010 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0011 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0012 //
0013 // Author     : M.Frank
0014 //
0015 //==========================================================================
0016 //
0017 // Modified for ATHENA detector
0018 //
0019 //==========================================================================
0020 #include "DD4hep/DetFactoryHelper.h"
0021 #include "XML/Layering.h"
0022 
0023 using namespace std;
0024 using namespace dd4hep;
0025 using namespace dd4hep::detail;
0026 
0027 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0028   xml_det_t x_det    = e;
0029   xml_dim_t dim      = x_det.dimensions();
0030   int det_id         = x_det.id();
0031   bool reflect       = x_det.reflect(true);
0032   string det_name    = x_det.nameStr();
0033   Material air       = description.air();
0034   int numsides       = dim.numsides();
0035   xml::Component pos = x_det.position();
0036   double rmin        = dim.rmin();
0037   double rmax        = dim.rmax();
0038   double zmin        = dim.zmin();
0039   Layering layering(x_det);
0040   double totalThickness = layering.totalThickness();
0041   Volume endcapVol("endcap", PolyhedraRegular(numsides, rmin, rmax, totalThickness), air);
0042   DetElement endcap("endcap", det_id);
0043 
0044   // std::cout << "totalThickness = " << totalThickness << "\n";
0045   // std::cout << "zmin = " << zmin << "\n";
0046   // std::cout << "rmin = " << rmin << "\n";
0047   // std::cout << "rmax = " << rmax << "\n";
0048   // std::cout << "nlayers = " << std::size(layering.layers()) << "\n";
0049   int l_num     = 1;
0050   int layerType = 0;
0051   double layerZ = -totalThickness / 2;
0052 
0053   endcapVol.setAttributes(description, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
0054 
0055   for (xml_coll_t xc(x_det, _U(layer)); xc; ++xc) {
0056     // std::cout << "l_num = " << l_num << "\n";
0057     // std::cout << "xc = " << xc << "\n";
0058     xml_comp_t x_layer = xc;
0059     double l_thick     = layering.layer(l_num - 1)->thickness();
0060     // std::cout << "xc = " << xc << "\n";
0061     string l_name = _toString(layerType, "layer%d");
0062     int l_repeat  = x_layer.repeat();
0063     Volume l_vol(l_name, PolyhedraRegular(numsides, rmin, rmax, l_thick), air);
0064     vector<PlacedVolume> sensitives;
0065 
0066     int s_num     = 1;
0067     double sliceZ = -l_thick / 2;
0068     for (xml_coll_t xs(x_layer, _U(slice)); xs; ++xs) {
0069       xml_comp_t x_slice = xs;
0070       string s_name      = _toString(s_num, "slice%d");
0071       double s_thick     = x_slice.thickness();
0072       Material s_mat     = description.material(x_slice.materialStr());
0073       Volume s_vol(s_name, PolyhedraRegular(numsides, M_PI / numsides, rmin, rmax, s_thick), s_mat);
0074 
0075       s_vol.setVisAttributes(description.visAttributes(x_slice.visStr()));
0076       sliceZ += s_thick / 2;
0077       PlacedVolume s_phv = l_vol.placeVolume(
0078           s_vol, Transform3D(RotationZYX(-M_PI / numsides, 0, 0), Position(0, 0, sliceZ)));
0079       s_phv.addPhysVolID("slice", s_num);
0080       if (x_slice.isSensitive()) {
0081         sens.setType("calorimeter");
0082         s_vol.setSensitiveDetector(sens);
0083         sensitives.push_back(s_phv);
0084       }
0085       sliceZ += s_thick / 2;
0086       s_num++;
0087     }
0088     l_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
0089     if (l_repeat <= 0)
0090       throw std::runtime_error(x_det.nameStr() + "> Invalid repeat value");
0091     for (int j = 0; j < l_repeat; ++j) {
0092       string phys_lay = _toString(l_num, "layer%d");
0093       layerZ += l_thick / 2;
0094       DetElement layer_elt(endcap, phys_lay, l_num);
0095       PlacedVolume pv = endcapVol.placeVolume(l_vol, Position(0, 0, layerZ));
0096       pv.addPhysVolID("layer", l_num);
0097       layer_elt.setPlacement(pv);
0098       for (size_t ic = 0; ic < sensitives.size(); ++ic) {
0099         PlacedVolume sens_pv = sensitives[ic];
0100         DetElement comp_elt(layer_elt, sens_pv.volume().name(), l_num);
0101         comp_elt.setPlacement(sens_pv);
0102       }
0103       layerZ += l_thick / 2;
0104       ++l_num;
0105     }
0106     ++layerType;
0107   }
0108 
0109   double z_pos = zmin + totalThickness / 2;
0110   PlacedVolume pv;
0111   // Reflect it.
0112   Assembly assembly(det_name);
0113   DetElement endcapAssyDE(det_name, det_id);
0114   Volume motherVol = description.pickMotherVolume(endcapAssyDE);
0115   if (reflect) {
0116     pv = assembly.placeVolume(
0117         endcapVol, Transform3D(RotationZYX(M_PI / numsides, M_PI, 0), Position(0, 0, -z_pos)));
0118     pv.addPhysVolID("barrel", 2);
0119     Ref_t(endcap)->SetName((det_name + "_backward").c_str());
0120     endcap.setPlacement(pv);
0121   } else {
0122     pv = assembly.placeVolume(
0123         endcapVol, Transform3D(RotationZYX(M_PI / numsides, 0, 0), Position(0, 0, z_pos)));
0124     pv.addPhysVolID("barrel", 1);
0125     Ref_t(endcap)->SetName((det_name + "_forward").c_str());
0126     endcap.setPlacement(pv);
0127   }
0128   endcapAssyDE.add(endcap);
0129   pv = motherVol.placeVolume(assembly, Position(pos.x(), pos.y(), pos.z()));
0130   pv.addPhysVolID("system", det_id);
0131   endcapAssyDE.setPlacement(pv);
0132   return endcapAssyDE;
0133 }
0134 
0135 // clang-format off
0136 DECLARE_DETELEMENT(epic_PolyhedraEndcapCalorimeter2, create_detector)
0137 DECLARE_DETELEMENT(epic_PolyhedraEndcapCalorimeter, create_detector)