14#include <framework/core/ModuleParam.templateDetails.h>
15#include <dqm/analysis/modules/DQMHistAnalysisInputPVSrv.h>
17#include <TDirectory.h>
34static void printChidInfo(chid ichid,
const char* message)
37 B2DEBUG(20,
"pv: " << ca_name(ichid) <<
" type(" << ca_field_type(ichid) <<
") nelements(" << ca_element_count(
38 ichid) <<
") host(" << ca_host_name(ichid)
39 <<
") read(" << ca_read_access(ichid) <<
") write(" << ca_write_access(ichid) <<
") state(" << ca_state(ichid) <<
")");
42static void exceptionCallback(
struct exception_handler_args args)
44 chid ichid = args.chid;
45 long stat = args.stat;
47 const char* noname =
"unknown";
49 channel = (ichid ? ca_name(ichid) : noname);
52 if (ichid) printChidInfo(ichid,
"exceptionCallback");
53 printf(
"exceptionCallback stat %s channel %s\n", ca_message(stat), channel);
56static void connectionCallback(
struct connection_handler_args args)
58 chid ichid = args.chid;
60 printChidInfo(ichid,
"connectionCallback");
63static void accessRightsCallback(
struct access_rights_handler_args args)
65 chid ichid = args.chid;
67 printChidInfo(ichid,
"accessRightsCallback");
69static void eventCallback(
struct event_handler_args eha)
71 chid ichid = eha.chid;
72 MYNODE* n = (MYNODE*)eha.usr;
74 if (eha.status != ECA_NORMAL) {
75 printChidInfo(ichid,
"eventCallback");
91 addParam(
"HistoList",
m_histlist,
"pvname, histname, histtitle, (bins,min,max[,bins,min,max])");
94 B2DEBUG(20,
"DQMHistAnalysisInputPVSrv: Constructor done.");
101 if (ca_current_context()) ca_context_destroy();
111 if (!ca_current_context()) SEVCHK(ca_context_create(ca_disable_preemptive_callback),
"ca_context_create");
112 SEVCHK(ca_add_exception_event(exceptionCallback, NULL),
"ca_add_exception_event");
114 if (it.size() != 4 && it.size() != 5) {
115 B2WARNING(
"Histolist with wrong nr of parameters " << it.size());
118 auto n = (MYNODE*) callocMustSucceed(1,
sizeof(MYNODE),
"caMonitor");
119 pmynode.push_back(n);
122 TDirectory* oldDir = gDirectory;
123 TDirectory* d = oldDir;
124 TString myl = it.at(1).c_str();
127 while (myl.Tokenize(tok, from,
"/")) {
131 if (myl.Tokenize(dummy, f,
"/")) {
132 d = d->mkdir(tok,
"",
true);
139 B2DEBUG(20,
"Create Histo " << tok);
143 strncpy(n->name, it.at(0).c_str(), MAX_PV_NAME_LEN - 1);
144 istringstream is(it.at(3));
148 if (it.size() == 4) {
149 n->histo = (TH1*)
new TH1F(tok, it.at(2).c_str(), x, xmin, xmax);
156 istringstream iss(it.at(4));
160 n->histo = (TH1*)
new TH2F(tok, it.at(2).c_str(), x, xmin, xmax, y, ymin, ymax);
172 for (
auto n : pmynode) {
173 SEVCHK(ca_create_channel(n->name, connectionCallback, n, 20, &n->mychid),
"ca_create_channel");
174 SEVCHK(ca_replace_access_rights_event(n->mychid, accessRightsCallback),
"ca_replace_access_rights_event");
176 SEVCHK(ca_create_subscription(DBR_STRING, 1, n->mychid, DBE_VALUE, eventCallback, n, &n->myevid),
"ca_create_subscription");
181 B2DEBUG(20,
"DQMHistAnalysisInputPVSrv: initialized.");
187 B2DEBUG(20,
"DQMHistAnalysisInputPVSrv: beginRun called.");
201 SEVCHK(ca_pend_event(0.0001),
"ca_pend_event");
203 for (
auto n : pmynode) {
206 if (ca_field_type(n->mychid) != DBF_LONG && ca_field_type(n->mychid) != DBF_FLOAT)
continue;
209#pragma GCC diagnostic push
210#pragma GCC diagnostic ignored "-Wtype-limits"
211 auto bufferorg =
new char[dbr_size_n(ca_field_type(n->mychid), ca_element_count(n->mychid))];
212#pragma GCC diagnostic pop
214 void* buffer = (
void*) bufferorg;
217 status = ca_array_get(ca_field_type(n->mychid), ca_element_count(n->mychid), n->mychid, buffer);
218 SEVCHK(status,
"ca_array_get()");
219 status = ca_pend_io(15.0);
220 if (status != ECA_NORMAL) {
221 B2WARNING(
"EPICS ca_array_get " << ca_name(n->mychid) <<
" didn't return a value.");
226 bins = ca_element_count(n->mychid) < n->binmax ? ca_element_count(n->mychid) : n->binmax;
227 TH1* histo = n->histo;
228 for (
unsigned int j = ca_element_count(n->mychid); j < n->binmax; j++) histo->SetBinContent(j + 1, 0);
229 switch (ca_field_type(n->mychid)) {
231 dbr_char_t* b = (dbr_char_t*)buffer;
232 for (
unsigned int j = 0; j < bins; j++) {
233 histo->SetBinContent(j + 1, b[j]);
238 dbr_short_t* b = (dbr_short_t*)buffer;
239 for (
unsigned int j = 0; j < bins; j++) {
240 histo->SetBinContent(j + 1, b[j]);
244 dbr_long_t* b = (dbr_long_t*)buffer;
245 for (
unsigned int j = 0; j < bins; j++) {
246 histo->SetBinContent(j + 1, b[j]);
250 dbr_float_t* b = (dbr_float_t*)buffer;
251 for (
unsigned int j = 0; j < bins; j++) {
252 histo->SetBinContent(j + 1, b[j]);
256 dbr_double_t* b = (dbr_double_t*)buffer;
257 for (
unsigned int j = 0; j < bins; j++) {
258 histo->SetBinContent(j + 1, b[j]);
273 }
while (!t.CheckTimer(gSystem->Now()));
279 B2DEBUG(20,
"DQMHistAnalysisInputPVSrv: endRun called");
285 B2DEBUG(20,
"DQMHistAnalysisInputPVSrv: terminate called");
The base class for the histogram analysis module.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.