Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:42

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2023 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #include "DD4hepTestsHelper.hpp"
0010 
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Plugins/DD4hep/DD4hepConversionHelpers.hpp"
0013 #include "Acts/Surfaces/Surface.hpp"
0014 
0015 #include <DD4hep/DD4hepUnits.h>
0016 
0017 void DD4hepTestsHelper::decodeBinning(
0018     dd4hep::rec::VariantParameters& variantParams, const xml_comp_t& xmlBinning,
0019     const std::string& bname, const std::vector<std::string>& bvals) {
0020   // Set the surface binninng parameter to true
0021   variantParams.set<int>(std::string(bname + "_dim"), bvals.size());
0022   for (const auto& bv : bvals) {
0023     // Gather the number of bins, 0 indicates variable binning
0024     int nBins = Acts::getAttrValueOr<int>(xmlBinning, std::string("n" + bv), 0);
0025     // Gather the bin expansion parameter, expansion of 0 is default
0026     int nExpansion =
0027         Acts::getAttrValueOr<int>(xmlBinning, std::string(bv + "expansion"), 0);
0028     // Auto-range detection
0029     bool autoRange = Acts::getAttrValueOr<bool>(
0030         xmlBinning, std::string(bv + "autorange"), false);
0031     variantParams.set<bool>(bname + "_" + bv + "_autorange", autoRange);
0032     variantParams.set<int>(bname + "_" + bv + "_exp", nExpansion);
0033     // Equidistant binning detected
0034     if (nBins > 0) {
0035       // Set the type identification
0036       variantParams.set<std::string>(bname + "_" + bv + "_type", "equidistant");
0037       // Set the number of bins
0038       variantParams.set<int>(bname + "_" + bv + "_n", nBins);
0039       // Set min/max parameter
0040       if (!autoRange) {
0041         variantParams.set<double>(
0042             bname + "_" + bv + "_min",
0043             xmlBinning.attr<double>(std::string(bv + "min").c_str()));
0044         variantParams.set<double>(
0045             bname + "_" + bv + "_max",
0046             xmlBinning.attr<double>(std::string(bv + "max").c_str()));
0047       }
0048     } else {
0049       // Variable binning detected
0050       variantParams.set<std::string>(bname + "_" + bv + "_type", "variable");
0051       // Get the number of bins explicitly
0052       auto boundaries =
0053           xmlBinning.attr<std::string>(std::string(bv + "boundaries").c_str());
0054       std::string del = ",";
0055       auto end = boundaries.find(del);
0056       int ib = 0;
0057       // Unit conversion
0058       double unitScalar = 1.;
0059       if (bv != "phi") {
0060         unitScalar = Acts::UnitConstants::mm / dd4hep::millimeter;
0061       }
0062       // Split and convert
0063       while (end != std::string::npos) {
0064         double bR = unitScalar * dd4hep::_toFloat(boundaries.substr(0, end));
0065         variantParams.set<double>(
0066             bname + "_" + bv + "_b" + std::to_string(ib++), bR);
0067         boundaries.erase(boundaries.begin(), boundaries.begin() + end + 1);
0068         end = boundaries.find(del);
0069       }
0070       double bR = unitScalar * std::stod(boundaries.substr(0, end));
0071       variantParams.set<double>(bname + "_" + bv + "_b" + std::to_string(ib),
0072                                 bR);
0073       // The number of bins are needed to unpack the data
0074       variantParams.set<int>(bname + "_" + bv + "_n", ib);
0075     }
0076   }
0077 }
0078 
0079 dd4hep::Transform3D DD4hepTestsHelper::createTransform(
0080     const xml_comp_t& x_det_comp) {
0081   // Build the transform - center def
0082   double cx = Acts::getAttrValueOr<double>(x_det_comp, "cx", 0.);
0083   double cy = Acts::getAttrValueOr<double>(x_det_comp, "cy", 0.);
0084   double cz = Acts::getAttrValueOr<double>(x_det_comp, "cz", 0.);
0085 
0086   double xx = Acts::getAttrValueOr<double>(x_det_comp, "xx", 1.);
0087   double xy = Acts::getAttrValueOr<double>(x_det_comp, "xy", 0.);
0088   double xz = Acts::getAttrValueOr<double>(x_det_comp, "xz", 0.);
0089 
0090   double yx = Acts::getAttrValueOr<double>(x_det_comp, "yx", 0.);
0091   double yy = Acts::getAttrValueOr<double>(x_det_comp, "yy", 1.);
0092   double yz = Acts::getAttrValueOr<double>(x_det_comp, "yz", 0.);
0093 
0094   Position xAxis(xx, xy, xz);
0095   Position yAxis(yx, yy, yz);
0096   Position zAxis = xAxis.Cross(yAxis);
0097   double zx = zAxis.X();
0098   double zy = zAxis.Y();
0099   double zz = zAxis.Z();
0100 
0101   // Create the transform
0102   return Transform3D(xx, yx, zx, cx, xy, yy, zy, cy, xz, yz, zz, cz);
0103 }
0104 
0105 std::string DD4hepTestsHelper::transformToXML(const Acts::Transform3& tf,
0106                                               const std::array<int, 2u>& axes) {
0107   auto tr = tf.translation();
0108   auto rot = tf.rotation();
0109 
0110   std::stringstream sxml;
0111   sxml << "cx=\"" << tr[0u] << "*mm\" ";
0112   sxml << "cy=\"" << tr[1u] << "*mm\" ";
0113   sxml << "cz=\"" << tr[2u] << "*mm\" ";
0114 
0115   sxml << "xx=\"" << rot.col(axes[0u])[0u] << "\" ";
0116   sxml << "xy=\"" << rot.col(axes[0u])[1u] << "\" ";
0117   sxml << "xz=\"" << rot.col(axes[0u])[2u] << "\" ";
0118   sxml << "yx=\"" << rot.col(axes[1u])[0u] << "\" ";
0119   sxml << "yy=\"" << rot.col(axes[1u])[1u] << "\" ";
0120   sxml << "yz=\"" << rot.col(axes[1u])[2u] << "\" ";
0121 
0122   return sxml.str();
0123 }
0124 
0125 std::string DD4hepTestsHelper::surfaceToXML(const Acts::GeometryContext& gctx,
0126                                             const Acts::Surface& surface,
0127                                             const Acts::Transform3& ref) {
0128   // The xml to be translated
0129   std::stringstream sxml;
0130   auto boundValues = surface.bounds().values();
0131 
0132   std::array<int, 2u> axes = {0, 1};
0133   // Change/adapt the behavior
0134   switch (surface.bounds().type()) {
0135     case Acts::SurfaceBounds::eRectangle: {
0136       sxml << "<box ";
0137       double dx = (boundValues[2u] - boundValues[0u]);
0138       double dy = (boundValues[3u] - boundValues[1u]);
0139       double dz = 0.125;
0140       sxml << "dx=\"" << dx << "*mm\" ";
0141       sxml << "dy=\"" << dy << "*mm\" ";
0142       sxml << "dz=\"" << dz << "*mm\" ";
0143     }; break;
0144     case Acts::SurfaceBounds::eTrapezoid: {
0145       axes = {2, 0};
0146 
0147       sxml << "<trap ";
0148       double hxmin = boundValues[0u];
0149       double hxmax = boundValues[1u];
0150       double dy = 2 * boundValues[2u];
0151       double dz = 0.125;
0152       sxml << "x1=\"" << hxmin << "*mm\" ";
0153       sxml << "x2=\"" << hxmax << "*mm\" ";
0154       sxml << "dy=\"" << dy << "*mm\" ";
0155       sxml << "dz=\"" << dz << "*mm\" ";
0156     }; break;
0157     default:
0158       break;
0159   }
0160 
0161   // Unwind the placement you have already
0162   auto relTransform = ref * surface.transform(gctx);
0163   sxml << transformToXML(relTransform, axes);
0164   sxml << " material=\"Air\"";
0165   sxml << " sensitive=\"true\"/>";
0166   return sxml.str();
0167 }