Belle II Software  release-08-01-10
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 
13 using namespace std;
14 using namespace Belle2;
15 
16 //-----------------------------------------------------------------
17 // Register the Module
18 //-----------------------------------------------------------------
19 REG_MODULE(DQMHistAnalysisEpicsExample);
20 
21 //-----------------------------------------------------------------
22 // Implementation
23 //-----------------------------------------------------------------
24 
25 DQMHistAnalysisEpicsExampleModule::DQMHistAnalysisEpicsExampleModule()
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.