Skip to content

Commit a5eb534

Browse files
committed
More robust fitting in PFClient
- only attempt fit if have 3 non-zero bins - improved memory handling - use a TH1F rather than a MonitorElement as a temporary
1 parent d3f1e31 commit a5eb534

File tree

2 files changed

+29
-23
lines changed

2 files changed

+29
-23
lines changed

DQMOffline/PFTau/plugins/PFClient.cc

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "DataFormats/Common/interface/Handle.h"
44
#include "FWCore/Framework/interface/Event.h"
55
#include "FWCore/ParameterSet/interface/ParameterSet.h"
6+
#include "FWCore/MessageLogger/interface/MessageLogger.h"
67
#include "FWCore/Utilities/interface/InputTag.h"
78

89
#include "DQMServices/Core/interface/DQMStore.h"
@@ -125,43 +126,47 @@ void PFClient::createResolutionPlots(DQMStore::IBooker &ibooker,
125126
float ymax = th->GetYaxis()->GetXmax();
126127
std::string xtit = th->GetXaxis()->GetTitle();
127128
std::string ytit = th->GetYaxis()->GetTitle();
128-
float *xbins = new float[nbinx + 1];
129+
std::unique_ptr<float[]> xbins{new float[nbinx + 1]};
129130
for (size_t ix = 1; ix < nbinx + 1; ++ix) {
130131
xbins[ix - 1] = th->GetXaxis()->GetBinLowEdge(ix);
131132
if (ix == nbinx)
132133
xbins[ix] = th->GetXaxis()->GetBinUpEdge(ix);
133134
}
134135
std::string tit_new = ";" + xtit + ";" + ytit;
135136
ibooker.setCurrentFolder(folder);
136-
MonitorElement *me_slice = ibooker.book1D("PFlowSlice", "PFlowSlice", nbiny, ymin, ymax);
137+
TH1F th_slice("PFlowSlice", "PFlowSlice", nbiny, ymin, ymax);
137138

138139
tit_new = ";" + xtit + ";Average_" + ytit;
139-
me_average = ibooker.book1D("average_" + name, tit_new, nbinx, xbins);
140+
me_average = ibooker.book1D("average_" + name, tit_new, nbinx, xbins.get());
140141
me_average->setEfficiencyFlag();
141142
tit_new = ";" + xtit + ";RMS_" + ytit;
142-
me_rms = ibooker.book1D("rms_" + name, tit_new, nbinx, xbins);
143+
me_rms = ibooker.book1D("rms_" + name, tit_new, nbinx, xbins.get());
143144
me_rms->setEfficiencyFlag();
144145
tit_new = ";" + xtit + ";Mean_" + ytit;
145-
me_mean = ibooker.book1D("mean_" + name, tit_new, nbinx, xbins);
146+
me_mean = ibooker.book1D("mean_" + name, tit_new, nbinx, xbins.get());
146147
me_mean->setEfficiencyFlag();
147148
tit_new = ";" + xtit + ";Sigma_" + ytit;
148-
me_sigma = ibooker.book1D("sigma_" + name, tit_new, nbinx, xbins);
149+
me_sigma = ibooker.book1D("sigma_" + name, tit_new, nbinx, xbins.get());
149150
me_sigma->setEfficiencyFlag();
150151

151152
double average, rms, mean, sigma;
152153

153154
for (size_t ix = 1; ix < nbinx + 1; ++ix) {
154-
me_slice->Reset();
155+
th_slice.Reset();
156+
unsigned int nNonZeroBins = 0;
155157
for (size_t iy = 1; iy < nbiny + 1; ++iy) {
156-
me_slice->setBinContent(iy, th->GetBinContent(ix, iy));
158+
auto value = th->GetBinContent(ix, iy);
159+
th_slice.SetBinContent(iy, value);
160+
if (value != 0) {
161+
++nNonZeroBins;
162+
}
157163
}
158-
getHistogramParameters(me_slice, average, rms, mean, sigma);
164+
getHistogramParameters(th_slice, nNonZeroBins, average, rms, mean, sigma);
159165
me_average->setBinContent(ix, average);
160166
me_rms->setBinContent(ix, rms);
161167
me_mean->setBinContent(ix, mean);
162168
me_sigma->setBinContent(ix, sigma);
163169
}
164-
delete[] xbins;
165170
}
166171
}
167172

@@ -257,7 +262,7 @@ void PFClient::createProfilePlots(DQMStore::IBooker &ibooker,
257262
// size_t nbiny = me->getNbinsY();
258263
// TProfile* profileX = th->ProfileX("",0,nbiny+1); add underflow and
259264
// overflow
260-
static const Int_t NUM_STAT = 7;
265+
static constexpr Int_t NUM_STAT = 7;
261266
Double_t stats[NUM_STAT] = {0};
262267
th->GetStats(stats);
263268

@@ -285,24 +290,24 @@ void PFClient::createProfilePlots(DQMStore::IBooker &ibooker,
285290
// -- Get Histogram Parameters
286291
//
287292
void PFClient::getHistogramParameters(
288-
MonitorElement *me_slice, double &average, double &rms, double &mean, double &sigma) {
293+
TH1F &th_slice, unsigned int nNonZeroBins, double &average, double &rms, double &mean, double &sigma) {
289294
average = 0.0;
290295
rms = 0.0;
291296
mean = 0.0;
292297
sigma = 0.0;
293298

294-
if (!me_slice)
295-
return;
296-
if (me_slice->kind() == MonitorElement::Kind::TH1F) {
297-
average = me_slice->getMean();
298-
rms = me_slice->getRMS();
299-
TH1F *th_slice = me_slice->getTH1F();
300-
if (th_slice && th_slice->GetEntries() > 0) {
301-
// need our own copy for thread safety
302-
TF1 gaus("mygaus", "gaus");
303-
th_slice->Fit(&gaus, "Q0 SERIAL");
299+
average = th_slice.GetMean();
300+
rms = th_slice.GetRMS();
301+
//Need a minimum of 3 points to fit a gaussian
302+
if (nNonZeroBins > 2) {
303+
// need our own copy for thread safety
304+
TF1 gaus("mygaus", "gaus", 0, 1, TF1::EAddToList::kNo);
305+
auto fit = th_slice.Fit(&gaus, "Q0 SERIAL");
306+
if (int(fit) == 0) {
304307
sigma = gaus.GetParameter(2);
305308
mean = gaus.GetParameter(1);
309+
} else {
310+
edm::LogWarning("FitFailed") << "Failed to fit gaussian";
306311
}
307312
}
308313
}

DQMOffline/PFTau/plugins/PFClient.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ class PFClient : public DQMEDHarvester {
2020
void doProjection(DQMStore::IBooker &, DQMStore::IGetter &);
2121
void doProfiles(DQMStore::IBooker &, DQMStore::IGetter &);
2222
void createResolutionPlots(DQMStore::IBooker &, DQMStore::IGetter &, std::string &folder, std::string &name);
23-
void getHistogramParameters(MonitorElement *me_slice, double &avarage, double &rms, double &mean, double &sigma);
23+
void getHistogramParameters(
24+
TH1F &th_slice, unsigned int nNonZeroBins, double &avarage, double &rms, double &mean, double &sigma);
2425
void createEfficiencyPlots(DQMStore::IBooker &, DQMStore::IGetter &, std::string &folder, std::string &name);
2526

2627
void createProjectionPlots(DQMStore::IBooker &, DQMStore::IGetter &, std::string &folder, std::string &name);

0 commit comments

Comments
 (0)