Belle II Software  release-08-01-10
DQMHistAnalysisDeltaTest.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 : DQMHistAnalysisDeltaTest.cc
10 // Description : Test Module for Delta Histogram Access
11 //-
12 
13 
14 #include <dqm/analysis/modules/DQMHistAnalysisDeltaTest.h>
15 #include <TROOT.h>
16 
17 using namespace std;
18 using namespace Belle2;
19 
20 //-----------------------------------------------------------------
21 // Register the Module
22 //-----------------------------------------------------------------
23 REG_MODULE(DQMHistAnalysisDeltaTest);
24 
25 //-----------------------------------------------------------------
26 // Implementation
27 //-----------------------------------------------------------------
28 
29 DQMHistAnalysisDeltaTestModule::DQMHistAnalysisDeltaTestModule()
31 {
32  // This module CAN NOT be run in parallel!
33  setDescription("Testing module for using delta histogramming functionality.");
34 
35  //Parameter definition
36  addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of Histogram dir", std::string("test"));
37  addParam("histogramName", m_histogramName, "Name of Histogram", std::string("testHist"));
38  addParam("PVPrefix", m_pvPrefix, "PV Prefix", std::string("DQM:TEST"));
39  B2DEBUG(1, "DQMHistAnalysisDeltaTest: Constructor done.");
40 
41 }
42 
44 {
45 #ifdef _BELLE2_EPICS
46  if (getUseEpics()) {
47  if (ca_current_context()) ca_context_destroy();
48  }
49 #endif
50 }
51 
53 {
54  B2DEBUG(1, "DQMHistAnalysisDeltaTest: initialized.");
55 
56  m_monObj = getMonitoringObject("test");
57 
58  gROOT->cd(); // this seems to be important, or strange things happen
59 
60  m_cTest = new TCanvas((m_histogramDirectoryName + "/c_Test").data());
61 
63 
64 #ifdef _BELLE2_EPICS
65  mychid.resize(2);
66  if (getUseEpics()) {
67  if (!ca_current_context()) SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
68  SEVCHK(ca_create_channel((m_pvPrefix + "TEST1").data(), NULL, NULL, 10, &mychid[0]), "ca_create_channel failure");
69  SEVCHK(ca_create_channel((m_pvPrefix + "TEST2").data(), NULL, NULL, 10, &mychid[1]), "ca_create_channel failure");
70 
71  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
72  }
73 #endif
74 }
75 
77 {
78  B2DEBUG(1, "DQMHistAnalysisDeltaTest: beginRun called.");
79 }
80 
82 {
83  B2DEBUG(1, "DQMHistAnalysisDeltaTest: endRun called.");
84 }
85 
87 {
88  double data_Test1 = 0.0;
89  double data_Test2 = 0.0;
90 
91  m_cTest->Clear();
92  m_cTest->Divide(3, 2);
93 
94  // more handy to have it as a full name, but find/get functions
95  // can work with one or two parameters
96  std::string fullname = m_histogramDirectoryName + "/" + m_histogramName;
97 
98  // get basic histogram (run integrated up)
99  auto hh1 = findHist(m_histogramDirectoryName, m_histogramName, false);// even if no update
100  if (hh1) {
101  m_cTest->cd(1);
102  auto a = (TH1*)hh1->DrawClone("hist");
103  a->SetTitle("Hist always");
104  data_Test2 = hh1->GetMean();
105  }
106 
107  auto hh2 = findHist(m_histogramDirectoryName, m_histogramName, true);// only if updated
108  if (hh2) {
109  m_cTest->cd(2);
110  auto a = (TH1*)hh2->DrawClone("hist");
111  a->SetTitle("Hist only if updated");
112  }
113 
114  // get most recent delta
115  auto hd2 = getDelta(m_histogramDirectoryName, m_histogramName, 0, false);// even if no update
116  if (hd2) {
117  m_cTest->cd(4);
118  auto a = (TH1*)hd2->DrawClone("hist");
119  a->SetTitle("Delta always");
120  }
121 
122  // get most recent delta
123  auto hd1 = getDelta(m_histogramDirectoryName, m_histogramName, 0, true);// only if updated
124  if (hd1) {
125  m_cTest->cd(5);
126  auto a = (TH1*)hd1->DrawClone("hist");
127  a->SetTitle("Delta only if updated");
128  data_Test1 = hd1->GetMean();
129  }
130 
131  UpdateCanvas(m_cTest->GetName(), hd1 != nullptr);
132 
133  if (!hd2) {
134  // Depending on you analysis, you want to see/plot
135  // the histogram even before the first condition for update is met
136  // thus, no delta histogram is available
137  if (hh1) {
138  m_cTest->cd(3);
139  auto a = (TH1*)hh1->DrawClone("hist");
140  a->SetLineColor(2);
141  a->SetTitle("initial sampling");
142  }
143  // but, as the statistics is low, we dont want to have it updated yet (e.g. in EPICS)
144  // data_Test1=hd1->GetMean(); //< thus, do not uncomment
145  }
146 
147  // plot all delta histograms, thus make recent shifts more visible
148  // it would be nicer to plot oldest first, left as exercise for reader
149  m_cTest->cd(6);
150  for (int i = 0; i < 99; i++) {
151  auto h = getDelta(fullname, i, false);
152  if (h == nullptr) break;
153  if (i == 0) {
154  h->Draw("hist");
155  } else {
156  h->SetLineColor(kBlue + 4 - i * 3); // a bit of shading
157  h->Draw("same");
158  }
159  }
160 
161  // I see no reason to access that histogram, but just as low-level example.
162  m_cTest->cd(7);
163  auto it = getDeltaList().find(m_histogramName);
164  if (it != getDeltaList().end()) {
165  auto h = it->second->m_lastHist;
166  if (h) {
167  auto a = (TH1*)h->DrawClone("hist");
168  a->SetTitle("last update histogram");
169  }
170  }
171 
172  m_cTest->cd(0);
173  m_cTest->Update();
174 
175  TString fn;
176  static int plot_count = 0;
177  fn.Form("ana_%s_Delta_%d.png", m_histogramName.data(), plot_count++);
178  m_cTest->Print(fn);
179 
180  // actually, we would prefer to only update the epics variable
181  // if the main histogram or delta~ has changed. but there is until now no easy
182  // way to check that
183  if (true) {
184  // currently, monObj are only used at end of run, thus this is not necessary
185  // but, in the future we may want to use finer granularity.
186  m_monObj->setVariable("data_Test1", data_Test1);
187  m_monObj->setVariable("data_Test2", data_Test2);
188 
189 #ifdef _BELLE2_EPICS
190  if (getUseEpics()) {
191  SEVCHK(ca_put(DBR_DOUBLE, mychid[0], (void*)&data_Test1), "ca_set failure");
192  SEVCHK(ca_put(DBR_DOUBLE, mychid[1], (void*)&data_Test2), "ca_set failure");
193  // write out
194  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
195  }
196 #endif
197  }
198 }
199 
201 {
202  B2DEBUG(1, "DQMHistAnalysisDeltaTest: terminate called");
203  // MiraBelle export code should run at end of Run
204  // but it still "remembers" the state from last event call.
205 }
206 
void terminate(void) override final
This method is called at the end of the event processing.
void initialize(void) override final
Initializer.
std::string m_histogramName
name of histogram
void endRun(void) override final
Called when run ends.
std::string m_pvPrefix
prefix for EPICS PVs
MonitoringObject * m_monObj
Monitoring Object.
std::string m_histogramDirectoryName
name of histogram directory
void beginRun(void) override final
Called when entering a new run.
void event(void) override final
This method is called for each event.
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).
static const DeltaList & getDeltaList()
Get the list of the delta histograms.
TH1 * getDelta(const std::string &fullname, int n=0, bool onlyIfUpdated=true)
Get Delta histogram.
bool getUseEpics(void)
Getter for EPICS usage.
void UpdateCanvas(std::string name, bool updated=true)
Mark canvas as updated (or not)
static MonitoringObject * getMonitoringObject(const std::string &histname)
Get MonitoringObject with given name (new object is created if non-existing)
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setVariable(const std::string &var, float val, float upErr=-1., float dwErr=-1)
set value to float variable (new variable is made if not yet existing)
void addCanvas(TCanvas *canv)
Add Canvas to monitoring object.
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.