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 Wouter Deconinck, 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 // Specialized generic detector constructor
0018 //
0019 //==========================================================================
0020 #include "DD4hep/DetFactoryHelper.h"
0021 
0022 using namespace std;
0023 using namespace dd4hep;
0024 using namespace dd4hep::detail;
0025 
0026 static Ref_t create_detector(Detector& description, xml_h e,
0027                              [[maybe_unused]] SensitiveDetector sens) {
0028   xml_det_t x_det = e;
0029   string det_name = x_det.nameStr();
0030   Material air    = description.air();
0031   DetElement sdet(det_name, x_det.id());
0032   Assembly assembly(det_name + "_assembly");
0033   PlacedVolume pv;
0034 
0035   int i_layer = 0;
0036   for (xml_coll_t l_iter(x_det, _U(layer)); l_iter; ++l_iter, ++i_layer) {
0037     xml_comp_t x_layer = l_iter;
0038     string l_name =
0039         getAttrOrDefault<string>(x_layer, _U(name), det_name + _toString(i_layer, "_layer%d"));
0040     double outer_z = x_layer.outer_z();
0041     double inner_r = x_layer.inner_r();
0042     double outer_r = inner_r;
0043     DetElement layer(sdet, _toString(i_layer, "layer%d"), x_layer.id());
0044     Tube l_tub(inner_r, 2 * inner_r, outer_z); // outer_r will be updated
0045     Volume l_vol(l_name, l_tub, air);
0046 
0047     int i_slice        = 0;
0048     double l_thickness = 0.0;
0049     for (xml_coll_t s_iter(x_layer, _U(slice)); s_iter; ++s_iter, ++i_slice) {
0050       // If slices are only given a thickness attribute, they are radially concentric slices
0051       // If slices are given an inner_z attribute, they are longitudinal slices with equal rmin
0052       xml_comp_t x_slice = s_iter;
0053       Material mat       = description.material(x_slice.materialStr());
0054       string s_name =
0055           getAttrOrDefault<string>(x_slice, _U(name), l_name + _toString(i_slice, "_slice%d"));
0056       double thickness = x_slice.thickness();
0057       if (thickness > l_thickness)
0058         l_thickness = thickness;
0059       double s_outer_z = dd4hep::getAttrOrDefault(x_slice, _Unicode(outer_z), outer_z);
0060       double s_inner_z = dd4hep::getAttrOrDefault(x_slice, _Unicode(inner_z), 0.0 * cm);
0061       Tube s_tub(inner_r, inner_r + thickness,
0062                  (s_inner_z > 0 ? 0.5 * (s_outer_z - s_inner_z) : s_outer_z));
0063       Volume s_vol(s_name, s_tub, mat);
0064 
0065       s_vol.setAttributes(description, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
0066       if (s_inner_z > 0) {
0067         // Place off-center volumes twice
0068         Position s_pos(0, 0, 0.5 * (s_outer_z + s_inner_z));
0069         pv = l_vol.placeVolume(s_vol, -s_pos);
0070         pv = l_vol.placeVolume(s_vol, +s_pos);
0071       } else {
0072         outer_r += l_thickness;
0073         pv = l_vol.placeVolume(s_vol);
0074       }
0075       // Slices have no extra id. Take the ID of the layer!
0076       pv.addPhysVolID("slice", i_slice);
0077     }
0078     l_tub.setDimensions(inner_r, outer_r, outer_z);
0079     l_vol.setVisAttributes(description, x_layer.visStr());
0080 
0081     pv = assembly.placeVolume(l_vol);
0082     pv.addPhysVolID("layer", i_layer);
0083     layer.setPlacement(pv);
0084   }
0085 
0086   // Get position and place volume
0087   xml::Component x_pos = x_det.position();
0088   Position pos(x_pos.x(), x_pos.y(), x_pos.z());
0089   pv = description.pickMotherVolume(sdet).placeVolume(assembly, pos);
0090   pv.addPhysVolID("system", sdet.id()).addPhysVolID("barrel", 0);
0091   sdet.setPlacement(pv);
0092   return sdet;
0093 }
0094 
0095 DECLARE_DETELEMENT(epic_Solenoid, create_detector)