Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:18:06

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 
0013 namespace SiCaloPt {
0014 
0015 // consistent return struct
0016 struct PtResult 
0017 {
0018     float pt_reco = std::numeric_limits<float>::quiet_NaN(); // reconstructed pt
0019     bool ok = false; // whether successful
0020     std::string err; // error message if any
0021 };
0022 
0023 // Five approaches enum
0024 enum class Method 
0025 {
0026     MethodEMD,   // EM Deflection Method
0027     MethodEproj, // Energy Projection Method
0028     MethodMLEMD, // ML EM Deflection Method
0029     MethodMLEproj, // ML Energy Projection Method
0030     MethodMLCombined // ML Combined Method
0031 };
0032 
0033 // Formula method input struct
0034 struct InputEMD 
0035 {
0036     float EMD_Angle = 0.f; // delta_phi - EM Deflection angle in rad is between two vectors, one vector connect inner INTT and outer INTT,  another one connect outer INTT and Calo cluster
0037     float EMD_Eta = 0.f; // track eta
0038     float EMD_Radius = 0.f; // EMCal Cluster radius in cm
0039 };
0040 
0041 struct InputEproj 
0042 {
0043     float Energy_Calo = 0.f; // EMCal Cluster energy in GeV
0044     float Radius_Calo = 0.f; // EMCal Cluster radius in cm
0045     float Z_Calo = 0.f; // EMCal Cluster z in cm
0046     float Radius_vertex = 0.f; // Vertex radius in cm
0047     float Z_vertex = 0.f; // Vertex z in cm
0048 };
0049 
0050 // ML Model input struct, using vector is convenient for ONNX, length and order must be consistent with training
0051 // Defination of length and order is in the tutorial file PtCalcMLTutorial.C
0052 struct InputMLEMD 
0053 {
0054     std::vector<float> features; // 2-d features:{ 1/dphi_EMD, eta_track}
0055 };
0056 
0057 struct InputMLEproj 
0058 {
0059     std::vector<float> features; // 7-d input features:{ INTT 3/4 layer R, INTT 3/4 layer Z, INTT 5/4 layer R, INTT 5/4 layer Z, Calo cluster R, Calo cluster Z, Calo cluster Energy }
0060 };
0061 
0062 struct InputMLCombined 
0063 {
0064     std::vector<float> features; // 2-d features:{pT reconstuct with deflection information, pT reconstuct with Calo energy information}
0065 };
0066 
0067 // consistent input variant for all methods
0068 using AnyInput = std::variant<InputEMD, InputEproj, InputMLEMD, InputMLEproj, InputMLCombined>;
0069 
0070 // Config(optional) for ML: ML paths, standardizer params, etc.
0071 struct PtCalculatorConfig 
0072 {
0073     std::optional<std::string> mlEMD_model_path;
0074     std::optional<std::string> mlEproj_model_path;
0075     std::optional<std::string> mlCombined_model_path;
0076 
0077     std::optional<std::string> mlEMD_scaler_json;
0078     std::optional<std::string> mlEproj_scaler_json;
0079     std::optional<std::string> mlCombined_scaler_json;
0080 };
0081 
0082 // PtCalculator MAIN CLASS 
0083 class PtCalculator {
0084 public:
0085     // Main Function. general func. for Pt calculation, dispatching according to method
0086     PtResult ComputePt(Method method, const AnyInput& input) const;
0087 
0088     // independent interfaces for finer control
0089     PtResult ComputeEMD(const InputEMD& in) const; // using electromagnetic deflection to calculate pT by analytic formula pT = C_eta × |Δφ|^(Power)
0090     PtResult ComputeEproj(const InputEproj& in) const; // project the Calo cluster energy to XY-plane to get pT by analytic formula pT = Energy_Calo × (ΔR / Distance) 
0091     PtResult ComputeMLEMD(const InputMLEMD& in) const; // machine learning model trained for the EMD method, the features are 2-d features: { 1/dphi_EMD, eta_track} please setting the eta_track = 0, cause I just add the dimension but not trained with the eta data now
0092     PtResult ComputeMLEproj(const InputMLEproj& in) const; // machine learning model trained for the Eproj method, the features are 7-d input features:{ INTT 3/4 layer R, INTT 3/4 layer Z, INTT 5/4 layer R, INTT 5/4 layer Z, Calo R, Calo Z, Calo Energy }
0093     PtResult ComputeMLCombined(const InputMLCombined& in) const; // machine learning model trained to combine the pT estimates obtained from two different methods based on two independent sets of information {deflection, energy}; the final combined pT is given by pT = w1 * pT(deflection) + w2 * pT(energy), where the weights w1 and w2 are predicted by the model for deflection and energy
0094 
0095     // EMD formula parameters setters
0096     void setParCeta(float v)  { m_par_Ceta = v; }
0097     void setParPower(float v) { m_par_Power = v; }
0098 
0099     // member functions
0100     PtCalculator() = default;
0101     explicit PtCalculator(const PtCalculatorConfig& cfg);
0102 
0103     // setting/configuration (does not auto-load external resources)
0104     void setConfig(const PtCalculatorConfig& cfg);
0105 
0106     // initialize (load models and scalers for ML methods)
0107     bool init(std::string* err = nullptr);
0108 
0109     // load ML infer, output is pt
0110     using InferFn = std::function<float(const std::vector<float>&)>;
0111     void setMLEMDInfer(InferFn fn);
0112     void setMLEprojInfer(InferFn fn);
0113     void setMLCombinedInfer(InferFn fn);
0114 
0115     //  optional: set standardizer for each ML model, or do standardization inside InferFn
0116     void setMLEMDStandardizer(std::vector<float> mean, std::vector<float> scale);
0117     void setMLEprojStandardizer(std::vector<float> mean, std::vector<float> scale);
0118     void setMLCombinedStandardizer(std::vector<float> mean, std::vector<float> scale);
0119 
0120 private:
0121     static void applyStandardize(std::vector<float>& x,
0122                                  const std::vector<float>& mean,
0123                                  const std::vector<float>& scale);
0124 
0125     static bool LoadScalerJson(const std::string& path,
0126                                 std::vector<float>& mean,
0127                                 std::vector<float>& scale,
0128                                 std::string* err = nullptr);
0129 
0130     static SiCaloPt::PtCalculator::InferFn MakeOnnxInfer(const std::string& onnx_path, std::string* err = nullptr);
0131 
0132 private:
0133     PtCalculatorConfig m_cfg;
0134 
0135     // ML Model infer functions
0136     InferFn m_mlEMD_infer;
0137     InferFn m_mlEproj_infer;
0138     InferFn m_mlCombined_infer;
0139 
0140     // optional: ML Scaler params for standardization, not exist for EMD and Combined model now
0141     std::vector<float> m_mlEMD_mean, m_mlEMD_scale;
0142     std::vector<float> m_mlEproj_mean, m_mlEproj_scale; 
0143     std::vector<float> m_mlCombined_mean, m_mlCombined_scale;
0144 
0145     // EMD formula parameters
0146     mutable float m_par_Ceta = 0.2;
0147     mutable float m_par_Power = -1.0;
0148 
0149     bool consider_eta_dependence_on_EMDcompute = true;
0150 
0151     bool charge_of_track_is_negative = false;
0152     bool charge_of_track_is_positive = false;
0153 };
0154 
0155 } // namespace SiCaloPt
0156 
0157 #endif // PT_CALCULATOR_H