From 17be8bd83ad84e74233ca20f36df4316e9d170aa Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Wed, 25 Feb 2015 09:42:44 +0000 Subject: [PATCH] refs #11056. Upgrade CreateSampleWorkspace Add options to move the banks and set the pixel spacing for the fake instrument. This is an important feature of working with SCD data, where we want to move the bank in such a way that we have coverage for specific reflections. I've unit tested the two new properties I've added as part of this. The default behaviour will be exactly the same as before. --- .../MantidAlgorithms/CreateSampleWorkspace.h | 4 +- .../Algorithms/src/CreateSampleWorkspace.cpp | 25 +++++- .../test/CreateSampleWorkspaceTest.h | 89 ++++++++++++++++++- 3 files changed, 110 insertions(+), 8 deletions(-) diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h index 4e18d6ed31ac..db11c9e0d69a 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h @@ -64,7 +64,7 @@ class DLLExport CreateSampleWorkspace : public API::Algorithm { const std::string &functionString, bool isRandom); Geometry::Instrument_sptr createTestInstrumentRectangular(int num_banks, int pixels, - double pixelSpacing = 0.008); + double pixelSpacing, const double bankDistanceFromSample); Geometry::Object_sptr createCappedCylinder(double radius, double height, const Kernel::V3D &baseCentre, const Kernel::V3D &axis, @@ -85,4 +85,4 @@ class DLLExport CreateSampleWorkspace : public API::Algorithm { } // namespace Algorithms } // namespace Mantid -#endif /* MANTID_ALGORITHMS_CREATESAMPLEWORKSPACE_H_ */ \ No newline at end of file +#endif /* MANTID_ALGORITHMS_CREATESAMPLEWORKSPACE_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp index 99496421e98c..0b665c471eb4 100644 --- a/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CreateSampleWorkspace.cpp @@ -122,6 +122,13 @@ void CreateSampleWorkspace::init() { declareProperty("BinWidth", 200.0, boost::make_shared>(0, 100000, true), "The bin width of the X axis (default:200)."); + declareProperty("PixelSpacing", 0.008, + boost::make_shared>(0, 100000, true), + "The spacing between detector pixels in M (default:0.008)"); + declareProperty("BankDistanceFromSample", 5.0, + boost::make_shared>(0, 1000, true), + "The distance along the beam direction from the sample to " + "bank in M (default:5.0)"); } //---------------------------------------------------------------------------------------------- @@ -139,6 +146,8 @@ void CreateSampleWorkspace::exec() { const double xMin = getProperty("XMin"); const double xMax = getProperty("XMax"); double binWidth = getProperty("BinWidth"); + const double pixelSpacing = getProperty("PixelSpacing"); + const double bankDistanceFromSample = getProperty("BankDistanceFromSample"); if (xMax <= xMin) { throw std::invalid_argument("XMax must be larger than XMin"); @@ -170,8 +179,10 @@ void CreateSampleWorkspace::exec() { m_randGen = new Kernel::MersenneTwister(seedValue); } - Instrument_sptr inst = - createTestInstrumentRectangular(numBanks, bankPixelWidth); + // Create an instrument with one or more rectangular banks. + Instrument_sptr inst = createTestInstrumentRectangular( + numBanks, bankPixelWidth, pixelSpacing, bankDistanceFromSample); + int num_bins = static_cast((xMax - xMin) / binWidth); MatrixWorkspace_sptr ws; if (wsType == "Event") { @@ -391,10 +402,15 @@ void CreateSampleWorkspace::replaceAll(std::string &str, * @param num_banks :: number of rectangular banks to create * @param pixels :: number of pixels in each direction. * @param pixelSpacing :: padding between pixels + * @param bankDistanceFromSample :: Distance of first bank from sample (defaults + *to 5.0m) */ Instrument_sptr CreateSampleWorkspace::createTestInstrumentRectangular( - int num_banks, int pixels, double pixelSpacing) { + int num_banks, int pixels, double pixelSpacing, + const double bankDistanceFromSample) { boost::shared_ptr testInst(new Instrument("basic_rect")); + // The instrument is going to be set up with z as the beam axis and y as the + // vertical axis. testInst->setReferenceFrame( boost::shared_ptr(new ReferenceFrame(Y, Z, Left, ""))); @@ -424,7 +440,8 @@ Instrument_sptr CreateSampleWorkspace::createTestInstrumentRectangular( } testInst->add(bank); - bank->setPos(V3D(0.0, 0.0, 5.0 * banknum)); + // Set the bank along the z-axis of the instrument. (beam direction). + bank->setPos(V3D(0.0, 0.0, bankDistanceFromSample * banknum)); } // Define a source component diff --git a/Code/Mantid/Framework/Algorithms/test/CreateSampleWorkspaceTest.h b/Code/Mantid/Framework/Algorithms/test/CreateSampleWorkspaceTest.h index b895a1726434..8096886acef7 100644 --- a/Code/Mantid/Framework/Algorithms/test/CreateSampleWorkspaceTest.h +++ b/Code/Mantid/Framework/Algorithms/test/CreateSampleWorkspaceTest.h @@ -3,6 +3,10 @@ #include +#include "MantidGeometry/Instrument.h" +#include "MantidGeometry/IComponent.h" +#include "MantidGeometry/Instrument/ReferenceFrame.h" +#include "MantidGeometry/Instrument/RectangularDetector.h" #include "MantidAlgorithms/CreateSampleWorkspace.h" #include "MantidDataObjects/Workspace2D.h" #include "MantidDataObjects/EventWorkspace.h" @@ -79,6 +83,87 @@ class CreateSampleWorkspaceTest : public CxxTest::TestSuite return ws; } + + void test_default_pixel_spacing() + { + CreateSampleWorkspace alg; + alg.setChild(true); + alg.initialize(); + alg.setPropertyValue("OutputWorkspace", "dummy"); + alg.execute(); + MatrixWorkspace_sptr outWS = alg.getProperty("OutputWorkspace"); + + const auto instrument = outWS->getInstrument(); + auto bank1 = boost::dynamic_pointer_cast(instrument->getComponentByName("bank1")); + TSM_ASSERT_EQUALS("PixelSpacing on the bank is not the same as the expected default in x", 0.008, bank1->xstep()); + TSM_ASSERT_EQUALS("PixelSpacing on the bank is not the same as the expected default in y", 0.008, bank1->ystep()); + } + + void test_apply_pixel_spacing() + { + // Set the spacing we want + const double pixelSpacing = 0.01; + + CreateSampleWorkspace alg; + alg.setChild(true); + alg.initialize(); + alg.setProperty("PixelSpacing", pixelSpacing); + alg.setPropertyValue("OutputWorkspace", "dummy"); + alg.execute(); + MatrixWorkspace_sptr outWS = alg.getProperty("OutputWorkspace"); + + const auto instrument = outWS->getInstrument(); + auto bank1 = boost::dynamic_pointer_cast(instrument->getComponentByName("bank1")); + TSM_ASSERT_EQUALS("Not the specified pixel spacing in x", pixelSpacing, bank1->xstep()); + TSM_ASSERT_EQUALS("Not the specified pixel spacing in y", pixelSpacing, bank1->ystep()); + } + + void test_default_instrument_bank_setup() + { + CreateSampleWorkspace alg; + alg.setChild(true); + alg.initialize(); + alg.setPropertyValue("OutputWorkspace", "dummy"); + alg.execute(); + MatrixWorkspace_sptr outWS = alg.getProperty("OutputWorkspace"); + + const auto instrument = outWS->getInstrument(); + const auto bank1 = instrument->getComponentByName("bank1"); + const auto bank2 = instrument->getComponentByName("bank2"); + const auto sample = instrument->getComponentByName("sample"); + + const V3D bank1ToSample = bank1->getPos() - sample->getPos(); + const V3D bank2ToSample = bank2->getPos() - sample->getPos(); + auto refFrame = instrument->getReferenceFrame(); + TSM_ASSERT_EQUALS("By default bank1 should be offset from the sample in the beam direction by 5m", 5.0, refFrame->vecPointingAlongBeam().scalar_prod(bank1ToSample)); + TSM_ASSERT_EQUALS("By default bank2 should be offset from the sample in the beam direction by 2 * 5m", 10.0, refFrame->vecPointingAlongBeam().scalar_prod(bank2ToSample)); + } + + void test_apply_offset_instrument_banks() + { + // Set the offset we want + const double bankToSampleDistance = 4.0; + + CreateSampleWorkspace alg; + alg.setChild(true); + alg.initialize(); + alg.setPropertyValue("OutputWorkspace", "dummy"); + alg.setProperty("BankDistanceFromSample", bankToSampleDistance); + alg.execute(); + MatrixWorkspace_sptr outWS = alg.getProperty("OutputWorkspace"); + + const auto instrument = outWS->getInstrument(); + const auto bank1 = instrument->getComponentByName("bank1"); + const auto bank2 = instrument->getComponentByName("bank2"); + const auto sample = instrument->getComponentByName("sample"); + + const V3D bank1ToSample = bank1->getPos() - sample->getPos(); + const V3D bank2ToSample = bank2->getPos() - sample->getPos(); + auto refFrame = instrument->getReferenceFrame(); + TSM_ASSERT_EQUALS("Wrong offset applied for bank1", bankToSampleDistance, refFrame->vecPointingAlongBeam().scalar_prod(bank1ToSample)); + TSM_ASSERT_EQUALS("Wrong offset applied for bank2", bankToSampleDistance * 2, refFrame->vecPointingAlongBeam().scalar_prod(bank2ToSample)); + } + void test_histogram_defaults() { @@ -93,7 +178,7 @@ class CreateSampleWorkspaceTest : public CxxTest::TestSuite TS_ASSERT_DELTA(ws->readY(0)[50], 10.3,0.0001); TS_ASSERT_DELTA(ws->readY(0)[60], 0.3,0.0001); TS_ASSERT_DELTA(ws->readY(0)[80], 0.3,0.0001); - + // Remove workspace from the data service. AnalysisDataService::Instance().remove(outWSName); } @@ -298,4 +383,4 @@ class CreateSampleWorkspaceTest : public CxxTest::TestSuite }; -#endif /* MANTID_ALGORITHMS_CREATESAMPLEWORKSPACETEST_H_ */ \ No newline at end of file +#endif /* MANTID_ALGORITHMS_CREATESAMPLEWORKSPACETEST_H_ */