diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt
index d7c643cdd072ce4de5db4cbe7a9bfbbf3e7a9a29..61aaea9e61e00160e4b5d40db73f1cc6c8b4bdeb 100644
--- a/Framework/Algorithms/CMakeLists.txt
+++ b/Framework/Algorithms/CMakeLists.txt
@@ -18,12 +18,12 @@ set ( SRC_FILES
 	src/Bin2DPowderDiffraction.cpp
 	src/BinaryOperateMasks.cpp
 	src/BinaryOperation.cpp
+	src/CalculateCarpenterSampleCorrection.cpp
 	src/CalculateCountRate.cpp
 	src/CalculateDIFC.cpp
 	src/CalculateEfficiency.cpp
 	src/CalculateFlatBackground.cpp
 	src/CalculateIqt.cpp
-	src/CalculateCarpenterSampleCorrection.cpp
 	src/CalculatePolynomialBackground.cpp
 	src/CalculateSlits.cpp
 	src/CalculateTransmission.cpp
@@ -177,6 +177,7 @@ set ( SRC_FILES
 	src/MagFormFactorCorrection.cpp
 	src/MaskBins.cpp
 	src/MaskBinsFromTable.cpp
+	src/MaskBinsIf.cpp
 	src/MaskDetectorsIf.cpp
 	src/MaskInstrument.cpp
 	src/MatrixWorkspaceAccess.cpp
@@ -348,12 +349,12 @@ set ( INC_FILES
 	inc/MantidAlgorithms/BinaryOperateMasks.h
 	inc/MantidAlgorithms/BinaryOperation.h
 	inc/MantidAlgorithms/BoostOptionalToAlgorithmProperty.h
+	inc/MantidAlgorithms/CalculateCarpenterSampleCorrection.h
 	inc/MantidAlgorithms/CalculateCountRate.h
 	inc/MantidAlgorithms/CalculateDIFC.h
 	inc/MantidAlgorithms/CalculateEfficiency.h
 	inc/MantidAlgorithms/CalculateFlatBackground.h
 	inc/MantidAlgorithms/CalculateIqt.h
-	inc/MantidAlgorithms/CalculateCarpenterSampleCorrection.h
 	inc/MantidAlgorithms/CalculatePolynomialBackground.h
 	inc/MantidAlgorithms/CalculateSlits.h
 	inc/MantidAlgorithms/CalculateTransmission.h
@@ -508,6 +509,7 @@ set ( INC_FILES
 	inc/MantidAlgorithms/MagFormFactorCorrection.h
 	inc/MantidAlgorithms/MaskBins.h
 	inc/MantidAlgorithms/MaskBinsFromTable.h
+	inc/MantidAlgorithms/MaskBinsIf.h
 	inc/MantidAlgorithms/MaskDetectorsIf.h
 	inc/MantidAlgorithms/MaskInstrument.h
 	inc/MantidAlgorithms/MatrixWorkspaceAccess.h
@@ -847,6 +849,7 @@ set ( TEST_FILES
 	MCInteractionVolumeTest.h
 	MagFormFactorCorrectionTest.h
 	MaskBinsFromTableTest.h
+	MaskBinsIfTest.h
 	MaskBinsTest.h
 	MaskDetectorsIfTest.h
 	MaskInstrumentTest.h
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsIf.h b/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsIf.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b6518af15981b53c4d7eb31d6e581fa9629f571
--- /dev/null
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MaskBinsIf.h
@@ -0,0 +1,38 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTID_ALGORITHMS_MASKBINSIF_H_
+#define MANTID_ALGORITHMS_MASKBINSIF_H_
+
+#include "MantidAlgorithms/DllConfig.h"
+#include "MantidAPI/Algorithm.h"
+
+namespace Mantid {
+namespace Algorithms {
+
+/** MaskBinsIf : Masks bins based on muparser expression
+*/
+class MANTID_ALGORITHMS_DLL MaskBinsIf : public API::Algorithm {
+public:
+  const std::string name() const override { return "MaskBinsIf"; }
+  int version() const override { return 1; }
+  const std::string category() const override { return "Transforms\\Masking"; }
+  const std::string summary() const override {
+    return "Masks bins based on muparser expression";
+  }
+  const std::vector<std::string> seeAlso() const override {
+    return {"MaskBins"};
+  }
+
+private:
+  void init() override;
+  void exec() override;
+};
+
+} // namespace Algorithms
+} // namespace Mantid
+
+#endif /* MANTID_ALGORITHMS_MASKBINSIF_H_ */
diff --git a/Framework/Algorithms/src/MaskBinsIf.cpp b/Framework/Algorithms/src/MaskBinsIf.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a8de35d07b31540575ec15577f17adbd3e175d7d
--- /dev/null
+++ b/Framework/Algorithms/src/MaskBinsIf.cpp
@@ -0,0 +1,94 @@
+#include "MantidAlgorithms/MaskBinsIf.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/NumericAxis.h"
+#include "MantidAPI/SpectraAxis.h"
+#include "MantidHistogramData/HistogramIterator.h"
+#include "MantidKernel/MultiThreaded.h"
+
+#include <muParser.h>
+
+namespace Mantid {
+namespace Algorithms {
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+using namespace API;
+using namespace Kernel;
+
+// Register the algorithm into the AlgorithmFactory
+DECLARE_ALGORITHM(MaskBinsIf)
+
+//----------------------------------------------------------------------------------------------
+/** Initialize the algorithm's properties.
+ */
+void MaskBinsIf::init() {
+  declareProperty(Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>(
+                      "InputWorkspace", "", Direction::Input),
+                  "An input workspace.");
+  declareProperty("Criterion", "",
+                  "Masking criterion as a muparser expression; y: bin count, "
+                  "e: bin error, x: bin center, dx: bin center error, s: "
+                  "spectrum axis value, i: workspace index.");
+  declareProperty(Kernel::make_unique<WorkspaceProperty<MatrixWorkspace>>(
+                      "OutputWorkspace", "", Direction::Output),
+                  "An output workspace.");
+}
+
+//----------------------------------------------------------------------------------------------
+/** Execute the algorithm.
+ */
+void MaskBinsIf::exec() {
+  const std::string criterion = getPropertyValue("Criterion");
+  MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
+  MatrixWorkspace_sptr outputWorkspace = getProperty("OutputWorkspace");
+  if (inputWorkspace != outputWorkspace) {
+    outputWorkspace = inputWorkspace->clone();
+  }
+  const auto spectrumAxis = outputWorkspace->getAxis(1);
+  const auto numeric = dynamic_cast<NumericAxis *>(spectrumAxis);
+  const auto spectrum = dynamic_cast<SpectraAxis *>(spectrumAxis);
+  const bool spectrumOrNumeric = numeric || spectrum;
+  PARALLEL_FOR_IF(Mantid::Kernel::threadSafe(*outputWorkspace))
+  for (size_t index = 0; index < outputWorkspace->getNumberHistograms();
+       ++index) {
+    PARALLEL_START_INTERUPT_REGION
+    double y, e, x, dx, s, i;
+    dx = 0.;
+    s = 0.;
+    i = index;
+    mu::Parser muParser;
+    muParser.DefineVar("y", &y);
+    muParser.DefineVar("e", &e);
+    muParser.DefineVar("x", &x);
+    muParser.DefineVar("dx", &dx);
+    muParser.DefineVar("s", &s);
+    muParser.DefineVar("i", &i);
+    muParser.SetExpr(criterion);
+    if (spectrumOrNumeric) {
+      s = spectrumAxis->getValue(index);
+    }
+    const auto &spectrum = outputWorkspace->histogram(index);
+    const bool hasDx = outputWorkspace->hasDx(index);
+    for (auto it = spectrum.begin(); it != spectrum.end(); ++it) {
+      const auto bin = std::distance(spectrum.begin(), it);
+      y = it->counts();
+      x = it->center();
+      e = it->countStandardDeviation();
+      if (hasDx) {
+        dx = it->centerError();
+      }
+      if (muParser.Eval() != 0.) {
+        outputWorkspace->maskBin(index, bin);
+      }
+    }
+    PARALLEL_END_INTERUPT_REGION
+  }
+  PARALLEL_CHECK_INTERUPT_REGION
+  setProperty("OutputWorkspace", outputWorkspace);
+}
+
+} // namespace Algorithms
+} // namespace Mantid
diff --git a/Framework/Algorithms/test/MaskBinsIfTest.h b/Framework/Algorithms/test/MaskBinsIfTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..ec15af25de3a32cda02af71f734fa774e1849db8
--- /dev/null
+++ b/Framework/Algorithms/test/MaskBinsIfTest.h
@@ -0,0 +1,136 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTID_ALGORITHMS_MASKBINSIFTEST_H_
+#define MANTID_ALGORITHMS_MASKBINSIFTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAlgorithms/CreateSampleWorkspace.h"
+#include "MantidAlgorithms/CreateWorkspace.h"
+#include "MantidAlgorithms/MaskBinsIf.h"
+
+using Mantid::Algorithms::CreateSampleWorkspace;
+using Mantid::Algorithms::CreateWorkspace;
+using Mantid::Algorithms::MaskBinsIf;
+using Mantid::API::MatrixWorkspace_sptr;
+
+class MaskBinsIfTest : public CxxTest::TestSuite {
+private:
+  MatrixWorkspace_sptr createWorkspace() {
+    CreateWorkspace creator;
+    creator.initialize();
+    creator.setChild(true);
+    creator.setAlwaysStoreInADS(false);
+    const std::vector<double> x = {1.1,  2.5,  3.2,  4.5,  6.7,  8.9,
+                                   10.3, 12.4, 13.9, 14.1, 15.3, 16.8};
+    const std::vector<double> y = {7,  23, 54, 34, 23, 64,
+                                   34, 23, 58, 63, 34, 25};
+    const std::vector<double> e = {3.2, 2.1, 8.4, 3.5, 6.3, 4.7,
+                                   4.9, 3.6, 4.1, 6.7, 5.1, 3.2};
+    const std::vector<double> dx = {0.1, 0.2, 0.4, 0.7, 0.9, 1.3,
+                                    1.5, 1.7, 1.9, 1.2, 4.5, 2.3};
+    const std::vector<std::string> spectrumAxis = {"3", "7", "11", "17"};
+    creator.setProperty("DataX", x);
+    creator.setProperty("DataY", y);
+    creator.setProperty("DataE", e);
+    creator.setProperty("Dx", dx);
+    creator.setProperty("NSpec", 4);
+    creator.setProperty("VerticalAxisValues", spectrumAxis);
+    creator.setProperty("VerticalAxisUnit", "Label");
+    creator.setProperty("OutputWorkspace", "__unused");
+    creator.execute();
+    MatrixWorkspace_sptr ws = creator.getProperty("OutputWorkspace");
+    return ws;
+  }
+
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static MaskBinsIfTest *createSuite() { return new MaskBinsIfTest(); }
+  static void destroySuite(MaskBinsIfTest *suite) { delete suite; }
+
+  void test_init() {
+    MaskBinsIf alg;
+    TS_ASSERT_THROWS_NOTHING(alg.initialize())
+    TS_ASSERT(alg.isInitialized())
+  }
+
+  void test_exec() {
+    MaskBinsIf alg;
+    alg.setChild(true);
+    alg.setRethrows(true);
+    alg.setAlwaysStoreInADS(false);
+    TS_ASSERT_THROWS_NOTHING(alg.initialize())
+    TS_ASSERT(alg.isInitialized())
+    const auto inputWS = createWorkspace();
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inputWS));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("OutputWorkspace", "__unused_for_child"));
+    const std::string criterion = "y>50 || e>6 || s<5 || i>2 || dx>1.6";
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Criterion", criterion));
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+    Mantid::API::MatrixWorkspace_sptr outputWS =
+        alg.getProperty("OutputWorkspace");
+    TS_ASSERT(outputWS);
+    const auto maskedBins1 = outputWS->maskedBins(0);
+    TS_ASSERT(maskedBins1.find(0) != maskedBins1.end());
+    TS_ASSERT(maskedBins1.find(1) != maskedBins1.end());
+    TS_ASSERT(maskedBins1.find(2) != maskedBins1.end());
+    const auto maskedBins2 = outputWS->maskedBins(1);
+    TS_ASSERT(maskedBins2.find(0) == maskedBins2.end());
+    TS_ASSERT(maskedBins2.find(1) != maskedBins2.end());
+    TS_ASSERT(maskedBins2.find(2) != maskedBins2.end());
+    const auto maskedBins3 = outputWS->maskedBins(2);
+    TS_ASSERT(maskedBins3.find(0) == maskedBins3.end());
+    TS_ASSERT(maskedBins3.find(1) != maskedBins3.end());
+    TS_ASSERT(maskedBins3.find(2) != maskedBins3.end());
+    const auto maskedBins4 = outputWS->maskedBins(3);
+    TS_ASSERT(maskedBins4.find(0) != maskedBins4.end());
+    TS_ASSERT(maskedBins4.find(1) != maskedBins4.end());
+    TS_ASSERT(maskedBins4.find(2) != maskedBins4.end());
+  }
+};
+
+class MaskBinsIfTestPerformance : public CxxTest::TestSuite {
+public:
+  static MaskBinsIfTestPerformance *createSuite() {
+    return new MaskBinsIfTestPerformance();
+  }
+  static void destroySuite(MaskBinsIfTestPerformance *suite) { delete suite; }
+
+  void setUp() override {
+    Mantid::API::FrameworkManager::Instance();
+    CreateSampleWorkspace creator;
+    creator.initialize();
+    creator.setChild(true);
+    creator.setAlwaysStoreInADS(false);
+    creator.setProperty("BankPixelWidth", 100);
+    creator.setProperty("NumBanks", 20);
+    creator.setProperty("BinWidth", 200.);
+    creator.setProperty("Random", true);
+    creator.setPropertyValue("OutputWorkspace", "__unused");
+    creator.execute();
+    Mantid::API::MatrixWorkspace_sptr ws =
+        creator.getProperty("OutputWorkspace");
+    m_alg.initialize();
+    m_alg.setChild(true);
+    m_alg.setAlwaysStoreInADS(false);
+    m_alg.setProperty("InputWorkspace", ws);
+    m_alg.setPropertyValue("Criterion", "y>100 || y<1");
+    m_alg.setProperty("OutputWorkspace", "__out");
+  }
+
+  void test_performance() { m_alg.execute(); }
+
+private:
+  MaskBinsIf m_alg;
+};
+
+#endif /* MANTID_ALGORITHMS_MASKBINSIFTEST_H_ */
diff --git a/Framework/HistogramData/inc/MantidHistogramData/HistogramItem.h b/Framework/HistogramData/inc/MantidHistogramData/HistogramItem.h
index ca47f52f5ca8c6481cc99308f78352482a87b7a3..d0da03dbd438c9f4e012304315306a9c996309b9 100644
--- a/Framework/HistogramData/inc/MantidHistogramData/HistogramItem.h
+++ b/Framework/HistogramData/inc/MantidHistogramData/HistogramItem.h
@@ -45,6 +45,11 @@ public:
     }
   }
 
+  double centerError() const {
+    const auto &dx = m_histogram.dx();
+    return dx[m_index];
+  }
+
   double binWidth() const {
     const auto &x = m_histogram.x();
     if (xModeIsPoints()) {
diff --git a/docs/source/algorithms/MaskBinsIf-v1.rst b/docs/source/algorithms/MaskBinsIf-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a1437f59a3a0d0672da9f8c9a005641e268f18e0
--- /dev/null
+++ b/docs/source/algorithms/MaskBinsIf-v1.rst
@@ -0,0 +1,35 @@
+
+.. algorithm::
+
+.. summary::
+
+.. relatedalgorithms::
+
+.. properties::
+
+Description
+-----------
+
+This algorithm masks bins according to the criteria specified as a `muparser <http://beltoforion.de/article.php?a=muparser>`_ expression.
+The variables entering the criteria are reserved as follows:
+
+- y : count in a bin
+- x : the bin center
+- e : the error on the count
+- dx : the error on the bin center
+- i : the workspace index
+- s : the value of spectrum axis, in case of SpectraAxis or NumericAxis.
+
+Usage
+-----
+
+**Example - MaskBinsIf**
+
+.. code-block:: python
+
+   CreateSampleWorkspace(BankPixelWidth=100, NumBanks=1, OutputWorkspace='out')
+   MaskBinsIf(InputWorkspace='out', Criterion='i >10 && i<20 && x>1000 && x<2000', OutputWorkspace='out')
+
+.. categories::
+
+.. sourcelink::
diff --git a/docs/source/release/v3.14.0/framework.rst b/docs/source/release/v3.14.0/framework.rst
index e0071118a39f0ba7d61c51143537a4fd532c857f..9e732a85e52e13c45a1e5a9c2e48610a184323ca 100644
--- a/docs/source/release/v3.14.0/framework.rst
+++ b/docs/source/release/v3.14.0/framework.rst
@@ -40,6 +40,7 @@ New Algorithms
 ##############
 
 - :ref:`MatchSpectra <algm-MatchSpectra>` is an algorithm that calculates factors to match all spectra to a reference spectrum.
+- :ref:`MaskBinsIf <algm-MaskBinsIf>` is an algorithm to mask bins according to criteria specified as a muparser expression.
 
 Improvements
 ############