Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-12 08:27:52

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 #include "XML/Utilities.h"
0023 
0024 using namespace std;
0025 using namespace dd4hep;
0026 using namespace dd4hep::detail;
0027 
0028 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
0029   xml_det_t x_det    = e;
0030   xml_dim_t dim      = x_det.dimensions();
0031   int det_id         = x_det.id();
0032   string det_name    = x_det.nameStr();
0033   bool allSensitive  = getAttrOrDefault(x_det, _Unicode(allSensitive), false);
0034   Material air       = description.air();
0035   int numsides       = dim.numsides();
0036   xml::Component pos = x_det.position();
0037   double rmin        = dim.rmin();
0038   double rmax        = dim.rmax();
0039   double zmin        = dim.zmin();
0040   Layering layering(x_det);
0041   double totalThickness = layering.totalThickness();
0042   Volume endcapVol("endcap", PolyhedraRegular(numsides, rmin, rmax, totalThickness), air);
0043   DetElement endcap("endcap", det_id);
0044 
0045   // apply any detector type flags set in XML
0046   dd4hep::xml::setDetectorTypeFlag(x_det, endcap);
0047 
0048   // std::cout << "totalThickness = " << totalThickness << "\n";
0049   // std::cout << "zmin = " << zmin << "\n";
0050   // std::cout << "rmin = " << rmin << "\n";
0051   // std::cout << "rmax = " << rmax << "\n";
0052   // std::cout << "nlayers = " << std::size(layering.layers()) << "\n";
0053   int l_num     = 1;
0054   int layerType = 0;
0055   double layerZ = -totalThickness / 2;
0056 
0057   endcapVol.setAttributes(description, x_det.regionStr(), x_det.limitsStr(), x_det.visStr());
0058 
0059   for (xml_coll_t xc(x_det, _U(layer)); xc; ++xc) {
0060     // std::cout << "l_num = " << l_num << "\n";
0061     // std::cout << "xc = " << xc << "\n";
0062     xml_comp_t x_layer = xc;
0063     double l_thick     = layering.layer(l_num - 1)->thickness();
0064     // std::cout << "xc = " << xc << "\n";
0065     string l_name = _toString(layerType, "layer%d");
0066     int l_repeat  = x_layer.repeat();
0067     Volume l_vol(l_name, PolyhedraRegular(numsides, rmin, rmax, l_thick), air);
0068     vector<PlacedVolume> sensitives;
0069 
0070     int s_num     = 1;
0071     double sliceZ = -l_thick / 2;
0072     for (xml_coll_t xs(x_layer, _U(slice)); xs; ++xs) {
0073       xml_comp_t x_slice = xs;
0074       string s_name      = _toString(s_num, "slice%d");
0075       double s_thick     = x_slice.thickness();
0076       Material s_mat     = description.material(x_slice.materialStr());
0077       Volume s_vol(s_name, PolyhedraRegular(numsides, rmin, rmax, s_thick), s_mat);
0078 
0079       s_vol.setVisAttributes(description.visAttributes(x_slice.visStr()));
0080       sliceZ += s_thick / 2;
0081       PlacedVolume s_phv = l_vol.placeVolume(s_vol, Position(0, 0, sliceZ));
0082       s_phv.addPhysVolID("slice", s_num);
0083       if (x_slice.isSensitive() || allSensitive) {
0084         sens.setType("calorimeter");
0085         s_vol.setSensitiveDetector(sens);
0086         sensitives.push_back(s_phv);
0087       }
0088       sliceZ += s_thick / 2;
0089       s_num++;
0090     }
0091     l_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
0092     if (l_repeat <= 0)
0093       throw std::runtime_error(x_det.nameStr() + "> Invalid repeat value");
0094     for (int j = 0; j < l_repeat; ++j) {
0095       string phys_lay = _toString(l_num, "layer%d");
0096       layerZ += l_thick / 2;
0097       DetElement layer_elt(endcap, phys_lay, l_num);
0098       PlacedVolume pv = endcapVol.placeVolume(l_vol, Position(0, 0, layerZ));
0099       pv.addPhysVolID("layer", l_num);
0100       layer_elt.setPlacement(pv);
0101       layer_elt.setTypeFlag(endcap.typeFlag()); // make sure type flags are propagated
0102       for (size_t ic = 0; ic < sensitives.size(); ++ic) {
0103         PlacedVolume sens_pv = sensitives[ic];
0104         DetElement comp_elt(layer_elt, sens_pv.volume().name(), l_num);
0105         comp_elt.setPlacement(sens_pv);
0106         comp_elt.setTypeFlag(endcap.typeFlag()); // make sure type flags are propagated
0107       }
0108       layerZ += l_thick / 2;
0109       ++l_num;
0110     }
0111     ++layerType;
0112   }
0113 
0114   double z_pos = zmin + totalThickness / 2;
0115   PlacedVolume pv;
0116   // Reflect it.
0117   Assembly assembly(det_name);
0118   DetElement endcapAssyDE(det_name, det_id);
0119   endcapAssyDE.setTypeFlag(endcap.typeFlag()); // make sure type flags are propagated
0120   Volume motherVol = description.pickMotherVolume(endcapAssyDE);
0121   pv =
0122       assembly.placeVolume(endcapVol, Transform3D(RotationZYX(0, M_PI, 0), Position(0, 0, -z_pos)));
0123   pv.addPhysVolID("barrel", 2);
0124   Ref_t(endcap)->SetName((det_name + "_backward").c_str());
0125   endcap.setPlacement(pv);
0126   endcapAssyDE.add(endcap);
0127   pv = motherVol.placeVolume(assembly, Position(pos.x(), pos.y(), pos.z()));
0128   pv.addPhysVolID("system", det_id);
0129   endcapAssyDE.setPlacement(pv);
0130   return endcapAssyDE;
0131 }
0132 
0133 // clang-format off
0134 DECLARE_DETELEMENT(epic_PolyhedraEndcapCalorimeter2, create_detector)
0135 DECLARE_DETELEMENT(epic_PolyhedraEndcapCalorimeter, create_detector)