Belle II Software  release-05-01-25
DQMHistAnalysisEpicsExample.cc
1 //+
2 // File : DQMHistAnalysisEpicsExample.cc
3 // Description :
4 //
5 // Author : Bjoern Spruck, Mainz Univerisity
6 // Date : 2017-2019
7 //-
8 
9 
10 #include <dqm/analysis/modules/DQMHistAnalysisEpicsExample.h>
11 #include <TROOT.h>
12 #include <TClass.h>
13 
14 using namespace std;
15 using namespace Belle2;
16 
17 //-----------------------------------------------------------------
18 // Register the Module
19 //-----------------------------------------------------------------
20 REG_MODULE(DQMHistAnalysisEpicsExample)
21 
22 //-----------------------------------------------------------------
23 // Implementation
24 //-----------------------------------------------------------------
25 
28 {
29  // This module CAN NOT be run in parallel!
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 
40 DQMHistAnalysisEpicsExampleModule::~DQMHistAnalysisEpicsExampleModule()
41 {
42 #ifdef _BELLE2_EPICS
43  if (ca_current_context()) ca_context_destroy();
44 #endif
45 }
46 
47 void DQMHistAnalysisEpicsExampleModule::initialize()
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 
110 void DQMHistAnalysisEpicsExampleModule::beginRun()
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.c_str());
118 
119  if (hh1 == NULL) {
120  B2DEBUG(20, "Histo " << m_histoname << " not in memfile");
121  // the following code sux ... is there no root function for that?
122  TDirectory* d = gROOT;
123  TString myl = m_histoname;
124  TString tok;
125  Ssiz_t from = 0;
126  while (myl.Tokenize(tok, from, "/")) {
127  TString dummy;
128  Ssiz_t f;
129  f = from;
130  if (myl.Tokenize(dummy, f, "/")) { // check if its the last one
131  auto e = d->GetDirectory(tok);
132  if (e) {
133  B2DEBUG(20, "Cd Dir " << tok);
134  d = e;
135  }
136  d->cd();
137  } else {
138  break;
139  }
140  }
141  TObject* obj = d->FindObject(tok);
142  if (obj != NULL) {
143  if (obj->IsA()->InheritsFrom("TH1")) {
144  B2DEBUG(20, "Histo " << m_histoname << " found in mem");
145  hh1 = (TH1*)obj;
146  }
147  } else {
148  B2DEBUG(20, "Histo " << m_histoname << " NOT found in mem");
149  }
150  }
151 
152  if (hh1 != NULL) {
153  m_c1->cd();
154  hh1->Draw();
155  m_line->Draw();
156  m_line_lo->Draw();
157  m_line_hi->Draw();
158  } else {
159  B2DEBUG(20, "Histo " << m_histoname << " not found");
160  }
161 }
162 
163 void DQMHistAnalysisEpicsExampleModule::event()
164 {
165  TH1* hh1;
166  bool flag = false;
167 
168  hh1 = findHist(m_histoname.c_str());
169  if (hh1 == NULL) {
170  B2DEBUG(20, "Histo " << m_histoname << " not in memfile");
171  // the following code sux ... is there no root function for that?
172  TDirectory* d = gROOT;
173  TString myl = m_histoname;
174  TString tok;
175  Ssiz_t from = 0;
176  while (myl.Tokenize(tok, from, "/")) {
177  TString dummy;
178  Ssiz_t f;
179  f = from;
180  if (myl.Tokenize(dummy, f, "/")) { // check if its the last one
181  auto e = d->GetDirectory(tok);
182  if (e) {
183  B2DEBUG(20, "Cd Dir " << tok);
184  d = e;
185  }
186  d->cd();
187  } else {
188  break;
189  }
190  }
191  TObject* obj = d->FindObject(tok);
192  if (obj != NULL) {
193  if (obj->IsA()->InheritsFrom("TH1")) {
194  B2DEBUG(20, "Histo " << m_histoname << " found in mem");
195  hh1 = (TH1*)obj;
196  flag = true;
197  }
198  } else {
199  B2DEBUG(20, "Histo " << m_histoname << " NOT found in mem");
200  }
201  }
202  if (hh1 != NULL) {
203  m_c1->cd();// necessary!
204  hh1->Fit(m_f1, "");
205  double y1 = hh1->GetMaximum();
206  double y2 = hh1->GetMinimum();
207  m_line->SetY1(y1 + (y1 - y2) * 0.05);
208  m_line_lo->SetY1(y1 + (y1 - y2) * 0.05);
209  m_line_hi->SetY1(y1 + (y1 - y2) * 0.05);
210 // m_line->SetY2(y2-(y1-y2)*0.05);
211 // m_line_lo->SetY2(y2-(y1-y2)*0.05);
212 // m_line_hi->SetY2(y2-(y1-y2)*0.05);
213  double x = m_f1->GetParameter(1);
214  m_line->SetX1(x);
215  m_line->SetX2(x);
216  if (!flag) {
217  // dont add another line...
218  m_line->Draw();
219  m_line_lo->Draw();
220  m_line_hi->Draw();
221  }
222  m_c1->Modified();
223  m_c1->Update();
224  } else {
225  B2DEBUG(20, "Histo " << m_histoname << " not found");
226  }
227 
228 #ifdef _BELLE2_EPICS
229  if (m_parameters > 0) {
230  for (auto i = 0; i < m_parameters; i++) {
231  double data;
232  data = m_f1->GetParameter(i);
233  if (mychid[i]) SEVCHK(ca_put(DBR_DOUBLE, mychid[i], (void*)&data), "ca_set failure");
234  }
235  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
236  }
237 #endif
238 }
239 
240 void DQMHistAnalysisEpicsExampleModule::endRun()
241 {
242  B2DEBUG(20, "DQMHistAnalysisEpicsExample : endRun called");
243 }
244 
245 
246 void DQMHistAnalysisEpicsExampleModule::terminate()
247 {
248 #ifdef _BELLE2_EPICS
249  if (m_parameters > 0) {
250  for (auto i = 0; i < m_parameters; i++) {
251  if (mychid[i]) SEVCHK(ca_clear_channel(mychid[i]), "ca_clear_channel failure");
252  }
253  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
254  }
255 #endif
256  B2DEBUG(20, "DQMHistAnalysisEpicsExample: terminate called");
257 }
258 
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::DQMHistAnalysisEpicsExampleModule
Class definition for the output module of Sequential ROOT I/O.
Definition: DQMHistAnalysisEpicsExample.h:29
Belle2::DQMHistAnalysisModule
The base class for the histogram analysis module.
Definition: DQMHistAnalysis.h:27