From 08826bed084801bbd5bf217d9f692057bc9f96bb Mon Sep 17 00:00:00 2001 From: Owen Arnold <owen.arnold@stfc.ac.uk> Date: Tue, 3 Dec 2013 11:50:03 +0000 Subject: [PATCH] refs #8371. toLam functionality implemented. Start work on toLam functionality using convert_to_wavlength.py as guide. Only the detector side of things has been implemented thus far, but test coverage is quite good, and I have implemented the pieces that mean that detector id ranges can be used. --- .../Framework/Algorithms/CMakeLists.txt | 1 + .../ReflectometryReductionOne.h | 15 ++-- .../src/ReflectometryReductionOne.cpp | 75 +++++++++++++++++-- .../test/ReflectometryReductionOneTest.h | 69 +++++++++++++++++ .../ReflectometryReductionOneTest.py | 21 +++++- 5 files changed, 164 insertions(+), 17 deletions(-) create mode 100644 Code/Mantid/Framework/Algorithms/test/ReflectometryReductionOneTest.h diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt index cd328f34b14..74aa53ac57a 100644 --- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt @@ -606,6 +606,7 @@ set ( TEST_FILES RebinTest.h RebinToWorkspaceTest.h RebunchTest.h + ReflectometryReductionOneTest.h RegroupTest.h RemoveBinsTest.h RemoveExpDecayTest.h diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h index 1bee126b82d..e08b60c71ad 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOne.h @@ -38,19 +38,24 @@ namespace Algorithms class DLLExport ReflectometryReductionOne : public API::DataProcessorAlgorithm { public: + + // Class typedefs + typedef boost::tuple<double, double> MinMax; + typedef boost::optional<double> OptionalDouble; + typedef boost::optional<Mantid::API::MatrixWorkspace_sptr> OptionalMatrixWorkspace_sptr; + typedef std::vector<int> WorkspaceIndexList; + typedef boost::optional< std::vector< int > > OptionalWorkspaceIndexes; + ReflectometryReductionOne(); virtual ~ReflectometryReductionOne(); virtual const std::string name() const; virtual int version() const; virtual const std::string category() const; + Mantid::API::MatrixWorkspace_sptr toLam(Mantid::API::MatrixWorkspace_sptr toConvert, const WorkspaceIndexList& detectorIndexRange, const int monitorIndex, const MinMax& wavelengthMinMax, const MinMax& backgroundMinMax); private: - typedef boost::tuple<double, double> MinMax; - typedef boost::optional<double> OptionalDouble; - typedef boost::optional<Mantid::API::MatrixWorkspace_sptr> OptionalMatrixWorkspace_sptr; - typedef std::vector<int> WorkspaceIndexList; - typedef boost::optional< std::vector< int > > OptionalWorkspaceIndexes; + bool isPropertyDefault(const std::string& propertyName) const; WorkspaceIndexList getWorkspaceIndexList(); void fetchOptionalLowerUpperPropertyValue(const std::string& propertyName, bool isPointDetector, OptionalWorkspaceIndexes& optionalUpperLower); diff --git a/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOne.cpp b/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOne.cpp index 6af29184d39..54c6df6138e 100644 --- a/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOne.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ReflectometryReductionOne.cpp @@ -5,6 +5,7 @@ #include "MantidAlgorithms/ReflectometryReductionOne.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidAPI/WorkspaceValidators.h" +#include "MantidAPI/WorkspaceFactory.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/MandatoryValidator.h" #include "MantidKernel/BoundedValidator.h" @@ -300,6 +301,68 @@ namespace Mantid } } + /* + WorkspaceIndexList getSpectrumIds(const WorkspaceIndexList& workspaceIds) + { + // Get spectrum ID. + WorkspaceIndexList detectorSpectrumIdRange; + for(size_t i = 0; i < detectorIndexRange.size(); ++i) + { + auto spectrum = inLam->getSpectrum(detectorIndexRange[i]); + specid_t specId = spectrum->getSpectrumNo(); + detectorSpectrumIdRange.push_back(specId); + } + } + */ + + MatrixWorkspace_sptr ReflectometryReductionOne::toLam(MatrixWorkspace_sptr toConvert, + const WorkspaceIndexList& detectorIndexRange, const int monitorIndex, + const MinMax& wavelengthMinMax, const MinMax& backgroundMinMax) + { + MatrixWorkspace_sptr detectorWS; + for (size_t i = 0; i < detectorIndexRange.size(); i += 2) + { + auto cropWorkspaceAlg = this->createChildAlgorithm("CropWorkspace"); + cropWorkspaceAlg->initialize(); + cropWorkspaceAlg->setProperty("InputWorkspace", toConvert); + cropWorkspaceAlg->setProperty("StartWorkspaceIndex", detectorIndexRange[i]); + cropWorkspaceAlg->setProperty("EndWorkspaceIndex", detectorIndexRange[i + 1]); + + cropWorkspaceAlg->execute(); + MatrixWorkspace_sptr subRange = cropWorkspaceAlg->getProperty("OutputWorkspace"); + if (i == 0) + { + detectorWS = subRange; + } + else + { + auto conjoinWorkspaceAlg = this->createChildAlgorithm("ConjoinWorkspaces"); + conjoinWorkspaceAlg->initialize(); + conjoinWorkspaceAlg->setProperty("InputWorkspace1", detectorWS); + conjoinWorkspaceAlg->setProperty("InputWorkspace2", subRange); + conjoinWorkspaceAlg->execute(); + detectorWS = conjoinWorkspaceAlg->getProperty("InputWorkspace1"); + } + } + + auto convertUnitsAlg = this->createChildAlgorithm("ConvertUnits"); + convertUnitsAlg->initialize(); + convertUnitsAlg->setProperty("InputWorkspace", detectorWS); + convertUnitsAlg->setProperty("Target", "Wavelength"); + convertUnitsAlg->setProperty("AlignBins", true); + convertUnitsAlg->execute(); + detectorWS = convertUnitsAlg->getProperty("OutputWorkspace"); + + auto cropWorkspaceAlg = this->createChildAlgorithm("CropWorkspace"); + cropWorkspaceAlg->initialize(); + cropWorkspaceAlg->setProperty("InputWorkspace", detectorWS); + cropWorkspaceAlg->setProperty("XMin", wavelengthMinMax.get<0>()); + cropWorkspaceAlg->setProperty("XMax", wavelengthMinMax.get<1>()); + cropWorkspaceAlg->execute(); + detectorWS = cropWorkspaceAlg->getProperty("OutputWorkspace"); + + return detectorWS; + } //---------------------------------------------------------------------------------------------- /** Execute the algorithm. @@ -338,15 +401,11 @@ namespace Mantid OptionalWorkspaceIndexes directBeam; fetchOptionalLowerUpperPropertyValue("RegionOfDirectBeam", isPointDetector, directBeam); - auto cloneAlg = this->createChildAlgorithm("CloneWorkspace"); - cloneAlg->initialize(); - cloneAlg->setProperty("InputWorkspace", runWS); - cloneAlg->setPropertyValue("OutputWorkspace", "OutWS"); - cloneAlg->execute(); - Workspace_sptr cloned = cloneAlg->getProperty("OutputWorkspace"); + const int i0MonitorIndex = getProperty("I0MonitorIndex"); + + auto outWS = toLam(runWS, indexList, i0MonitorIndex, wavelengthInterval, monitorBackgroundWavelengthInterval); - setProperty("OutputWorkspace", cloned); - // Convert To Lambda. + setProperty("OutputWorkspace", outWS); } diff --git a/Code/Mantid/Framework/Algorithms/test/ReflectometryReductionOneTest.h b/Code/Mantid/Framework/Algorithms/test/ReflectometryReductionOneTest.h new file mode 100644 index 00000000000..d5a492b8294 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/ReflectometryReductionOneTest.h @@ -0,0 +1,69 @@ + +#ifndef REFLECTOMETRYREDUCTIONONETEST_H_ +#define REFLECTOMETRYREDUCTIONONETEST_H_ + +#include <cxxtest/TestSuite.h> +#include <algorithm> +#include "MantidAlgorithms/ReflectometryReductionOne.h" +#include "MantidAPI/AlgorithmManager.h" + +using namespace Mantid; +using namespace Mantid::Kernel; +using namespace Mantid::API; +using Mantid::Algorithms::ReflectometryReductionOne; + +class ReflectometryReductionOneTest : public CxxTest::TestSuite +{ +public: + + void test_tolam() + { + auto loadAlg = AlgorithmManager::Instance().create("Load"); + loadAlg->initialize(); + loadAlg->setProperty("Filename", "INTER00013460.nxs"); + loadAlg->setPropertyValue("OutputWorkspace", "demo"); + loadAlg->execute(); + + MatrixWorkspace_sptr toConvert = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("demo"); + std::vector<int> detectorIndexRange; + size_t workspaceIndexToKeep1 = 3; + size_t workspaceIndexToKeep2 = 4; + + specid_t specId1 = toConvert->getSpectrum(workspaceIndexToKeep1)->getSpectrumNo(); + specid_t specId2 = toConvert->getSpectrum(workspaceIndexToKeep2)->getSpectrumNo(); + // Define one spectra to keep + detectorIndexRange.push_back(workspaceIndexToKeep1); + detectorIndexRange.push_back(workspaceIndexToKeep1); + // Define another spectra to keep + detectorIndexRange.push_back(workspaceIndexToKeep2); + detectorIndexRange.push_back(workspaceIndexToKeep2); + // Define a wavelength range for the detector workspace + const double wavelengthMin = 10; + const double wavelengthMax = 15; + + ReflectometryReductionOne alg; + MatrixWorkspace_sptr inLam = alg.toLam(toConvert, detectorIndexRange, 0, boost::tuple<double, double>(wavelengthMin, wavelengthMax), boost::tuple<double, double>(0, 0)); + + TS_ASSERT_EQUALS("Wavelength", inLam->getAxis(0)->unit()->unitID()); + + // Check the number of spectrum kept. + TS_ASSERT_EQUALS(2, inLam->getNumberHistograms()); + + auto map = inLam->getSpectrumToWorkspaceIndexMap(); + // Check the spectrum ids retained. + TS_ASSERT_EQUALS(map[specId1], 0); + TS_ASSERT_EQUALS(map[specId2], 1); + + // Check the cropped x range + Mantid::MantidVec copyX = inLam->readX(0); + std::sort(copyX.begin(), copyX.end()); + TS_ASSERT(copyX.front() >= wavelengthMin); + TS_ASSERT(copyX.back() <= wavelengthMax); + + } + +}; + + + +#endif /* REFLECTOMETRYREDUCTIONONETEST_H_ */ diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ReflectometryReductionOneTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ReflectometryReductionOneTest.py index fd1c6f4f9d2..802f94342f4 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ReflectometryReductionOneTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ReflectometryReductionOneTest.py @@ -1,5 +1,6 @@ import unittest from mantid.simpleapi import * +import mantid.api import inspect import re @@ -53,7 +54,7 @@ class ReflectometryReductionOneTest(unittest.TestCase): def construct_standard_algorithm(self): alg = make_decorator(ReflectometryReductionOne) - alg.set_InputWorkspace(self.__tof.getName()) + alg.set_InputWorkspace(self.__tof) alg.set_WavelengthMin(0.0) alg.set_WavelengthMax(1.0) alg.set_I0MonitorIndex(0) @@ -65,15 +66,15 @@ class ReflectometryReductionOneTest(unittest.TestCase): return alg def setUp(self): - tof = CreateWorkspace(UnitX="TOF", DataX=[0,0,0], DataY=[0,0,0], NSpec=1) - not_tof = CreateWorkspace(UnitX="1/q", DataX=[0,0,0], DataY=[0,0,0], NSpec=1) + tof = CreateWorkspace(UnitX="TOF", DataX=[0,0,0,0], DataY=[0,0,0], NSpec=1) + not_tof = CreateWorkspace(UnitX="1/q", DataX=[0,0,0,0], DataY=[0,0,0], NSpec=1) self.__tof = tof self.__not_tof = not_tof def tearDown(self): DeleteWorkspace(self.__tof) DeleteWorkspace(self.__not_tof) - + def test_check_input_workpace_not_tof_throws(self): alg = self.construct_standard_algorithm() alg.set_InputWorkspace(self.__not_tof) @@ -183,6 +184,18 @@ class ReflectometryReductionOneTest(unittest.TestCase): alg.set_RegionOfDirectBeam([1, 0]); self.assertRaises(ValueError, alg.execute) + def test_output_in_lam(self): + alg = self.construct_standard_algorithm() + real_run = Load('INTER00013460.nxs') + alg.set_InputWorkspace(real_run) + alg.set_WorkspaceIndexList([3,3,4,4]) + out_ws = alg.execute() + + self.assertTrue(isinstance(out_ws, mantid.api.MatrixWorkspace), "Should be a matrix workspace") + self.assertEqual("Wavelength", out_ws.getAxis(0).getUnit().unitID()) + self.assertEqual(2, out_ws.getNumberHistograms()) + DeleteWorkspace(real_run) + if __name__ == '__main__': unittest.main() -- GitLab