Belle II Software development
DQMHistOutputToEPICS.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8//+
9// File : DQMHistOutputToEPICS.cc
10// Description : Write Histogram Content to EPICS Arrays
11//-
12
13
14#include <dqm/analysis/modules/DQMHistOutputToEPICS.h>
15#include <framework/core/ModuleParam.templateDetails.h>
16
17using namespace std;
18using namespace Belle2;
19
20//-----------------------------------------------------------------
21// Register the Module
22//-----------------------------------------------------------------
23REG_MODULE(DQMHistOutputToEPICS);
24
25//-----------------------------------------------------------------
26// Implementation
27//-----------------------------------------------------------------
28
31{
32 // This module CAN NOT be run in parallel!
33
34 //Parameter definition
35 addParam("HistoList", m_histlist, "histname, pvname");
36 B2DEBUG(99, "DQMHistOutputToEPICS: Constructor done.");
37}
38
40{
41}
42
44{
45 for (auto& it : m_histlist) {
46 if (it.size() < 2) {
47 B2WARNING("Histolist with wrong nr of parameters " << it.size());
48 continue;
49 }
50#ifdef _BELLE2_EPICS
51 auto n = new MYNODE;
52 n->histoname = it.at(0);
53 SEVCHK(ca_create_channel(it.at(1).c_str(), NULL, NULL, 10, &n->mychid), "ca_create_channel failure");
54 if (it.size() >= 3) {
55 SEVCHK(ca_create_channel(it.at(2).c_str(), NULL, NULL, 10, &n->mychid_last), "ca_create_channel failure");
56 } else {
57 n->mychid_last = 0;
58 }
59 pmynode.push_back(n);
60#endif
61 }
62
63 B2DEBUG(99, "DQMHistOutputToEPICS: initialized.");
64}
65
67{
68#ifdef _BELLE2_EPICS
69 for (auto* it : pmynode) {
70 if (!it->mychid) continue;
71 int length = int(ca_element_count(it->mychid));
72 if (length > 0) {
73 it->data.resize(length, 0.0);
74 SEVCHK(ca_array_put(DBR_DOUBLE, length, it->mychid, (void*)(it->data.data())), "ca_put failure");
75 if (it->mychid_last) {
76 if (length == int(ca_element_count(it->mychid_last))) {
77 SEVCHK(ca_array_put(DBR_DOUBLE, length, it->mychid_last, (void*)(it->data.data())), "ca_put failure");
78 }
79 }
80 }
81 }
82#endif
83}
84
86{
87 B2DEBUG(99, "DQMHistOutputToEPICS: beginRun called.");
88 cleanPVs();
89 m_dirty = true;
90}
91
93{
94#ifdef _BELLE2_EPICS
95 for (auto& it : pmynode) {
96 if (!it->mychid) continue;
97 int length = it->data.size();
98 TH1* hh1 = findHist(it->histoname);
99 if (hh1 && hh1->GetNcells() > 2 && length > 0 && length == int(ca_element_count(it->mychid))) {
100 // If bin count doesn't match, we loose bins but otherwise ca_array_put will complain
101 // We fill up the array with ZEROs otherwise
102 if (hh1->GetDimension() == 1) {
103 int i = 0;
104 int nx = hh1->GetNbinsX() + 1;
105 for (int x = 1; x < nx && i < length ; x++) {
106 it->data[i++] = hh1->GetBinContent(x);
107 }
108
109 } else if (hh1->GetDimension() == 2) {
110 int i = 0;
111 int nx = hh1->GetNbinsX() + 1;
112 int ny = hh1->GetNbinsY() + 1;
113 for (int y = 1; y < ny && i < length; y++) {
114 for (int x = 1; x < nx && i < length ; x++) {
115 it->data[i++] = hh1->GetBinContent(x, y);
116 }
117 }
118 }
119
120 SEVCHK(ca_array_put(DBR_DOUBLE, length, it->mychid, (void*)it->data.data()), "ca_set failure");
121 }
122 }
123#endif
124}
125
127{
128 if (!m_dirty) return;
129#ifdef _BELLE2_EPICS
130 for (auto* it : pmynode) {
131 if (it->mychid && it->mychid_last) {
132 // copy PVs to last-run-PV if existing
133 int length = it->data.size();
134 if (length > 0 && length == int(ca_element_count(it->mychid_last))) {
135 SEVCHK(ca_array_put(DBR_DOUBLE, length, it->mychid_last, (void*)it->data.data()), "ca_put failure");
136 }
137 }
138 }
139 SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
140#endif
141
142 m_dirty = false;
143}
144
146{
147 B2DEBUG(99, "DQMHistOutputToEPICS: endRun called");
148 copyToLast();
149}
150
152{
153 B2DEBUG(99, "DQMHistOutputToEPICS: terminate called");
154 copyToLast();
155 // the following belongs to terminate
156#ifdef _BELLE2_EPICS
157 for (auto* it : pmynode) {
158 if (it->mychid) SEVCHK(ca_clear_channel(it->mychid), "ca_clear_channel failure");
159 if (it->mychid_last) SEVCHK(ca_clear_channel(it->mychid_last), "ca_clear_channel failure");
160 }
161#endif
162}
163
The base class for the histogram analysis module.
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
void terminate(void) override final
This method is called at the end of the event processing.
void initialize(void) override final
Initializer.
void endRun(void) override final
This method is called for each event.
void cleanPVs(void)
set PVs to zero content (at run start)
std::vector< std::vector< std::string > > m_histlist
Parameter list for histograms.
void copyToLast(void)
copy over to "last" PV
bool m_dirty
Flag to mark that a new runs as started and data not copied to last PV.
void beginRun(void) override final
Called when entering a new run.
void event(void) override final
This method is called if the current run ends.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:649
Abstract base class for different kinds of events.
STL namespace.