41 if (!
object.
IsA()->InheritsFrom(
"TH1")) {
42 throw dqm_core::BadConfig(ERS_HERE, name,
"histogram does not inherit from TH1");
46 throw dqm_core::BadConfig(ERS_HERE, name,
"histogram has more than one dimension");
49 if (
histogram.GetEffectiveEntries() < minstat) {
50 dqm_core::Result *
result =
new dqm_core::Result(dqm_core::Result::Undefined);
51 result->tags_[
"InsufficientEffectiveEntries"] =
histogram.GetEffectiveEntries();
55 if (sigmaRange <= 0) {
56 throw dqm_core::BadConfig(ERS_HERE, name,
"SigmaRange must be greater than zero.");
59 ERS_DEBUG(1,
"Careful, your SigmaRange = " << sigmaRange <<
" is rather small");
64 throw dqm_core::BadConfig(ERS_HERE, name,
"SigmaMax must be greater than zero.");
67 std::unique_ptr<TH1>
h(
static_cast<TH1 *
>(
histogram.Clone()));
69 auto f = std::make_unique<TF1> (
"f",
"gaus");
71 f->SetParLimits(2, 0, sigmaMax);
72 f->SetParameter(2, sigmaMax / 2);
73 f->SetRange(meanNominal - sigmaMax, meanNominal + sigmaMax);
76 const unsigned int maxIterations = 10;
77 const double sufficientPrecision = 0.01;
81 const double sigmaOld = (i == 0) ? 0 : f->GetParameter(2);
82 std::string fitOptions(
"INQ");
83 if (i > 0 || sigmaMax) fitOptions.append(
"R");
84 if (sigmaMax) fitOptions.append(
"B");
86 const int fitStatus =
h->Fit(f.get(), fitOptions.c_str());
88 ERS_DEBUG(1,
"Fit failed in iteration " << i <<
", status = " << fitStatus);
89 dqm_core::Result *
result =
new dqm_core::Result(dqm_core::Result::Red);
90 if (fitStatus < 0)
result->status_ = dqm_core::Result::Undefined;
91 result->tags_[
"Iteration"] = i;
92 result->tags_[
"FitStatus"] = fitStatus;
96 const double mean = f->GetParameter(1);
97 const double sigma = f->GetParameter(2);
98 ERS_DEBUG(2,
"Iteration " << i <<
": mean = " <<
mean <<
", sigma = " << sigma);
99 f->SetRange(
mean - sigmaRange * sigma,
mean + sigmaRange * sigma);
102 ERS_DEBUG(1,
"Fit yielded sigma = 0 in iteration " << i);
103 dqm_core::Result *
result =
new dqm_core::Result(dqm_core::Result::Red);
104 result->tags_[
"Iteration"] = i;
106 result->tags_[
"Sigma"] = sigma;
110 if (sigma == sigmaMax) {
111 ERS_DEBUG(1,
"Fit result for sigma is at the limit " << sigmaMax);
112 dqm_core::Result *
result =
new dqm_core::Result(dqm_core::Result::Red);
113 result->tags_[
"Iteration"] = i;
114 result->tags_[
"Sigma"] = sigma;
115 result->tags_[
"SigmaMax"] = sigmaMax;
119 if ((std::fabs(sigma - sigmaOld) / sigma) < sufficientPrecision)
break;
121 if (i >= maxIterations) {
122 ERS_DEBUG(1,
"Sorry, this is not taking us anywhere: the iteration does not seem to converge");
123 dqm_core::Result *
result =
new dqm_core::Result(dqm_core::Result::Undefined);
124 result->tags_[
"Iteration"] = i;
125 result->tags_[
"SigmaOld"] = sigmaOld;
126 result->tags_[
"SigmaNew"] = sigma;
132 const int ndf = f->GetNDF();
133 const double chi2 = f->GetChisquare();
134 const double chi2NDF = (ndf > 0) ? (
chi2 / ndf) : 0;
136 std::map<std::string, double> resultValues;
137 resultValues[
"Constant"] = f->GetParameter(0);
138 resultValues[
"ConstantError"] = f->GetParError(0);
139 resultValues[
"Mean"] = f->GetParameter(1);
140 resultValues[
"MeanError"] = f->GetParError(1);
141 resultValues[
"Sigma"] = f->GetParameter(2);
142 resultValues[
"SigmaError"] = f->GetParError(2);
143 resultValues[
"Chi2NDF"] = chi2NDF;
144 resultValues[
"Probability"] = f->GetProb();
145 resultValues[
"MeanDeviation"] = std::fabs(f->GetParameter(1) - meanNominal);
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")