9 #include <dqm_core/AlgorithmConfig.h>
20 #include <dqm_core/AlgorithmManager.h>
51 const TObject &
object,
52 const dqm_core::AlgorithmConfig &
config )
55 if(
object.
IsA()->InheritsFrom(
"TH1" ) ) {
58 throw dqm_core::BadConfig( ERS_HERE,
name,
"dimension > 2 " );
61 throw dqm_core::BadConfig( ERS_HERE,
name,
"does not inherit from TH1" );
63 const double minstat = 1;
65 ERS_INFO(
"Too few entries: " <<
histogram->GetEntries() );
76 std::pair<bool,double> grayValue;
84 catch ( dqm_core::Exception & ex ) {
85 throw dqm_core::BadConfig( ERS_HERE,
name, ex.what(), ex );
91 catch ( dqm_core::Exception & ex ) {
92 grayValue.first=
false;
98 catch ( dqm_core::Exception & ex ) {
105 ERS_INFO(
"'EqualityPrecision cannot be negative: it will be re-set to its absolute value.");
106 m_precision=std::abs(m_precision);
109 ERS_INFO(
"You set search window size (WindowSize) <= 0: I will search the whole histogram.");
112 if(n_bins>window_size) {
113 ERS_INFO(
"You set the minimum number of bins for throwing error/warning (NBins) larger than the window size (WindowSize): in this way the algorithm can never return error/warning. Setting NBins=WindowSize.");
118 ERS_INFO(
"You set the minimum number of bins for throwing error/warning (NBins) <= 0: in this way the algorithm would always return error. Setting NBins=1 (default value).");
122 grayValue.first=checkUndefinedStatusValue(m_name,gthreshold,rthreshold,grayValue);
127 throw dqm_core::BadConfig( ERS_HERE,
name,
"TH2 received. This algorithm only works with TH1" );
128 }
else if (
histogram->InheritsFrom(
"TH1")) {
131 throw dqm_core::BadConfig( ERS_HERE,
name,
"does not inherit from TH1" );
134 resulthisto->Reset();
139 if(start_from_last>=0)
140 i_currentLB-=start_from_last;
143 while(i_currentLB>=1)
145 if(
histogram->GetBinContent(i_currentLB)!=0)
break;
150 if(i_currentLB<=0 || i_currentLB<n_bins)
152 ERS_DEBUG(1,
"start_from_last parameter >= total number of bins, I just cannot do the check. Do nothing.");
161 while(iLB>=1 && (window_size<0 || (i_currentLB-iLB)<window_size))
165 if(LBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin)
169 if(LBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aRedBin)
173 if(LBstatus==dqm_algorithms::BinHeightThreshold::binStatus::anUndefBin)
178 resulthisto->SetBinContent(iLB,
content);
183 ERS_DEBUG(1,
"Found " << countRed <<
" red bins and " << countYellow <<
" red bins. In a window of size " << window_size <<
" bins, starting at bin " << i_currentLB);
184 ERS_DEBUG(1,
"To be compared with: " << n_bins);
185 ERS_DEBUG(1,
"Green treshold=" << gthreshold <<
" Red threshold=" << rthreshold );
187 result->tags_[
"NRedBins"] = countRed;
188 result->tags_[
"NYellowBins"] = countYellow;
189 result->object_ = (boost::shared_ptr<TObject>)(TObject*)(resulthisto);
194 else if(countRed+countYellow>=n_bins)
196 result->status_ = dqm_core::Result::Yellow;
198 else if(countGray>=n_bins)
213 if(
type==
"GreaterThan" ||
type==
"GreaterThanEqual")
215 if(thresholdGr>=thresholdRed)
216 ERS_INFO(
"'BinHeight_" <<
type <<
"_Threshold' algorithm expects red > yellow > green. You set the warning threshold (" << thresholdGr <<
") >= error threshold (" << thresholdRed <<
"): it will never return 'yellow/warning'.");
218 if(
type==
"LessThan" ||
type==
"LessThanEqual")
220 if(thresholdGr<=thresholdRed)
221 ERS_INFO(
"'BinHeight_" <<
type <<
"_Threshold' algorithm expects red < yellow < green. You set the warning threshold (" << thresholdGr <<
") <= error threshold (" << thresholdRed <<
"): it will never return 'yellow/warning'. Are you sure this is what you want?");
223 if(
type==
"redEqual_yellowGreaterThan")
225 if(thresholdRed>0 && thresholdRed<thresholdGr)
226 ERS_INFO(
"You set the error threshold (" << thresholdRed <<
") between zero and the warning threshold (" << thresholdGr <<
") in 'BinHeight_redEqual_yellowGreaterThan_Threshgold' algorithm. Are you sure this is what you want?");
228 if(
type==
"redEqual_yellowLessThan")
230 if(thresholdRed>thresholdGr)
231 ERS_INFO(
"You set the error threshold (" << thresholdRed <<
") larger than the warning threshold (" << thresholdGr <<
") in 'BinHeight_redEqual_yellowLessThan_Threshold' algorithm. Are you sure this is what you want?");
238 return valueGray.first;
240 if(
type==
"LessThan" ||
type==
"GreaterThan")
241 return valueGray.first;
243 if(equalWithinPrecision(valueGray.second,thresholdRed))
245 ERS_INFO(
"You have set 'UndefinedStatus' equal to the error threshold in 'BinHeight_" <<
type <<
"_Threshold' algorithm. Error has the precedence here: the bin content WILL NOT be checked against 'UndefinedStatus'");
249 if(
type!=
"redEqual_yellowLessThan" &&
type!=
"redEqual_yellowGreaterThan" && equalWithinPrecision(valueGray.second,thresholdGr))
251 ERS_INFO(
"You have set 'UndefinedStatus' equal to the warning threshold in 'BinHeight_" <<
type <<
"_Threshold' algorithm. Warning has the precedence here: the bin content WILL NOT be checked against 'UndefinedStatus'");
255 return valueGray.first;
264 if(equalWithinPrecision(bincontent,valueGray.second))
266 return dqm_algorithms::BinHeightThreshold::binStatus::anUndefBin;
270 if(
type==
"GreaterThan")
272 if(bincontent>thresholdRed)
273 return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
274 if(bincontent>thresholdGr)
275 return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
276 return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
280 if(bincontent<thresholdRed)
281 return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
282 if(bincontent<thresholdGr)
283 return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
284 return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
286 if(
type==
"GreaterThanEqual")
288 if(bincontent>thresholdRed || equalWithinPrecision(bincontent,thresholdRed))
289 return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
290 if(bincontent>thresholdGr || equalWithinPrecision(bincontent,thresholdGr))
291 return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
292 return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
294 if(
type==
"LessThanEqual")
296 if(bincontent<thresholdRed || equalWithinPrecision(bincontent,thresholdRed))
297 return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
298 if(bincontent<thresholdGr || equalWithinPrecision(bincontent,thresholdGr))
299 return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
300 return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
302 if(
type==
"redEqual_yellowGreaterThan")
304 if(equalWithinPrecision(bincontent,thresholdRed))
305 return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
306 if(bincontent>thresholdGr)
307 return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
308 return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
310 if(
type==
"redEqual_yellowLessThan")
312 if(equalWithinPrecision(bincontent,thresholdRed))
313 return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
314 if(bincontent<thresholdGr)
315 return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
316 return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
320 if(equalWithinPrecision(bincontent,thresholdRed))
321 return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
322 if(equalWithinPrecision(bincontent,thresholdGr))
323 return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
324 return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
326 return dqm_algorithms::BinHeightThreshold::binStatus::anUndefBin;
334 double absA = std::abs(
a);
335 double absB = std::abs(
b);
336 double diff = std::abs(
a -
b);
341 else if (
a == 0 ||
b == 0 ||
diff < DBL_MIN) {
344 return diff < (m_precision * DBL_MIN);
347 return (
diff /
std::min((absA + absB), DBL_MAX)) < m_precision;
354 TString redCond,yellowCond;
355 if(m_name==
"redEqual_yellowGreaterThan" || m_name==
"redEqual_yellowLessThan" || m_name==
"Equal")
357 redCond=
"bin_content==redThreshold";
359 yellowCond=
"bin_content==yellowThreshold && bin_content!=redThreshold";
360 else if(m_name==
"redEqual_yellowGreaterThan")
361 yellowCond=
"bin_content>yellowThreshold && bin_content!=redThreshold";
363 yellowCond=
"bin_content<yellowThreshold && bin_content!=redThreshold";
367 if(m_name==
"GreaterThan")
369 redCond=
"bin_content>redThreshold";
370 yellowCond=
"redThreshold>=bin_content>yellowThreshold";
372 else if(m_name==
"LessThan")
374 redCond=
"bin_content<redThreshold";
375 yellowCond=
"redThreshold<=bin_content<yellowThreshold";
377 else if(m_name==
"GreaterThanEqual")
379 redCond=
"bin_content>=redThreshold";
380 yellowCond=
"redThreshold>bin_content>=yellowThreshold";
384 redCond=
"bin_content<=redThreshold";
385 yellowCond=
"redThreshold<bin_content<=yellowThreshold";
388 out <<
"BinHeight_" << m_name <<
"_Threshold checks the bin height of a TH1. Ideally, a quantity as a function of LB. LB is expected to be on x axis, the quantity of interest is the bin content." << std::endl;
389 out <<
"BinHeight_" << m_name <<
"_Threshold defines 'red' and 'yellow' bins depending on the value of the bin content:\n \t-if " << redCond <<
": the bin is 'red'.\n \t-if " << yellowCond <<
": the bin is 'yellow'.\n \t-if (OPTIONAL) an 'UndefinedStatus' value is set and bin_content==UndefinedStatus, the bin is 'gray'.";
390 if(m_name!=
"GreaterThan" && m_name!=
"LessThan")
391 out <<
" Note that if 'UndefinedStatus' is equal to 'redThreshold' or 'yellowThreshold', the bin will be 'red'/'yellow' rather than 'gray'.";
392 out <<
"\n \t-otherwise the bin is 'green'" << std::endl;
393 out <<
"The algorithm checks all the bins in a window of size 'WindowSize', starting from:\n \t a) the last but X bin.\n \t b) the last non-zero bin.\n Oprion a) or b) is chosen by the parameter 'StartFromLast': if('StartFromLast'>=0), (a) holds and X is equal to 'StartFromLast', while (b) holds if 'StartFromLast'<0." << std::endl;
394 out <<
"In the window of interest, the number of red/yellow/gray bins is counted, respectively Nred/Nyellow/Ngray. The output is then defined comparing these numbers against the parameter 'NBins':\n \t- if Nred>=NBins: returns 'RED'.\n \t- else, if (Nred+Nyellow)>=NBins: returns 'YELLOW'.\n \t- else, if Ngray>=NBins: returns 'GREY'.\n \t- else returns 'GREEN'." << std::endl;
395 out <<
"NOTE: to avoid issues due to rounding in double precision, the equality between the bin content and any parameter is defined asking for the relative difference between the two to be smaller than a given parameter. I.e. content==Y is implemented as (abs(content-Y)/(content+Y))<epsilon. epsilon is equal to the parameter 'EqualityPrecision' which is tunable and set to 10^-4 by default\n"<<std::endl;
397 out<<
"Mandatory Parameter: HeightThreshold: sets the warning (yellowThreshold) and error (redThreshold) thresholds."<<std::endl;
398 out<<
"Optional Parameter: NBins: minimum number of red/(yellow+red)/gray bins in the window of interest for the algorithm to return Red/Yellow/Grey. Default is 1."<<std::endl;
399 out<<
"Optional Parameter: WindowSize: size of the x-axis range (in number of bins) in which red/yellow/gray bins are searched for. If WindowSize<=0, the whole istogram is searched for. Default is 1."<<std::endl;
400 out<<
"Optional Parameter: StartFromLast: if StartFromLast=X with X>=0, the algorithm will check the bins starting from the last but X bin. If StartFromLast<0, it will start from the first bin of nonzero content. Default is -1."<<std::endl;
401 out<<
"Optional Parameter: UndefinedStatus: a bin is defined to be 'gray' if its content is equal to UndefinedStatus. If not set, bins are not check against it."<<std::endl;
402 out<<
"Optional Parameter: EqualityPrecision: sets the precision with which the bin content is defined to be 'equal' to a parameter, as described above. Default is 10^-4."<<std::endl;