Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:15:46

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   string det_name    = x_det.nameStr();
0032   bool allSensitive  = getAttrOrDefault(x_det, _Unicode(allSensitive), false);
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, 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(s_vol, Position(0, 0, sliceZ));
0078       s_phv.addPhysVolID("slice", s_num);
0079       if (x_slice.isSensitive() || allSensitive) {
0080         sens.setType("calorimeter");
0081         s_vol.setSensitiveDetector(sens);
0082         sensitives.push_back(s_phv);
0083       }
0084       sliceZ += s_thick / 2;
0085       s_num++;
0086     }
0087     l_vol.setVisAttributes(description.visAttributes(x_layer.visStr()));
0088     if (l_repeat <= 0)
0089       throw std::runtime_error(x_det.nameStr() + "> Invalid repeat value");
0090     for (int j = 0; j < l_repeat; ++j) {
0091       string phys_lay = _toString(l_num, "layer%d");
0092       layerZ += l_thick / 2;
0093       DetElement layer_elt(endcap, phys_lay, l_num);
0094       PlacedVolume pv = endcapVol.placeVolume(l_vol, Position(0, 0, layerZ));
0095       pv.addPhysVolID("layer", l_num);
0096       layer_elt.setPlacement(pv);
0097       for (size_t ic = 0; ic < sensitives.size(); ++ic) {
0098         PlacedVolume sens_pv = sensitives[ic];
0099         DetElement comp_elt(layer_elt, sens_pv.volume().name(), l_num);
0100         comp_elt.setPlacement(sens_pv);
0101       }
0102       layerZ += l_thick / 2;
0103       ++l_num;
0104     }
0105     ++layerType;
0106   }
0107 
0108   double z_pos = zmin + totalThickness / 2;
0109   PlacedVolume pv;
0110   // Reflect it.
0111   Assembly assembly(det_name);
0112   DetElement endcapAssyDE(det_name, det_id);
0113   Volume motherVol = description.pickMotherVolume(endcapAssyDE);
0114   pv =
0115       assembly.placeVolume(endcapVol, Transform3D(RotationZYX(0, M_PI, 0), Position(0, 0, -z_pos)));
0116   pv.addPhysVolID("barrel", 2);
0117   Ref_t(endcap)->SetName((det_name + "_backward").c_str());
0118   endcap.setPlacement(pv);
0119   endcapAssyDE.add(endcap);
0120   pv = motherVol.placeVolume(assembly, Position(pos.x(), pos.y(), pos.z()));
0121   pv.addPhysVolID("system", det_id);
0122   endcapAssyDE.setPlacement(pv);
0123   return endcapAssyDE;
0124 }
0125 
0126 // clang-format off
0127 DECLARE_DETELEMENT(epic_PolyhedraEndcapCalorimeter2, create_detector)
0128 DECLARE_DETELEMENT(epic_PolyhedraEndcapCalorimeter, create_detector)