File indexing completed on 2025-07-08 08:10:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Io/Json/JsonDigitizationConfig.hpp"
0010
0011 #include "Acts/Definitions/TrackParametrization.hpp"
0012 #include "Acts/Plugins/Json/UtilitiesJsonConverter.hpp"
0013 #include "Acts/Utilities/BinningData.hpp"
0014 #include "ActsExamples/Digitization/Smearers.hpp"
0015 #include "ActsExamples/Framework/RandomNumbers.hpp"
0016 #include "ActsFatras/Digitization/UncorrelatedHitSmearer.hpp"
0017
0018 #include <cstddef>
0019 #include <fstream>
0020 #include <stdexcept>
0021 #include <utility>
0022 #include <vector>
0023
0024 namespace ActsExamples {
0025 namespace {
0026 void to_json(nlohmann::json& j, const ActsFatras::SingleParameterSmearFunction<
0027 ActsExamples::RandomEngine>& f) {
0028
0029 auto gauss = f.target<const Digitization::Gauss>();
0030 if (gauss != nullptr) {
0031 j["type"] = "Gauss";
0032 j["mean"] = 0;
0033 j["stddev"] = gauss->sigma;
0034 return;
0035 }
0036
0037 auto gaussT = f.target<const Digitization::GaussTrunc>();
0038 if (gaussT != nullptr) {
0039 j["type"] = "GaussTrunc";
0040 j["mean"] = 0;
0041 j["stddev"] = gaussT->sigma;
0042 j["range"] = gaussT->range;
0043 return;
0044 }
0045
0046 auto gaussC = f.target<const Digitization::GaussClipped>();
0047 if (gaussC != nullptr) {
0048 j["type"] = "GaussClipped";
0049 j["mean"] = 0;
0050 j["stddev"] = gaussC->sigma;
0051 j["range"] = gaussC->range;
0052 j["max_attempts"] = gaussC->maxAttemps;
0053 return;
0054 }
0055
0056 auto uniform = f.target<const Digitization::Uniform>();
0057 if (uniform != nullptr) {
0058 j["type"] = "Uniform";
0059 j["bindata"] = nlohmann::json(uniform->binningData);
0060 return;
0061 }
0062
0063 auto digital = f.target<const Digitization::Digital>();
0064 if (digital != nullptr) {
0065 j["type"] = "Digital";
0066 j["bindata"] = nlohmann::json(digital->binningData);
0067 return;
0068 }
0069
0070 auto exact = f.target<const Digitization::Exact>();
0071 if (exact != nullptr) {
0072 j["type"] = "Exact";
0073 j["stddev"] = exact->sigma;
0074 return;
0075 }
0076
0077 throw std::runtime_error("Unable to serialize smearer");
0078 }
0079
0080 void from_json(
0081 const nlohmann::json& j,
0082 ActsFatras::SingleParameterSmearFunction<ActsExamples::RandomEngine>& f) {
0083 std::string sType = j["type"];
0084
0085 if (sType == "Gauss") {
0086 f = Digitization::Gauss(j["stddev"]);
0087 } else if (sType == "GaussTrunc") {
0088 double sigma = j["stddev"];
0089 std::pair<double, double> range = j["range"];
0090 f = Digitization::GaussTrunc(sigma, range);
0091 } else if (sType == "GaussClipped") {
0092 double sigma = j["stddev"];
0093 std::pair<double, double> range = j["range"];
0094 f = Digitization::GaussClipped(sigma, range);
0095 } else if (sType == "Uniform") {
0096 Acts::BinningData bd;
0097 from_json(j["bindata"], bd);
0098 f = Digitization::Uniform(bd);
0099 } else if (sType == "Digital") {
0100 Acts::BinningData bd;
0101 from_json(j["bindata"], bd);
0102 f = Digitization::Digital(bd);
0103 } else if (sType == "Exact") {
0104 f = Digitization::Exact(j["stddev"]);
0105 } else {
0106 throw std::invalid_argument("Unknown smearer type '" + sType + "'");
0107 }
0108 }
0109
0110 }
0111 }
0112
0113 void ActsExamples::to_json(nlohmann::json& j,
0114 const ActsExamples::ParameterSmearingConfig& psc) {
0115 j["index"] = psc.index;
0116 j["forcePositiveValues"] = psc.forcePositiveValues;
0117 to_json(j, psc.smearFunction);
0118 }
0119
0120 void ActsExamples::from_json(const nlohmann::json& j,
0121 ActsExamples::ParameterSmearingConfig& psc) {
0122 psc.index = static_cast<Acts::BoundIndices>(j["index"]);
0123 if (j.find("forcePositiveValues") != j.end()) {
0124 psc.forcePositiveValues = j["forcePositiveValues"];
0125 }
0126 from_json(j, psc.smearFunction);
0127 }
0128
0129 void ActsExamples::to_json(nlohmann::json& j,
0130 const ActsExamples::GeometricConfig& gdc) {
0131 std::vector<std::size_t> indices;
0132 for (const auto& idx : gdc.indices) {
0133 indices.push_back(static_cast<std::size_t>(idx));
0134 }
0135 j["indices"] = indices;
0136 j["segmentation"] = nlohmann::json(gdc.segmentation);
0137 j["thickness"] = gdc.thickness;
0138 j["threshold"] = gdc.threshold;
0139 j["digital"] = gdc.digital;
0140 if (j.find("charge-smearing") != j.end()) {
0141 to_json(j["charge-smearing"], gdc.chargeSmearer);
0142 }
0143 }
0144
0145 void ActsExamples::from_json(const nlohmann::json& j,
0146 ActsExamples::GeometricConfig& gdc) {
0147 for (const auto& jidx : j["indices"]) {
0148 gdc.indices.push_back(static_cast<Acts::BoundIndices>(jidx));
0149 }
0150 from_json(j["segmentation"], gdc.segmentation);
0151 gdc.thickness = j["thickness"];
0152 gdc.threshold = j["threshold"];
0153 gdc.digital = j["digital"];
0154 if (j.find("variances") != j.end()) {
0155
0156 auto jvariances = j["variances"];
0157 for (const auto& jvar : jvariances) {
0158 auto idx =
0159 static_cast<Acts::BoundIndices>(jvar["index"].get<std::size_t>());
0160 auto vars = jvar["rms"].get<std::vector<double>>();
0161 gdc.varianceMap[idx] = vars;
0162 }
0163 }
0164 if (j.find("charge-smearing") != j.end()) {
0165 from_json(j["charge-smearing"], gdc.chargeSmearer);
0166 }
0167 }
0168
0169 void ActsExamples::to_json(nlohmann::json& j,
0170 const ActsExamples::SmearingConfig& sdc) {
0171 for (const auto& sc : sdc.params) {
0172 j.push_back(nlohmann::json(sc));
0173 }
0174 }
0175
0176 void ActsExamples::from_json(const nlohmann::json& j,
0177 ActsExamples::SmearingConfig& sdc) {
0178 for (const auto& jpsc : j) {
0179 ActsExamples::ParameterSmearingConfig psc;
0180 from_json(jpsc, psc);
0181 sdc.params.push_back(psc);
0182 }
0183 }
0184
0185 void ActsExamples::to_json(nlohmann::json& j,
0186 const ActsExamples::DigiComponentsConfig& dc) {
0187 if (!dc.geometricDigiConfig.indices.empty()) {
0188 j["geometric"] = nlohmann::json(dc.geometricDigiConfig);
0189 }
0190 if (!dc.smearingDigiConfig.params.empty()) {
0191 j["smearing"] = nlohmann::json(dc.smearingDigiConfig);
0192 }
0193 }
0194
0195 void ActsExamples::from_json(const nlohmann::json& j,
0196 ActsExamples::DigiComponentsConfig& dc) {
0197 if (j.find("geometric") != j.end()) {
0198 nlohmann::json jgdc = j["geometric"];
0199 from_json(jgdc, dc.geometricDigiConfig);
0200 }
0201 if (j.find("smearing") != j.end()) {
0202 nlohmann::json jsdc = j["smearing"];
0203 from_json(jsdc, dc.smearingDigiConfig);
0204 }
0205 }
0206
0207 Acts::GeometryHierarchyMap<ActsExamples::DigiComponentsConfig>
0208 ActsExamples::readDigiConfigFromJson(const std::string& path) {
0209 nlohmann::json djson;
0210 if (path.empty()) {
0211 return Acts::GeometryHierarchyMap<ActsExamples::DigiComponentsConfig>();
0212 }
0213 std::ifstream infile(path, std::ifstream::in | std::ifstream::binary);
0214
0215 infile.exceptions(std::ofstream::failbit | std::ofstream::badbit);
0216 infile >> djson;
0217 return DigiConfigConverter("digitization-configuration").fromJson(djson);
0218 }
0219
0220 void ActsExamples::writeDigiConfigToJson(
0221 const Acts::GeometryHierarchyMap<DigiComponentsConfig>& cfg,
0222 const std::string& path) {
0223 std::ofstream outfile(path, std::ofstream::out | std::ofstream::binary);
0224
0225 outfile.exceptions(std::ofstream::failbit | std::ofstream::badbit);
0226 outfile << DigiConfigConverter("digitization-configuration")
0227 .toJson(cfg, nullptr)
0228 .dump(2);
0229 }