File indexing completed on 2026-04-05 08:11:42
0001 #ifndef PT_CALCULATOR_H
0002 #define PT_CALCULATOR_H
0003
0004 #include <functional>
0005 #include <string>
0006 #include <variant>
0007 #include <vector>
0008 #include <optional>
0009 #include <limits>
0010 #include <array>
0011 #include <memory>
0012 #include <iostream>
0013
0014 namespace SiCaloPt {
0015
0016
0017 struct PtResult
0018 {
0019 float pt_reco = std::numeric_limits<float>::quiet_NaN();
0020 bool ok = false;
0021 std::string err;
0022 };
0023
0024
0025 enum class Method
0026 {
0027 MethodEMD,
0028 MethodEproj,
0029 MethodMLEMD,
0030 MethodMLEproj,
0031 MethodMLCombined
0032 };
0033
0034
0035 struct InputEMD
0036 {
0037 float EMD_Angle = 0.f;
0038 float EMD_Eta = 0.f;
0039 float EMD_Radius = 0.f;
0040 };
0041
0042 struct InputEproj
0043 {
0044 float Energy_Calo = 0.f;
0045 float Radius_Calo = 0.f;
0046 float Z_Calo = 0.f;
0047 float Radius_vertex = 0.f;
0048 float Z_vertex = 0.f;
0049 };
0050
0051
0052
0053 struct InputMLEMD
0054 {
0055 std::vector<float> features;
0056 };
0057
0058 struct InputMLEproj
0059 {
0060 std::vector<float> features;
0061 };
0062
0063 struct InputMLCombined
0064 {
0065 std::vector<float> features;
0066 };
0067
0068
0069 using AnyInput = std::variant<InputEMD, InputEproj, InputMLEMD, InputMLEproj, InputMLCombined>;
0070
0071
0072 struct PtCalculatorConfig
0073 {
0074 std::optional<std::string> mlEMD_model_path;
0075 std::optional<std::string> mlEproj_model_path;
0076 std::optional<std::string> mlCombined_model_path;
0077
0078 std::optional<std::string> mlEMD_scaler_json;
0079 std::optional<std::string> mlEproj_scaler_json;
0080 std::optional<std::string> mlCombined_scaler_json;
0081 };
0082
0083
0084 class PtCalculator {
0085 public:
0086
0087 PtResult ComputePt(Method method, const AnyInput& input) const;
0088
0089
0090 PtResult ComputeEMD(const InputEMD& in) const;
0091 PtResult ComputeEproj(const InputEproj& in) const;
0092 PtResult ComputeMLEMD(const InputMLEMD& in) const;
0093 PtResult ComputeMLEproj(const InputMLEproj& in) const;
0094 PtResult ComputeMLCombined(const InputMLCombined& in) const;
0095
0096
0097
0098 void setClusterRecoMode(int mode)
0099 {
0100 if (mode < 0 || mode > 2) {
0101 std::cerr << "ERROR: ClusterRecoMode must be 0/1/2" << std::endl;
0102 return;
0103 }
0104 ClusterRecoMode = mode;
0105 }
0106 int getClusterRecoMode() const { return ClusterRecoMode; }
0107
0108
0109 void setParCeta(float v) { m_par_Ceta = v; }
0110 void setParPower(float v) { m_par_Power = v; }
0111
0112
0113 PtCalculator() = default;
0114 explicit PtCalculator(const PtCalculatorConfig& cfg);
0115
0116
0117 void setConfig(const PtCalculatorConfig& cfg);
0118
0119
0120 bool init(std::string* err = nullptr);
0121
0122
0123 using InferFn = std::function<float(const std::vector<float>&)>;
0124 void setMLEMDInfer(InferFn fn);
0125 void setMLEprojInfer(InferFn fn);
0126 void setMLCombinedInfer(InferFn fn);
0127
0128
0129 void setMLEMDStandardizer(std::vector<float> mean, std::vector<float> scale);
0130 void setMLEprojStandardizer(std::vector<float> mean, std::vector<float> scale);
0131 void setMLCombinedStandardizer(std::vector<float> mean, std::vector<float> scale);
0132
0133 private:
0134 static void applyStandardize(std::vector<float>& x,
0135 const std::vector<float>& mean,
0136 const std::vector<float>& scale);
0137
0138 static bool LoadScalerJson(const std::string& path,
0139 std::vector<float>& mean,
0140 std::vector<float>& scale,
0141 std::string* err = nullptr);
0142
0143 static SiCaloPt::PtCalculator::InferFn MakeOnnxInfer(const std::string& onnx_path, std::string* err = nullptr);
0144
0145 private:
0146 PtCalculatorConfig m_cfg;
0147
0148 int getScenario(double bending_angle = 0.1) const
0149 {
0150 int TrkrCharge = -1;
0151 if (bending_angle > 0)
0152 TrkrCharge = +1;
0153 else if (bending_angle < 0)
0154 TrkrCharge = -1;
0155
0156
0157 int track_scenario = TrkrCharge*10 + TrkrCharge*ClusterRecoMode;
0158 if (!((track_scenario >= -12 && track_scenario <= -10) ||
0159 (track_scenario >= 10 && track_scenario <= 12)))
0160 {
0161 std::cerr << "[PtCalculator] Invalid scenario = "
0162 << track_scenario
0163 << " (charge=" << TrkrCharge
0164 << ", mode=" << ClusterRecoMode << ")"
0165 << std::endl;
0166
0167 return -999;
0168 }
0169
0170 return track_scenario;
0171 }
0172
0173
0174 int ClusterRecoMode = 0;
0175
0176
0177 InferFn m_mlEMD_infer;
0178 InferFn m_mlEproj_infer;
0179 InferFn m_mlCombined_infer;
0180
0181
0182 std::vector<float> m_mlEMD_mean, m_mlEMD_scale;
0183 std::vector<float> m_mlEproj_mean, m_mlEproj_scale;
0184 std::vector<float> m_mlCombined_mean, m_mlCombined_scale;
0185
0186
0187 mutable float m_par_Ceta = 0.2;
0188 mutable float m_par_Power = -1.0;
0189
0190 bool consider_eta_dependence_on_EMDcompute = true;
0191 };
0192
0193 }
0194
0195 #endif