Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-06-26 07:05:48

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2024 Dmitry Kalinkin
0003 
0004 #include <algorithms/logger.h>
0005 #include <functional>
0006 #include <mutex>
0007 #include <string>
0008 #include <unordered_map>
0009 #include <utility>
0010 #include <vector>
0011 
0012 namespace eicrecon {
0013 
0014 /**
0015  * @brief Provides an interface to a compiler that converts string expressions
0016  * to native `std::function`.
0017  *
0018  * The underlying implementation relies on ROOT's TInterpreter, but this may
0019  * change in the future. User can inspect the full C++ code by setting
0020  * `-PEvaluatorSvc:LogLevel=debug`, the list of provided variables is apparent
0021  * from the same output.
0022  *
0023  * Currently, return type is fixed to `double`, and all input parameters have
0024  * to be convertible to double.
0025  */
0026 class EvaluatorSvc : public algorithms::LoggedService<EvaluatorSvc> {
0027 public:
0028   void init();
0029 
0030   /**
0031    * @brief Compile expression `expr` to std::function
0032    * @param expr String expression to compile (e.g. `"a + b"`)
0033    * @param Args Types of arguments for the resulting function
0034    * @param transform Function providing mapping from Args
0035    *
0036    * The `Args` must be default-constructible types, since transform need to be
0037    * called at compilation time to determine the list of available parameters.
0038    */
0039   template <class... Args>
0040   std::function<double(Args...)>
0041   compile(const std::string& expr,
0042           std::function<std::unordered_map<std::string, double>(Args...)> transform) {
0043     std::vector<std::string> params;
0044     // Call transform with default values to detect parameter names
0045     for (auto& p : transform(Args{}...)) {
0046       params.push_back(p.first);
0047     }
0048     auto compiled_expr = _compile(expr, params);
0049     return [compiled_expr, transform](Args... args) {
0050       return compiled_expr(transform(std::forward<Args>(args)...));
0051     };
0052   };
0053 
0054   /**
0055    * @brief Compile expression `expr` to std::function
0056    * @param expr String expression to compile (e.g. `"a + b"`)
0057    * @param params List of parameter names used in the expression (e.g. `{"a", "b"}`)
0058    *
0059    * The resulting function accepts a dictionary (`std::unordered_map`) of
0060    * parameter values.
0061    */
0062   std::function<double(const std::unordered_map<std::string, double>&)>
0063   _compile(const std::string& expr, std::vector<std::string> params);
0064 
0065 private:
0066   unsigned int m_function_id = 0;
0067   std::mutex m_interpreter_mutex;
0068 
0069   ALGORITHMS_DEFINE_LOGGED_SERVICE(EvaluatorSvc);
0070 };
0071 
0072 } // namespace eicrecon