Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-21 08:26:50

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2024 Dmitry Kalinkin
0003 
0004 #include <TInterpreter.h>
0005 #include <TInterpreterValue.h>
0006 #include <format>
0007 #include <memory>
0008 #include <sstream>
0009 
0010 #include "EvaluatorSvc.h"
0011 
0012 namespace eicrecon {
0013 
0014 void EvaluatorSvc::init() {
0015   // This is needed to bypass condition in algorithms::LoggerMixin::report and
0016   // forward all messages to our instance of LogSvc/spdlog.
0017   level(algorithms::LogLevel::kTrace);
0018 }
0019 
0020 std::function<double(const std::unordered_map<std::string, double>&)>
0021 EvaluatorSvc::_compile(const std::string& expr, const std::vector<std::string>& params) {
0022   std::lock_guard<std::mutex> guard(m_interpreter_mutex);
0023 
0024   std::string func_name = std::format("_eicrecon_{}", m_function_id++);
0025   std::ostringstream sstr;
0026   sstr << "double " << func_name << "(double params[]){";
0027   for (unsigned int param_ix = 0; const auto& p : params) {
0028     sstr << "double " << p << " = params[" << (param_ix++) << "];";
0029   }
0030   sstr << "return " << expr << ";";
0031   sstr << "}";
0032 
0033   TInterpreter* interp = TInterpreter::Instance();
0034   debug("Compiling {}", sstr.str());
0035   interp->ProcessLine(sstr.str().c_str());
0036   std::shared_ptr<TInterpreterValue> func_val{gInterpreter->MakeInterpreterValue()};
0037   interp->Evaluate(func_name.c_str(), *func_val);
0038 
0039   using func_t = double (*)(double params[]);
0040   // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
0041   auto func = reinterpret_cast<func_t>(func_val->GetAsPointer());
0042 
0043   // func_val is captured to extend the lifetime of the underlying object that func points to
0044   return [params, func, func_val](const std::unordered_map<std::string, double>& param_values) {
0045     std::vector<double> value_list;
0046     value_list.reserve(params.size());
0047     for (const auto& p : params) {
0048       value_list.push_back(param_values.at(p));
0049     }
0050     return func(value_list.data());
0051   };
0052 }
0053 
0054 } // namespace eicrecon