15 #include "dqm_core/exceptions.h"
16 #include "dqm_core/AlgorithmManager.h"
17 #include "dqm_core/AlgorithmConfig.h"
18 #include "dqm_core/Result.h"
35 message +=
"Description: Defines a warning and an error threshold for individual bins.\n";
36 message +=
" The status is the worst case summary of individual bin comparisons.\n";
37 message +=
" Some of the parameter names depend on whether the histogram is 1D or 2D.\n";
38 message +=
"Mandatory Parameter: UseValue:\n";
39 message +=
" 1: Flag bin contents >= Value\n";
40 message +=
" >1: Flag bin contents > Value\n";
41 message +=
" -1: Flag bin contents <= Value\n";
42 message +=
" <-1: Flag bin contents < Value\n";
43 message +=
"Mandatory Parameter: TypeValue:\n";
44 message +=
" 0: Value is compared to total entries in bin\n";
45 message +=
" 1: Value is compared to fraction of entries in histogram appearing in bin\n";
46 message +=
" This also determines how the bin contents will be listed if published.\n";
47 message +=
"Optional Parameter: Publish: Default = -1\n";
48 message +=
" -1: Print no values\n";
49 message +=
" 0: Print the number of bins exceeding their threshold\n";
50 message +=
" # > 0: Print bins exceeding their thresholds individually\n";
51 message +=
" At most # bins are printed, and the excess is also listed\n";
52 message +=
"Optional Parameter: TypePublish: Default = 0\n";
53 message +=
" 0: Print only bins exceeding their error threshold Values\n";
54 message +=
" 1: Print only bins exceeding their error or warning threshold Values\n";
55 message +=
" 2: Print all unmasked bins\n";
56 message +=
"Profile Configuration:\n";
57 message +=
"Optional Parameter: BinMinEntries: Default = 0\n";
58 message +=
" Minimum number of entries in a TProfile (1D only) for a bin to be checked against thresolds\n";
59 message +=
" If a bin does not have a sufficient number of entries it also will not be printed\n";
60 message +=
"1D Histogram Configuration:\n";
62 message +=
" Arguments are given for individual bins.\n";
63 message +=
" To make a single threshold check, set Warning:Value == Error:Value\n";
64 message +=
" Example of asserting the thresholds for a 3 bin histogram with the 2nd bin masked\n";
65 message +=
" ***In thresholds declaration:\n";
66 message +=
" limits Value_1 {\n";
70 message +=
" limits Value_3 {\n";
74 message +=
"Limits: Value_All\n";
75 message +=
" Unmasks and sets thresholds uniformly for all bins.\n";
76 message +=
" Example of alternative declaration of the 3 bins histogram thresholds and masking above:\n";
77 message +=
" ***In algorithm declaration\n";
79 message +=
" ***In thresholds declaration:\n";
80 message +=
" limits Value_All {\n";
84 message +=
" limits Value_3 {\n";
88 message +=
"Optional Parameters: Mask_# Default = See Note below.\n";
90 message +=
"2D Histogram Configuration:\n";
91 message +=
"Limits: Value_#_#\n";
92 message +=
" Arguments are given for individual bins.\n";
93 message +=
" Example of setting the X = 1, Y = 2 bin thresholds:\n";
94 message +=
" ***In thresholds declaration:\n";
95 message +=
" limits Value_1_2 {\n";
99 message +=
"Optional Parameters: Mask_#_# Default = See Note below.\n";
101 message +=
" Example of masking the X = 1, Y = 2 bin:\n";
102 message +=
" ***In algorithm declaration\n";
104 message +=
"Note Mask_## = 1 has precedence over the unmasking from a Value_## declaration\n";
105 message +=
"and that Value_## settings take precedence over the Value_All settings.\n";
106 message +=
"The un-masking option Mask_## = 0 is ignored in order to avoid unmasking an unconfigured bin.";
113 : m_name(
"BinThresh")
154 if (!
data.IsA()->InheritsFrom(
"TH1")) {
155 throw dqm_core::BadConfig(ERS_HERE,
name,
"does not inherit from TH1");
157 const TH1*
h =
static_cast<const TH1*
>(&
data);
158 if (
h->GetDimension() > 2) {
159 throw dqm_core::BadConfig(ERS_HERE,
name,
"dimension > 2 ");
174 catch (dqm_core::Exception & ex) {
175 throw dqm_core::BadConfig( ERS_HERE,
name, ex.what(), ex );
177 if ( UseValue == 0 ) ERS_INFO(
"UseValue == 0 is meaningless");
182 if (
data.IsA()->InheritsFrom(
"TProfile") ) {
188 std::vector<BinThresh::mask_limits> Limits;
192 catch (dqm_core::Exception & ex) {
193 throw dqm_core::BadConfig( ERS_HERE,
name, ex.what(), ex );
198 if ((UseValue > 0 && Limits[
bin].WarningValue > Limits[
bin].ErrorValue) ||
199 (UseValue < 0 && Limits[
bin].WarningValue < Limits[
bin].ErrorValue)) {
201 if ( !Limits[
bin].Mask ) {
202 std::string problem_message = Form(
"Incompatible Warning and Error Values in bin_%d : Warning = %e -> Error = %e",
bin + 1, Limits[
bin].WarningValue, Limits[
bin].ErrorValue);
203 ERS_INFO(problem_message.c_str());
209 double h_entries = hp->GetEntries();
212 Limits[
bin].WarningValue = Limits[
bin].WarningValue * h_entries;
213 Limits[
bin].ErrorValue = Limits[
bin].ErrorValue * h_entries;
219 double bincon = hp->GetBinContent(
bin + 1);
220 if ( !Limits[
bin].Mask && hp->GetBinEntries(
bin + 1) >= BinMinEntries ) {
222 if ((UseValue == 1 && bincon >= Limits[
bin].ErrorValue) ||
223 (UseValue > 1 && bincon > Limits[
bin].ErrorValue) ||
224 (UseValue == -1 && bincon <= Limits[
bin].ErrorValue) ||
225 (UseValue < -1 && bincon < Limits[
bin].ErrorValue) ) {
227 if ( NErrors + NWarnings + NGoodPrint <= Publish ) {
228 double binval = hp->GetXaxis()->GetBinCenter(
bin + 1);
233 std::string binname = Form(
"%s_ErrorBin(%u | %.*e)",
name.c_str(),
bin, 2, binval);
235 if ( TypeValue > 0.5 ) {
236 result->tags_[binname.c_str()] = (bincon / h_entries);
238 result->tags_[binname.c_str()] = bincon;
243 else if ((UseValue == 1 && bincon >= Limits[
bin].WarningValue) ||
244 (UseValue > 1 && bincon > Limits[
bin].WarningValue) ||
245 (UseValue == -1 && bincon <= Limits[
bin].WarningValue) ||
246 (UseValue < -1 && bincon < Limits[
bin].WarningValue) ) {
248 if ( TypePublish >= 1 && NErrors + NWarnings + NGoodPrint <= Publish ) {
249 float binval = hp->GetXaxis()->GetBinCenter(
bin + 1);
253 std::string binname = Form(
"%s_WarningBin(%u | %.*e)",
name.c_str(),
bin, 2, binval);
254 if ( TypeValue > 0.5 ) {
255 result->tags_[binname.c_str()] = (bincon / h_entries);
257 result->tags_[binname.c_str()] = bincon;
264 if ( TypePublish >= 2 && NErrors + NWarnings + NGoodPrint <= Publish ) {
265 float binval = hp->GetXaxis()->GetBinCenter(
bin + 1);
269 std::string binname = Form(
"%s_GoodBin(%u | %.*e)",
name.c_str(),
bin, 2, binval);
270 if ( TypeValue > 0.5 ) {
271 result->tags_[binname.c_str()] = (bincon / h_entries);
273 result->tags_[binname.c_str()] = bincon;
284 if ( (!
data.IsA()->InheritsFrom(
"TProfile")) &&
h->GetDimension() == 1 ) {
288 std::vector<BinThresh::mask_limits> Limits;
292 catch (dqm_core::Exception & ex) {
293 throw dqm_core::BadConfig( ERS_HERE,
name, ex.what(), ex );
298 if ((UseValue > 0 && Limits[
bin].WarningValue > Limits[
bin].ErrorValue) ||
299 (UseValue < 0 && Limits[
bin].WarningValue < Limits[
bin].ErrorValue)) {
301 if ( !Limits[
bin].Mask ) {
302 std::string problem_message = Form(
"Incompatible Warning and Error Values in bin_%d : Warning = %e -> Error = %e",
bin + 1, Limits[
bin].WarningValue, Limits[
bin].ErrorValue);
303 ERS_INFO(problem_message.c_str());
309 double h_entries =
h->GetEntries();
312 Limits[
bin].WarningValue = Limits[
bin].WarningValue * h_entries;
313 Limits[
bin].ErrorValue = Limits[
bin].ErrorValue * h_entries;
319 double bincon =
h->GetBinContent(
bin + 1);
320 if ( !Limits[
bin].Mask ) {
322 if ((UseValue == 1 && bincon >= Limits[
bin].ErrorValue) ||
323 (UseValue > 1 && bincon > Limits[
bin].ErrorValue) ||
324 (UseValue == -1 && bincon <= Limits[
bin].ErrorValue) ||
325 (UseValue < -1 && bincon < Limits[
bin].ErrorValue) ) {
327 if ( NErrors + NWarnings + NGoodPrint <= Publish ) {
328 double binval =
h->GetXaxis()->GetBinCenter(
bin + 1);
333 std::string binname = Form(
"%s_ErrorBin(%u | %.*e)",
name.c_str(),
bin, 2, binval);
335 if ( TypeValue > 0.5 ) {
336 result->tags_[binname.c_str()] = (bincon / h_entries);
338 result->tags_[binname.c_str()] = bincon;
343 else if ((UseValue == 1 && bincon >= Limits[
bin].WarningValue) ||
344 (UseValue > 1 && bincon > Limits[
bin].WarningValue) ||
345 (UseValue == -1 && bincon <= Limits[
bin].WarningValue) ||
346 (UseValue < -1 && bincon < Limits[
bin].WarningValue) ) {
348 if ( TypePublish >= 1 && NErrors + NWarnings + NGoodPrint <= Publish ) {
349 float binval =
h->GetXaxis()->GetBinCenter(
bin + 1);
353 std::string binname = Form(
"%s_WarningBin(%u | %.*e)",
name.c_str(),
bin, 2, binval);
354 if ( TypeValue > 0.5 ) {
355 result->tags_[binname.c_str()] = (bincon / h_entries);
357 result->tags_[binname.c_str()] = bincon;
364 if ( TypePublish >= 2 && NErrors + NWarnings + NGoodPrint <= Publish ) {
365 float binval =
h->GetXaxis()->GetBinCenter(
bin + 1);
369 std::string binname = Form(
"%s_GoodBin(%u | %.*e)",
name.c_str(),
bin, 2, binval);
370 if ( TypeValue > 0.5 ) {
371 result->tags_[binname.c_str()] = (bincon / h_entries);
373 result->tags_[binname.c_str()] = bincon;
384 if ( (!
data.IsA()->InheritsFrom(
"TProfile")) &&
h->GetDimension() == 2 ) {
389 std::vector< std::vector<BinThresh::mask_limits> > Limits;
393 catch (dqm_core::Exception & ex) {
394 throw dqm_core::BadConfig( ERS_HERE,
name, ex.what(), ex );
400 if ( (UseValue > 0 && Limits[
binX][
binY].WarningValue > Limits[
binX][
binY].ErrorValue) ||
401 (UseValue < 0 && Limits[
binX][
binY].WarningValue < Limits[
binX][
binY].ErrorValue)) {
404 std::string problem_message = Form(
"Incompatible Warning and Error Values in bin_%d_%d : Warning = %e -> Error = %e",
binX + 1,
binY + 1, Limits[
binX][
binY].WarningValue, Limits[
binX][
binY].ErrorValue);
405 ERS_INFO(problem_message.c_str());
411 double h_entries =
h->GetEntries();
415 Limits[
binX][
binY].WarningValue = Limits[
binX][
binY].WarningValue * h_entries;
423 double bincon =
h->GetBinContent(
binX + 1,
binY + 1);
426 if ( (UseValue == 1 && bincon >= Limits[
binX][
binY].ErrorValue) ||
427 (UseValue > 1 && bincon > Limits[
binX][
binY].ErrorValue) ||
428 (UseValue == -1 && bincon <= Limits[
binX][
binY].ErrorValue) ||
429 (UseValue < -1 && bincon < Limits[
binX][
binY].ErrorValue) ) {
431 if ( NErrors + NWarnings + NGoodPrint <= Publish ) {
432 float binvalX =
h->GetXaxis()->GetBinCenter(
binX + 1);
433 float binvalY =
h->GetYaxis()->GetBinCenter(
binY + 1);
434 std::string binname = Form(
"%s_ErrorBin((%u,%u) | %.*e,%.*e)",
name.c_str(),
binX,
binY, 2, binvalX, 2, binvalY);
436 if ( TypeValue > 0.5 ) {
437 result->tags_[binname.c_str()] = (bincon / h_entries);
439 result->tags_[binname.c_str()] = bincon;
444 else if ( (UseValue == 1 && bincon >= Limits[
binX][
binY].WarningValue) ||
445 (UseValue > 1 && bincon > Limits[
binX][
binY].WarningValue) ||
446 (UseValue == -1 && bincon <= Limits[
binX][
binY].WarningValue) ||
447 (UseValue < -1 && bincon < Limits[
binX][
binY].WarningValue) ) {
449 if ( TypePublish >= 1 && NErrors + NWarnings + NGoodPrint <= Publish ) {
450 float binvalX =
h->GetXaxis()->GetBinCenter(
binX + 1);
451 float binvalY =
h->GetYaxis()->GetBinCenter(
binY + 1);
452 std::string binname = Form(
"%s_WarningBin((%u,%u) | %.*e,%.*e)",
name.c_str(),
binX,
binY, 2, binvalX, 2, binvalY);
453 if ( TypeValue > 0.5 ) {
454 result->tags_[binname.c_str()] = (bincon / h_entries);
456 result->tags_[binname.c_str()] = bincon;
463 if ( TypePublish >= 2 && NErrors + NWarnings + NGoodPrint <= Publish ) {
464 float binvalX =
h->GetXaxis()->GetBinCenter(
binX + 1);
465 float binvalY =
h->GetYaxis()->GetBinCenter(
binY + 1);
466 std::string binname = Form(
"%s_GoodBin((%u,%u) | %.*e,%.*e)",
name.c_str(),
binX,
binY, 2, binvalX, 2, binvalY);
467 if ( TypeValue > 0.5 ) {
468 result->tags_[binname.c_str()] = (bincon / h_entries);
470 result->tags_[binname.c_str()] = bincon;
479 if ( Publish >= 0 ) {
480 std::string pub_error = Form(
"%s_Bin_Errors",
name.c_str());
481 result->tags_[pub_error.c_str()] = NErrors;
482 if ( TypePublish >= 1 ) {
483 std::string pub_warning = Form(
"%s_Bin_Warnings",
name.c_str());
484 result->tags_[pub_warning.c_str()] = NWarnings;
490 if ( (NErrors == 0) && (NWarnings > 0) )
result->status_ = dqm_core::Result::Yellow;
502 std::map<std::string, double>::const_iterator
it =
params.find(
"Publish");
504 return((
int)
it->second);
512 std::map<std::string, double>::const_iterator
it =
params.find(
"TypePublish");
514 if (
it->second > 1.5 )
return(2);
515 else if (
it->second > 0.5 )
return(1);
524 std::map<std::string, double>::const_iterator
it =
params.find(
"UseValue");
526 return((
int)
it->second);
534 std::map<std::string, double>::const_iterator
it =
params.find(
"TypeValue");
536 if (
it->second > 0.5 )
return(1);
545 std::map<std::string, double>::const_iterator
it =
params.find(
"BinMinEntries");
547 return((
int)
it->second);
554 const std::map<std::string, double> & warning_params,
555 const std::map<std::string, double> & error_params )
557 std::map<std::string, double>::const_iterator warning_map_bin;
558 std::map<std::string, double>::const_iterator error_map_bin;
559 std::map<std::string, double>::const_iterator mask_map_bin;
565 default_Limits.
Mask =
true;
568 warning_map_bin = warning_params.find(
"Value_All");
569 error_map_bin = error_params.find(
"Value_All");
570 if ( warning_map_bin != warning_params.end() &&
571 error_map_bin != error_params.end() ) {
573 default_Limits.
ErrorValue = error_map_bin->second;
574 default_Limits.
Mask =
false;
578 std::vector<BinThresh::mask_limits> Limits(
m_NbinsX, default_Limits);
582 std::string value_bin = Form(
"Value_%d",
bin + 1);
584 warning_map_bin = warning_params.find(value_bin.c_str());
585 error_map_bin = error_params.find(value_bin.c_str());
586 if ( warning_map_bin != warning_params.end() &&
587 error_map_bin != error_params.end() ) {
588 Limits[
bin].WarningValue = warning_map_bin->second;
589 Limits[
bin].ErrorValue = error_map_bin->second;
590 Limits[
bin].Mask =
false;
595 std::string mask_bin = Form(
"Mask_%d",
bin + 1);
596 mask_map_bin =
params.find(mask_bin.c_str());
597 if ( mask_map_bin !=
params.end() ) {
598 if(mask_map_bin->second > 0.5) Limits[
bin].Mask =
true;
607 const std::map<std::string, double> & warning_params,
608 const std::map<std::string, double> & error_params )
610 std::map<std::string, double>::const_iterator warning_map_bin;
611 std::map<std::string, double>::const_iterator error_map_bin;
612 std::map<std::string, double>::const_iterator mask_map_bin;
618 default_Limits.
Mask =
true;
621 warning_map_bin = warning_params.find(
"Value_All");
622 error_map_bin = error_params.find(
"Value_All");
623 if ( warning_map_bin != warning_params.end() &&
624 error_map_bin != error_params.end() ) {
626 default_Limits.
ErrorValue = error_map_bin->second;
627 default_Limits.
Mask =
false;
631 std::vector< std::vector<BinThresh::mask_limits> > Limits(
m_NbinsX, std::vector<BinThresh::mask_limits>(
m_NbinsY, default_Limits));
636 std::string value_bin = Form(
"Value_%d_%d",
binX + 1,
binY + 1);
638 warning_map_bin = warning_params.find(value_bin.c_str());
639 error_map_bin = error_params.find(value_bin.c_str());
640 if ( warning_map_bin != warning_params.end() &&
641 error_map_bin != error_params.end() ) {
642 Limits[
binX][
binY].WarningValue = warning_map_bin->second;
643 Limits[
binX][
binY].ErrorValue = error_map_bin->second;
649 std::string mask_bin = Form(
"Mask_%d_%d",
binX + 1,
binY + 1);
650 mask_map_bin =
params.find(mask_bin.c_str());
651 if ( mask_map_bin !=
params.end() ) {
652 if(mask_map_bin->second > 0.5) Limits[
binX][
binY].Mask =
true;