From 918da905b467b89cffdc3acfbbf336c740b4772b Mon Sep 17 00:00:00 2001
From: Nick Draper <nick.draper@stfc.ac.uk>
Date: Fri, 28 Nov 2014 14:50:56 +0000
Subject: [PATCH] re #10657 added protection around xmin and xmax values + unit
 test

---
 .../Algorithms/src/CreateSampleWorkspace.cpp  | 17 ++++++++--
 .../test/CreateSampleWorkspaceTest.h          | 32 +++++++++++++++++++
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp
index 6eab55e4df2..73996265d03 100644
--- a/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp
+++ b/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp
@@ -19,6 +19,7 @@
 #include <cmath>
 #include <ctime>
 #include <numeric>
+#include <stdexcept>
 
 namespace Mantid
 {
@@ -91,7 +92,7 @@ namespace Algorithms
     declareProperty("UserDefinedFunction","","Parameters defining the fitting function and its initial values");
 
     declareProperty("NumBanks", 2,boost::make_shared<BoundedValidator<int> >(0,100), "The Number of banks in the instrument (default:2)");
-    declareProperty("BankPixelWidth", 10,boost::make_shared<BoundedValidator<int> >(0,1000), "The width & height of each bank in pixels (default:10).");
+    declareProperty("BankPixelWidth", 10,boost::make_shared<BoundedValidator<int> >(0,10000), "The width & height of each bank in pixels (default:10).");
     declareProperty("NumEvents", 1000,boost::make_shared<BoundedValidator<int> >(0,100000), "The number of events per detector, this is only used for EventWorkspaces (default:1000).");
     declareProperty("Random", false, "Whether to randomise the placement of events and data (default:false).");
 
@@ -117,7 +118,19 @@ namespace Algorithms
     const std::string xUnit = getProperty("XUnit");
     const double xMin = getProperty("XMin");
     const double xMax = getProperty("XMax");
-    const double binWidth = getProperty("BinWidth");
+    double binWidth = getProperty("BinWidth");
+
+    if (xMax <= xMin)
+    {
+      throw std::invalid_argument("XMax must be larger than XMin");
+    }
+
+    if (binWidth > (xMax-xMin))
+    {
+      //the bin width is so large that there is less than one bin - so adjust it down
+      binWidth = xMax-xMin;
+      g_log.warning()<<"The bin width is so large that there is less than one bin - it has been changed to " << binWidth << std::endl;
+    }
 
     std::string functionString = "";
     if (m_preDefinedFunctionmap.find(preDefinedFunction) != m_preDefinedFunctionmap.end())
diff --git a/Code/Mantid/Framework/Algorithms/test/CreateSampleWorkspaceTest.h b/Code/Mantid/Framework/Algorithms/test/CreateSampleWorkspaceTest.h
index 517aea13cd7..b895a172643 100644
--- a/Code/Mantid/Framework/Algorithms/test/CreateSampleWorkspaceTest.h
+++ b/Code/Mantid/Framework/Algorithms/test/CreateSampleWorkspaceTest.h
@@ -263,6 +263,38 @@ public:
     AnalysisDataService::Instance().remove(outWSName);
   }
   
+  void test_failure_due_to_bad_bin_width()
+  {
+    /* Equivalent of this python command:
+      mono_ws = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=4, NumEvents=10000,XUnit='DeltaE',XMin=-5,XMax=15)
+    */
+    std::string outWSName = "CreateSampleWorkspaceTest_test_failure_due_to_bad_bin_width";
+    CreateSampleWorkspace alg;
+    TS_ASSERT_THROWS_NOTHING( alg.initialize() );
+    TS_ASSERT( alg.isInitialized() );
+    alg.setPropertyValue("OutputWorkspace", outWSName);
+    TS_ASSERT_THROWS_NOTHING( alg.setProperty("NumBanks", 1) );
+    TS_ASSERT_THROWS_NOTHING( alg.setProperty("BankPixelWidth", 4) );
+    TS_ASSERT_THROWS_NOTHING( alg.setProperty("NumEvents", 10000) );
+    TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("XUnit", "DeltaE") );
+    TS_ASSERT_THROWS_NOTHING( alg.setProperty("XMin", -5.0) );
+    TS_ASSERT_THROWS_NOTHING( alg.setProperty("XMax", 15.0) );
+    //leave the default bin width of 200, which is inappropriate
+    
+    TS_ASSERT_THROWS_NOTHING( alg.execute(); );
+    TS_ASSERT( alg.isExecuted() );
+
+    // Retrieve the workspace from data service. TODO: Change to your desired type
+    MatrixWorkspace_sptr ws;
+    TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(outWSName) );
+    TS_ASSERT(ws);
+    //just one bin
+    TS_ASSERT_EQUALS(ws->blocksize(),1);
+
+    // Remove workspace from the data service.
+    AnalysisDataService::Instance().remove(outWSName);
+  }
+
 };
 
 
-- 
GitLab