Belle II Software development
DQMHistAnalysisEpicsExample.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#include <dqm/analysis/modules/DQMHistAnalysisEpicsExample.h>
10#include <TROOT.h>
11#include <TClass.h>
12
13using namespace std;
14using namespace Belle2;
15
16//-----------------------------------------------------------------
17// Register the Module
18//-----------------------------------------------------------------
19REG_MODULE(DQMHistAnalysisEpicsExample);
20
21//-----------------------------------------------------------------
22// Implementation
23//-----------------------------------------------------------------
24
27{
28 // This module CAN NOT be run in parallel!
29 setDescription("Example module for EPICS");
30
31 //Parameter definition
32 addParam("HistoName", m_histoname, "Name of Histogram (incl dir)", std::string(""));
33 addParam("Function", m_function, "Fit function definition", std::string("gaus"));
34 addParam("Parameters", m_parameters, "Fit function parameters for EPICS", 3);
35 addParam("PVName", m_pvPrefix, "PV Prefix", std::string("DQM:TEST:hist:"));
36 B2DEBUG(20, "DQMHistAnalysisEpicsExample: Constructor done.");
37}
38
39
41{
42#ifdef _BELLE2_EPICS
43 if (ca_current_context()) ca_context_destroy();
44#endif
45}
46
48{
49 B2DEBUG(20, "DQMHistAnalysisEpicsExample: initialized.");
50
51 TString a;
52 a = m_histoname;
53 a.ReplaceAll("/", "_");
54 m_c1 = new TCanvas("c_" + a);
55 m_f1 = new TF1("f_" + a, TString(m_function), -30, 300);
56 m_f1->SetParameter(0, 1000);
57 m_f1->SetParameter(1, 0);
58 m_f1->SetParameter(2, 10);
59 m_f1->SetLineColor(4);
60 m_f1->SetNpx(512);
61 m_f1->SetNumberFitPoints(512);
62
63 m_line = new TLine(0, 10, 0, 0);
64 m_line->SetVertical(true);
65 m_line->SetLineColor(8);
66 m_line->SetLineWidth(3);
67
68 m_line_lo = new TLine(0, 10, 0, 0);
69 m_line_lo->SetVertical(true);
70 m_line_lo->SetLineColor(2);
71 m_line_lo->SetLineWidth(3);
72
73 m_line_hi = new TLine(0, 10, 0, 0);
74 m_line_hi->SetVertical(true);
75 m_line_hi->SetLineColor(2);
76 m_line_hi->SetLineWidth(3);
77
78 m_line_lo->SetX1(5);// get from epics
79 m_line_lo->SetX2(5);
80
81 m_line_hi->SetX1(50);// get from epics
82 m_line_hi->SetX2(50);
83
84 // need the function to get parameter names
85 if (m_parameters > 0) {
86 if (m_parameters > 10) m_parameters = 10; // hard limit
87#ifdef _BELLE2_EPICS
88 if (!ca_current_context()) SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
89#endif
90 for (auto i = 0; i < m_parameters; i++) {
91 std::string aa;
92 aa = m_f1->GetParName(i);
93 if (aa == "") aa = string("par") + string(TString::Itoa(i, 10).Data());
94 aa = m_pvPrefix + aa;
95#ifdef _BELLE2_EPICS
96 SEVCHK(ca_create_channel(aa.c_str(), NULL, NULL, 10, &mychid[i]), "ca_create_channel failure");
97 // Read LO and HI limits from EPICS, seems this needs additional channels?
98 // SEVCHK(ca_get(DBR_DOUBLE,mychid[i],(void*)&data),"ca_get failure"); // data is only valid after ca_pend_io!!
99#endif
100 }
101#ifdef _BELLE2_EPICS
102 SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
103#endif
104 } else {
105 m_parameters = 0;
106 }
107}
108
109
111{
112 //m_serv->SetTimer(100, kFALSE);
113 B2DEBUG(20, "DQMHistAnalysisEpicsExample: beginRun called.");
114 m_c1->Clear();
115
116 TH1* hh1;
117 hh1 = findHist(m_histoname);
118
119 if (hh1 == NULL) {
120 B2DEBUG(20, "Histo " << m_histoname << " not in memfile");
121 TDirectory* d = gROOT;
122 TString myl = m_histoname;
123 TString tok;
124 Ssiz_t from = 0;
125 while (myl.Tokenize(tok, from, "/")) {
126 TString dummy;
127 Ssiz_t f;
128 f = from;
129 if (myl.Tokenize(dummy, f, "/")) { // check if its the last one
130 auto e = d->GetDirectory(tok);
131 if (e) {
132 B2DEBUG(20, "Cd Dir " << tok);
133 d = e;
134 }
135 d->cd();
136 } else {
137 break;
138 }
139 }
140 TObject* obj = d->FindObject(tok);
141 if (obj != NULL) {
142 if (obj->IsA()->InheritsFrom("TH1")) {
143 B2DEBUG(20, "Histo " << m_histoname << " found in mem");
144 hh1 = (TH1*)obj;
145 }
146 } else {
147 B2DEBUG(20, "Histo " << m_histoname << " NOT found in mem");
148 }
149 }
150
151 if (hh1 != NULL) {
152 m_c1->cd();
153 hh1->Draw();
154 m_line->Draw();
155 m_line_lo->Draw();
156 m_line_hi->Draw();
157 } else {
158 B2DEBUG(20, "Histo " << m_histoname << " not found");
159 }
160}
161
163{
164 TH1* hh1;
165 bool flag = false;
166
167 hh1 = findHist(m_histoname);
168 if (hh1 == NULL) {
169 B2DEBUG(20, "Histo " << m_histoname << " not in memfile");
170 TDirectory* d = gROOT;
171 TString myl = m_histoname;
172 TString tok;
173 Ssiz_t from = 0;
174 while (myl.Tokenize(tok, from, "/")) {
175 TString dummy;
176 Ssiz_t f;
177 f = from;
178 if (myl.Tokenize(dummy, f, "/")) { // check if its the last one
179 auto e = d->GetDirectory(tok);
180 if (e) {
181 B2DEBUG(20, "Cd Dir " << tok);
182 d = e;
183 }
184 d->cd();
185 } else {
186 break;
187 }
188 }
189 TObject* obj = d->FindObject(tok);
190 if (obj != NULL) {
191 if (obj->IsA()->InheritsFrom("TH1")) {
192 B2DEBUG(20, "Histo " << m_histoname << " found in mem");
193 hh1 = (TH1*)obj;
194 flag = true;
195 }
196 } else {
197 B2DEBUG(20, "Histo " << m_histoname << " NOT found in mem");
198 }
199 }
200 if (hh1 != NULL) {
201 m_c1->cd();// necessary!
202 hh1->Fit(m_f1, "");
203 double y1 = hh1->GetMaximum();
204 double y2 = hh1->GetMinimum();
205 m_line->SetY1(y1 + (y1 - y2) * 0.05);
206 m_line_lo->SetY1(y1 + (y1 - y2) * 0.05);
207 m_line_hi->SetY1(y1 + (y1 - y2) * 0.05);
208// m_line->SetY2(y2-(y1-y2)*0.05);
209// m_line_lo->SetY2(y2-(y1-y2)*0.05);
210// m_line_hi->SetY2(y2-(y1-y2)*0.05);
211 double x = m_f1->GetParameter(1);
212 m_line->SetX1(x);
213 m_line->SetX2(x);
214 if (!flag) {
215 // dont add another line...
216 m_line->Draw();
217 m_line_lo->Draw();
218 m_line_hi->Draw();
219 }
220 m_c1->Modified();
221 m_c1->Update();
222 } else {
223 B2DEBUG(20, "Histo " << m_histoname << " not found");
224 }
225
226#ifdef _BELLE2_EPICS
227 if (m_parameters > 0) {
228 for (auto i = 0; i < m_parameters; i++) {
229 double data;
230 data = m_f1->GetParameter(i);
231 if (mychid[i]) SEVCHK(ca_put(DBR_DOUBLE, mychid[i], (void*)&data), "ca_set failure");
232 }
233 SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
234 }
235#endif
236}
237
239{
240 B2DEBUG(20, "DQMHistAnalysisEpicsExample : endRun called");
241}
242
243
245{
246#ifdef _BELLE2_EPICS
247 if (m_parameters > 0) {
248 for (auto i = 0; i < m_parameters; i++) {
249 if (mychid[i]) SEVCHK(ca_clear_channel(mychid[i]), "ca_clear_channel failure");
250 }
251 SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
252 }
253#endif
254 B2DEBUG(20, "DQMHistAnalysisEpicsExample: terminate called");
255}
256
TLine * m_line_hi
The line for the higher bound.
void terminate() override final
This method is called at the end of the event processing.
Int_t m_parameters
The fit function parameters for EPICS.
void event() override final
This method is called for each event.
TLine * m_line_lo
The line for the lower bound.
void endRun() override final
This method is called if the current run ends.
std::string m_histoname
The name of the histogram.
void beginRun() override final
Called when entering a new run.
TLine * m_line
The line for the fitting result.
std::string m_function
The definition of the fit function.
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 setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.
STL namespace.