diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt index 817a288f1efbb4620298645c64b87c68a7ef395c..e7e34fdfd88bbb3ed6ebdf2b2d3a87604b186492 100644 --- a/Framework/Algorithms/CMakeLists.txt +++ b/Framework/Algorithms/CMakeLists.txt @@ -51,6 +51,7 @@ set ( SRC_FILES src/ConvertSpectrumAxis.cpp src/ConvertSpectrumAxis2.cpp src/ConvertTableToMatrixWorkspace.cpp + src/ConvertToConstantL2.cpp src/ConvertToDistribution.cpp src/ConvertToEventWorkspace.cpp src/ConvertToHistogram.cpp @@ -358,6 +359,7 @@ set ( INC_FILES inc/MantidAlgorithms/ConvertSpectrumAxis.h inc/MantidAlgorithms/ConvertSpectrumAxis2.h inc/MantidAlgorithms/ConvertTableToMatrixWorkspace.h + inc/MantidAlgorithms/ConvertToConstantL2.h inc/MantidAlgorithms/ConvertToDistribution.h inc/MantidAlgorithms/ConvertToEventWorkspace.h inc/MantidAlgorithms/ConvertToHistogram.h @@ -677,6 +679,7 @@ set ( TEST_FILES ConvertSpectrumAxis2Test.h ConvertSpectrumAxisTest.h ConvertTableToMatrixWorkspaceTest.h + ConvertToConstantL2Test.h ConvertToDistributionTest.h ConvertToEventWorkspaceTest.h ConvertToHistogramTest.h @@ -689,7 +692,6 @@ set ( TEST_FILES CopyLogsTest.h CopySampleTest.h CorelliCrossCorrelateTest.h - CorrectFlightPathsTest.h CorrectKiKfTest.h CorrectToFileTest.h CreateCalFileByNamesTest.h diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h new file mode 100644 index 0000000000000000000000000000000000000000..bc00562a1017bfc3d6d384f1e9e2ffdf1473d87b --- /dev/null +++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertToConstantL2.h @@ -0,0 +1,84 @@ +#ifndef MANTID_ALGORITHMS_ConvertToConstantL2_H_ +#define MANTID_ALGORITHMS_ConvertToConstantL2_H_ + +#include "MantidAPI/Algorithm.h" +#include "MantidGeometry/Instrument.h" + +namespace Mantid { +namespace Algorithms { +/** Convert workspace to have a constant L2 + + Required Properties: + <UL> + <LI> InputWorkspace - The name of the Workspace to take as input </LI> + <LI> OutputWorkspace - The name of the workspace in which to store the result + </LI> + </UL> + + + @author Ricardo Ferraz Leal + @date 30/01/2013 + + Copyright © 2008-9 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> + */ +class DLLExport ConvertToConstantL2 : public API::Algorithm { +public: + /// Default constructor + ConvertToConstantL2(); + /// Algorithm's name for identification overriding a virtual method + const std::string name() const override { return "ConvertToConstantL2"; } + /// Summary of algorithms purpose + const std::string summary() const override { + return "Used to convert flight paths to have a constant l2 in 2D shaped " + "detectors."; + } + /// Algorithm's version for identification overriding a virtual method + int version() const override { return 1; } + /// Algorithm's category for identification overriding a virtual method + const std::string category() const override { + return "Inelastic\\Corrections;CorrectionFunctions\\InstrumentCorrections"; + } + +private: + // Overridden Algorithm methods + void init() override; + void exec() override; + void initWorkspaces(); + double getRunProperty(std::string); + double getInstrumentProperty(std::string); + double calculateTOF(double); + + /// The user selected (input) workspace + API::MatrixWorkspace_const_sptr m_inputWS; + /// The output workspace, maybe the same as the input one + API::MatrixWorkspace_sptr m_outputWS; + + Geometry::Instrument_const_sptr m_instrument; + + double m_l2; + double m_wavelength; +}; + +} // namespace Algorithm +} // namespace Mantid + +#endif /*MANTID_ALGORITHMS_ConvertToConstantL2_H_*/ diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CorrectFlightPaths.h b/Framework/Algorithms/inc/MantidAlgorithms/CorrectFlightPaths.h index 44448fac8facc6e473e8b9ceca0d7ba176126538..7b3698de6b09ad9bd8432d70517e517cb060a5d7 100644 --- a/Framework/Algorithms/inc/MantidAlgorithms/CorrectFlightPaths.h +++ b/Framework/Algorithms/inc/MantidAlgorithms/CorrectFlightPaths.h @@ -1,8 +1,12 @@ #ifndef MANTID_ALGORITHMS_CorrectFlightPaths_H_ #define MANTID_ALGORITHMS_CorrectFlightPaths_H_ +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidAlgorithms/ConvertToConstantL2.h" #include "MantidAPI/Algorithm.h" -#include "MantidGeometry/Instrument.h" +#include "MantidAPI/DeprecatedAlgorithm.h" namespace Mantid { namespace Algorithms { @@ -40,44 +44,14 @@ namespace Algorithms { File change history is stored at: <https://github.com/mantidproject/mantid> Code Documentation is available at: <http://doxygen.mantidproject.org> */ -class DLLExport CorrectFlightPaths : public API::Algorithm { +class DLLExport CorrectFlightPaths : public ConvertToConstantL2, + public API::DeprecatedAlgorithm { public: - /// Default constructor CorrectFlightPaths(); - /// Algorithm's name for identification overriding a virtual method const std::string name() const override { return "CorrectFlightPaths"; } - /// Summary of algorithms purpose - const std::string summary() const override { - return "Used to correct flight paths in 2D shaped detectors."; - } - /// Algorithm's version for identification overriding a virtual method - int version() const override { return 1; } - /// Algorithm's category for identification overriding a virtual method - const std::string category() const override { - return "Inelastic\\Corrections;CorrectionFunctions\\InstrumentCorrections"; - } - -private: - // Overridden Algorithm methods - void init() override; - void exec() override; - void initWorkspaces(); - double getRunProperty(std::string); - double getInstrumentProperty(std::string); - double calculateTOF(double); - - /// The user selected (input) workspace - API::MatrixWorkspace_const_sptr m_inputWS; - /// The output workspace, maybe the same as the input one - API::MatrixWorkspace_sptr m_outputWS; - - Geometry::Instrument_const_sptr m_instrument; - - double m_l2; - double m_wavelength; }; } // namespace Algorithm } // namespace Mantid -#endif /*MANTID_ALGORITHMS_CorrectFlightPaths_H_*/ +#endif /*MANTID_ALGORITHMS_CorrectFlightPaths_H_*/ \ No newline at end of file diff --git a/Framework/Algorithms/src/ConvertToConstantL2.cpp b/Framework/Algorithms/src/ConvertToConstantL2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8a2d807fe4fb76cdcf1b8a2af890f30d2ab27418 --- /dev/null +++ b/Framework/Algorithms/src/ConvertToConstantL2.cpp @@ -0,0 +1,165 @@ +#include "MantidAlgorithms/ConvertToConstantL2.h" +#include "MantidAPI/HistogramValidator.h" +#include "MantidAPI/Run.h" +#include "MantidAPI/SpectrumInfo.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidAPI/WorkspaceUnitValidator.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidDataObjects/Workspace2D.h" +#include "MantidGeometry/Instrument/ComponentHelper.h" +#include "MantidGeometry/Instrument/ParameterMap.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/UnitFactory.h" + +#include <cmath> + +namespace Mantid { +namespace Algorithms { + +using namespace Kernel; +using namespace API; +using namespace Geometry; + +// Register the class into the algorithm factory +DECLARE_ALGORITHM(ConvertToConstantL2) + +// Constructor +ConvertToConstantL2::ConvertToConstantL2() + : API::Algorithm(), m_inputWS(), m_outputWS(), m_instrument(), m_l2(0.), + m_wavelength(0.) {} + +/** Initialisation method. Declares properties to be used in algorithm. + * + */ +void ConvertToConstantL2::init() { + auto wsValidator = boost::make_shared<CompositeValidator>(); + wsValidator->add<WorkspaceUnitValidator>("TOF"); + wsValidator->add<HistogramValidator>(); + declareProperty(make_unique<WorkspaceProperty<API::MatrixWorkspace>>( + "InputWorkspace", "", Direction::Input, wsValidator), + "Name of the input workspace"); + declareProperty(make_unique<WorkspaceProperty<API::MatrixWorkspace>>( + "OutputWorkspace", "", Direction::Output), + "Name of the output workspace, can be the same as the input"); +} + +/** + * Initialises input and output workspaces. + * + */ +void ConvertToConstantL2::initWorkspaces() { + // Get the workspaces + m_inputWS = this->getProperty("InputWorkspace"); + m_outputWS = this->getProperty("OutputWorkspace"); + m_instrument = m_inputWS->getInstrument(); + // If input and output workspaces are not the same, create a new workspace for + // the output + if (m_outputWS != this->m_inputWS) { + m_outputWS = API::WorkspaceFactory::Instance().create(m_inputWS); + } + + m_wavelength = getRunProperty("wavelength"); + g_log.debug() << "Wavelength = " << m_wavelength; + m_l2 = getInstrumentProperty("l2"); + g_log.debug() << " L2 = " << m_l2 << '\n'; +} + +/** + * Executes the algorithm + * + */ +void ConvertToConstantL2::exec() { + + initWorkspaces(); + + Geometry::ParameterMap &pmap = m_outputWS->instrumentParameters(); + + // Calculate the number of spectra in this workspace + const size_t numberOfSpectra = m_inputWS->getNumberHistograms(); + API::Progress prog(this, 0.0, 1.0, numberOfSpectra); + + int64_t numberOfSpectra_i = + static_cast<int64_t>(numberOfSpectra); // cast to make openmp happy + + const auto &spectrumInfo = m_inputWS->spectrumInfo(); + + // Loop over the histograms (detector spectra) + PARALLEL_FOR_IF(Kernel::threadSafe(*m_inputWS, *m_outputWS)) + for (int64_t i = 0; i < numberOfSpectra_i; ++i) { + PARALLEL_START_INTERUPT_REGION + m_outputWS->setHistogram(i, m_inputWS->histogram(i)); + + // Should not move the monitors + if (spectrumInfo.isMonitor(i)) { + continue; + } + + // subract the diference in l2 + double thisDetL2 = spectrumInfo.l2(i); + double deltaL2 = std::abs(thisDetL2 - m_l2); + double deltaTOF = calculateTOF(deltaL2); + deltaTOF *= 1e6; // micro sec + + // position - set all detector distance to constant l2 + double r, theta, phi; + V3D oldPos = spectrumInfo.position(i); + oldPos.getSpherical(r, theta, phi); + V3D newPos; + newPos.spherical(m_l2, theta, phi); + ComponentHelper::moveComponent(spectrumInfo.detector(i), pmap, newPos, + ComponentHelper::Absolute); + + m_outputWS->mutableX(i) -= deltaTOF; + + prog.report("Aligning elastic line..."); + PARALLEL_END_INTERUPT_REGION + } // end for i + PARALLEL_CHECK_INTERUPT_REGION + + this->setProperty("OutputWorkspace", this->m_outputWS); +} + +/* + * Get run property as double + * @s - input property name + * + */ +double ConvertToConstantL2::getRunProperty(std::string s) { + Mantid::Kernel::Property *prop = m_inputWS->run().getProperty(s); + double val; + if (!prop || !Strings::convert(prop->value(), val)) { + std::string mesg = "Run property " + s + "doesn't exist!"; + g_log.error(mesg); + throw std::runtime_error(mesg); + } + return val; +} +/* + * Get instrument property as double + * @s - input property name + * + */ +double ConvertToConstantL2::getInstrumentProperty(std::string s) { + std::vector<std::string> prop = m_instrument->getStringParameter(s); + if (prop.empty()) { + std::string mesg = "Property <" + s + "> doesn't exist!"; + g_log.error(mesg); + throw std::runtime_error(mesg); + } + g_log.debug() << "prop[0] = " << prop[0] << '\n'; + return boost::lexical_cast<double>(prop[0]); +} + +/* + * Returns the neutron TOF + * @distance - Distance in meters + */ +double ConvertToConstantL2::calculateTOF(double distance) { + double velocity = PhysicalConstants::h / (PhysicalConstants::NeutronMass * + m_wavelength * 1e-10); // m/s + + return distance / velocity; +} + +} // namespace Algorithm +} // namespace Mantid diff --git a/Framework/Algorithms/src/CorrectFlightPaths.cpp b/Framework/Algorithms/src/CorrectFlightPaths.cpp index 4d286adfdfa93de553fc6504fbd03cb7bf2ca528..0c0eead86d43782e487bbfa6839e44a2f3b84f32 100644 --- a/Framework/Algorithms/src/CorrectFlightPaths.cpp +++ b/Framework/Algorithms/src/CorrectFlightPaths.cpp @@ -1,17 +1,5 @@ #include "MantidAlgorithms/CorrectFlightPaths.h" -#include "MantidAPI/HistogramValidator.h" -#include "MantidAPI/Run.h" -#include "MantidAPI/SpectrumInfo.h" -#include "MantidAPI/WorkspaceFactory.h" -#include "MantidAPI/WorkspaceUnitValidator.h" -#include "MantidDataObjects/EventWorkspace.h" -#include "MantidDataObjects/Workspace2D.h" -#include "MantidGeometry/Instrument/ComponentHelper.h" -#include "MantidGeometry/Instrument/ParameterMap.h" -#include "MantidKernel/CompositeValidator.h" -#include "MantidKernel/UnitFactory.h" - -#include <cmath> +#include "MantidAlgorithms/ConvertToConstantL2.h" namespace Mantid { namespace Algorithms { @@ -23,144 +11,9 @@ using namespace Geometry; // Register the class into the algorithm factory DECLARE_ALGORITHM(CorrectFlightPaths) -// Constructor -CorrectFlightPaths::CorrectFlightPaths() - : API::Algorithm(), m_inputWS(), m_outputWS(), m_instrument(), m_l2(0.), - m_wavelength(0.) {} - -/** Initialisation method. Declares properties to be used in algorithm. - * - */ -void CorrectFlightPaths::init() { - - // todo: add validator for TOF - - auto wsValidator = boost::make_shared<CompositeValidator>(); - wsValidator->add<WorkspaceUnitValidator>("TOF"); - wsValidator->add<HistogramValidator>(); - declareProperty(make_unique<WorkspaceProperty<API::MatrixWorkspace>>( - "InputWorkspace", "", Direction::Input, wsValidator), - "Name of the input workspace"); - declareProperty(make_unique<WorkspaceProperty<API::MatrixWorkspace>>( - "OutputWorkspace", "", Direction::Output), - "Name of the output workspace, can be the same as the input"); -} - -/** - * Initialises input and output workspaces. - * - */ -void CorrectFlightPaths::initWorkspaces() { - // Get the workspaces - m_inputWS = this->getProperty("InputWorkspace"); - m_outputWS = this->getProperty("OutputWorkspace"); - m_instrument = m_inputWS->getInstrument(); - // If input and output workspaces are not the same, create a new workspace for - // the output - if (m_outputWS != this->m_inputWS) { - m_outputWS = API::WorkspaceFactory::Instance().create(m_inputWS); - } - - m_wavelength = getRunProperty("wavelength"); - g_log.debug() << "Wavelength = " << m_wavelength; - m_l2 = getInstrumentProperty("l2"); - g_log.debug() << " L2 = " << m_l2 << '\n'; -} - -/** - * Executes the algorithm - * - */ -void CorrectFlightPaths::exec() { - - initWorkspaces(); - - Geometry::ParameterMap &pmap = m_outputWS->instrumentParameters(); - - const size_t numberOfChannels = this->m_inputWS->blocksize(); - // Calculate the number of spectra in this workspace - const int numberOfSpectra = - static_cast<int>(this->m_inputWS->size() / numberOfChannels); - API::Progress prog(this, 0.0, 1.0, numberOfSpectra); - - int64_t numberOfSpectra_i = - static_cast<int64_t>(numberOfSpectra); // cast to make openmp happy - - const auto &spectrumInfo = m_inputWS->spectrumInfo(); - - // Loop over the histograms (detector spectra) - PARALLEL_FOR_IF(Kernel::threadSafe(*m_inputWS, *m_outputWS)) - for (int64_t i = 0; i < numberOfSpectra_i; ++i) { - PARALLEL_START_INTERUPT_REGION - m_outputWS->setHistogram(i, m_outputWS->histogram(i)); - // Copy the energy transfer axis - // TOF - - // subract the diference in l2 - double thisDetL2 = spectrumInfo.l2(i); - double deltaL2 = std::abs(thisDetL2 - m_l2); - double deltaTOF = calculateTOF(deltaL2); - deltaTOF *= 1e6; // micro sec - - // position - set all detector distance to constant l2 - double r, theta, phi; - V3D oldPos = spectrumInfo.position(i); - oldPos.getSpherical(r, theta, phi); - V3D newPos; - newPos.spherical(m_l2, theta, phi); - ComponentHelper::moveComponent(spectrumInfo.detector(i), pmap, newPos, - ComponentHelper::Absolute); - - m_outputWS->mutableX(i) -= deltaTOF; - - prog.report("Aligning elastic line..."); - PARALLEL_END_INTERUPT_REGION - } // end for i - PARALLEL_CHECK_INTERUPT_REGION - - this->setProperty("OutputWorkspace", this->m_outputWS); -} - -/* - * Get run property as double - * @s - input property name - * - */ -double CorrectFlightPaths::getRunProperty(std::string s) { - Mantid::Kernel::Property *prop = m_inputWS->run().getProperty(s); - double val; - if (!prop || !Strings::convert(prop->value(), val)) { - std::string mesg = "Run property " + s + "doesn't exist!"; - g_log.error(mesg); - throw std::runtime_error(mesg); - } - return val; -} -/* - * Get instrument property as double - * @s - input property name - * - */ -double CorrectFlightPaths::getInstrumentProperty(std::string s) { - std::vector<std::string> prop = m_instrument->getStringParameter(s); - if (prop.empty()) { - std::string mesg = "Property <" + s + "> doesn't exist!"; - g_log.error(mesg); - throw std::runtime_error(mesg); - } - g_log.debug() << "prop[0] = " << prop[0] << '\n'; - return boost::lexical_cast<double>(prop[0]); -} - -/* - * Returns the neutron TOF - * @distance - Distance in meters - */ -double CorrectFlightPaths::calculateTOF(double distance) { - double velocity = PhysicalConstants::h / (PhysicalConstants::NeutronMass * - m_wavelength * 1e-10); // m/s - - return distance / velocity; +/// Constructor +CorrectFlightPaths::CorrectFlightPaths() : ConvertToConstantL2() { + this->useAlgorithm("ConvertToConstantL2", 1); } } // namespace Algorithm diff --git a/Framework/Algorithms/test/ConvertToConstantL2Test.h b/Framework/Algorithms/test/ConvertToConstantL2Test.h new file mode 100644 index 0000000000000000000000000000000000000000..88b6374ab863e538902aedabddfa7691648398be --- /dev/null +++ b/Framework/Algorithms/test/ConvertToConstantL2Test.h @@ -0,0 +1,177 @@ +#ifndef MANTID_ALGORITHMS_CONVERTTOCONSTANTL2TEST_H_ +#define MANTID_ALGORITHMS_CONVERTTOCONSTANTL2TEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidAlgorithms/ConvertToConstantL2.h" +#include "MantidAlgorithms/CreateSampleWorkspace.h" +#include "MantidAlgorithms/DetectorEfficiencyCorUser.h" +#include "MantidAPI/Axis.h" +#include "MantidAPI/FrameworkManager.h" +#include "MantidAPI/IAlgorithm.h" +#include "MantidAPI/SpectrumInfo.h" +#include "MantidDataObjects/Workspace2D.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" +#include "MantidTestHelpers/ComponentCreationHelper.h" +#include "MantidKernel/ArrayProperty.h" +#include <cmath> + +using namespace Mantid::API; +using namespace Mantid; +using namespace Kernel; + +using Mantid::Algorithms::ConvertToConstantL2; + +class ConvertToConstantL2Test : public CxxTest::TestSuite { +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static ConvertToConstantL2Test *createSuite() { + return new ConvertToConstantL2Test(); + } + static void destroySuite(ConvertToConstantL2Test *suite) { delete suite; } + + ConvertToConstantL2Test() : m_l2(4) { FrameworkManager::Instance(); } + + void testTheBasics() { + ConvertToConstantL2 c; + TS_ASSERT_EQUALS(c.name(), "ConvertToConstantL2"); + TS_ASSERT_EQUALS(c.version(), 1); + } + + void test_detectors_move() { + int numberOfAngles = 5; + int numberOfBins = 10; + + auto inputWS = createTestWorkspace(numberOfAngles, numberOfBins); + + do_test_move(inputWS); + } + + void test_monitors_do_not_get_moved() { + auto inputWS = createTestMonitorWorkspace(); + do_test_move(inputWS); + } + + void do_test_move(MatrixWorkspace_sptr inputWS) { + // BEFORE - check the L2 values differ + const auto &spectrumInfoInput = inputWS->spectrumInfo(); + for (size_t i = 0; i < inputWS->getNumberHistograms(); i++) { + double r, theta, phi; + Mantid::Kernel::V3D pos = spectrumInfoInput.position(i); + pos.getSpherical(r, theta, phi); + TS_ASSERT_DIFFERS(r, m_l2) + } + + ConvertToConstantL2 c; + if (!c.isInitialized()) + c.initialize(); + + c.setPropertyValue("InputWorkspace", inputWSName); + c.setPropertyValue("OutputWorkspace", outputWSName); + c.execute(); + TS_ASSERT(c.isExecuted()); + + Mantid::API::MatrixWorkspace_const_sptr outputWS = + Mantid::API::AnalysisDataService::Instance() + .retrieveWS<Mantid::API::MatrixWorkspace>(outputWSName); + + // AFTER - test the first tube to see if distance was well corrected to l2 + const auto &spectrumInfoOutput = outputWS->spectrumInfo(); + for (size_t i = 0; i < outputWS->getNumberHistograms(); i++) { + double r, theta, phi; + Mantid::Kernel::V3D pos = spectrumInfoOutput.position(i); + pos.getSpherical(r, theta, phi); + + // Corrected distance to l2, but not form monitors. + if (spectrumInfoOutput.isMonitor(i)) { + TS_ASSERT_DIFFERS(r, m_l2) + } else { + TS_ASSERT_DELTA(r, m_l2, 0.001) + } + } + + // Check the contents of the y and e parts of the histogram are the same, + // and x differs + for (size_t i = 0; i < outputWS->getNumberHistograms(); i++) { + if (spectrumInfoOutput.isMonitor(i)) { + TS_ASSERT_EQUALS(outputWS->x(i).rawData(), inputWS->x(i).rawData()); + } else { + TS_ASSERT_DIFFERS(outputWS->x(i).rawData(), inputWS->x(i).rawData()); + } + TS_ASSERT_EQUALS(outputWS->y(i).rawData(), inputWS->y(i).rawData()); + TS_ASSERT_EQUALS(outputWS->e(i).rawData(), inputWS->e(i).rawData()); + } + + AnalysisDataService::Instance().remove(outputWSName); + AnalysisDataService::Instance().remove(inputWSName); + } + +private: + int m_l2; + double m_wavelength = 5.0; + + std::string inputWSName = "test_input_ws"; + std::string outputWSName = "test_output_ws"; + + MatrixWorkspace_sptr createTestWorkspace(int numberOfAngles, + int numberOfBins) { + std::vector<double> L2(numberOfAngles, 5); + std::vector<double> polar(numberOfAngles, (30. / 180.) * M_PI); + polar[0] = 0; + std::vector<double> azimuthal(numberOfAngles, 0); + azimuthal[1] = (45. / 180.) * M_PI; + azimuthal[2] = (90. / 180.) * M_PI; + azimuthal[3] = (135. / 180.) * M_PI; + azimuthal[4] = (180. / 180.) * M_PI; + + Mantid::API::MatrixWorkspace_sptr inputWS = + WorkspaceCreationHelper::createProcessedInelasticWS( + L2, polar, azimuthal, numberOfBins, -1, 3, 3); + + inputWS->getAxis(0)->setUnit("TOF"); + + addSampleLogs(inputWS); + + API::AnalysisDataService::Instance().addOrReplace(inputWSName, inputWS); + + return inputWS; + } + + MatrixWorkspace_sptr createTestMonitorWorkspace() { + /* + * Ideally this would test the detectors from CreateSampleWorkspace too, but + * due to the way they are created in banks they do not get moved properly. + * This may need fixing if the IN5 instrument definition is changed to use + * banks. + */ + + Mantid::Algorithms::CreateSampleWorkspace create; + create.initialize(); + create.setProperty("NumBanks", 0); + create.setProperty("NumMonitors", 1); + create.setProperty("BankDistanceFromSample", 5.0); + create.setPropertyValue("OutputWorkspace", inputWSName); + create.execute(); + + MatrixWorkspace_sptr inputWS = + Mantid::API::AnalysisDataService::Instance() + .retrieveWS<Mantid::API::MatrixWorkspace>(inputWSName); + inputWS->populateInstrumentParameters(); + + addSampleLogs(inputWS); + + return inputWS; + } + + void addSampleLogs(MatrixWorkspace_sptr inputWS) { + inputWS->mutableRun().addProperty( + "wavelength", boost::lexical_cast<std::string>(m_wavelength)); + + inputWS->instrumentParameters().addString( + inputWS->getInstrument()->getComponentID(), "l2", + boost::lexical_cast<std::string>(m_l2)); + } +}; + +#endif /* MANTID_ALGORITHMS_CONVERTTOCONSTANTL2TEST_H_ */ diff --git a/Framework/Algorithms/test/CorrectFlightPathsTest.h b/Framework/Algorithms/test/CorrectFlightPathsTest.h deleted file mode 100644 index 81deed6b5f2fae747e9a87fce1de585dfe6e168f..0000000000000000000000000000000000000000 --- a/Framework/Algorithms/test/CorrectFlightPathsTest.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef MANTID_ALGORITHMS_CORRECTFLIGHTPATHSTEST_H_ -#define MANTID_ALGORITHMS_CORRECTFLIGHTPATHSTEST_H_ - -#include <cxxtest/TestSuite.h> - -#include "MantidAlgorithms/CorrectFlightPaths.h" -#include "MantidAlgorithms/DetectorEfficiencyCorUser.h" -#include "MantidAPI/Axis.h" -#include "MantidAPI/FrameworkManager.h" -#include "MantidAPI/IAlgorithm.h" -#include "MantidDataObjects/Workspace2D.h" -#include "MantidTestHelpers/WorkspaceCreationHelper.h" -#include "MantidTestHelpers/ComponentCreationHelper.h" -#include "MantidKernel/ArrayProperty.h" -#include <cmath> - -using namespace Mantid::API; -using namespace Mantid; -using namespace Kernel; - -using Mantid::Algorithms::CorrectFlightPaths; - -class CorrectFlightPathsTest : public CxxTest::TestSuite { -public: - // This pair of boilerplate methods prevent the suite being created statically - // This means the constructor isn't called when running other tests - static CorrectFlightPathsTest *createSuite() { - return new CorrectFlightPathsTest(); - } - static void destroySuite(CorrectFlightPathsTest *suite) { delete suite; } - - CorrectFlightPathsTest() - : // alter here if needed - m_l2(4) {} - - void testTheBasics() { - CorrectFlightPaths c; - TS_ASSERT_EQUALS(c.name(), "CorrectFlightPaths"); - TS_ASSERT_EQUALS(c.version(), 1); - } - - void testExec() { - - std::string inputWSName("test_input_ws"); - std::string outputWSName("test_output_ws"); - - std::vector<double> L2(5, 5); - std::vector<double> polar(5, (30. / 180.) * M_PI); - polar[0] = 0; - std::vector<double> azimutal(5, 0); - azimutal[1] = (45. / 180.) * M_PI; - azimutal[2] = (90. / 180.) * M_PI; - azimutal[3] = (135. / 180.) * M_PI; - azimutal[4] = (180. / 180.) * M_PI; - - int numBins = 10; - Mantid::API::MatrixWorkspace_sptr dataws = - WorkspaceCreationHelper::createProcessedInelasticWS(L2, polar, azimutal, - numBins, -1, 3, 3); - - dataws->getAxis(0)->setUnit("TOF"); - dataws->mutableRun().addProperty("wavelength", - boost::lexical_cast<std::string>(5)); - - dataws->instrumentParameters().addString( - dataws->getInstrument()->getComponentID(), "l2", - boost::lexical_cast<std::string>(m_l2)); - - API::AnalysisDataService::Instance().addOrReplace(inputWSName, dataws); - - // BEFORE - for (int i = 0; i < 5; i++) { - Mantid::Geometry::IDetector_const_sptr det = dataws->getDetector(i); - double r, theta, phi; - Mantid::Kernel::V3D pos = det->getPos(); - pos.getSpherical(r, theta, phi); - // Corrected distance to 4! - TS_ASSERT_DIFFERS(r, m_l2) - } - - CorrectFlightPaths c; - if (!c.isInitialized()) - c.initialize(); - - c.setPropertyValue("InputWorkspace", inputWSName); - c.setPropertyValue("OutputWorkspace", outputWSName); - c.execute(); - TS_ASSERT(c.isExecuted()); - - Mantid::API::MatrixWorkspace_const_sptr output; - output = Mantid::API::AnalysisDataService::Instance() - .retrieveWS<Mantid::API::MatrixWorkspace>(outputWSName); - - // AFTER - // test the first tube to see if distance was well corrected to l2 - for (int i = 0; i < 5; i++) { - Mantid::Geometry::IDetector_const_sptr det = output->getDetector(i); - double r, theta, phi; - Mantid::Kernel::V3D pos = det->getPos(); - pos.getSpherical(r, theta, phi); - // Corrected distance to l2! - // TS_ASSERT_EQUALS(r, m_l2) - TS_ASSERT_DELTA(r, m_l2, 0.001) - } - - AnalysisDataService::Instance().remove(outputWSName); - AnalysisDataService::Instance().remove(inputWSName); - } - -private: - int m_l2; -}; - -#endif /* MANTID_ALGORITHMS_CORRECTFLIGHTPATHSTEST_H_ */ diff --git a/Testing/Data/DocTest/ILL/IN5/104007.nxs.md5 b/Testing/Data/DocTest/ILL/IN5/104007.nxs.md5 new file mode 100644 index 0000000000000000000000000000000000000000..24c40894f228c988dee2522e1d57e076742f0d93 --- /dev/null +++ b/Testing/Data/DocTest/ILL/IN5/104007.nxs.md5 @@ -0,0 +1 @@ +48f8bb0d26b1f6d817ffcd6499cbdf3c diff --git a/docs/source/algorithms/ConvertToConstantL2-v1.rst b/docs/source/algorithms/ConvertToConstantL2-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..69fe64bb920025d92bed49e802f5f654147334c2 --- /dev/null +++ b/docs/source/algorithms/ConvertToConstantL2-v1.rst @@ -0,0 +1,65 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Moves the instrument and then corrects the flight paths such that a flat detector appears spherical with a constant l2 value. + +Both time-of-flight sample-detector time and sample to detector distance are corrected to constant values. + +The sample to detector distance must be specified as **l2** in the instrument parameters file. + +So far this has only be tested on the ILL IN5 instrument. + +Note +################################### +This algorithm is intended for visualisation only. It is not recommended as part of any reduction process. + +**Example - Add multiple sample logs** + +.. testcode:: IN5Example + + # Load an IN5 file + ws = Load('ILL/IN5/104007.nxs') + + print("Before conversion:") + print("Monitor {0} distance from origin: {1:.3f}".format(0, ws.getDetector(0).getPos().norm())) + for i in range(1, 6): + print("Detector {0} distance from origin: {1:.3f}".format(i, ws.getDetector(i).getPos().norm())) + + # Convert to a detector with constant L2 + converted_ws = ConvertToConstantL2(ws) + + print("After conversion:") + print("Monitor {0} distance from origin: {1:.3f}".format(0, converted_ws.getDetector(0).getPos().norm())) + for i in range(1, 6): + print("Detector {0} distance from origin: {1:.3f}".format(i, converted_ws.getDetector(i).getPos().norm())) + +Output: + +.. testoutput:: IN5Example + + Before conversion: + Monitor 0 distance from origin: 0.500 + Detector 1 distance from origin: 4.296 + Detector 2 distance from origin: 4.291 + Detector 3 distance from origin: 4.287 + Detector 4 distance from origin: 4.283 + Detector 5 distance from origin: 4.278 + After conversion: + Monitor 0 distance from origin: 0.500 + Detector 1 distance from origin: 4.000 + Detector 2 distance from origin: 4.000 + Detector 3 distance from origin: 4.000 + Detector 4 distance from origin: 4.000 + Detector 5 distance from origin: 4.000 + +.. categories:: + +.. sourcelink:: diff --git a/docs/source/algorithms/CorrectFlightPaths-v1.rst b/docs/source/algorithms/CorrectFlightPaths-v1.rst index c8738cf9895e84e2208c8b71effe930a8969c8af..f323c8563489302591d355e4426ce24498a81ae7 100644 --- a/docs/source/algorithms/CorrectFlightPaths-v1.rst +++ b/docs/source/algorithms/CorrectFlightPaths-v1.rst @@ -9,17 +9,22 @@ Description ----------- -Corrects the flight paths of a flat detector. +.. warning:: -Both TOF sample-detector and distance sample-detector are corrected to constant values, i.e., this algorithm make the detector spherical rather than flat. + This algorithm will be deprecated in the next version of Mantid. Please, use :ref:`algm-ConvertToConstantL2` instead, which + is the new name for this algorithm. + +Moves the instrument and then corrects the flight paths such that a flat detector appears spherical with a constant l2 value. + +Both time-of-flight sample-detector time and sample to detector distance are corrected to constant values. The sample to detector distance must be specified as **l2** in the instrument parameters file. -So far this has only be tested on the ILL IN5. +So far this has only be tested on the ILL IN5 instrument. Note ################################### -This algorithm was coded as a proof of concept. It may be deprecated in the future. +This algorithm is intended for visualisaion only. It is not recommended as part of any reduction process. .. categories:: diff --git a/docs/source/release/v3.9.0/framework.rst b/docs/source/release/v3.9.0/framework.rst index 721f6f31f3499719042075e842fceb5012c68b57..ce414e3e898940a97ac57f1f2461c9eae632f775 100644 --- a/docs/source/release/v3.9.0/framework.rst +++ b/docs/source/release/v3.9.0/framework.rst @@ -11,6 +11,7 @@ Algorithms New ### +- :ref:`ConvertToConstantL2 <algm-ConvertToConstantL2>` is the new name for CorrectFlightPaths. Improved ######## @@ -21,6 +22,8 @@ Improved Deprecated ########## +- :ref:`CorrectFlightPaths <algm-CorrectFlightPaths>` has been renamed to ConvertToConstantL2. + MD Algorithms (VATES CLI) #########################