#ifndef CALCULATEEFFICIENCYTEST_H_ #define CALCULATEEFFICIENCYTEST_H_ #include <cxxtest/TestSuite.h> #include "MantidAlgorithms/CalculateEfficiency.h" #include "MantidDataHandling/LoadSpice2D.h" #include "MantidDataHandling/MoveInstrumentComponent.h" #include "MantidTestHelpers/SANSInstrumentCreationHelper.h" using namespace Mantid::API; using namespace Mantid::Kernel; class CalculateEfficiencyTest : public CxxTest::TestSuite { public: /* * Generate fake data for which we know what the result should be */ void setUpWorkspace() { inputWS = "sampledata"; Mantid::DataObjects::Workspace2D_sptr ws = SANSInstrumentCreationHelper::createSANSInstrumentWorkspace(inputWS); // Set up the X bin for the monitor channels for (int i = 0; i < SANSInstrumentCreationHelper::nMonitors; i++) { Mantid::MantidVec &X = ws->dataX(i); X[0] = 1; X[1] = 2; } for (int ix = 0; ix < SANSInstrumentCreationHelper::nBins; ix++) { for (int iy = 0; iy < SANSInstrumentCreationHelper::nBins; iy++) { int i = ix * SANSInstrumentCreationHelper::nBins + iy + SANSInstrumentCreationHelper::nMonitors; Mantid::MantidVec &X = ws->dataX(i); Mantid::MantidVec &Y = ws->dataY(i); Mantid::MantidVec &E = ws->dataE(i); X[0] = 1; X[1] = 2; Y[0] = 2.0; E[0] = 1; } } // Change one of the bins so that it will be excluded for having a high // signal Mantid::MantidVec &Y = ws->dataY(SANSInstrumentCreationHelper::nMonitors + 5); Y[0] = 202.0; } void testName() { TS_ASSERT_EQUALS(correction.name(), "CalculateEfficiency") } void testVersion() { TS_ASSERT_EQUALS(correction.version(), 1) } void testInit() { TS_ASSERT_THROWS_NOTHING(correction.initialize()) TS_ASSERT(correction.isInitialized()) } void testExec() { setUpWorkspace(); if (!correction.isInitialized()) correction.initialize(); const std::string outputWS("result"); correction.setPropertyValue("InputWorkspace", inputWS); TS_ASSERT_THROWS_NOTHING( correction.setPropertyValue("OutputWorkspace", outputWS)) TS_ASSERT_THROWS_NOTHING(correction.execute()) TS_ASSERT(correction.isExecuted()) Mantid::API::Workspace_sptr ws_out; TS_ASSERT_THROWS_NOTHING( ws_out = Mantid::API::AnalysisDataService::Instance().retrieve(outputWS)); Mantid::DataObjects::Workspace2D_sptr ws2d_out = boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>(ws_out); double tolerance(1e-03); TS_ASSERT_DELTA( ws2d_out->dataY(1 + SANSInstrumentCreationHelper::nMonitors)[0], 0.9, tolerance); TS_ASSERT_DELTA( ws2d_out->dataY(15 + SANSInstrumentCreationHelper::nMonitors)[0], 0.9, tolerance); TS_ASSERT_DELTA( ws2d_out->dataY(6 + SANSInstrumentCreationHelper::nMonitors)[0], 0.9, tolerance); TS_ASSERT_DELTA( ws2d_out->dataY(5 + SANSInstrumentCreationHelper::nMonitors)[0], 90.9, tolerance); TS_ASSERT_DELTA( ws2d_out->dataE(1 + SANSInstrumentCreationHelper::nMonitors)[0], 0.4502, tolerance); TS_ASSERT_DELTA( ws2d_out->dataE(15 + SANSInstrumentCreationHelper::nMonitors)[0], 0.4502, tolerance); TS_ASSERT_DELTA( ws2d_out->dataE(6 + SANSInstrumentCreationHelper::nMonitors)[0], 0.4502, tolerance); // Check that pixels that were out of range were masked TS_ASSERT( !ws2d_out->getDetector(5 + SANSInstrumentCreationHelper::nMonitors) ->isMasked()) TS_ASSERT( !ws2d_out->getDetector(1 + SANSInstrumentCreationHelper::nMonitors) ->isMasked()) // Repeat the calculation by excluding high/low pixels TS_ASSERT_THROWS_NOTHING( correction.setProperty<double>("MinEfficiency", 0.5)) TS_ASSERT_THROWS_NOTHING( correction.setProperty<double>("MaxEfficiency", 1.50)) TS_ASSERT_THROWS_NOTHING(correction.execute()) TS_ASSERT(correction.isExecuted()) TS_ASSERT_THROWS_NOTHING( ws_out = Mantid::API::AnalysisDataService::Instance().retrieve(outputWS)); ws2d_out = boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>(ws_out); TS_ASSERT_DELTA( ws2d_out->dataX(1 + SANSInstrumentCreationHelper::nMonitors)[0], 1.0, tolerance); TS_ASSERT_DELTA( ws2d_out->dataX(1 + SANSInstrumentCreationHelper::nMonitors)[1], 2.0, tolerance); TS_ASSERT_DELTA( ws2d_out->dataY(1 + SANSInstrumentCreationHelper::nMonitors)[0], 1.0, tolerance); TS_ASSERT_DELTA( ws2d_out->dataY(15 + SANSInstrumentCreationHelper::nMonitors)[0], 1.0, tolerance); TS_ASSERT_DELTA( ws2d_out->dataY(6 + SANSInstrumentCreationHelper::nMonitors)[0], 1.0, tolerance); TS_ASSERT_DELTA( ws2d_out->dataE(1 + SANSInstrumentCreationHelper::nMonitors)[0], 0.5002, tolerance); TS_ASSERT_DELTA( ws2d_out->dataE(15 + SANSInstrumentCreationHelper::nMonitors)[0], 0.5002, tolerance); TS_ASSERT_DELTA( ws2d_out->dataE(6 + SANSInstrumentCreationHelper::nMonitors)[0], 0.5002, tolerance); // Check that pixels that were out of range were masked TS_ASSERT(ws2d_out->getDetector(5 + SANSInstrumentCreationHelper::nMonitors) ->isMasked()) TS_ASSERT( !ws2d_out->getDetector(1 + SANSInstrumentCreationHelper::nMonitors) ->isMasked()) Mantid::API::AnalysisDataService::Instance().remove(inputWS); Mantid::API::AnalysisDataService::Instance().remove(outputWS); } /* * Function that will validate results against known results found with * "standard" HFIR reduction package. */ void validate() { Mantid::DataHandling::LoadSpice2D loader; loader.initialize(); loader.setPropertyValue("Filename", "BioSANS_exp61_scan0004_0001.xml"); const std::string inputWS("wav"); loader.setPropertyValue("OutputWorkspace", inputWS); loader.execute(); Mantid::DataHandling::MoveInstrumentComponent mover; mover.initialize(); mover.setPropertyValue("Workspace", "wav"); mover.setPropertyValue("ComponentName", "detector1"); // According to the instrument geometry, the center of the detector is // located at N_pixel / 2 + 0.5 // X = (16-192.0/2.0+0.5)*5.15/1000.0 = -0.409425 // Y = (95-192.0/2.0+0.5)*5.15/1000.0 = -0.002575 mover.setPropertyValue("X", "0.409425"); mover.setPropertyValue("Y", "0.002575"); mover.setPropertyValue("Z", "6"); mover.execute(); if (!correction.isInitialized()) correction.initialize(); const std::string outputWS("result"); TS_ASSERT_THROWS_NOTHING( correction.setPropertyValue("InputWorkspace", inputWS)) TS_ASSERT_THROWS_NOTHING( correction.setPropertyValue("OutputWorkspace", outputWS)) TS_ASSERT_THROWS_NOTHING( correction.setProperty<double>("MinEfficiency", 0.5)) TS_ASSERT_THROWS_NOTHING( correction.setProperty<double>("MaxEfficiency", 1.50)) correction.execute(); TS_ASSERT(correction.isExecuted()) Mantid::API::MatrixWorkspace_sptr result; TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>( Mantid::API::AnalysisDataService::Instance().retrieve(outputWS))) TS_ASSERT_EQUALS(result->getNumberHistograms(), 36866) TS_ASSERT_EQUALS(result->getAxis(0)->unit()->unitID(), "Wavelength") Mantid::API::Workspace_sptr ws_in; TS_ASSERT_THROWS_NOTHING( ws_in = Mantid::API::AnalysisDataService::Instance().retrieve(inputWS)); Mantid::DataObjects::Workspace2D_sptr ws2d_in = boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>(ws_in); Mantid::API::Workspace_sptr ws_out; TS_ASSERT_THROWS_NOTHING( ws_out = Mantid::API::AnalysisDataService::Instance().retrieve(outputWS)); Mantid::DataObjects::Workspace2D_sptr ws2d_out = boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>(ws_out); // Number of monitors int nmon = Mantid::DataHandling::LoadSpice2D::nMonitors; // Get the coordinate of the detector pixel double tolerance(1e-03); TS_ASSERT_DELTA(ws2d_out->dataY(1 + nmon)[0], 0.980083, tolerance); TS_ASSERT_DELTA(ws2d_out->dataY(193 + nmon)[0], 1.23006, tolerance); TS_ASSERT_DELTA(ws2d_out->dataY(6 + nmon)[0], 1.10898, tolerance); TS_ASSERT_DELTA(ws2d_out->dataE(1 + nmon)[0], 0.0990047, tolerance); TS_ASSERT_DELTA(ws2d_out->dataE(193 + nmon)[0], 0.110913, tolerance); TS_ASSERT_DELTA(ws2d_out->dataE(6 + nmon)[0], 0.105261, tolerance); // Check that pixels that were out of range were masked TS_ASSERT(ws2d_out->getDetector(1826)->isMasked()) TS_ASSERT(ws2d_out->getDetector(2014)->isMasked()) TS_ASSERT(ws2d_out->getDetector(2015)->isMasked()) Mantid::API::AnalysisDataService::Instance().remove(inputWS); Mantid::API::AnalysisDataService::Instance().remove(outputWS); } private: Mantid::Algorithms::CalculateEfficiency correction; std::string inputWS; }; #endif /*Q1DTEST_H_*/