Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 07:48:18

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsPlugins/Json/BetheHeitlerApproxJsonConverter.hpp"
0010 
0011 #include "Acts/Utilities/RangeXD.hpp"
0012 
0013 #include <fstream>
0014 #include <stdexcept>
0015 
0016 void Acts::to_json(nlohmann::json& j,
0017                    const Acts::PolynomialBetheHeitlerApprox::PolyData& data) {
0018   j["weight_coeffs"] = data.weightCoeffs;
0019   j["mean_coeffs"] = data.meanCoeffs;
0020   j["var_coeffs"] = data.varCoeffs;
0021 }
0022 
0023 void Acts::from_json(const nlohmann::json& j,
0024                      Acts::PolynomialBetheHeitlerApprox::PolyData& data) {
0025   data.weightCoeffs = j.at("weight_coeffs").get<std::vector<double>>();
0026   data.meanCoeffs = j.at("mean_coeffs").get<std::vector<double>>();
0027   data.varCoeffs = j.at("var_coeffs").get<std::vector<double>>();
0028 }
0029 
0030 void Acts::to_json(nlohmann::json& j,
0031                    const Acts::PolynomialBetheHeitlerApprox::RangeData& data) {
0032   j["low_x0"] = data.range.min();
0033   j["high_x0"] = data.range.max();
0034   j["transform"] = data.transform;
0035 
0036   nlohmann::json components = nlohmann::json::array();
0037   for (const auto& cmp : data.data) {
0038     nlohmann::json jcmp;
0039     Acts::to_json(jcmp, cmp);
0040     components.push_back(jcmp);
0041   }
0042   j["components"] = components;
0043 }
0044 
0045 void Acts::from_json(const nlohmann::json& j,
0046                      Acts::PolynomialBetheHeitlerApprox::RangeData& data) {
0047   data.range = Acts::Range1D<double>{j.at("low_x0").get<double>(),
0048                                      j.at("high_x0").get<double>()};
0049   data.transform = j.value("transform", true);
0050 
0051   if (j.contains("components")) {
0052     data.data.clear();
0053     for (const auto& jcmp : j["components"]) {
0054       Acts::PolynomialBetheHeitlerApprox::PolyData component;
0055       Acts::from_json(jcmp, component);
0056       data.data.push_back(component);
0057     }
0058   } else if (j.contains("weight_coeffs")) {
0059     Acts::PolynomialBetheHeitlerApprox::PolyData component;
0060     Acts::from_json(j, component);
0061     data.data = {component};
0062   } else {
0063     throw std::runtime_error(
0064         "JSON range data must contain either 'components' array or "
0065         "'weight_coeffs' (flat format)");
0066   }
0067 }
0068 
0069 Acts::PolynomialBetheHeitlerApprox Acts::loadBetheHeitlerApproxFromJson(
0070     const std::string& filepath, bool clampToRange, double noChangeLimit,
0071     double singleGaussianLimit) {
0072   std::ifstream in(filepath);
0073   if (!in) {
0074     throw std::invalid_argument("Could not open JSON file '" + filepath + "'");
0075   }
0076   nlohmann::json j;
0077   in >> j;
0078 
0079   if (!j.contains("ranges")) {
0080     throw std::invalid_argument(
0081         "JSON file must contain 'ranges' array with at least one range");
0082   }
0083 
0084   std::vector<Acts::PolynomialBetheHeitlerApprox::RangeData> ranges;
0085   for (const auto& jrange : j["ranges"]) {
0086     Acts::PolynomialBetheHeitlerApprox::RangeData range;
0087     Acts::from_json(jrange, range);
0088     ranges.push_back(range);
0089   }
0090 
0091   if (ranges.empty()) {
0092     throw std::invalid_argument(
0093         "JSON file must contain 'ranges' array with at least one range");
0094   }
0095 
0096   return Acts::PolynomialBetheHeitlerApprox(std::move(ranges), clampToRange,
0097                                             noChangeLimit, singleGaussianLimit);
0098 }