Belle II Software  release-05-01-25
DQMHistAnalysisPXDCharge.cc
1 //+
2 // File : DQMHistAnalysisPXDCharge.cc
3 // Description : Analysis of PXD Cluster Charge
4 //
5 // Author : Bjoern Spruck, University Mainz
6 // Date : 2018
7 //-
8 
9 
10 #include <dqm/analysis/modules/DQMHistAnalysisPXDCharge.h>
11 #include <TROOT.h>
12 #include <TLatex.h>
13 #include <vxd/geometry/GeoCache.h>
14 
15 using namespace std;
16 using namespace Belle2;
17 
18 //-----------------------------------------------------------------
19 // Register the Module
20 //-----------------------------------------------------------------
21 REG_MODULE(DQMHistAnalysisPXDCharge)
22 
23 //-----------------------------------------------------------------
24 // Implementation
25 //-----------------------------------------------------------------
26 
29 {
30  // This module CAN NOT be run in parallel!
31 
32  //Parameter definition
33  addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of Histogram dir", std::string("PXDER"));
34  addParam("RangeLow", m_rangeLow, "Lower boarder for fit", 30.);
35  addParam("RangeHigh", m_rangeHigh, "High border for fit", 85.);
36  addParam("PVPrefix", m_pvPrefix, "PV Prefix", std::string("DQM:PXD:Charge:"));
37  addParam("useEpics", m_useEpics, "useEpics", true);
38  B2DEBUG(99, "DQMHistAnalysisPXDCharge: Constructor done.");
39 }
40 
41 DQMHistAnalysisPXDChargeModule::~DQMHistAnalysisPXDChargeModule()
42 {
43 #ifdef _BELLE2_EPICS
44  if (m_useEpics) {
45  if (ca_current_context()) ca_context_destroy();
46  }
47 #endif
48 }
49 
50 void DQMHistAnalysisPXDChargeModule::initialize()
51 {
52  B2DEBUG(99, "DQMHistAnalysisPXDCharge: initialized.");
53 
54  m_monObj = getMonitoringObject("pxd");
55  const VXD::GeoCache& geo = VXD::GeoCache::getInstance();
56 
57  //collect the list of all PXD Modules in the geometry here
58  std::vector<VxdID> sensors = geo.getListOfSensors();
59  for (VxdID& aVxdID : sensors) {
60  VXD::SensorInfoBase info = geo.getSensorInfo(aVxdID);
61  if (info.getType() != VXD::SensorInfoBase::PXD) continue;
62  m_PXDModules.push_back(aVxdID); // reorder, sort would be better
63  }
64  std::sort(m_PXDModules.begin(), m_PXDModules.end()); // back to natural order
65 
66  gROOT->cd(); // this seems to be important, or strange things happen
67 
68  m_cCharge = new TCanvas((m_histogramDirectoryName + "/c_Charge").data());
69  m_hCharge = new TH1F("Cluster Charge", "Cluster Charge; Module; Track Cluster Charge", m_PXDModules.size(), 0, m_PXDModules.size());
70  m_hCharge->SetDirectory(0);// dont mess with it, this is MY histogram
71  m_hCharge->SetStats(false);
72  for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
73  TString ModuleName = (std::string)m_PXDModules[i];
74  m_hCharge->GetXaxis()->SetBinLabel(i + 1, ModuleName);
75  }
76  //Unfortunately this only changes the labels, but can't fill the bins by the VxdIDs
77  m_hCharge->Draw("");
78 
79  m_monObj->addCanvas(m_cCharge);
80 
82 // m_line1 = new TLine(0, 10, m_PXDModules.size(), 10);
83 // m_line2 = new TLine(0, 16, m_PXDModules.size(), 16);
84 // m_line3 = new TLine(0, 3, m_PXDModules.size(), 3);
85 // m_line1->SetHorizontal(true);
86 // m_line1->SetLineColor(3);// Green
87 // m_line1->SetLineWidth(3);
88 // m_line2->SetHorizontal(true);
89 // m_line2->SetLineColor(1);// Black
90 // m_line2->SetLineWidth(3);
91 // m_line3->SetHorizontal(true);
92 // m_line3->SetLineColor(1);
93 // m_line3->SetLineWidth(3);
94 
96 
97  m_fLandau = new TF1("f_Landau", "landau", m_rangeLow, m_rangeHigh);
98  m_fLandau->SetParameter(0, 1000);
99  m_fLandau->SetParameter(1, 50);
100  m_fLandau->SetParameter(2, 10);
101  m_fLandau->SetLineColor(4);
102  m_fLandau->SetNpx(60);
103  m_fLandau->SetNumberFitPoints(60);
104 
105  m_fMean = new TF1("f_Mean", "pol0", 0.5, m_PXDModules.size() - 0.5);
106  m_fMean->SetParameter(0, 50);
107  m_fMean->SetLineColor(5);
108  m_fMean->SetNpx(m_PXDModules.size());
109  m_fMean->SetNumberFitPoints(m_PXDModules.size());
110 
111 #ifdef _BELLE2_EPICS
112  if (m_useEpics) {
113  if (!ca_current_context()) SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
114  mychid.resize(3);
115  SEVCHK(ca_create_channel((m_pvPrefix + "Mean").data(), NULL, NULL, 10, &mychid[0]), "ca_create_channel failure");
116  SEVCHK(ca_create_channel((m_pvPrefix + "Diff").data(), NULL, NULL, 10, &mychid[1]), "ca_create_channel failure");
117  SEVCHK(ca_create_channel((m_pvPrefix + "Status").data(), NULL, NULL, 10, &mychid[2]), "ca_create_channel failure");
118  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
119  }
120 #endif
121 }
122 
123 
124 void DQMHistAnalysisPXDChargeModule::beginRun()
125 {
126  B2DEBUG(99, "DQMHistAnalysisPXDCharge: beginRun called.");
127 
128  m_cCharge->Clear();
129 }
130 
131 void DQMHistAnalysisPXDChargeModule::event()
132 {
133  if (!m_cCharge) return;
134  m_hCharge->Reset(); // dont sum up!!!
135 
136  bool enough = false;
137 
138  for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
139  std::string name = "DQMER_PXD_" + (std::string)m_PXDModules[i] + "_ClusterCharge";
140  std::replace(name.begin(), name.end(), '.', '_');
141 
142  TH1* hh1 = findHist(name);
143  if (hh1 == NULL) {
144  hh1 = findHist(m_histogramDirectoryName, name);
145  }
146  if (hh1) {
147 // B2INFO("Histo " << name << " found in mem");
149  m_fLandau->SetParameter(0, 1000);
150  m_fLandau->SetParameter(1, 50);
151  m_fLandau->SetParLimits(1, 10, 80);
152  m_fLandau->SetParameter(2, 10);
153  m_fLandau->SetParLimits(2, 1, 50);
154  if (hh1->GetEntries() > 100) {
155  hh1->Fit(m_fLandau, "R");
156  m_hCharge->SetBinContent(i + 1, m_fLandau->GetParameter(1));
157  m_hCharge->SetBinError(i + 1, m_fLandau->GetParError(1));
158  } else {
159  m_hCharge->SetBinContent(i + 1, 50);
160  m_hCharge->SetBinError(i + 1, 100);
161  }
162  // m_hCharge->SetBinError(i + 1, m_fLandau->GetParameter(2) * 0.25); // arbitrary scaling
163  // cout << m_fLandau->GetParameter(0) << " " << m_fLandau->GetParameter(1) << " " << m_fLandau->GetParameter(2) << endl;
164 
165  // m_hCharge->Fill(i, hh1->GetMean());
166  m_cCharge->cd();
167  hh1->Draw();
168  if (hh1->GetEntries() > 100) m_fLandau->Draw("same");
169 // m_cCharge->Print(str(format("cc_%d.pdf") % i).data());
170 
171  if (hh1->GetEntries() > 1000) enough = true;
172  }
173  }
174  m_cCharge->cd();
175 
176  double data = 0;
177  double diff = 0;
178  if (m_hCharge && enough) {
179  double currentMin, currentMax;
180  m_hCharge->Draw("");
181 // m_line1->Draw();
182 // m_line2->Draw();
183 // m_line3->Draw();
184  m_hCharge->Fit(m_fMean, "R");
185  data = m_fMean->GetParameter(0); // we are more interessted in the maximum deviation from mean
186  m_hCharge->GetMinimumAndMaximum(currentMin, currentMax);
187  diff = fabs(data - currentMin) > fabs(currentMax - data) ? fabs(data - currentMin) : fabs(currentMax - data);
188  if (0) B2INFO("Mean: " << data << " Max Diff: " << diff);
189  }
190 
191 #ifdef _BELLE2_EPICS
192  if (m_useEpics) {
193  SEVCHK(ca_put(DBR_DOUBLE, mychid[0], (void*)&data), "ca_set failure");
194  SEVCHK(ca_put(DBR_DOUBLE, mychid[1], (void*)&diff), "ca_set failure");
195  }
196 #endif
197 
198  int status = 0;
199 
200  if (!enough) {
201  // not enough Entries
202  m_cCharge->Pad()->SetFillColor(kGray);// Magenta or Gray
203  status = 0; // default
204  } else {
206  if (fabs(data - 50.) > 20. || diff > 30) {
207  m_cCharge->Pad()->SetFillColor(kRed);// Red
208  status = 4;
209  } else if (fabs(data - 50) > 15. || diff > 10) {
210  m_cCharge->Pad()->SetFillColor(kYellow);// Yellow
211  status = 3;
212  } else {
213  m_cCharge->Pad()->SetFillColor(kGreen);// Green
214  status = 2;
215  }
216 
217  // FIXME overwrite for now
218  m_cCharge->Pad()->SetFillColor(kGreen);// Green
219  }
220 
221 #ifdef _BELLE2_EPICS
222  if (m_useEpics) {
223  SEVCHK(ca_put(DBR_INT, mychid[2], (void*)&status), "ca_set failure");
224  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
225  }
226 #endif
227 
228  auto tt = new TLatex(5.5, 0, "1.3.2 Module is excluded, please ignore");
229  tt->SetTextAngle(90);// Rotated
230  tt->SetTextAlign(12);// Centered
231  tt->Draw();
232 
233  m_cCharge->Modified();
234  m_cCharge->Update();
235 }
236 
237 void DQMHistAnalysisPXDChargeModule::endRun()
238 {
239  B2DEBUG(99, "DQMHistAnalysisPXDCharge : endRun called");
240 }
241 
242 
243 void DQMHistAnalysisPXDChargeModule::terminate()
244 {
245  // should delete canvas here, maybe hist, too? Who owns it?
246 #ifdef _BELLE2_EPICS
247  if (m_useEpics) {
248  for (auto m : mychid) SEVCHK(ca_clear_channel(m), "ca_clear_channel failure");
249  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
250  }
251 #endif
252  B2DEBUG(99, "DQMHistAnalysisPXDCharge: terminate called");
253 }
254 
Belle2::VxdID
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:43
Belle2::DQMHistAnalysisPXDChargeModule
DQM Histogram Analysis for PXD Cluster Charge.
Definition: DQMHistAnalysisPXDCharge.h:30
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::VXD::SensorInfoBase
Base class to provide Sensor Information for PXD and SVD.
Definition: SensorInfoBase.h:40
Belle2::VXD::GeoCache::getListOfSensors
const std::vector< VxdID > getListOfSensors() const
Get list of all sensors.
Definition: GeoCache.cc:60
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::VXD::GeoCache
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:41
Belle2::VXD::GeoCache::getSensorInfo
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:68
Belle2::DQMHistAnalysisModule
The base class for the histogram analysis module.
Definition: DQMHistAnalysis.h:27