File indexing completed on 2025-01-30 10:30:04
0001
0002
0003
0004
0005
0006 #include <thread>
0007 #include <cstdio>
0008 #include <chrono>
0009 using namespace std;
0010
0011
0012 #include <JANA/JApplication.h>
0013 #include <JANA/CLI/JMain.h>
0014 #include <JANA/Utils/JCpuInfo.h>
0015 #include <JANA/Services/JParameterManager.h>
0016
0017 #include <pybind11/pybind11.h>
0018 #include <pybind11/embed.h>
0019 namespace py = pybind11;
0020 #include "JEventProcessorPY.h"
0021
0022 static py::module_ *PY_MODULE = nullptr;
0023
0024 bool PY_INITIALIZED = false;
0025 static bool PY_MODULE_INSTANTIATED_JAPPLICATION = false;
0026 static JApplication *pyjapp = nullptr;
0027
0028
0029
0030
0031 inline void janapy_Start(void) { PY_INITIALIZED = true; }
0032 inline void janapy_Quit(bool skip_join=false) { pyjapp->Quit(skip_join); }
0033 inline void janapy_Stop(bool wait_until_idle=false) { pyjapp->Stop(wait_until_idle); }
0034
0035 inline bool janapy_IsInitialized(void) { return pyjapp->IsInitialized(); }
0036 inline bool janapy_IsQuitting(void) { return pyjapp->IsQuitting(); }
0037 inline bool janapy_IsDrainingQueues(void) { return pyjapp->IsDrainingQueues(); }
0038
0039 inline void janapy_AddPlugin(string plugin_name) { pyjapp->AddPlugin(plugin_name); }
0040 inline void janapy_AddPluginPath(string path) { pyjapp->AddPluginPath(path); }
0041 inline void janapy_AddEventSource(string source) { pyjapp->Add( source ); }
0042 inline void janapy_SetTicker(bool ticker_on=true) { pyjapp->SetTicker(ticker_on); }
0043 inline uint64_t janapy_GetNeventsProcessed(void) { return pyjapp->GetNEventsProcessed(); }
0044 inline float janapy_GetIntegratedRate(void) { return pyjapp->GetIntegratedRate(); }
0045 inline float janapy_GetInstantaneousRate(void) { return pyjapp->GetInstantaneousRate(); }
0046 inline uint32_t janapy_GetNThreads(void) { return pyjapp->GetNThreads(); }
0047 inline uint32_t janapy_SetNThreads(int Nthreads) { auto prev = pyjapp->GetNThreads(); pyjapp->Scale(Nthreads); return prev; }
0048 inline size_t janapy_GetNcores(void) { return JCpuInfo::GetNumCpus(); }
0049 inline void janapy_PrintStatus(void) { pyjapp->PrintStatus(); }
0050 inline void janapy_PrintParameters(bool all=false) { pyjapp->GetJParameterManager()->PrintParameters((all ? 3 : 1), 0); }
0051 inline string janapy_GetParameterValue(string key) { return pyjapp->GetJParameterManager()->Exists(key) ? pyjapp->GetParameterValue<string>(key):"Not Defined"; }
0052
0053 inline void janapy_Run(void)
0054 {
0055 if(PY_MODULE_INSTANTIATED_JAPPLICATION) {
0056
0057 auto options = jana::ParseCommandLineOptions(0, nullptr, false);
0058 auto exit_code = jana::Execute(pyjapp, options);
0059 LOG << "JANA processing complete. Exit code: " << exit_code << LOG_END;
0060 }else{
0061
0062 janapy_Start();
0063 }
0064 }
0065
0066
0067 inline void janapy_SetParameterValue(string key, py::object valobj)
0068 {
0069
0070 stringstream ss;
0071 try {
0072 auto val = valobj.cast<string>();
0073 ss << val;
0074 }catch(...){
0075 try {
0076 auto val = valobj.cast<double>();
0077 ss << val;
0078 }catch(...) {
0079 try {
0080 auto val = valobj.cast<long>();
0081 ss << val;
0082 }catch(...){}
0083 }
0084 }
0085 pyjapp->SetParameterValue<string>( key, ss.str() );
0086 }
0087
0088
0089
0090
0091 inline void janapy_AddProcessor(py::object &pyproc ) {
0092
0093
0094
0095
0096
0097 JEventProcessorPY *proc = pyproc.cast<JEventProcessorPY *>();
0098 proc->pymodule = PY_MODULE;
0099
0100
0101 if (pyjapp != nullptr) {
0102 cout << "[INFO] Adding JEventProcessorPY" << endl;
0103 pyjapp->Add( new JEventProcessorPYTrampoline(pyjapp, proc) );
0104 }else {
0105 cerr << "[ERROR] pyjapp not set before call to janapy_AddProcessor() !!" << endl;
0106 }
0107 }
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 #define JANA_MODULE_DEF \
0122 \
0123 \
0124 py::class_<JEventProcessorPY>(m, "JEventProcessor")\
0125 .def(py::init<py::object&>())\
0126 .def("Init", &JEventProcessorPY::Init)\
0127 .def("Process", &JEventProcessorPY::Process)\
0128 .def("Finish", &JEventProcessorPY::Finish)\
0129 .def("Prefetch", &JEventProcessorPY::Prefetch, py::arg("fac_name"), py::arg("tag")="")\
0130 .def("Get", &JEventProcessorPY::Get, py::arg("fac_name"), py::arg("tag")="");\
0131 \
0132 \
0133 m.def("Start", &janapy_Start, "Allow JANA system to start processing data. (Not needed for short scripts.)"); \
0134 m.def("Run", &janapy_Run, "Begin processing events (use when running python as an extension)"); \
0135 m.def("Quit", &janapy_Quit, "Tell JANA to quit gracefully", py::arg("skip_join")=false); \
0136 m.def("Stop", &janapy_Stop, "Tell JANA to (temporarily) stop event processing. If optional agrument is True then block until all threads are stopped."); \
0137 \
0138 m.def("IsInitialized", &janapy_IsInitialized, "Check if JApplication has already been initialized."); \
0139 m.def("IsQuitting", &janapy_IsQuitting, "Check if JApplication is in the process of quitting."); \
0140 m.def("IsDrainingQueues", &janapy_IsDrainingQueues, "Check if JApplication is in the process of draining the queues."); \
0141 \
0142 m.def("AddPlugin", &janapy_AddPlugin, "Add a plugin to the list of plugins to be attached (call before calling Run)"); \
0143 m.def("AddPluginPath", &janapy_AddPluginPath, "Add directory to plugin search path"); \
0144 m.def("AddEventSource", &janapy_AddEventSource, "Add an event source (e.g. filename). Can be given multiple arguments and/or called multiple times."); \
0145 m.def("SetTicker", &janapy_SetTicker, "Turn off/on the standard screen ticker", py::arg("ticker_on")=true); \
0146 m.def("GetNeventsProcessed", &janapy_GetNeventsProcessed, "Return the number of events processed so far."); \
0147 m.def("GetIntegratedRate", &janapy_GetIntegratedRate, "Return integrated rate."); \
0148 m.def("GetInstantaneousRate", &janapy_GetInstantaneousRate, "Return instantaneous rate."); \
0149 m.def("GetNThreads", &janapy_GetNThreads, "Return current number of JThread objects."); \
0150 m.def("SetNThreads", &janapy_SetNThreads, "Set number of JThread objects. (returns previous number)"); \
0151 m.def("GetNcores", &janapy_GetNcores, "Return number of cores reported by system (full + logical)."); \
0152 m.def("PrintStatus", &janapy_PrintStatus, "Print the status of the current job to the screen"); \
0153 m.def("PrintParameters", &janapy_PrintParameters, "Print config. parameters (give argument True to print all parameters)"); \
0154 m.def("GetParameterValue", &janapy_GetParameterValue, "Return value of given configuration parameter."); \
0155 m.def("SetParameterValue", &janapy_SetParameterValue, "Set configuration parameter."); \
0156 m.def("AddProcessor", &janapy_AddProcessor, "Add an event processor"); \
0157 \
0158 PY_MODULE = &m;\
0159
0160
0161
0162
0163
0164
0165
0166 #if 0
0167 try{\
0168 PY_MODULE_JSON = py::module_::import("json");\
0169 }catch(pybind11::type_error &e){\
0170 _DBG_<<" Error importing python json module!"<<std::endl;\
0171 }catch(...){\
0172 _DBG_<<" Error importing python json module!"<<std::endl;\
0173 }\
0174 \
0175
0176 #endif