diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinHeightThreshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeightThreshold.h
index 657044eb735069f1d6f4f4a410420fa097a1486c..19025fb2a2c2fc290ffcf7b6be5f5867be68827d 100644
--- a/DataQuality/dqm_algorithms/dqm_algorithms/BinHeightThreshold.h
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeightThreshold.h
@@ -17,16 +17,21 @@ namespace dqm_algorithms
 	struct BinHeightThreshold : public dqm_core::Algorithm
         {
 	  enum binStatus {aRedBin,aYellowBin,aGreenBin,anUndefBin=-1};
-	  BinHeightThreshold();
+	  BinHeightThreshold(const std::string & name);
 
 	    //overwrites virtual functions
 	  BinHeightThreshold * clone( );
 	  dqm_core::Result * execute( const std::string & , const TObject & , const dqm_core::AlgorithmConfig & );
-          BinHeightThreshold::binStatus CompareBinHeightThreshold(double bincontent, double thresholdGr, double thresholdRed);
+	  void CheckThresholds(const std::string & type, double thresholdGr, double thresholdRed);
+	  bool checkUndefinedStatusValue(const std::string & type,double thresholdGr, double thresholdRed,std::pair<bool,double> valueGray);
+          BinHeightThreshold::binStatus CompareBinHeightThreshold(const std::string & type, double bincontent, double thresholdGr, double thresholdRed,std::pair<bool,double> valueGray);
+	  bool equalWithinPrecision(double a,double b);
           using dqm_core::Algorithm::printDescription;
 	  void  printDescription(std::ostream& out);
  
 	  private:
+	  std::string name_;
+	  double precision_;
 	};
 }
 
diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_Equal_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_Equal_Threshold.h
new file mode 100644
index 0000000000000000000000000000000000000000..f43745468ba15c1a8394171ab56ab62e166afb9a
--- /dev/null
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_Equal_Threshold.h
@@ -0,0 +1,24 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*! \file BinHeight_Equal_Threshold.h file declares the dqm_algorithms::BinHeight_Equal_Threshold  class.
+ * \author Margherita Spalla, following what's done in BinsGreaterThanThreshold.h
+*/
+
+#ifndef DQM_ALGORITHMS_BINHEIGHT_EQUAL_THRESHOLD_H
+#define DQM_ALGORITHMS_BINHEIGHT_EQUAL_THRESHOLD_H
+
+#include <dqm_core/Algorithm.h>
+#include <dqm_algorithms/BinHeightThreshold.h>
+
+namespace dqm_algorithms
+{
+	struct BinHeight_Equal_Threshold : public BinHeightThreshold
+        {
+	  BinHeight_Equal_Threshold(): BinHeightThreshold("Equal") {};
+
+	};
+}
+
+#endif // DQM_ALGORITHMS_BINHEIGHT_EQUAL_THRESHOLD_H
diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_GreaterThanEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_GreaterThanEqual_Threshold.h
new file mode 100644
index 0000000000000000000000000000000000000000..7dc34f8373bfc92531210735acf26e98c14bf65a
--- /dev/null
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_GreaterThanEqual_Threshold.h
@@ -0,0 +1,24 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*! \file BinHeight_GreaterThanEqual_Threshold.h file declares the dqm_algorithms::BinHeight_GreaterThanEqual_Threshold  class.
+ * \author Margherita Spalla, following what's done in BinsGreaterThanThreshold.h
+*/
+
+#ifndef DQM_ALGORITHMS_BINHEIGHT_GREATERTHANEQUAL_THRESHOLD_H
+#define DQM_ALGORITHMS_BINHEIGHT_GREATERTHANEQUAL_THRESHOLD_H
+
+#include <dqm_core/Algorithm.h>
+#include <dqm_algorithms/BinHeightThreshold.h>
+
+namespace dqm_algorithms
+{
+	struct BinHeight_GreaterThanEqual_Threshold : public BinHeightThreshold
+        {
+	  BinHeight_GreaterThanEqual_Threshold(): BinHeightThreshold("GreaterThanEqual") {};
+
+	};
+}
+
+#endif // DQM_ALGORITHMS_BINHEIGHT_GREATERTHANEQUAL_THRESHOLD_H
diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_GreaterThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_GreaterThan_Threshold.h
new file mode 100644
index 0000000000000000000000000000000000000000..49ec7f1afa1b233b247dbcde8ee135747dcff948
--- /dev/null
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_GreaterThan_Threshold.h
@@ -0,0 +1,24 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*! \file BinHeight_GreaterThan_Threshold.h file declares the dqm_algorithms::BinHeight_GreaterThan_Threshold  class.
+ * \author Margherita Spalla, following what's done in BinsGreaterThanThreshold.h
+*/
+
+#ifndef DQM_ALGORITHMS_BINHEIGHT_GREATERTHAN_THRESHOLD_H
+#define DQM_ALGORITHMS_BINHEIGHT_GREATERTHAN_THRESHOLD_H
+
+#include <dqm_core/Algorithm.h>
+#include <dqm_algorithms/BinHeightThreshold.h>
+
+namespace dqm_algorithms
+{
+	struct BinHeight_GreaterThan_Threshold : public BinHeightThreshold
+        {
+	  BinHeight_GreaterThan_Threshold(): BinHeightThreshold("GreaterThan") {};
+
+	};
+}
+
+#endif // DQM_ALGORITHMS_BINHEIGHT_GREATERTHAN_THRESHOLD_H
diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_LessThanEqual_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_LessThanEqual_Threshold.h
new file mode 100644
index 0000000000000000000000000000000000000000..85bd1cf9de9150c0475735aad357480e71c53b3e
--- /dev/null
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_LessThanEqual_Threshold.h
@@ -0,0 +1,24 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*! \file BinHeight_LessThanEqual_Threshold.h file declares the dqm_algorithms::BinHeight_LessThanEqual_Threshold  class.
+ * \author Margherita Spalla, following what's done in BinsGreaterThanThreshold.h
+*/
+
+#ifndef DQM_ALGORITHMS_BINHEIGHT_LESSTHANEQUAL_THRESHOLD_H
+#define DQM_ALGORITHMS_BINHEIGHT_LESSTHANEQUAL_THRESHOLD_H
+
+#include <dqm_core/Algorithm.h>
+#include <dqm_algorithms/BinHeightThreshold.h>
+
+namespace dqm_algorithms
+{
+	struct BinHeight_LessThanEqual_Threshold : public BinHeightThreshold
+        {
+	  BinHeight_LessThanEqual_Threshold(): BinHeightThreshold("LessThanEqual") {};
+
+	};
+}
+
+#endif // DQM_ALGORITHMS_BINHEIGHT_LESSTHANEQUAL_THRESHOLD_H
diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_LessThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_LessThan_Threshold.h
new file mode 100644
index 0000000000000000000000000000000000000000..f2b91defb893feea15e368f836296d540eabfbeb
--- /dev/null
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_LessThan_Threshold.h
@@ -0,0 +1,24 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*! \file BinHeight_LessThan_Threshold.h file declares the dqm_algorithms::BinHeight_LessThan_Threshold  class.
+ * \author Margherita Spalla, following what's done in BinsGreaterThanThreshold.h
+*/
+
+#ifndef DQM_ALGORITHMS_BINHEIGHT_LESSTHAN_THRESHOLD_H
+#define DQM_ALGORITHMS_BINHEIGHT_LESSTHAN_THRESHOLD_H
+
+#include <dqm_core/Algorithm.h>
+#include <dqm_algorithms/BinHeightThreshold.h>
+
+namespace dqm_algorithms
+{
+	struct BinHeight_LessThan_Threshold : public BinHeightThreshold
+        {
+	  BinHeight_LessThan_Threshold(): BinHeightThreshold("LessThan") {};
+
+	};
+}
+
+#endif // DQM_ALGORITHMS_BINHEIGHT_LESSTHAN_THRESHOLD_H
diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_redEqual_yellowGreaterThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_redEqual_yellowGreaterThan_Threshold.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed405ab8056e50fdb4d31f46e01a0e4c30a5c480
--- /dev/null
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_redEqual_yellowGreaterThan_Threshold.h
@@ -0,0 +1,24 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*! \file BinHeight_redEqual_yellowGreaterThan_Threshold.h file declares the dqm_algorithms::BinHeight_redEqual_yellowGreaterThan_Threshold  class.
+ * \author Margherita Spalla, following what's done in BinsGreaterThanThreshold.h
+*/
+
+#ifndef DQM_ALGORITHMS_BINHEIGHT_REDEQ_YELLOWGT_THRESHOLD_H
+#define DQM_ALGORITHMS_BINHEIGHT_REDEQ_YELLOWGT_THRESHOLD_H
+
+#include <dqm_core/Algorithm.h>
+#include <dqm_algorithms/BinHeightThreshold.h>
+
+namespace dqm_algorithms
+{
+	struct BinHeight_redEqual_yellowGreaterThan_Threshold : public BinHeightThreshold
+        {
+	  BinHeight_redEqual_yellowGreaterThan_Threshold(): BinHeightThreshold("redEqual_yellowGreaterThan") {};
+
+	};
+}
+
+#endif // DQM_ALGORITHMS_BINHEIGHT_REDEQ_YELLOWGT_THRESHOLD_H
diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_redEqual_yellowLessThan_Threshold.h b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_redEqual_yellowLessThan_Threshold.h
new file mode 100644
index 0000000000000000000000000000000000000000..79f691ee27fbbd2f386bf2ab961c598065e6877a
--- /dev/null
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/BinHeight_redEqual_yellowLessThan_Threshold.h
@@ -0,0 +1,24 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+/*! \file BinHeight_redEqual_yellowLessThan_Threshold.h file declares the dqm_algorithms::BinHeight_redEqual_yellowLessThan_Threshold  class.
+ * \author Margherita Spalla, following what's done in BinsGreaterThanThreshold.h
+*/
+
+#ifndef DQM_ALGORITHMS_BINHEIGHT_REDEQ_YELLOWLT_THRESHOLD_H
+#define DQM_ALGORITHMS_BINHEIGHT_REDEQ_YELLOWLT_THRESHOLD_H
+
+#include <dqm_core/Algorithm.h>
+#include <dqm_algorithms/BinHeightThreshold.h>
+
+namespace dqm_algorithms
+{
+	struct BinHeight_redEqual_yellowLessThan_Threshold : public BinHeightThreshold
+        {
+	  BinHeight_redEqual_yellowLessThan_Threshold(): BinHeightThreshold("redEqual_yellowLessThan") {};
+
+	};
+}
+
+#endif // DQM_ALGORITHMS_BINHEIGHT_REDEQ_YELLOWLT_THRESHOLD_H
diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/dqm_algorithmsDict.h b/DataQuality/dqm_algorithms/dqm_algorithms/dqm_algorithmsDict.h
index 360f58e51b45e62cef8a858a063f6af37c82f9b3..515b906b61f1db7025e7964491d5d93d62556172 100644
--- a/DataQuality/dqm_algorithms/dqm_algorithms/dqm_algorithmsDict.h
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/dqm_algorithmsDict.h
@@ -31,6 +31,13 @@
 #include "dqm_algorithms/BinThresh.h"
 #include "dqm_algorithms/BinThreshold.h"
 #include "dqm_algorithms/BinHeightThreshold.h"
+#include "dqm_algorithms/BinHeight_GreaterThan_Threshold.h"
+#include "dqm_algorithms/BinHeight_GreaterThanEqual_Threshold.h"
+#include "dqm_algorithms/BinHeight_LessThan_Threshold.h"
+#include "dqm_algorithms/BinHeight_LessThanEqual_Threshold.h"
+#include "dqm_algorithms/BinHeight_redEqual_yellowGreaterThan_Threshold.h"
+#include "dqm_algorithms/BinHeight_redEqual_yellowLessThan_Threshold.h"
+#include "dqm_algorithms/BinHeight_Equal_Threshold.h"
 #include "dqm_algorithms/BinsDiffByStrips.h"
 #include "dqm_algorithms/BinsDiffFromStripMedian.h"
 #include "dqm_algorithms/BinsDiffFromStripMedianOnline.h"
diff --git a/DataQuality/dqm_algorithms/dqm_algorithms/selection.xml b/DataQuality/dqm_algorithms/dqm_algorithms/selection.xml
index 4eaa329fe533e9f6ee23f5d09291453ec37c1589..64d3b1fc0682ddc5c006c6f5f7ccbe480aa9fd8c 100644
--- a/DataQuality/dqm_algorithms/dqm_algorithms/selection.xml
+++ b/DataQuality/dqm_algorithms/dqm_algorithms/selection.xml
@@ -26,6 +26,13 @@
   <class name="dqm_algorithms::BinThresh"/>
   <class name="dqm_algorithms::BinThreshold"/>
   <class name="dqm_algorithms::BinHeightThreshold"/>
+  <class name="dqm_algorithms::BinHeight_GreaterThan_Threshold"/>
+  <class name="dqm_algorithms::BinHeight_GreaterThanEqual_Threshold"/>
+  <class name="dqm_algorithms::BinHeight_LessThan_Threshold"/>
+  <class name="dqm_algorithms::BinHeight_LessThanEqual_Threshold"/>
+  <class name="dqm_algorithms::BinHeight_redEqual_yellowGreaterThan_Threshold"/>
+  <class name="dqm_algorithms::BinHeight_redEqual_yellowLessThan_Threshold"/>
+  <class name="dqm_algorithms::BinHeight_Equal_Threshold"/>
   <class name="dqm_algorithms::BinsDiffByStrips"/>
   <class name="dqm_algorithms::BinsDiffFromStripMedian"/>
   <class name="dqm_algorithms::BinsDiffFromStripMedianOnline"/>
diff --git a/DataQuality/dqm_algorithms/src/BinHeightThreshold.cxx b/DataQuality/dqm_algorithms/src/BinHeightThreshold.cxx
index de7df11c5a43793f3745b73de467535d92711011..b1e3401bd868bb0d8a00a462c4a4c2fac7e9e4dd 100644
--- a/DataQuality/dqm_algorithms/src/BinHeightThreshold.cxx
+++ b/DataQuality/dqm_algorithms/src/BinHeightThreshold.cxx
@@ -19,17 +19,29 @@
 #include <dqm_core/AlgorithmManager.h>
 
 
+//static dqm_algorithms::BinHeightThreshold myInstance;
+namespace
+{
+  dqm_algorithms::BinHeightThreshold HeightGreaterThan( "GreaterThan" );
+  dqm_algorithms::BinHeightThreshold HeightGreaterThanEqual( "GreaterThanEqual" );
+  dqm_algorithms::BinHeightThreshold HeightLessThan( "LessThan" );
+  dqm_algorithms::BinHeightThreshold HeightLessThanEqual( "LessThanEqual" );
+  dqm_algorithms::BinHeightThreshold HeightRedEqYellowGT( "redEqual_yellowGreaterThan" );
+  dqm_algorithms::BinHeightThreshold HeightRedEqYellowLT( "redEqual_yellowLessThan" );
+  dqm_algorithms::BinHeightThreshold HeightEqual( "Equal" );
+}
 
-dqm_algorithms::BinHeightThreshold::BinHeightThreshold()
+dqm_algorithms::BinHeightThreshold::BinHeightThreshold( const std::string & name )
+  : name_( name )
 {
-  dqm_core::AlgorithmManager::instance().registerAlgorithm("BinHeightThreshold", this);
+  precision_=1e-4;
+  dqm_core::AlgorithmManager::instance().registerAlgorithm("BinHeight_"+name+"_Threshold", this);
 }
 
 dqm_algorithms::BinHeightThreshold * 
 dqm_algorithms::BinHeightThreshold::clone()
-{
-  
-  return new BinHeightThreshold();
+{  
+  return new BinHeightThreshold(name_);
 }
 
 
@@ -49,24 +61,64 @@ dqm_algorithms::BinHeightThreshold::execute(	const std::string &  name,
   }
   const double minstat = 1;
   if (histogram->GetEntries() < minstat ) {
+    ERS_INFO( "Too few entries: " << histogram->GetEntries() );
     dqm_core::Result *result = new dqm_core::Result(dqm_core::Result::Undefined);
     result->tags_["InsufficientEntries"] = histogram->GetEntries();
     return result;
   }
 
-  double bin_threshold_red;
-  double bin_threshold_yellow; 
+  int start_from_last;
+  int n_bins;
+  int window_size; 
   double gthreshold;
   double rthreshold;
+  std::pair<bool,double> grayValue;
   try {
-    bin_threshold_yellow = dqm_algorithms::tools::GetFirstFromMap( "NBins", config.getParameters() );
-    bin_threshold_red = dqm_algorithms::tools::GetFirstFromMap( "NRedBins", config.getParameters() ,bin_threshold_yellow); //with this method, bin_threshold_red should be set ==bin_threshold_yellow if a 'NRedBins' option is not provided
-    rthreshold = dqm_algorithms::tools::GetFromMap( "RedThreshold", config.getRedThresholds() );
-    gthreshold = dqm_algorithms::tools::GetFromMap( "GreenThreshold", config.getGreenThresholds() );
+    n_bins = dqm_algorithms::tools::GetFirstFromMap( "NBins", config.getParameters() ,1);
+    window_size = dqm_algorithms::tools::GetFirstFromMap( "WindowSize", config.getParameters() ,1); 
+    start_from_last = dqm_algorithms::tools::GetFirstFromMap( "StartFromLast", config.getParameters() ,-1); 
+    gthreshold = dqm_algorithms::tools::GetFromMap( "HeightThreshold", config.getGreenThresholds() );
+    rthreshold = dqm_algorithms::tools::GetFromMap( "HeightThreshold", config.getRedThresholds() );
   }
   catch ( dqm_core::Exception & ex ) {
     throw dqm_core::BadConfig( ERS_HERE, name, ex.what(), ex );
   }
+  grayValue.first=true;
+  try {
+    grayValue.second = dqm_algorithms::tools::GetFirstFromMap( "UndefinedStatus", config.getParameters() );
+  }
+  catch ( dqm_core::Exception & ex ) {
+    grayValue.first=false;
+    grayValue.second=-1;
+  }
+  try {
+    precision_ = dqm_algorithms::tools::GetFirstFromMap( "EqualityPrecision", config.getParameters(),1e-4);
+  }
+  catch ( dqm_core::Exception & ex ) {
+    precision_=1e-4;
+  }
+
+
+  //check if the provided parameter values make sense
+  if(precision_<0) {
+    ERS_INFO("'EqualityPrecision cannot be negative: it will be re-set to its absolute value.");
+    precision_=fabs(precision_);
+  }
+  if(window_size<=0) {
+      ERS_INFO("You set search window size (WindowSize) <= 0: I will search the whole histogram.");
+    }
+  else {
+    if(n_bins>window_size) {
+      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.");
+      n_bins=window_size;
+    }
+  }
+  if(n_bins<=0)  {
+    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).");
+    n_bins=1;
+  }
+  CheckThresholds(name_,gthreshold,rthreshold);
+  grayValue.first=checkUndefinedStatusValue(name_,gthreshold,rthreshold,grayValue);
 
   dqm_core::Result* result = new dqm_core::Result();
   TH1* resulthisto;
@@ -80,63 +132,73 @@ dqm_algorithms::BinHeightThreshold::execute(	const std::string &  name,
  
   resulthisto->Reset();
 
-  int countConsec=0;
-  //first, look for the last filled LB, i.e. the bin with nonzero content of largest x
+
+  //first, look for the last filled LB, i.e. the bin with nonzero content of largest x if start_from_last<0, if start_from_last>=0, then starts from last but N-th bin, where N=start_from_last
   int i_currentLB=histogram->GetNbinsX();
-  while(i_currentLB>=1)
+  if(start_from_last>=0)
+    i_currentLB-=start_from_last;
+  else
     {
-      if(histogram->GetBinContent(i_currentLB)!=0) break;
-      i_currentLB--;
+      while(i_currentLB>=1)
+	{
+	  if(histogram->GetBinContent(i_currentLB)!=0) break;
+	  i_currentLB--;
+	}
     }
-  //if the histogram is just empty, do nothing (check already done, in principle should not happen)
-   if(i_currentLB<=0)
+  //if the histogram is just empty, or still has too few bins, do nothing 
+   if(i_currentLB<=0 || i_currentLB<n_bins)
     {
-     ERS_DEBUG(1,"Histogram is empty");
+     ERS_DEBUG(1,"start_from_last parameter >= total number of bins, I just cannot do the check. Do nothing.");
      return result;
     }
-   //check current LB
-   double currentLBcont= histogram -> GetBinContent(i_currentLB);
-   dqm_algorithms::BinHeightThreshold::binStatus currentLBstatus=CompareBinHeightThreshold(currentLBcont, gthreshold , rthreshold);
-//if current LB is not green, check the number of consecutive non-green bins
-   if(currentLBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin || currentLBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aRedBin) 
-    {
+
+   //now loop over an x window of size 'window_size'
     int iLB=i_currentLB;
-    double content;
-    dqm_algorithms::BinHeightThreshold::binStatus LBstatus;
-    while(iLB>=1)
+    int countYellow=0;
+    int countRed=0;
+    int countGray=0;
+    while(iLB>=1 && (window_size<0 || (i_currentLB-iLB)<window_size))
        {
-	content=histogram->GetBinContent(iLB);
-	LBstatus=CompareBinHeightThreshold(content, gthreshold , rthreshold);
-	if(LBstatus==currentLBstatus) 
+	double content=histogram->GetBinContent(iLB);
+	dqm_algorithms::BinHeightThreshold::binStatus LBstatus=CompareBinHeightThreshold(name_,content, gthreshold , rthreshold,grayValue);
+	if(LBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin) 
 	{
-	  countConsec++;
- 	//fill result histogram
-          resulthisto->SetBinContent(iLB,content);
+	  countYellow++;
    	}
-	else break;
+	if(LBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aRedBin) 
+	{
+	  countRed++;
+   	}
+	if(LBstatus==dqm_algorithms::BinHeightThreshold::binStatus::anUndefBin) 
+	{
+	  countGray++;
+   	}
+ 	//fill result histogram
+	resulthisto->SetBinContent(iLB,content);
 	iLB--;
        }
-    }
+
        
-    std::string thrName="RED/YELLOW";
-    if(currentLBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin) thrName="YELLOW";
-    if(currentLBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aRedBin) thrName="RED";
-    ERS_DEBUG(1,"Found " << countConsec << " consecutive " << thrName << " bins");
-    ERS_DEBUG(1,"Min. # of consecutive red bins for returning Red: " << bin_threshold_red);
-    ERS_DEBUG(1,"Min. # of consecutive yellow bins for returning Yellow: " << bin_threshold_yellow);
+    ERS_DEBUG(1,"Found " << countRed << " red bins and " << countYellow << " red bins. In a window of size " << window_size << " bins, starting at bin " << i_currentLB);
+    ERS_DEBUG(1,"To be compared with: " << n_bins);
     ERS_DEBUG(1,"Green treshold=" << gthreshold << " Red threshold=" << rthreshold );
 
-  result->tags_["NBins"] = countConsec;
+  result->tags_["NRedBins"] = countRed;
+  result->tags_["NYellowBins"] = countYellow;
   result->object_ =  (std::auto_ptr<TObject>)(TObject*)(resulthisto);
-  if(currentLBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aRedBin && countConsec>=bin_threshold_red) 
+  if(countRed>=n_bins)
     {
       result->status_ = dqm_core::Result::Red;
     } 
-  else if(currentLBstatus==dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin && countConsec>=bin_threshold_yellow) 
+  else if(countRed+countYellow>=n_bins)
     {
       result->status_ = dqm_core::Result::Yellow;
     } 
-  else 
+  else if(countGray>=n_bins)
+    {
+      result->status_ = dqm_core::Result::Undefined;
+    }
+  else
     {
       result->status_ = dqm_core::Result::Green;
     }
@@ -145,37 +207,197 @@ dqm_algorithms::BinHeightThreshold::execute(	const std::string &  name,
   
 }
 
+
+void dqm_algorithms::BinHeightThreshold::CheckThresholds(const std::string & type, double thresholdGr, double thresholdRed) {
+  if(type=="GreaterThan" || type=="GreaterThanEqual")
+    {
+      if(thresholdGr>=thresholdRed)
+	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'.");
+    }
+  if(type=="LessThan" || type=="LessThanEqual")
+    {
+      if(thresholdGr<=thresholdRed)
+	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?");
+    }
+  if(type=="redEqual_yellowGreaterThan")
+    {
+      if(thresholdRed>0 && thresholdRed<thresholdGr)
+	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?");
+    }
+  if(type=="redEqual_yellowLessThan")
+    {
+      if(thresholdRed>thresholdGr)
+	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?");
+    }
+}
+
+bool 
+dqm_algorithms::BinHeightThreshold::checkUndefinedStatusValue(const std::string & type,double thresholdGr, double thresholdRed,std::pair<bool,double> valueGray) {
+  if(!valueGray.first)
+    return valueGray.first;
+    
+  if(type=="LessThan" || type=="GreaterThan")
+    return valueGray.first;
+
+  if(equalWithinPrecision(valueGray.second,thresholdRed))
+    {
+      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'");
+      return false;
+    }
+    
+  if(type!="redEqual_yellowLessThan" && type!="redEqual_yellowGreaterThan" && equalWithinPrecision(valueGray.second,thresholdGr))
+    {
+      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'");
+      return false;
+    }
+
+  return valueGray.first;
+}
+
+
+
 dqm_algorithms::BinHeightThreshold::binStatus
-dqm_algorithms::BinHeightThreshold::CompareBinHeightThreshold(double bincontent, double thresholdGr, double thresholdRed) {
-if(thresholdRed!=-1)
-  {
-    if(bincontent>=thresholdRed)
+dqm_algorithms::BinHeightThreshold::CompareBinHeightThreshold(const std::string & type,double bincontent, double thresholdGr, double thresholdRed,std::pair<bool,double> valueGray) {
+  if(valueGray.first)
+    {
+      if(equalWithinPrecision(bincontent,valueGray.second))
+	{
+	  return dqm_algorithms::BinHeightThreshold::binStatus::anUndefBin;
+	}
+    }
+
+  if(type=="GreaterThan")
+    {
+      if(bincontent>thresholdRed)
 	return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
-    if(bincontent>=thresholdGr)
+      if(bincontent>thresholdGr)
 	return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;  
-    return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
-  }
-else
-  {
-    if(bincontent==thresholdRed)
-       return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
-    if(bincontent==thresholdGr)
-        return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
-    if(bincontent>thresholdGr) 
-      return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
-    return dqm_algorithms::BinHeightThreshold::binStatus::anUndefBin;
-  }
+      return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
+    }
+  if(type=="LessThan")
+    {
+      if(bincontent<thresholdRed)
+	return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
+      if(bincontent<thresholdGr)
+	return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;  
+      return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
+    }
+  if(type=="GreaterThanEqual")
+    {
+      if(bincontent>thresholdRed || equalWithinPrecision(bincontent,thresholdRed))
+	return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
+      if(bincontent>thresholdGr || equalWithinPrecision(bincontent,thresholdGr))
+	return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;  
+      return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
+    }
+  if(type=="LessThanEqual")
+    {
+      if(bincontent<thresholdRed || equalWithinPrecision(bincontent,thresholdRed))
+	return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
+      if(bincontent<thresholdGr || equalWithinPrecision(bincontent,thresholdGr))
+	return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;  
+      return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
+    }
+  if(type=="redEqual_yellowGreaterThan")
+    {
+      if(equalWithinPrecision(bincontent,thresholdRed))
+	return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
+      if(bincontent>thresholdGr) 
+	return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
+      return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
+    }
+  if(type=="redEqual_yellowLessThan")
+    {
+      if(equalWithinPrecision(bincontent,thresholdRed))
+	return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
+      if(bincontent<thresholdGr) 
+	return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
+      return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
+    }
+  if(type=="Equal")
+    {
+      if(equalWithinPrecision(bincontent,thresholdRed))
+	return dqm_algorithms::BinHeightThreshold::binStatus::aRedBin;
+      if(equalWithinPrecision(bincontent,thresholdGr)) 
+	return dqm_algorithms::BinHeightThreshold::binStatus::aYellowBin;
+      return dqm_algorithms::BinHeightThreshold::binStatus::aGreenBin;
+    }
+  return dqm_algorithms::BinHeightThreshold::binStatus::anUndefBin;
 }
 
 
+bool 
+dqm_algorithms::BinHeightThreshold::equalWithinPrecision(double a,double b)
+{
+  //relative difference method (following what suggested in (non-ATLAS) web page http://floating-point-gui.de/errors/comparison/)
+  double absA = fabs(a);
+  double absB = fabs(b);
+  double diff = fabs(a - b);
+
+  if (a == b) { // shortcut, handles infinities
+    return true;
+  } 
+  else if (a == 0 || b == 0 || diff < DBL_MIN) {
+    // a or b is zero or both are extremely close to it
+    // relative error is less meaningful here
+    return diff < (precision_ * DBL_MIN);
+  } 
+  else { // use relative error
+    return (diff / std::min((absA + absB), DBL_MAX)) < precision_;
+  }
+}
+
 void
 dqm_algorithms::BinHeightThreshold::printDescription(std::ostream& out)
 {
-  out<<"BinHeightThreshold is built to monitor trigger pre-scale (PS) as a function of lumi-block (LB). It only works with TH1 as input. LB is expected to be on x axis, PS is the bin content. It defines 'red' and 'yellow' bins depending on the value of the bin content. The algorithm looks for a set of consecutive bins which:\n \t-include the current LB (i.e. the nonzero bin at largest x).\n \t-are all 'red' or all 'yellow'.\n If the bin set is found and it is longer than Nbins, then the algorithm returns 'Red' for a set of 'red' bins, 'Yellow' for a set of 'yellow' bins.\n"<<std::endl;
-  out<<"Mandatory Parameter: NBins: number of consecutive red(yellow) bins over which the algorithm returns Red(Yellow).\n"<<std::endl;
-  out<<"Optional Parameter: NRedBins: if set, replace NBins in the case of a set of red bins. To be used if different thresholds are desired for red and yellow bin sets.\n"<<std::endl;
-  out<<"Mandatory Parameter: RedThreshold: used in defining 'red'/'yellow'/'green' bins (see the following).\n"<<std::endl; 
-  out<<"Mandatory Parameter: GreenThreshold: used in defining 'red'/'yellow'/'green' bins (see the following).\n"<<std::endl;
-  out<<"'red'/'yellow'/'green' bins are defined depending on the RedThreshold and GreenThreshold parameters.\n If RedThreshold==-1:\n \t BinContent==RedThreshold --> red bin (i.e. trigger disabled)\n \t BinContent==GreenThreshold --> green bin\n \t BinContent>GreenThreshold --> yellow bin (i.e. trigger pre-scaled). \n If RedThreshold>0:\n \t BinContent<GreenThreshold --> green bin\n \t GreenThreshold<=BinContent<RedThreshold --> yellow bin\n \t BinContent>=RedThreshold --> red bin\n"<<std::endl; 
+  TString redCond,yellowCond;
+  if(name_=="redEqual_yellowGreaterThan" || name_=="redEqual_yellowLessThan" || name_=="Equal")
+    {
+      redCond="bin_content==redThreshold";
+      if(name_=="Equal")
+	yellowCond="bin_content==yellowThreshold && bin_content!=redThreshold";
+      else if(name_=="redEqual_yellowGreaterThan")
+	yellowCond="bin_content>yellowThreshold && bin_content!=redThreshold";
+      else
+	yellowCond="bin_content<yellowThreshold && bin_content!=redThreshold";
+    }
+  else
+    {
+      if(name_=="GreaterThan")
+	{
+	  redCond="bin_content>redThreshold";
+	  yellowCond="redThreshold>=bin_content>yellowThreshold";
+	}
+      else if(name_=="LessThan")
+	{
+	  redCond="bin_content<redThreshold";
+	  yellowCond="redThreshold<=bin_content<yellowThreshold";
+	}
+      else if(name_=="GreaterThanEqual")
+	{
+	  redCond="bin_content>=redThreshold";
+	  yellowCond="redThreshold>bin_content>=yellowThreshold";
+	}
+      else //LessThenEqual is the only remaining
+	{
+	  redCond="bin_content<=redThreshold";
+	  yellowCond="redThreshold<bin_content<=yellowThreshold";
+	}
+    }
+  out << "BinHeight_" << 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;
+  out << "BinHeight_" << 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'.";
+  if(name_!="GreaterThan" && name_!="LessThan")
+    out << " Note that if 'UndefinedStatus' is equal to 'redThreshold' or 'yellowThreshold', the bin will be 'red'/'yellow' rather than 'gray'.";
+  out << "\n \t-otherwise the bin is 'green'" << std::endl;
+  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;
+  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;
+  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;
+
+  out<<"Mandatory Parameter: HeightThreshold: sets the warning (yellowThreshold) and error (redThreshold) thresholds."<<std::endl; 
+  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;
+  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;
+  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;
+  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;
+  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;
 }