14 #include <framework/core/ModuleParam.templateDetails.h>
15 #include <dqm/analysis/modules/DQMHistAnalysisInputPVSrv.h>
17 #include <TDirectory.h>
34 static 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) <<
")");
42 static 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);
56 static void connectionCallback(
struct connection_handler_args args)
58 chid ichid = args.chid;
60 printChidInfo(ichid,
"connectionCallback");
63 static void accessRightsCallback(
struct access_rights_handler_args args)
65 chid ichid = args.chid;
67 printChidInfo(ichid,
"accessRightsCallback");
69 static 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");
86 DQMHistAnalysisInputPVSrvModule::DQMHistAnalysisInputPVSrvModule()
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,
"/")) {
133 e = d->GetDirectory(tok);
135 B2DEBUG(20,
"Cd Dir " << tok);
138 B2DEBUG(20,
"Create Dir " << tok);
147 B2DEBUG(20,
"Create Histo " << tok);
151 strncpy(n->name, it.at(0).c_str(), MAX_PV_NAME_LEN - 1);
152 istringstream is(it.at(3));
156 if (it.size() == 4) {
157 n->histo = (TH1*)
new TH1F(tok, it.at(2).c_str(), x, xmin, xmax);
164 istringstream iss(it.at(4));
168 n->histo = (TH1*)
new TH2F(tok, it.at(2).c_str(), x, xmin, xmax, y, ymin, ymax);
180 for (
auto n : pmynode) {
181 SEVCHK(ca_create_channel(n->name, connectionCallback, n, 20, &n->mychid),
"ca_create_channel");
182 SEVCHK(ca_replace_access_rights_event(n->mychid, accessRightsCallback),
"ca_replace_access_rights_event");
184 SEVCHK(ca_create_subscription(DBR_STRING, 1, n->mychid, DBE_VALUE, eventCallback, n, &n->myevid),
"ca_create_subscription");
189 B2DEBUG(20,
"DQMHistAnalysisInputPVSrv: initialized.");
195 B2DEBUG(20,
"DQMHistAnalysisInputPVSrv: beginRun called.");
209 SEVCHK(ca_pend_event(0.0001),
"ca_pend_event");
211 for (
auto n : pmynode) {
214 if (ca_field_type(n->mychid) != DBF_LONG && ca_field_type(n->mychid) != DBF_FLOAT)
continue;
217 #pragma GCC diagnostic push
218 #pragma GCC diagnostic ignored "-Wtype-limits"
219 auto bufferorg =
new char[dbr_size_n(ca_field_type(n->mychid), ca_element_count(n->mychid))];
220 #pragma GCC diagnostic pop
222 void* buffer = (
void*) bufferorg;
225 status = ca_array_get(ca_field_type(n->mychid), ca_element_count(n->mychid), n->mychid, buffer);
226 SEVCHK(status,
"ca_array_get()");
227 status = ca_pend_io(15.0);
228 if (status != ECA_NORMAL) {
229 B2WARNING(
"EPICS ca_array_get " << ca_name(n->mychid) <<
" didn't return a value.");
234 bins = ca_element_count(n->mychid) < n->binmax ? ca_element_count(n->mychid) : n->binmax;
235 TH1* histo = n->histo;
236 for (
unsigned int j = ca_element_count(n->mychid); j < n->binmax; j++) histo->SetBinContent(j + 1, 0);
237 switch (ca_field_type(n->mychid)) {
239 dbr_char_t* b = (dbr_char_t*)buffer;
240 for (
unsigned int j = 0; j < bins; j++) {
241 histo->SetBinContent(j + 1, b[j]);
246 dbr_short_t* b = (dbr_short_t*)buffer;
247 for (
unsigned int j = 0; j < bins; j++) {
248 histo->SetBinContent(j + 1, b[j]);
252 dbr_long_t* b = (dbr_long_t*)buffer;
253 for (
unsigned int j = 0; j < bins; j++) {
254 histo->SetBinContent(j + 1, b[j]);
258 dbr_float_t* b = (dbr_float_t*)buffer;
259 for (
unsigned int j = 0; j < bins; j++) {
260 histo->SetBinContent(j + 1, b[j]);
264 dbr_double_t* b = (dbr_double_t*)buffer;
265 for (
unsigned int j = 0; j < bins; j++) {
266 histo->SetBinContent(j + 1, b[j]);
281 }
while (!t.CheckTimer(gSystem->Now()));
287 B2DEBUG(20,
"DQMHistAnalysisInputPVSrv: endRun called");
293 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.