From e9b231341ba594037d367a566d0bb0abdae34cf0 Mon Sep 17 00:00:00 2001 From: Sylvester Joosten <sjoosten@anl.gov> Date: Mon, 25 Apr 2022 23:30:02 +0000 Subject: [PATCH] Added proper service/support plugin --- CMakeLists.txt | 1 + src/TrackerSupport_geo.cpp | 123 +++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 src/TrackerSupport_geo.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ab176a0..21a36e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,7 @@ dd4hep_add_plugin(${a_lib_name} SOURCES src/SimpleDiskDetector_geo.cpp src/Solenoid_geo.cpp src/TrapEndcapTracker_geo.cpp + src/TrackerSupport_geo.cpp USES ActsCore ActsPluginDD4hep ) target_link_libraries(${a_lib_name} diff --git a/src/TrackerSupport_geo.cpp b/src/TrackerSupport_geo.cpp new file mode 100644 index 0000000..8afcd9e --- /dev/null +++ b/src/TrackerSupport_geo.cpp @@ -0,0 +1,123 @@ +/** \addtogroup Trackers Trackers + * \brief Type: **BarrelTrackerWithFrame**. + * \author W. Armstrong + * + * \ingroup trackers + * + * @{ + */ +#include <DD4hep/DetFactoryHelper.h> +#include <DD4hep/Printout.h> +#include <DD4hep/Shapes.h> +#include <XML/Layering.h> +#include <XML/Utilities.h> + +#include <cassert> + +using namespace std; +using namespace dd4hep; + +namespace { + std::pair<Volume, Transform3D> build_shape(const Detector& descr, const xml_det_t& x_det, const xml_comp_t& x_support, + const xml_comp_t& x_child, const double offset = 0) + { + // Get rotation/translation info + xml_dim_t x_pos(x_child.child(_U(position), false)); + xml_dim_t x_rot(x_child.child(_U(rotation), false)); + Position pos3D{0, 0, 0}; + Rotation3D rot3D; + + if (x_rot) { + rot3D = RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)); + } + if (x_pos) { + pos3D = Position(x_pos.x(0), x_pos.y(0), x_pos.z(0)); + } + Transform3D tr(rot3D, pos3D); + + // handle different known shapes and create solids + Solid solid; + const std::string type = x_support.attr<std::string>(_U(type)); + if (type == "Tube") { + const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); + const double length = getAttrOrDefault(x_child, _U(length), x_support.length()); + const double rmin = getAttrOrDefault(x_child, _U(rmin), x_support.rmin()); + solid = Tube(rmin + offset, rmin + thickness + offset, length / 2); + } + if (type == "Cone") { + const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); + const double length = getAttrOrDefault(x_child, _U(length), x_support.length()); + const double rmin1 = getAttrOrDefault(x_child, _U(rmin1), x_support.rmin2()); + const double rmin2 = getAttrOrDefault(x_child, _U(rmin2), x_support.rmin2()); + // Account for the fact that the distance between rmin1 and rmax2 is the projection + // of the thickness on the transverse direction + const double transverse_thickness = thickness / cos(atan2(fabs(rmin2 - rmin1), length)); + const double rmax1 = rmin1 + transverse_thickness; + const double rmax2 = rmin2 + transverse_thickness; + solid = Cone(length / 2, rmin1, rmax1, rmin2, rmax2); + } else { + printout(ERROR, x_det.nameStr(), "Unknown support type: %s", type); + std::exit(1); + } + // Materials + Material mat = descr.material(getAttrOrDefault<std::string>(x_child, _U(material), "Air")); + // Create our volume + Volume vol{getAttrOrDefault<std::string>(x_child, _U(name), "support_vol"), solid, mat}; + + // visualization? + if (x_child.hasAttr(_U(vis))) { + vol.setVisAttributes(descr.visAttributes(x_child.visStr())); + } + return {vol, tr}; + } + std::pair<Volume, Transform3D> build_shape(const Detector& descr, const xml_det_t& x_det, const xml_comp_t& x_support, + const double offset = 0) + { + return build_shape(descr, x_det, x_support, x_support, offset); + } +} // namespace + +/** Generic tracker support implementation, can consist of arbitrary shapes + * + * @author Sylvester Joosten + */ +static Ref_t create_TrackerSupport(Detector& description, xml_h e, SensitiveDetector sens) +{ + const xml_det_t x_det = e; + const Material air = description.air(); + const int det_id = x_det.id(); + const string det_name = x_det.nameStr(); + + // global z-offset for the entire support assembly + const double offset = getAttrOrDefault(x_det, _U(offset), 0.); + + DetElement det(det_name, det_id); + Assembly assembly(det_name + "_assembly"); + + // Loop over the supports + for (xml_coll_t su{x_det, _U(support)}; su; ++su) { + xml_comp_t x_sup = su; + auto [vol, tr] = build_shape(description, x_det, x_sup); + auto pv = assembly.placeVolume(vol, tr); + // Loop over support components, if any + double cumulative_thickness = 0; + for (xml_coll_t com{x_sup, _U(component)}; com; ++com) { + xml_comp_t x_com = com; + auto [cvol, ctr] = build_shape(description, x_det, x_sup, x_com, cumulative_thickness); + vol.placeVolume(cvol, ctr); + cumulative_thickness += x_com.thickness(); + } + } + + // final placement + Volume motherVol = description.pickMotherVolume(det); + Position pos(0, 0, offset); + PlacedVolume pv = motherVol.placeVolume(assembly, pos); + pv.addPhysVolID("system", det.id()); + det.setPlacement(pv); + + return det; +} + +// clang-format off +DECLARE_DETELEMENT(eic_TrackerSupport, create_TrackerSupport) -- GitLab