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 if (auto hh1 = findHist(m_histogramDirectoryName, name); hh1 != nullptr) {
132// B2INFO("Histo " << name << " found in mem");
134 m_fLandau->SetParameter(0, 1000);
135 m_fLandau->SetParameter(1, 50);
136 m_fLandau->SetParLimits(1, 10, 80);
137 m_fLandau->SetParameter(2, 10);
138 m_fLandau->SetParLimits(2, 1, 50);
139 if (hh1->GetEntries() > 100) {
140 hh1->Fit(m_fLandau, "R");
141 m_hCharge->SetBinContent(i + 1, m_fLandau->GetParameter(1));
142 m_hCharge->SetBinError(i + 1, m_fLandau->GetParError(1));
143 } else {
144 m_hCharge->SetBinContent(i + 1, 50);
145 m_hCharge->SetBinError(i + 1, 100);
146 }
147 // m_hCharge->SetBinError(i + 1, m_fLandau->GetParameter(2) * 0.25); // arbitrary scaling
148 // cout << m_fLandau->GetParameter(0) << " " << m_fLandau->GetParameter(1) << " " << m_fLandau->GetParameter(2) << endl;
149
150 // m_hCharge->Fill(i, hh1->GetMean());
151 m_cCharge->cd();
152 hh1->Draw();
153 if (hh1->GetEntries() > 100) m_fLandau->Draw("same");
154// m_cCharge->Print(str(format("cc_%d.pdf") % i).data());
155
156 if (hh1->GetEntries() > 1000) enough = true;
157 }
158 }
159 m_cCharge->cd();
160
161 double data = 0;
162 double diff = 0;
163 if (m_hCharge && enough) {
164 double currentMin, currentMax;
165 m_hCharge->Draw("");
166// m_line1->Draw();
167// m_line2->Draw();
168// m_line3->Draw();
169 m_hCharge->Fit(m_fMean, "R");
170 data = m_fMean->GetParameter(0); // we are more interested in the maximum deviation from mean
171 m_hCharge->GetMinimumAndMaximum(currentMin, currentMax);
172 diff = fabs(data - currentMin) > fabs(currentMax - data) ? fabs(data - currentMin) : fabs(currentMax - data);
173 if (0) B2INFO("Mean: " << data << " Max Diff: " << diff);
174 }
175
176 setEpicsPV("Mean", data);
177 setEpicsPV("Diff", diff);
178
179 int status = 0;
180
181 if (!enough) {
182 // not enough Entries
183 m_cCharge->Pad()->SetFillColor(kGray);// Magenta or Gray
184 status = 0; // default
185 } else {
187 if (fabs(data - 50.) > 20. || diff > 30) {
188 m_cCharge->Pad()->SetFillColor(kRed);// Red
189 status = 4;
190 } else if (fabs(data - 50) > 15. || diff > 10) {
191 m_cCharge->Pad()->SetFillColor(kYellow);// Yellow
192 status = 3;
193 } else {
194 m_cCharge->Pad()->SetFillColor(kGreen);// Green
195 status = 2;
196 }
197
198 // FIXME overwrite for now
199 m_cCharge->Pad()->SetFillColor(kGreen);// Green
200 }
201
202 setEpicsPV("Status", status);
203
204 for (const auto& it : m_excluded) {
205 static std::map <int, TLatex*> ltmap;
206 auto tt = ltmap[it];
207 if (!tt) {
208 tt = new TLatex(it + 0.5, 0, (" " + std::string(m_PXDModules[it]) + " Module is excluded, please ignore").c_str());
209 tt->SetTextSize(0.035);
210 tt->SetTextAngle(90);// Rotated
211 tt->SetTextAlign(12);// Centered
212 ltmap[it] = tt;
213 }
214 tt->Draw();
215 }
216
217 m_cCharge->Modified();
218 m_cCharge->Update();
220}
221
223{
224 B2DEBUG(99, "DQMHistAnalysisPXDCharge : endRun called");
225}
226
227
229{
230 B2DEBUG(99, "DQMHistAnalysisPXDCharge: terminate called");
231
232 if (m_cCharge) delete m_cCharge;
233 if (m_hCharge) delete m_hCharge;
234 if (m_fLandau) delete m_fLandau;
235 if (m_fMean) delete m_fMean;
236}
237
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 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.
static TH1 * findHist(const std::string &dirname, const std::string &histname="", bool onlyIfUpdated=false)
Find histogram.
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.