Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:09

0001 #ifndef DQMSERVICES_CORE_Q_CRITERION_H
0002 #define DQMSERVICES_CORE_Q_CRITERION_H
0003 
0004 #include "DQMServices/Core/interface/MonitorElement.h"
0005 #include "TProfile2D.h"
0006 #include "TProfile.h"
0007 #include "TH2F.h"
0008 #include "TH1F.h"
0009 #include <sstream>
0010 #include <string>
0011 #include <map>
0012 #include <utility>
0013 
0014 //#include "DQMServices/Core/interface/DQMStore.h"
0015 
0016 using DQMChannel = MonitorElementData::QReport::DQMChannel;
0017 using QReport = MonitorElementData::QReport;
0018 
0019 /** Base class for quality tests run on Monitoring Elements;
0020 
0021     Currently supporting the following tests:
0022     - Comparison to reference (Chi2, Kolmogorov)
0023     - Contents within [Xmin, Xmax]
0024     - Contents within [Ymin, Ymax]
0025     - Identical contents
0026     - Mean value within expected value
0027     - Check for dead or noisy channels
0028     - Check that mean, RMS of bins are within allowed range
0029     (support for 2D histograms, 1D, 2D profiles)  */
0030 
0031 class QCriterion {
0032   /// (class should be created by DQMStore class)
0033 
0034 public:
0035   typedef dqm::legacy::MonitorElement MonitorElement;
0036   /// get test status
0037   int getStatus() const { return status_; }
0038   /// get message attached to test
0039   std::string getMessage() const { return message_; }
0040   /// get name of quality test
0041   std::string getName() const { return qtname_; }
0042   /// get algorithm name
0043   std::string algoName() const { return algoName_; }
0044   /// set probability limit for warning and error (default: 90% and 50%)
0045   void setWarningProb(float prob) { warningProb_ = prob; }
0046   void setErrorProb(float prob) { errorProb_ = prob; }
0047   /// get vector of channels that failed test
0048   /// (not relevant for all quality tests!)
0049   virtual std::vector<DQMChannel> getBadChannels() const { return std::vector<DQMChannel>(); }
0050 
0051   QCriterion(std::string qtname) {
0052     qtname_ = std::move(qtname);
0053     init();
0054   }
0055   /// initialize values
0056   void init();
0057 
0058   virtual ~QCriterion() = default;
0059 
0060   /// default "probability" values for setting warnings & errors when running tests
0061   static const float WARNING_PROB_THRESHOLD;
0062   static const float ERROR_PROB_THRESHOLD;
0063 
0064   float runTest(const MonitorElement *me, QReport &qr, DQMNet::QValue &qv) {
0065     assert(qv.qtname == qtname_);
0066 
0067     prob_ = runTest(me);  // this runTest goes to SimpleTest derivates
0068 
0069     if (prob_ < errorProb_)
0070       status_ = dqm::qstatus::ERROR;
0071     else if (prob_ < warningProb_)
0072       status_ = dqm::qstatus::WARNING;
0073     else
0074       status_ = dqm::qstatus::STATUS_OK;
0075 
0076     setMessage();  // this goes to SimpleTest derivates
0077 
0078     if (verbose_ == 2)
0079       std::cout << " Message = " << message_ << std::endl;
0080     if (verbose_ == 2)
0081       std::cout << " Name = " << qtname_ << " / Algorithm = " << algoName_ << " / Status = " << status_
0082                 << " / Prob = " << prob_ << std::endl;
0083 
0084     qv.code = status_;
0085     qv.message = message_;
0086     qv.qtname = qtname_;
0087     qv.algorithm = algoName_;
0088     qv.qtresult = prob_;
0089     qr.setBadChannels(getBadChannels());
0090 
0091     return prob_;
0092   }
0093 
0094 protected:
0095   /// set algorithm name
0096   void setAlgoName(std::string name) { algoName_ = std::move(name); }
0097 
0098   virtual float runTest(const MonitorElement *me);
0099 
0100   /// set message after test has run
0101   virtual void setMessage() = 0;
0102 
0103   std::string qtname_;    /// name of quality test
0104   std::string algoName_;  /// name of algorithm
0105   float prob_;
0106   int status_;                     /// quality test status
0107   std::string message_;            /// message attached to test
0108   float warningProb_, errorProb_;  /// probability limits for warnings, errors
0109   void setVerbose(int verbose) { verbose_ = verbose; }
0110   int verbose_;
0111 
0112 private:
0113   /// for running the test
0114   friend class dqm::legacy::MonitorElement;
0115   friend class dqm::impl::MonitorElement;
0116 };
0117 
0118 //////////////////////////////////////////////////////////////////////
0119 //////////////////////////////////////////////////////////////////////
0120 //////////////////////////////////////////////////////////////////////
0121 
0122 class SimpleTest : public QCriterion {
0123 public:
0124   SimpleTest(const std::string &name, bool keepBadChannels = false)
0125       : QCriterion(name), minEntries_(0), keepBadChannels_(keepBadChannels) {}
0126 
0127   /// set minimum # of entries needed
0128   void setMinimumEntries(unsigned n) { minEntries_ = n; }
0129   /// get vector of channels that failed test (not always relevant!)
0130   std::vector<DQMChannel> getBadChannels() const override {
0131     return keepBadChannels_ ? badChannels_ : QCriterion::getBadChannels();
0132   }
0133 
0134 protected:
0135   /// set status & message after test has run
0136   void setMessage() override { message_.clear(); }
0137 
0138   unsigned minEntries_;  //< minimum # of entries needed
0139   std::vector<DQMChannel> badChannels_;
0140   bool keepBadChannels_;
0141 };
0142 
0143 //===============================================================//
0144 //========= Classes for particular QUALITY TESTS ================//
0145 //===============================================================//
0146 
0147 //==================== ContentsXRange =========================//
0148 //== Check that histogram contents are between [Xmin, Xmax] ==//
0149 class ContentsXRange : public SimpleTest {
0150 public:
0151   ContentsXRange(const std::string &name) : SimpleTest(name) {
0152     rangeInitialized_ = false;
0153     setAlgoName(getAlgoName());
0154   }
0155   static std::string getAlgoName() { return "ContentsXRange"; }
0156   float runTest(const MonitorElement *me) override;
0157 
0158   /// set allowed range in X-axis (default values: histogram's X-range)
0159   virtual void setAllowedXRange(double xmin, double xmax) {
0160     xmin_ = xmin;
0161     xmax_ = xmax;
0162     rangeInitialized_ = true;
0163   }
0164 
0165 protected:
0166   double xmin_;
0167   double xmax_;
0168   bool rangeInitialized_;
0169 };
0170 
0171 //==================== ContentsYRange =========================//
0172 //== Check that histogram contents are between [Ymin, Ymax] ==//
0173 class ContentsYRange : public SimpleTest {
0174 public:
0175   ContentsYRange(const std::string &name) : SimpleTest(name, true) {
0176     rangeInitialized_ = false;
0177     setAlgoName(getAlgoName());
0178   }
0179   static std::string getAlgoName() { return "ContentsYRange"; }
0180   float runTest(const MonitorElement *me) override;
0181 
0182   void setUseEmptyBins(unsigned int useEmptyBins) { useEmptyBins_ = useEmptyBins; }
0183   virtual void setAllowedYRange(double ymin, double ymax) {
0184     ymin_ = ymin;
0185     ymax_ = ymax;
0186     rangeInitialized_ = true;
0187   }
0188 
0189 protected:
0190   double ymin_;
0191   double ymax_;
0192   bool rangeInitialized_;
0193   unsigned int useEmptyBins_;
0194 };
0195 
0196 //============================== DeadChannel =================================//
0197 /// test that histogram contents are above Ymin
0198 class DeadChannel : public SimpleTest {
0199 public:
0200   DeadChannel(const std::string &name) : SimpleTest(name, true) {
0201     rangeInitialized_ = false;
0202     setAlgoName(getAlgoName());
0203   }
0204   static std::string getAlgoName() { return "DeadChannel"; }
0205   float runTest(const MonitorElement *me) override;
0206 
0207   /// set Ymin (inclusive) threshold for "dead" channel (default: 0)
0208   void setThreshold(double ymin) {
0209     ymin_ = ymin;
0210     rangeInitialized_ = true;
0211   }  /// ymin - threshold
0212 
0213 protected:
0214   double ymin_;
0215   bool rangeInitialized_;
0216 };
0217 
0218 //==================== NoisyChannel =========================//
0219 /// Check if any channels are noisy compared to neighboring ones.
0220 class NoisyChannel : public SimpleTest {
0221 public:
0222   NoisyChannel(const std::string &name) : SimpleTest(name, true) {
0223     rangeInitialized_ = false;
0224     numNeighbors_ = 1;
0225     setAlgoName(getAlgoName());
0226   }
0227   static std::string getAlgoName() { return "NoisyChannel"; }
0228   float runTest(const MonitorElement *me) override;
0229 
0230   /// set # of neighboring channels for calculating average to be used
0231   /// for comparison with channel under consideration;
0232   /// use 1 for considering bin+1 and bin-1 (default),
0233   /// use 2 for considering bin+1,bin-1, bin+2,bin-2, etc;
0234   /// Will use rollover when bin+i or bin-i is beyond histogram limits (e.g.
0235   /// for histogram with N bins, bin N+1 corresponds to bin 1,
0236   /// and bin -1 corresponds to bin N)
0237   void setNumNeighbors(unsigned n) {
0238     if (n > 0)
0239       numNeighbors_ = n;
0240   }
0241 
0242   /// set (percentage) tolerance for considering a channel noisy;
0243   /// eg. if tolerance = 20%, a channel will be noisy
0244   /// if (contents-average)/|average| > 20%; average is calculated from
0245   /// neighboring channels (also see method setNumNeighbors)
0246   void setTolerance(float percentage) {
0247     if (percentage >= 0) {
0248       tolerance_ = percentage;
0249       rangeInitialized_ = true;
0250     }
0251   }
0252 
0253 protected:
0254   /// get average for bin under consideration
0255   /// (see description of method setNumNeighbors)
0256   double getAverage(int bin, const TH1 *h) const;
0257   double getAverage2D(int binX, int binY, const TH2 *h) const;
0258 
0259   float tolerance_;       /*< tolerance for considering a channel noisy */
0260   unsigned numNeighbors_; /*< # of neighboring channels for calculating average to be used
0261                  for comparison with channel under consideration */
0262   bool rangeInitialized_; /*< init-flag for tolerance */
0263 };
0264 
0265 //===============ContentSigma (Emma Yeager and Chad Freer)=====================//
0266 /// Check the sigma of each bin against the rest of the chamber by a factor of tolerance/
0267 class ContentSigma : public SimpleTest {
0268 public:
0269   ContentSigma(const std::string &name) : SimpleTest(name, true) {
0270     rangeInitialized_ = false;
0271     numXblocks_ = 1;
0272     numYblocks_ = 1;
0273     numNeighborsX_ = 1;
0274     numNeighborsY_ = 1;
0275     setAlgoName(getAlgoName());
0276   }
0277   static std::string getAlgoName() { return "ContentSigma"; }
0278 
0279   float runTest(const MonitorElement *me) override;
0280   /// set # of neighboring channels for calculating average to be used
0281   /// for comparison with channel under consideration;
0282   /// use 1 for considering bin+1 and bin-1 (default),
0283   /// use 2 for considering bin+1,bin-1, bin+2,bin-2, etc;
0284   /// Will use rollover when bin+i or bin-i is beyond histogram limits (e.g.
0285   /// for histogram with N bins, bin N+1 corresponds to bin 1,
0286   /// and bin -1 corresponds to bin N)
0287   void setNumXblocks(unsigned ncx) {
0288     if (ncx > 0)
0289       numXblocks_ = ncx;
0290   }
0291   void setNumYblocks(unsigned ncy) {
0292     if (ncy > 0)
0293       numYblocks_ = ncy;
0294   }
0295   void setNumNeighborsX(unsigned ncx) {
0296     if (ncx > 0)
0297       numNeighborsX_ = ncx;
0298   }
0299   void setNumNeighborsY(unsigned ncy) {
0300     if (ncy > 0)
0301       numNeighborsY_ = ncy;
0302   }
0303 
0304   /// set factor tolerance for considering a channel noisy or dead;
0305   /// eg. if tolerance = 1, channel will be noisy if (content - 1 x sigma) > chamber_avg
0306   /// or channel will be dead if (content - 1 x sigma) < chamber_avg
0307   void setToleranceNoisy(float factorNoisy) {
0308     if (factorNoisy >= 0) {
0309       toleranceNoisy_ = factorNoisy;
0310       rangeInitialized_ = true;
0311     }
0312   }
0313   void setToleranceDead(float factorDead) {
0314     if (factorDead >= 0) {
0315       toleranceDead_ = factorDead;
0316       rangeInitialized_ = true;
0317     }
0318   }
0319   void setNoisy(bool noisy) { noisy_ = noisy; }
0320   void setDead(bool dead) { dead_ = dead; }
0321 
0322   void setXMin(unsigned xMin) { xMin_ = xMin; }
0323   void setXMax(unsigned xMax) { xMax_ = xMax; }
0324   void setYMin(unsigned yMin) { yMin_ = yMin; }
0325   void setYMax(unsigned yMax) { yMax_ = yMax; }
0326 
0327 protected:
0328   /// for each bin get sum of the surrounding neighbors
0329   // double getNeighborSum(int binX, int binY, unsigned Xblocks, unsigned Yblocks, unsigned neighborsX, unsigned neighborsY, const TH1 *h) const;
0330   double getNeighborSum(unsigned groupx,
0331                         unsigned groupy,
0332                         unsigned Xblocks,
0333                         unsigned Yblocks,
0334                         unsigned neighborsX,
0335                         unsigned neighborsY,
0336                         const TH1 *h) const;
0337   double getNeighborSigma(double average,
0338                           unsigned groupx,
0339                           unsigned groupy,
0340                           unsigned Xblocks,
0341                           unsigned Yblocks,
0342                           unsigned neighborsX,
0343                           unsigned neighborsY,
0344                           const TH1 *h) const;
0345 
0346   bool noisy_;
0347   bool dead_;            /*< declare if test will be checking for noisy channels, dead channels, or both */
0348   float toleranceNoisy_; /*< factor by which sigma is compared for noisy channels */
0349   float toleranceDead_;  /*< factor by which sigma is compared for dead channels*/
0350   unsigned numXblocks_;
0351   unsigned numYblocks_;
0352   unsigned numNeighborsX_; /*< # of neighboring channels along x-axis for calculating average to be used
0353                  for comparison with channel under consideration */
0354   unsigned numNeighborsY_; /*< # of neighboring channels along y-axis for calculating average to be used
0355                  for comparison with channel under consideration */
0356   bool rangeInitialized_;  /*< init-flag for tolerance */
0357   unsigned xMin_;
0358   unsigned xMax_;
0359   unsigned yMin_;
0360   unsigned yMax_;
0361 };
0362 
0363 //==================== ContentsWithinExpected  =========================//
0364 // Check that every TH2 channel has mean, RMS within allowed range.
0365 class ContentsWithinExpected : public SimpleTest {
0366 public:
0367   ContentsWithinExpected(const std::string &name) : SimpleTest(name, true) {
0368     checkMean_ = checkRMS_ = false;
0369     minMean_ = maxMean_ = minRMS_ = maxRMS_ = 0.0;
0370     checkMeanTolerance_ = false;
0371     toleranceMean_ = -1.0;
0372     setAlgoName(getAlgoName());
0373   }
0374   static std::string getAlgoName() { return "ContentsWithinExpected"; }
0375   float runTest(const MonitorElement *me) override;
0376 
0377   void setUseEmptyBins(unsigned int useEmptyBins) { useEmptyBins_ = useEmptyBins; }
0378   void setMeanRange(double xmin, double xmax);
0379   void setRMSRange(double xmin, double xmax);
0380 
0381   /// set (fractional) tolerance for mean
0382   void setMeanTolerance(float fracTolerance) {
0383     if (fracTolerance >= 0.0) {
0384       toleranceMean_ = fracTolerance;
0385       checkMeanTolerance_ = true;
0386     }
0387   }
0388 
0389 protected:
0390   bool checkMean_;           //< if true, check the mean value
0391   bool checkRMS_;            //< if true, check the RMS value
0392   bool checkMeanTolerance_;  //< if true, check mean tolerance
0393   float toleranceMean_;      //< fractional tolerance on mean (use only if checkMeanTolerance_ = true)
0394   float minMean_, maxMean_;  //< allowed range for mean (use only if checkMean_ = true)
0395   float minRMS_, maxRMS_;    //< allowed range for mean (use only if checkRMS_ = true)
0396   unsigned int useEmptyBins_;
0397 };
0398 
0399 //==================== MeanWithinExpected  =========================//
0400 /// Algorithm for testing if histogram's mean value is near expected value.
0401 class MeanWithinExpected : public SimpleTest {
0402 public:
0403   MeanWithinExpected(const std::string &name) : SimpleTest(name) { setAlgoName(getAlgoName()); }
0404   static std::string getAlgoName() { return "MeanWithinExpected"; }
0405   float runTest(const MonitorElement *me) override;
0406 
0407   void setExpectedMean(double mean) { expMean_ = mean; }
0408   void useRange(double xmin, double xmax);
0409   void useSigma(double expectedSigma);
0410   void useRMS();
0411 
0412 protected:
0413   bool useRMS_;         //< if true, will use RMS of distribution
0414   bool useSigma_;       //< if true, will use expected_sigma
0415   bool useRange_;       //< if true, will use allowed range
0416   double sigma_;        //< sigma to be used in probability calculation (use only if useSigma_ = true)
0417   double expMean_;      //< expected mean value (used only if useSigma_ = true or useRMS_ = true)
0418   double xmin_, xmax_;  //< allowed range for mean (use only if useRange_ = true)
0419 };
0420 
0421 //==================== AllContentWithinFixedRange   =========================//
0422 /*class AllContentWithinFixedRange : public SimpleTest
0423 {
0424 public:
0425   AllContentWithinFixedRange(const std::string &name) : SimpleTest(name)
0426   { 
0427     setAlgoName(getAlgoName()); 
0428   }
0429   static std::string getAlgoName(void) { return "RuleAllContentWithinFixedRange"; }
0430   float runTest(const MonitorElement *me);
0431 
0432   void set_x_min(double x)             { x_min  = x; }
0433   void set_x_max(double x)             { x_max  = x; }
0434   void set_epsilon_max(double epsilon) { epsilon_max = epsilon; }
0435   void set_S_fail(double S)        { S_fail = S; }
0436   void set_S_pass(double S)        { S_pass = S; }
0437   double get_epsilon_obs(void)         { return epsilon_obs; }
0438   double get_S_fail_obs(void)          { return S_fail_obs;  }
0439   double get_S_pass_obs(void)          { return S_pass_obs;  }
0440   int get_result(void)             { return result; }
0441 
0442 protected:
0443   TH1F *histogram ; //define Test histo
0444   double x_min, x_max;
0445   double epsilon_max;
0446   double S_fail, S_pass;
0447   double epsilon_obs;
0448   double S_fail_obs, S_pass_obs;
0449   int result;
0450 };
0451 */
0452 //==================== AllContentWithinFloatingRange  =========================//
0453 /*class AllContentWithinFloatingRange : public SimpleTest
0454 {
0455 public:
0456   AllContentWithinFloatingRange(const std::string &name) : SimpleTest(name)
0457   { 
0458     setAlgoName(getAlgoName()); 
0459   }
0460   static std::string getAlgoName(void) { return "RuleAllContentWithinFloatingRange"; }
0461 
0462   void set_Nrange(int N)               { Nrange = N; }
0463   void set_epsilon_max(double epsilon) { epsilon_max = epsilon; }
0464   void set_S_fail(double S)        { S_fail = S; }
0465   void set_S_pass(double S)        { S_pass = S; }
0466   double get_epsilon_obs(void)         { return epsilon_obs; }
0467   double get_S_fail_obs(void)          { return S_fail_obs;  }
0468   double get_S_pass_obs(void)          { return S_pass_obs;  }
0469   int get_result(void)             { return result; }
0470 
0471   float runTest(const MonitorElement *me );
0472 
0473 protected:
0474   TH1F *histogram ; //define Test histo
0475   int Nrange;
0476   double epsilon_max;
0477   double S_fail, S_pass;
0478   double epsilon_obs;
0479   double S_fail_obs, S_pass_obs;
0480   int result;
0481 };*/
0482 
0483 //==================== FlatOccupancy1d   =========================//
0484 #if 0  // FIXME: need to know what parameters to set before runTest!
0485 class FlatOccupancy1d : public SimpleTest
0486 {
0487 public:
0488   FlatOccupancy1d(const std::string &name) : SimpleTest(name)
0489   {
0490     Nbins = 0;
0491     FailedBins[0] = 0;
0492     FailedBins[1] = 0;
0493     setAlgoName(getAlgoName());
0494   }
0495 
0496   ~FlatOccupancy1d(void)
0497   {
0498     delete [] FailedBins[0];
0499     delete [] FailedBins[1];
0500   }
0501 
0502   static std::string getAlgoName(void) { return "RuleFlatOccupancy1d"; }
0503 
0504   void set_ExclusionMask(double *mask) { ExclusionMask = mask; }
0505   void set_epsilon_min(double epsilon) { epsilon_min = epsilon; }
0506   void set_epsilon_max(double epsilon) { epsilon_max = epsilon; }
0507   void set_S_fail(double S)            { S_fail = S; }
0508   void set_S_pass(double S)            { S_pass = S; }
0509   double get_FailedBins(void)          { return *FailedBins[1]; } // FIXME: WRONG! OFF BY ONE!?
0510   int get_result()                     { return result; }
0511 
0512   float runTest(const MonitorElement*me);
0513 
0514 protected:
0515   double *ExclusionMask;
0516   double epsilon_min, epsilon_max;
0517   double S_fail, S_pass;
0518   double *FailedBins[2];
0519   int    Nbins;
0520   int    result;
0521 };
0522 #endif
0523 
0524 //==================== FixedFlatOccupancy1d   =========================//
0525 class FixedFlatOccupancy1d : public SimpleTest {
0526 public:
0527   FixedFlatOccupancy1d(const std::string &name) : SimpleTest(name) {
0528     Nbins = 0;
0529     FailedBins[0] = nullptr;
0530     FailedBins[1] = nullptr;
0531     setAlgoName(getAlgoName());
0532   }
0533 
0534   ~FixedFlatOccupancy1d() override {
0535     if (Nbins > 0) {
0536       delete[] FailedBins[0];
0537       delete[] FailedBins[1];
0538     }
0539   }
0540 
0541   static std::string getAlgoName() { return "RuleFixedFlatOccupancy1d"; }
0542 
0543   void set_Occupancy(double level) { b = level; }
0544   void set_ExclusionMask(double *mask) { ExclusionMask = mask; }
0545   void set_epsilon_min(double epsilon) { epsilon_min = epsilon; }
0546   void set_epsilon_max(double epsilon) { epsilon_max = epsilon; }
0547   void set_S_fail(double S) { S_fail = S; }
0548   void set_S_pass(double S) { S_pass = S; }
0549   double get_FailedBins() { return *FailedBins[1]; }  // FIXME: WRONG! OFF BY ONE!?
0550   int get_result() { return result; }
0551 
0552   float runTest(const MonitorElement *me) override;
0553 
0554 protected:
0555   double b;
0556   double *ExclusionMask;
0557   double epsilon_min, epsilon_max;
0558   double S_fail, S_pass;
0559   double *FailedBins[2];
0560   int Nbins;
0561   int result;
0562 };
0563 
0564 //==================== CSC01   =========================//
0565 class CSC01 : public SimpleTest {
0566 public:
0567   CSC01(const std::string &name) : SimpleTest(name) { setAlgoName(getAlgoName()); }
0568   static std::string getAlgoName() { return "RuleCSC01"; }
0569 
0570   void set_epsilon_max(double epsilon) { epsilon_max = epsilon; }
0571   void set_S_fail(double S) { S_fail = S; }
0572   void set_S_pass(double S) { S_pass = S; }
0573   double get_epsilon_obs() { return epsilon_obs; }
0574   double get_S_fail_obs() { return S_fail_obs; }
0575   double get_S_pass_obs() { return S_pass_obs; }
0576   int get_result() { return result; }
0577 
0578   float runTest(const MonitorElement *me) override;
0579 
0580 protected:
0581   double epsilon_max;
0582   double S_fail, S_pass;
0583   double epsilon_obs;
0584   double S_fail_obs, S_pass_obs;
0585   int result;
0586 };
0587 
0588 //======================== CompareToMedian ====================//
0589 class CompareToMedian : public SimpleTest {
0590 public:
0591   //Initialize for TProfile, colRings
0592   CompareToMedian(const std::string &name) : SimpleTest(name, true) {
0593     this->_min = 0.2;
0594     this->_max = 3.0;
0595     this->_emptyBins = 0;
0596     this->_maxMed = 10;
0597     this->_minMed = 0;
0598     this->nBins = 0;
0599     this->_statCut = 0;
0600     reset();
0601     setAlgoName(getAlgoName());
0602   };
0603 
0604   ~CompareToMedian() override = default;
0605   ;
0606 
0607   static std::string getAlgoName() { return "CompareToMedian"; }
0608 
0609   float runTest(const MonitorElement *me) override;
0610   void setMin(float min) { _min = min; };
0611   void setMax(float max) { _max = max; };
0612   void setEmptyBins(int eB) { eB > 0 ? _emptyBins = 1 : _emptyBins = 0; };
0613   void setMaxMedian(float max) { _maxMed = max; };
0614   void setMinMedian(float min) { _minMed = min; };
0615   void setStatCut(float cut) { _statCut = (cut > 0) ? cut : 0; };
0616 
0617 protected:
0618   void setMessage() override {
0619     std::ostringstream message;
0620     message << "Test " << qtname_ << " (" << algoName_ << "): Entry fraction within range = " << prob_;
0621     message_ = message.str();
0622   }
0623 
0624 private:
0625   float _min, _max;        //Test values
0626   int _emptyBins;          //use empty bins
0627   float _maxMed, _minMed;  //Global max for median&mean
0628   float _statCut;          //Minimal number of non zero entries needed for the quality test
0629 
0630   int nBinsX, nBinsY;  //Dimensions of hystogram
0631 
0632   int nBins;  //Number of (non empty) bins
0633 
0634   //Vector contain bin values
0635   std::vector<float> binValues;
0636 
0637   void reset() { binValues.clear(); };
0638 };
0639 //======================== CompareLastFilledBin ====================//
0640 class CompareLastFilledBin : public SimpleTest {
0641 public:
0642   //Initialize for TProfile, colRings
0643   CompareLastFilledBin(const std::string &name) : SimpleTest(name, true) {
0644     this->_min = 0.0;
0645     this->_max = 1.0;
0646     this->_average = 0.0;
0647     setAlgoName(getAlgoName());
0648   };
0649 
0650   ~CompareLastFilledBin() override = default;
0651   ;
0652 
0653   static std::string getAlgoName() { return "CompareLastFilledBin"; }
0654 
0655   float runTest(const MonitorElement *me) override;
0656   void setAverage(float average) { _average = average; };
0657   void setMin(float min) { _min = min; };
0658   void setMax(float max) { _max = max; };
0659 
0660 protected:
0661   void setMessage() override {
0662     std::ostringstream message;
0663     message << "Test " << qtname_ << " (" << algoName_ << "): Last Bin filled with desired value = " << prob_;
0664     message_ = message.str();
0665   }
0666 
0667 private:
0668   float _min, _max;  //Test values
0669   float _average;
0670 };
0671 
0672 //==================== AllContentAlongDiagonal   =========================//
0673 #if 0  // FIXME: need to know what parameters to set before runTest!
0674 class AllContentAlongDiagonal : public SimpleTest
0675 
0676 public:
0677   AllContentAlongDiagonal(const std::string &name) : SimpleTest(name)
0678   { 
0679     setAlgoName(getAlgoName()); 
0680   }
0681   static std::string getAlgoName(void) { return "RuleAllContentAlongDiagonal"; }
0682 
0683   void set_epsilon_max(double epsilon) { epsilon_max = epsilon; }
0684   void set_S_fail(double S)        { S_fail = S; }
0685   void set_S_pass(double S)        { S_pass = S; } 
0686   double get_epsilon_obs()         { return epsilon_obs; }
0687   double get_S_fail_obs()          { return S_fail_obs;  }
0688   double get_S_pass_obs()          { return S_pass_obs;  }
0689   int get_result()             { return result; }
0690 
0691   //public:
0692   //using SimpleTest::runTest;
0693   float runTest(const MonitorElement*me); 
0694 
0695 protected:
0696   double epsilon_max;
0697   double S_fail, S_pass;
0698   double epsilon_obs;
0699   double S_fail_obs, S_pass_obs;
0700   int result;
0701 };
0702 #endif
0703 //==================== CheckVariance =========================//
0704 //== Check the variance of a TProfile//
0705 class CheckVariance : public SimpleTest {
0706 public:
0707   CheckVariance(const std::string &name) : SimpleTest(name) { setAlgoName(getAlgoName()); }
0708   /// get algorithm name
0709   static std::string getAlgoName() { return "CheckVariance"; }
0710   float runTest(const MonitorElement *me) override;
0711 };
0712 #endif  // DQMSERVICES_CORE_Q_CRITERION_H