From 8c17e2c404d0b8761be59e9e0a6d18179aabcc3d Mon Sep 17 00:00:00 2001
From: Anton Piccardo-Selg <anton.piccardo-selg@tessella.com>
Date: Wed, 12 Aug 2015 12:00:35 +0100
Subject: [PATCH] Refs #13314 Add system tests for QResolution integration

---
 .../SANSCollimationLengthEstimator.h          |  2 +-
 .../src/SANSCollimationLengthEstimator.cpp    | 55 +++++++++++++++---
 .../tests/analysis/SANSQResolutionTest.py     | 57 +++++++++++++++++++
 3 files changed, 104 insertions(+), 10 deletions(-)
 create mode 100644 Code/Mantid/Testing/SystemTests/tests/analysis/SANSQResolutionTest.py

diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/SANSCollimationLengthEstimator.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/SANSCollimationLengthEstimator.h
index 20126e97f80..c10a53a65e6 100644
--- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/SANSCollimationLengthEstimator.h
+++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/SANSCollimationLengthEstimator.h
@@ -5,7 +5,6 @@
 #include "MantidAPI/MatrixWorkspace_fwd.h"
   /**Helper class which provides the Collimation Length for SANS instruments
 
-
   Copyright &copy; 2015 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
 
   This file is part of Mantid.
@@ -35,6 +34,7 @@ public:
   double provideCollimationLength(Mantid::API::MatrixWorkspace_sptr workspace);
 private:
   double getCollimationLengthWithGuides(Mantid::API::MatrixWorkspace_sptr inOutWS, const double L1, const double collimationLengthCorrection) const;
+  double getGuideValue(Mantid::Kernel::Property* prop) const;
 };
 }
 }
diff --git a/Code/Mantid/Framework/Algorithms/src/SANSCollimationLengthEstimator.cpp b/Code/Mantid/Framework/Algorithms/src/SANSCollimationLengthEstimator.cpp
index f7a356af7ff..d2a6adbd356 100644
--- a/Code/Mantid/Framework/Algorithms/src/SANSCollimationLengthEstimator.cpp
+++ b/Code/Mantid/Framework/Algorithms/src/SANSCollimationLengthEstimator.cpp
@@ -2,12 +2,28 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/TimeSeriesProperty.h"
+#include "MantidKernel/Property.h"
 #include "MantidKernel/V3D.h"
-
+#include "boost/lexical_cast.hpp"
 
 
 namespace{
-  Mantid::Kernel::Logger g_log("SANSCollimationLengthEstimator");
+Mantid::Kernel::Logger g_log("SANSCollimationLengthEstimator");
+
+/**
+ * Provide an string and check if it can be converted to a double
+ * @param val: a value as a string
+ * @returns true if it is convertible else false
+ */
+bool checkForDouble(std::string val) {
+  auto isDouble = false;
+  try {
+    boost::lexical_cast<double>(val);
+    isDouble = true;
+  } catch (boost::bad_lexical_cast const &) {
+  }
+  return isDouble;
+}
 }
 
 
@@ -48,16 +64,20 @@ double SANSCollimationLengthEstimator::provideCollimationLength(Mantid::API::Mat
   if (workspace->getInstrument()->hasParameter("special-default-collimation-length-method")){
     auto specialCollimationMethod =workspace->getInstrument()->getStringParameter("special-default-collimation-length-method");
     if (specialCollimationMethod[0] == "guide") {
-      return getCollimationLengthWithGuides(workspace, L1, collimationLengthCorrection[0]);
+      try {
+        return getCollimationLengthWithGuides(workspace, L1, collimationLengthCorrection[0]);
+      } catch (std::invalid_argument &ex) {
+        g_log.notice() << ex.what();
+        g_log.notice() << "SANSCollimationLengthEstimator: Not using any guides";
+        return L1 - collimationLengthCorrection[0];
+      }
     } else {
       throw std::invalid_argument("Error in SANSCollimationLengthEstimator: Unknown special collimation method.");
     }
-  } else {
-    return L1 - collimationLengthCorrection[0];
   }
+    return L1 - collimationLengthCorrection[0];
 }
 
-
 /**
  * This extraction strategy gets applied when guides are used to calculate the collimation length. The instrument
  * parameter file contains the information about the number of guides to use. The guide data itself is fetched
@@ -89,13 +109,12 @@ double SANSCollimationLengthEstimator::getCollimationLengthWithGuides(MatrixWork
 
 
   // Make sure that all guides are there. They are labelled as Guide1, Guide2, Guide3, ...
-  // The entry is a numeric TimeSeriesProperty
+  // The entry is a numeric TimeSeriesProperty or a numeric entry, if something else then default
   std::vector<double> guideValues;
   for (unsigned int i = 1; i <= numberOfGuides; i++) {
     auto guideName = "Guide" + boost::lexical_cast<std::string>(i);
     if (inOutWS->run().hasProperty(guideName)) {
-      auto guideProperty = inOutWS->run().getTimeSeriesProperty<double>(guideName);
-      guideValues.push_back(guideProperty->firstValue());
+
     } else {
       throw std::invalid_argument("TOFSANSResolutionByPixel: Mismatch between specified number of Guides and actual Guides.");
     }
@@ -123,5 +142,23 @@ double SANSCollimationLengthEstimator::getCollimationLengthWithGuides(MatrixWork
   }
   return lCollim;
 }
+
+/**
+ * Extracts the value of the guide
+ * @param prop: a property
+ * @returns the guide value
+ */
+double SANSCollimationLengthEstimator::getGuideValue(Mantid::Kernel::Property* prop) const {
+  if (auto timeSeriesProperty = dynamic_cast<TimeSeriesProperty<double>*>(prop)) {
+    return timeSeriesProperty->firstValue();
+  } else if (auto doubleProperty = dynamic_cast<PropertyWithValue<double> *>(prop)){
+    auto val = doubleProperty->value();
+    if (checkForDouble(val)) {
+      g_log.warning("SANSCollimationLengthEstimator: The Guide was not recoginized as a TimeSeriesProperty, but rather as a Numeric.");
+      return boost::lexical_cast<double, std::string>(val);
+    }
+  }
+  throw std::invalid_argument("TOFSANSResolutionByPixel: Unknown type for Guides. Currently only Numeric and TimeSeries are supported.");
+}
 }
 }
\ No newline at end of file
diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANSQResolutionTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSQResolutionTest.py
new file mode 100644
index 00000000000..27d110e3c61
--- /dev/null
+++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSQResolutionTest.py
@@ -0,0 +1,57 @@
+#pylint: disable=no-init
+import stresstesting
+from mantid.simpleapi import *
+from ISISCommandInterface import *
+
+class SANSQResolutionWithoutGravity(stresstesting.MantidStressTest):
+    def runTest(self):
+        SANS2D()
+        MaskFile('MASKSANS2D_094i_RKH.txt')
+        SetDetectorOffsets('REAR', -16.0, 58.0, 0.0, 0.0, 0.0, 0.0)
+        SetDetectorOffsets('FRONT', -44.0, -20.0, 47.0, 0.0, 1.0, 1.0)
+        Gravity(False)
+        Set1D()
+        AssignSample('2500.nxs')
+
+        # Provide settings for QResolution
+        set_q_resolution_use(True)
+        moderator_file_name = "ModeratorStdDev_TS2_SANS_30Jul2015.txt"
+        set_q_resolution_a1(a1 = 2)
+        set_q_resolution_a2(a2 = 3)
+        set_q_resolution_delta_r(delta_r = 2)
+        set_q_resolution_collimation_length(collimation_length=10)
+        set_q_resolution_moderator(file_name = moderator_file_name)
+
+        WavRangeReduction(4.6, 12.85, False)
+
+    def validate(self):
+        self.disableChecking.append('Instrument')
+        return True
+
+class SANSQResolutionWithGravity(stresstesting.MantidStressTest):
+    def runTest(self):
+        SANS2D()
+        MaskFile('MASKSANS2D_094i_RKH.txt')
+        SetDetectorOffsets('REAR', -16.0, 58.0, 0.0, 0.0, 0.0, 0.0)
+        SetDetectorOffsets('FRONT', -44.0, -20.0, 47.0, 0.0, 1.0, 1.0)
+        Gravity(flag = True, extra_length = 10.0)
+        Set1D()
+        AssignSample('2500.nxs')
+
+        # Provide settings for QResolution
+        set_q_resolution_use(True)
+        moderator_file_name = "ModeratorStdDev_TS2_SANS_30Jul2015.txt"
+        set_q_resolution_h1(h1 = 2)
+        set_q_resolution_w1(w1 = 3)
+        set_q_resolution_h2(h2 = 4)
+        set_q_resolution_w2(w2 = 5)
+
+        set_q_resolution_delta_r(delta_r = 2)
+        set_q_resolution_collimation_length(collimation_length=5)
+        set_q_resolution_moderator(file_name = moderator_file_name)
+
+        WavRangeReduction(4.6, 12.85, False)
+
+    def validate(self):
+        self.disableChecking.append('Instrument')
+        return True
-- 
GitLab