Belle II Software development
DQMHistAnalysisPXDCharge.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 : DQMHistAnalysisPXDCharge.cc
10// Description : Analysis of PXD Cluster Charge
11//-
12
13
14#include <dqm/analysis/modules/DQMHistAnalysisPXDCharge.h>
15#include <TROOT.h>
16#include <TLatex.h>
17#include <vxd/geometry/GeoCache.h>
18
19using namespace std;
20using namespace Belle2;
21
22//-----------------------------------------------------------------
23// Register the Module
24//-----------------------------------------------------------------
25REG_MODULE(DQMHistAnalysisPXDCharge);
26
27//-----------------------------------------------------------------
28// Implementation
29//-----------------------------------------------------------------
30
33{
34 // This module CAN NOT be run in parallel!
35 setDescription("DQM Analysis for PXD Cluster Charge");
36
37 // Parameter definition
38 addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of Histogram dir", std::string("PXDER"));
39 addParam("RangeLow", m_rangeLow, "Lower boarder for fit", 30.);
40 addParam("RangeHigh", m_rangeHigh, "High border for fit", 85.);
41 addParam("excluded", m_excluded, "excluded module (indizes starting from 0 to 39)", std::vector<int>());
42 B2DEBUG(99, "DQMHistAnalysisPXDCharge: Constructor done.");
43}
44
46{
47 B2DEBUG(99, "DQMHistAnalysisPXDCharge: initialized.");
48
51
52 //collect the list of all PXD Modules in the geometry here
53 std::vector<VxdID> sensors = geo.getListOfSensors();
54 for (const auto& aVxdID : sensors) {
55 VXD::SensorInfoBase info = geo.getSensorInfo(aVxdID);
56 if (info.getType() != VXD::SensorInfoBase::PXD) continue;
57 m_PXDModules.push_back(aVxdID); // reorder, sort would be better
58 }
59 std::sort(m_PXDModules.begin(), m_PXDModules.end()); // back to natural order
60
61 gROOT->cd(); // this seems to be important, or strange things happen
62
63 m_cCharge = new TCanvas((m_histogramDirectoryName + "/c_Charge").data());
64 m_hCharge = new TH1F("hPXDClusterCharge", "PXD Cluster Charge; Module; Track Cluster Charge", m_PXDModules.size(), 0,
65 m_PXDModules.size());
66 m_hCharge->SetDirectory(0);// dont mess with it, this is MY histogram
67 m_hCharge->SetStats(false);
68 for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
69 TString ModuleName = (std::string)m_PXDModules[i];
70 m_hCharge->GetXaxis()->SetBinLabel(i + 1, ModuleName);
71 }
72 //Unfortunately this only changes the labels, but can't fill the bins by the VxdIDs
73 m_hCharge->Draw("");
74
75 m_monObj->addCanvas(m_cCharge);
76
78// m_line1 = new TLine(0, 10, m_PXDModules.size(), 10);
79// m_line2 = new TLine(0, 16, m_PXDModules.size(), 16);
80// m_line3 = new TLine(0, 3, m_PXDModules.size(), 3);
81// m_line1->SetHorizontal(true);
82// m_line1->SetLineColor(3);// Green
83// m_line1->SetLineWidth(3);
84// m_line2->SetHorizontal(true);
85// m_line2->SetLineColor(1);// Black
86// m_line2->SetLineWidth(3);
87// m_line3->SetHorizontal(true);
88// m_line3->SetLineColor(1);
89// m_line3->SetLineWidth(3);
90
92
93 m_fLandau = new TF1("f_Landau", "landau", m_rangeLow, m_rangeHigh);
94 m_fLandau->SetParameter(0, 1000);
95 m_fLandau->SetParameter(1, 50);
96 m_fLandau->SetParameter(2, 10);
97 m_fLandau->SetLineColor(4);
98 m_fLandau->SetNpx(60);
99 m_fLandau->SetNumberFitPoints(60);
100
101 m_fMean = new TF1("f_Mean", "pol0", 0.5, m_PXDModules.size() - 0.5);
102 m_fMean->SetParameter(0, 50);
103 m_fMean->SetLineColor(5);
104 m_fMean->SetNpx(m_PXDModules.size());
105 m_fMean->SetNumberFitPoints(m_PXDModules.size());
106
107 registerEpicsPV("PXD:Charge:Mean", "Mean");
108 registerEpicsPV("PXD:Charge:Diff", "Diff");
109 registerEpicsPV("PXD:Charge:Status", "Status");
110}
111
112
114{
115 B2DEBUG(99, "DQMHistAnalysisPXDCharge: beginRun called.");
116
117 m_cCharge->Clear();
118}
119
121{
122 if (!m_cCharge) return;
123 m_hCharge->Reset(); // dont sum up!!!
124
125 bool enough = false;
126
127 for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
128 std::string name = "DQMER_PXD_" + (std::string)m_PXDModules[i] + "_ClusterCharge";
129 std::replace(name.begin(), name.end(), '.', '_');
130
131 TH1* hh1 = findHist(name);
132 if (hh1 == NULL) {
134 }
135 if (hh1) {
136// B2INFO("Histo " << name << " found in mem");
138 m_fLandau->SetParameter(0, 1000);
139 m_fLandau->SetParameter(1, 50);
140 m_fLandau->SetParLimits(1, 10, 80);
141 m_fLandau->SetParameter(2, 10);
142 m_fLandau->SetParLimits(2, 1, 50);
143 if (hh1->GetEntries() > 100) {
144 hh1->Fit(m_fLandau, "R");
145 m_hCharge->SetBinContent(i + 1, m_fLandau->GetParameter(1));
146 m_hCharge->SetBinError(i + 1, m_fLandau->GetParError(1));
147 } else {
148 m_hCharge->SetBinContent(i + 1, 50);
149 m_hCharge->SetBinError(i + 1, 100);
150 }
151 // m_hCharge->SetBinError(i + 1, m_fLandau->GetParameter(2) * 0.25); // arbitrary scaling
152 // cout << m_fLandau->GetParameter(0) << " " << m_fLandau->GetParameter(1) << " " << m_fLandau->GetParameter(2) << endl;
153
154 // m_hCharge->Fill(i, hh1->GetMean());
155 m_cCharge->cd();
156 hh1->Draw();
157 if (hh1->GetEntries() > 100) m_fLandau->Draw("same");
158// m_cCharge->Print(str(format("cc_%d.pdf") % i).data());
159
160 if (hh1->GetEntries() > 1000) enough = true;
161 }
162 }
163 m_cCharge->cd();
164
165 double data = 0;
166 double diff = 0;
167 if (m_hCharge && enough) {
168 double currentMin, currentMax;
169 m_hCharge->Draw("");
170// m_line1->Draw();
171// m_line2->Draw();
172// m_line3->Draw();
173 m_hCharge->Fit(m_fMean, "R");
174 data = m_fMean->GetParameter(0); // we are more interested in the maximum deviation from mean
175 m_hCharge->GetMinimumAndMaximum(currentMin, currentMax);
176 diff = fabs(data - currentMin) > fabs(currentMax - data) ? fabs(data - currentMin) : fabs(currentMax - data);
177 if (0) B2INFO("Mean: " << data << " Max Diff: " << diff);
178 }
179
180 setEpicsPV("Mean", data);
181 setEpicsPV("Diff", diff);
182
183 int status = 0;
184
185 if (!enough) {
186 // not enough Entries
187 m_cCharge->Pad()->SetFillColor(kGray);// Magenta or Gray
188 status = 0; // default
189 } else {
191 if (fabs(data - 50.) > 20. || diff > 30) {
192 m_cCharge->Pad()->SetFillColor(kRed);// Red
193 status = 4;
194 } else if (fabs(data - 50) > 15. || diff > 10) {
195 m_cCharge->Pad()->SetFillColor(kYellow);// Yellow
196 status = 3;
197 } else {
198 m_cCharge->Pad()->SetFillColor(kGreen);// Green
199 status = 2;
200 }
201
202 // FIXME overwrite for now
203 m_cCharge->Pad()->SetFillColor(kGreen);// Green
204 }
205
206 setEpicsPV("Status", status);
207
208 for (const auto& it : m_excluded) {
209 static std::map <int, TLatex*> ltmap;
210 auto tt = ltmap[it];
211 if (!tt) {
212 tt = new TLatex(it + 0.5, 0, (" " + std::string(m_PXDModules[it]) + " Module is excluded, please ignore").c_str());
213 tt->SetTextSize(0.035);
214 tt->SetTextAngle(90);// Rotated
215 tt->SetTextAlign(12);// Centered
216 ltmap[it] = tt;
217 }
218 tt->Draw();
219 }
220
221 m_cCharge->Modified();
222 m_cCharge->Update();
224}
225
227{
228 B2DEBUG(99, "DQMHistAnalysisPXDCharge : endRun called");
229}
230
231
233{
234 B2DEBUG(99, "DQMHistAnalysisPXDCharge: terminate called");
235
236 if (m_cCharge) delete m_cCharge;
237 if (m_hCharge) delete m_hCharge;
238 if (m_fLandau) delete m_fLandau;
239 if (m_fMean) delete m_fMean;
240}
241
int registerEpicsPV(const std::string &pvname, const std::string &keyname="")
EPICS related Functions.
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
static void UpdateCanvas(const std::string &name, bool updated=true)
Mark canvas as updated (or not)
DQMHistAnalysisModule()
Constructor / Destructor.
void setEpicsPV(const std::string &keyname, double value)
Write value to a EPICS PV.
void terminate(void) override final
This method is called at the end of the event processing.
double m_rangeLow
fit range lo edge for landau
void initialize(void) override final
Initializer.
TH1F * m_hCharge
Histogram covering all modules.
void endRun(void) override final
This method is called if the current run ends.
MonitoringObject * m_monObj
Monitoring Object.
TF1 * m_fMean
Fit the Mean for all modules.
std::vector< VxdID > m_PXDModules
IDs of all PXD Modules to iterate over.
std::string m_histogramDirectoryName
name of histogram directory
double m_rangeHigh
fit range hi edge for landau
std::vector< int > m_excluded
Indizes of excluded PXD Modules.
TF1 * m_fLandau
only one fit function for all Landaus
void beginRun(void) override final
Called when entering a new run.
void event(void) override final
This method is called for each event.
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Class to facilitate easy access to sensor information of the VXD like coordinate transformations or p...
Definition GeoCache.h:38
const std::vector< VxdID > getListOfSensors() const
Get list of all sensors.
Definition GeoCache.cc:59
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a reference to the SensorInfo of a given SensorID.
Definition GeoCache.cc:67
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition GeoCache.cc:214
Base class to provide Sensor Information for PXD and SVD.
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
STL namespace.