From a09f1940df45a9683957a4ee32a1265b4d045dc2 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Banos <raquel.alvarez.banos@gmail.com> Date: Wed, 19 Nov 2014 12:02:09 +0000 Subject: [PATCH] Re #10577 Cleanning PhaseQuad and adding unit test --- .../Framework/Algorithms/CMakeLists.txt | 5 +- .../inc/MantidAlgorithms/PhaseQuadMuon.h | 40 +-- .../Algorithms/src/PhaseQuadMuon.cpp | 286 +++++++++--------- .../Algorithms/test/PhaseQuadMuonTest.h | 99 ++++++ 4 files changed, 270 insertions(+), 160 deletions(-) create mode 100644 Code/Mantid/Framework/Algorithms/test/PhaseQuadMuonTest.h diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt index c987ec6e3ac..63079e86632 100644 --- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt @@ -14,7 +14,6 @@ set ( SRC_FILES src/AppendSpectra.cpp src/ApplyCalibration.cpp src/ApplyDeadTimeCorr.cpp - src/PhaseQuadMuon.cpp src/ApplyDetailedBalance.cpp src/ApplyTransmissionCorrection.cpp src/AsymmetryCalc.cpp @@ -161,6 +160,7 @@ set ( SRC_FILES src/PDFFourierTransform.cpp src/Pause.cpp src/PerformIndexOperations.cpp + src/PhaseQuadMuon.cpp src/PlotAsymmetryByLogValue.cpp src/Plus.cpp src/PointByPointVCorrection.cpp @@ -263,7 +263,6 @@ set ( INC_FILES inc/MantidAlgorithms/AppendSpectra.h inc/MantidAlgorithms/ApplyCalibration.h inc/MantidAlgorithms/ApplyDeadTimeCorr.h - inc/MantidAlgorithms/PhaseQuadMuon.h inc/MantidAlgorithms/ApplyDetailedBalance.h inc/MantidAlgorithms/ApplyTransmissionCorrection.h inc/MantidAlgorithms/AsymmetryCalc.h @@ -411,6 +410,7 @@ set ( INC_FILES inc/MantidAlgorithms/PDFFourierTransform.h inc/MantidAlgorithms/Pause.h inc/MantidAlgorithms/PerformIndexOperations.h + inc/MantidAlgorithms/PhaseQuadMuon.h inc/MantidAlgorithms/PlotAsymmetryByLogValue.h inc/MantidAlgorithms/Plus.h inc/MantidAlgorithms/PointByPointVCorrection.h @@ -658,6 +658,7 @@ set ( TEST_FILES PDFFourierTransformTest.h PauseTest.h PerformIndexOperationsTest.h + PhaseQuadMuonTest.h PlotAsymmetryByLogValueTest.h PlusTest.h PointByPointVCorrectionTest.h diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h index cdd2d9b8f18..99ee4a137ff 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h @@ -45,7 +45,7 @@ namespace Mantid /// Algorithm's name for identification overriding a virtual method virtual const std::string name() const { return "PhaseQuad";} ///Summary of algorithms purpose - virtual const std::string summary() const {return "Calculate Muon spectra from PhaseTable.";} + virtual const std::string summary() const {return "Calculate Muon squashograms from inputWorkspace and PhaseTable.";} /// Algorithm's version for identification overriding a virtual method virtual int version() const { return 1;} @@ -56,13 +56,13 @@ namespace Mantid class HistData { // TODO: do I need all the members? public: - double n0; // - double alpha; // Efective asymmetry - double phi; // Phase - double lag; // Time-shift - double dead; // - double deadm; // - double chisq; // Of silver fit + bool detOK; // Detector is OK + double alpha; // Detector efficiency + double phi; // Detector phase + double lag; // Detector time-shift + double dead; // Dead TODO remove if not used + double deadm; // Dead TODO remove if not used + double chisq; // Of silver fit TODO remove if not used }; /// Initialise the properties @@ -71,7 +71,7 @@ namespace Mantid void exec(); /// Load the PhaseTable void loadPhaseTable(const std::string& filename); - /// TODO + /// Rescale detector efficiency to maximum value void normaliseAlphas (std::vector<HistData>& m_histData); /// Remove exponential decay from input histograms void removeExponentialDecay (API::MatrixWorkspace_sptr inputWs, API::MatrixWorkspace_sptr outputWs); @@ -79,31 +79,33 @@ namespace Mantid void loseExponentialDecay (API::MatrixWorkspace_sptr inputWs, API::MatrixWorkspace_sptr outputWs); /// Create squashograms void squash(API::MatrixWorkspace_sptr tempWs, API::MatrixWorkspace_sptr outputWs); + /// Put back in exponential decay + void regainExponential(API::MatrixWorkspace_sptr outputWs); /// Number of input histograms size_t m_nHist; /// Number of datapoints per histogram size_t m_nData; - /// TODO + /// TODO: remove if not necessary double m_res; - /// Mean of time-shifts + /// Mean of time-shifts TODO: remove if not necessary double m_meanLag; - /// Good muons from here on (bin no) + /// Good muons from here on (bin no) TODO: remove if not necessary size_t m_tValid; - /// Pulse definitely finished by here (bin no) + /// Pulse definitely finished by here (bin no) TODO: remove if not necessary size_t m_tNoPulse; - /// Double-pulse flag + /// Double-pulse flag TODO: remove if not necessary bool m_isDouble; - /// Muon decay curve + /// Muon decay curve TODO: remove if not necessary double m_tau; - /// Freq (of silver run) + /// Freq (of silver run) TODO: remove if not necessary double m_w; /// Muon lifetime double m_muLife; - /// Poisson limit + /// Poisson limit TODO: remove if not necessary double m_poissonLim; - /// TODO + /// Maximum counts expected double m_bigNumber; - /// Vector of histograms data + /// Vector of detector data std::vector<HistData> m_histData; }; diff --git a/Code/Mantid/Framework/Algorithms/src/PhaseQuadMuon.cpp b/Code/Mantid/Framework/Algorithms/src/PhaseQuadMuon.cpp index 8d9e1a022e3..0ab6d942695 100644 --- a/Code/Mantid/Framework/Algorithms/src/PhaseQuadMuon.cpp +++ b/Code/Mantid/Framework/Algorithms/src/PhaseQuadMuon.cpp @@ -5,6 +5,7 @@ #include "MantidAlgorithms/PhaseQuadMuon.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/IFileLoader.h" +#include "MantidAPI/FrameworkManager.h" namespace Mantid { @@ -29,12 +30,6 @@ void PhaseQuadMuon::init() declareProperty(new API::WorkspaceProperty<API::MatrixWorkspace>("OutputWorkspace", "", Direction::Output), "Name of the output workspace" ); - declareProperty(new API::WorkspaceProperty<API::MatrixWorkspace>("OutputWorkspace1","", Direction::Output), - "Name of the output workspace" ); - - declareProperty(new API::WorkspaceProperty<API::MatrixWorkspace>("OutputWorkspace2","", Direction::Output), - "Name of the output workspace" ); - declareProperty(new API::FileProperty("PhaseTable", "", API::FileProperty::Load, ".INF"), "The name of the list of phases for each spectrum"); } @@ -44,8 +39,6 @@ void PhaseQuadMuon::init() */ void PhaseQuadMuon::exec() { - // TODO - // Get input workspace API::MatrixWorkspace_sptr inputWs = getProperty("InputWorkspace"); @@ -53,51 +46,46 @@ void PhaseQuadMuon::exec() std::string filename = getPropertyValue("PhaseTable"); loadPhaseTable ( filename ); + // Set number of data points per histogram m_nData = inputWs->getSpectrum(0)->readY().size(); - m_nHist = inputWs->getNumberHistograms(); + + // Check number of histograms in inputWs match number of detectors in phase table + if (m_nHist != inputWs->getNumberHistograms()) + { + throw std::runtime_error("PhaseQuad: Number of histograms in phase table does not match number of spectra in workspace"); + } // Create temporary workspace to perform operations on it - API::MatrixWorkspace_sptr tempWs1 = boost::dynamic_pointer_cast<API::MatrixWorkspace>( - API::WorkspaceFactory::Instance().create("Workspace2D", inputWs->getNumberHistograms(), inputWs->getSpectrum(0)->readX().size(), inputWs->getSpectrum(0)->readY().size())); - // Create temporary workspace to perform operations on it - API::MatrixWorkspace_sptr tempWs2 = boost::dynamic_pointer_cast<API::MatrixWorkspace>( - API::WorkspaceFactory::Instance().create("Workspace2D", inputWs->getNumberHistograms(), inputWs->getSpectrum(0)->readX().size(), inputWs->getSpectrum(0)->readY().size())); + API::MatrixWorkspace_sptr tempWs = boost::dynamic_pointer_cast<API::MatrixWorkspace>( + API::WorkspaceFactory::Instance().create("Workspace2D", m_nHist, m_nData+1, m_nData)); - // Create output workspace with two spectra + // Create output workspace with two spectra (squashograms) API::MatrixWorkspace_sptr outputWs = getProperty("OutputWorkspace"); outputWs = boost::dynamic_pointer_cast<API::MatrixWorkspace>( - API::WorkspaceFactory::Instance().create("Workspace2D", 2, inputWs->getSpectrum(0)->readX().size(), inputWs->getSpectrum(0)->readY().size())); + API::WorkspaceFactory::Instance().create("Workspace2D", 2, m_nData+1, m_nData)); outputWs->getAxis(0)->unit() = inputWs->getAxis(0)->unit(); + // Rescale detector efficiency to maximum value normaliseAlphas(m_histData); - removeExponentialDecay(inputWs,tempWs1); - loseExponentialDecay(inputWs,tempWs2); - squash (tempWs2, outputWs); + // Remove exponential decay and save results into tempWs + loseExponentialDecay(inputWs,tempWs); + // Compute squashograms + squash (tempWs, outputWs); + // Regain exponential decay + regainExponential(outputWs); - setProperty("OutputWorkspace", outputWs); // TODO: change this - setProperty("OutputWorkspace1", tempWs1); // TODO: change this - setProperty("OutputWorkspace2", tempWs2); // TODO: change this -} + setProperty("OutputWorkspace", outputWs); + //setProperty("OutputWorkspace1", tempWs1); // TODO: change this + //setProperty("OutputWorkspace2", tempWs2); // TODO: change this + // TODO remove temporary workspace tempWs + //Mantid::API::FrameworkManager::Instance().deleteWorkspace(tempWs); + -void PhaseQuadMuon::normaliseAlphas (std::vector<HistData>& histData) -{ - double max=0; - for (size_t h=0; h<m_nHist; h++) - { - if (histData[h].alpha>max) - { - max = histData[h].alpha; - } - } - for (size_t h=0; h<m_nHist; h++) - { - histData[h].alpha /= max; - } } //---------------------------------------------------------------------------------------------- /** Load PhaseTable file to a vector of HistData. -* @param filename :: phase table .inf filename +* @param filename :: [input] phase table .inf filename */ void PhaseQuadMuon::loadPhaseTable(const std::string& filename ) { @@ -132,24 +120,25 @@ void PhaseQuadMuon::loadPhaseTable(const std::string& filename ) // Read first useful line input >> m_nHist >> m_tValid >> m_tNoPulse >> m_meanLag; + // Read histogram data int cont=0; - while( !input.eof() ) + HistData tempData; + while( input >> tempData.detOK >> tempData.alpha >> tempData.phi >> tempData.lag >> tempData.dead >> tempData.deadm ) { - // Read histogram data - HistData tempData; - input >> tempData.n0 >> tempData.alpha >> tempData.phi >> tempData.lag >> tempData.dead >> tempData.deadm; m_histData.push_back (tempData); cont++; } - if ( cont!= m_nHist ) - { - throw Exception::FileError("PhaseQuad: File was not in expected format", filename); // TODO: specify that number of lines is wrong - } - - if ( cont<3 ) + if ( cont != m_nHist ) { - throw std::runtime_error("PhaseQuad: Found less than 4 histograms"); + if ( cont < m_nHist ) + { + throw Exception::FileError("PhaseQuad: Lines missing in phase table ", filename); + } + else + { + throw Exception::FileError("PhaseQuad: Extra lines in phase table ", filename); + } } } @@ -162,6 +151,31 @@ void PhaseQuadMuon::loadPhaseTable(const std::string& filename ) } +//---------------------------------------------------------------------------------------------- +/** Rescale detector efficiencies to maximum value. +* @param histData :: vector of HistData containing detector efficiencies +*/ +void PhaseQuadMuon::normaliseAlphas (std::vector<HistData>& histData) +{ + double max=0; + for (size_t h=0; h<m_nHist; h++) + { + if (histData[h].alpha>max) + { + max = histData[h].alpha; + } + } + if ( !max ) + { + throw std::runtime_error("PhaseQuad: Could not rescale efficiencies"); + } + + for (size_t h=0; h<m_nHist; h++) + { + histData[h].alpha /= max; + } +} + //---------------------------------------------------------------------------------------------- /** Remove exponential decay from input histograms, i.e., calculate asymmetry @@ -170,49 +184,38 @@ void PhaseQuadMuon::loadPhaseTable(const std::string& filename ) */ void PhaseQuadMuon::removeExponentialDecay (API::MatrixWorkspace_sptr inputWs, API::MatrixWorkspace_sptr outputWs) { + // Muon decay: N(t) = N0 exp(-t/tau) [ 1 + a P(t) ] + // N(t) - N0 exp(-t/tau) = 1 + a P(t) + // Int N(t) dt = N0 Int exp(-t/tau) dt - if ( m_nHist != inputWs->getNumberHistograms() ) - { - throw std::runtime_error("InputWorkspace and PhaseTable do not have the same number of spectra"); - } - else + for (size_t h=0; h<inputWs->getNumberHistograms(); h++) { + auto specIn = inputWs->getSpectrum(h); + auto specOut = outputWs->getSpectrum(h); - // Muon decay: N(t) = N0 exp(-t/tau) [ 1 + a P(t) ] - // N(t) - N0 exp(-t/tau) = 1 + a P(t) - // N0? - // Int N(t) dt = N0 Int exp(-t/tau) dt + specOut->dataX()=specIn->readX(); - for (size_t h=0; h<inputWs->getNumberHistograms(); h++) + double sum1, sum2; + sum1=sum2=0; + for(int i=0; i<m_nData; i++) { - auto specIn = inputWs->getSpectrum(h); - auto specOut = outputWs->getSpectrum(h); - - specOut->dataX()=specIn->readX(); - - double sum1, sum2; - sum1=sum2=0; - for(int i=0; i<m_nData; i++) + if ( specIn->readX()[i]>=0 ) { - if ( specIn->readX()[i]>=0 ) - { - sum1 += specIn->dataY()[i]; - sum2 += exp( -((specIn->dataX()[i+1]-specIn->dataX()[i])*0.5+specIn->dataX()[i])/m_muLife); - } + sum1 += specIn->dataY()[i]; + sum2 += exp( -((specIn->dataX()[i+1]-specIn->dataX()[i])*0.5+specIn->dataX()[i])/m_muLife); } - double N0 = sum1/sum2; + } + double N0 = sum1/sum2; - for (int i=0; i<m_nData; i++) + for (int i=0; i<m_nData; i++) + { + if ( specIn->readX()[i]>=0 ) { - if ( specIn->readX()[i]>=0 ) - { - specOut->dataY()[i] = specIn->dataY()[i] - N0*exp(-((specIn->dataX()[i+1]-specIn->dataX()[i])*0.5+specIn->dataX()[i])/m_muLife); - specOut->dataE()[i] = ( specIn->readY()[i] > m_poissonLim) ? specIn->readE()[i] : sqrt(N0*exp(-specIn->readX()[i]/m_muLife)); - } + specOut->dataY()[i] = specIn->dataY()[i] - N0*exp(-((specIn->dataX()[i+1]-specIn->dataX()[i])*0.5+specIn->dataX()[i])/m_muLife); + specOut->dataE()[i] = ( specIn->readY()[i] > m_poissonLim) ? specIn->readE()[i] : sqrt(N0*exp(-specIn->readX()[i]/m_muLife)); } - } // Histogram loop - - }// else + } + } // Histogram loop } @@ -223,62 +226,57 @@ void PhaseQuadMuon::removeExponentialDecay (API::MatrixWorkspace_sptr inputWs, A */ void PhaseQuadMuon::loseExponentialDecay (API::MatrixWorkspace_sptr inputWs, API::MatrixWorkspace_sptr outputWs) { - - if ( m_nHist != inputWs->getNumberHistograms() ) + for (size_t h=0; h<inputWs->getNumberHistograms(); h++) { - throw std::runtime_error("InputWorkspace and PhaseTable do not have the same number of spectra"); - } - else - { - - for (size_t h=0; h<inputWs->getNumberHistograms(); h++) - { - auto specIn = inputWs->getSpectrum(h); - auto specOut = outputWs->getSpectrum(h); + auto specIn = inputWs->getSpectrum(h); + auto specOut = outputWs->getSpectrum(h); - specOut->dataX()=specIn->readX(); + specOut->dataX()=specIn->readX(); - for(int i=0; i<m_nData; i++) + for(int i=0; i<m_nData; i++) + { + if ( specIn->readX()[i]>=0 ) { - if ( specIn->readX()[i]>=0 ) - { - double usey = specIn->readY()[i]; - double oops = ( (usey<=0) || (specIn->readE()[i]>=m_bigNumber)); - specOut->dataY()[i] = oops ? 0 : log(usey); - specOut->dataE()[i] = oops ? m_bigNumber : specIn->readE()[i]/usey; - } + double usey = specIn->readY()[i]; + double oops = ( (usey<=0) || (specIn->readE()[i]>=m_bigNumber)); + specOut->dataY()[i] = oops ? 0 : log(usey); + specOut->dataE()[i] = oops ? m_bigNumber : specIn->readE()[i]/usey; } + } - double s, sx, sy, sig; - s = sx = sy =0; - for (int i=0; i<m_nData; i++) + double s, sx, sy, sig; + s = sx = sy =0; + for (int i=0; i<m_nData; i++) + { + if ( specIn->readX()[i]>=0 ) { - if ( specIn->readX()[i]>=0 ) - { - sig = specOut->readE()[i]*specOut->readE()[i]; - s += 1./sig; - sx+= specOut->readX()[i]/sig; - sy+= specOut->readY()[i]/sig; - } + sig = specOut->readE()[i]*specOut->readE()[i]; + s += 1./sig; + sx+= specOut->readX()[i]/sig; + sy+= specOut->readY()[i]/sig; } - double N0 = (sy+sx/m_muLife)/s; - N0=exp(N0); + } + double N0 = (sy+sx/m_muLife)/s; + N0=exp(N0); - for (int i=0; i<m_nData; i++) + for (int i=0; i<m_nData; i++) + { + if ( specIn->readX()[i]>=0 ) { - if ( specIn->readX()[i]>=0 ) - { - specOut->dataY()[i] = specIn->dataY()[i] - N0 *exp(-specIn->readX()[i]/m_muLife); - specOut->dataE()[i] = ( specIn->readY()[i] > m_poissonLim) ? specIn->readE()[i] : sqrt(N0*exp(-specIn->readX()[i]/m_muLife)); - } + specOut->dataY()[i] = specIn->dataY()[i] - N0 *exp(-specIn->readX()[i]/m_muLife); + specOut->dataE()[i] = ( specIn->readY()[i] > m_poissonLim) ? specIn->readE()[i] : sqrt(N0*exp(-specIn->readX()[i]/m_muLife)); } - } // Histogram loop - - }// else + } + } // Histogram loop } +//---------------------------------------------------------------------------------------------- +/** Compute Squashograms +* @param tempWs :: input workspace containing the asymmetry in the lab frame +* @param outputWs :: output workspace to hold squashograms +*/ void PhaseQuadMuon::squash(API::MatrixWorkspace_sptr tempWs, API::MatrixWorkspace_sptr outputWs) { @@ -286,11 +284,11 @@ void PhaseQuadMuon::squash(API::MatrixWorkspace_sptr tempWs, API::MatrixWorkspac double syy=0; double sxy=0; - for (size_t h=0; h<tempWs->getNumberHistograms(); h++) + for (size_t h=0; h<m_nHist; h++) { auto data = m_histData[h]; - double X = data.n0 * data.alpha * cos(data.phi); - double Y = data.n0 * data.alpha * sin(data.phi); + double X = data.detOK * data.alpha * cos(data.phi); + double Y = data.detOK * data.alpha * sin(data.phi); sxx += X*X; syy += Y*Y; sxy += X*Y; @@ -305,8 +303,8 @@ void PhaseQuadMuon::squash(API::MatrixWorkspace_sptr tempWs, API::MatrixWorkspac for (size_t h=0; h<m_nHist; h++) { auto data = m_histData[h]; - double X = data.n0 * data.alpha * cos(data.phi); - double Y = data.n0 * data.alpha * sin(data.phi); + double X = data.detOK * data.alpha * cos(data.phi); + double Y = data.detOK * data.alpha * sin(data.phi); aj.push_back( (lam1 * X + mu1 * Y)*0.5 ); bj.push_back( (lam2 * X + mu2 * Y)*0.5 ); } @@ -327,17 +325,6 @@ void PhaseQuadMuon::squash(API::MatrixWorkspace_sptr tempWs, API::MatrixWorkspac sigm2[i] = sqrt(sigm2[i]); } - for (size_t i=0; i<m_nData; i++) - { - double x = tempWs->getSpectrum(0)->readX()[i]; - double xp= tempWs->getSpectrum(0)->readX()[i+1]; - double e = exp(-( (xp-x)*0.5+x )/m_muLife); - data1[i] /= e; - data2[i] /= e; - sigm1[i] /= e; - sigm2[i] /= e; - } - outputWs->getSpectrum(0)->dataX() = tempWs->getSpectrum(0)->readX(); outputWs->getSpectrum(0)->dataY() = data1; outputWs->getSpectrum(0)->dataE() = sigm1; @@ -348,5 +335,26 @@ void PhaseQuadMuon::squash(API::MatrixWorkspace_sptr tempWs, API::MatrixWorkspac } +//---------------------------------------------------------------------------------------------- +/** Put back in exponential decay +* @param outputWs :: output workspace with squashograms to update +*/ +void PhaseQuadMuon::regainExponential(API::MatrixWorkspace_sptr outputWs) +{ + auto specRe = outputWs->getSpectrum(0); + auto specIm = outputWs->getSpectrum(1); + + for (size_t i=0; i<m_nData; i++) + { + double x = outputWs->getSpectrum(0)->readX()[i]; + double xp= outputWs->getSpectrum(0)->readX()[i+1]; + double e = exp(-( (xp-x)*0.5+x )/m_muLife); + specRe->dataY()[i] /= e; + specIm->dataY()[i] /= e; + specRe->dataE()[i] /= e; + specIm->dataE()[i] /= e; + } +} + } } \ No newline at end of file diff --git a/Code/Mantid/Framework/Algorithms/test/PhaseQuadMuonTest.h b/Code/Mantid/Framework/Algorithms/test/PhaseQuadMuonTest.h new file mode 100644 index 00000000000..22e2591dffe --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/PhaseQuadMuonTest.h @@ -0,0 +1,99 @@ +#ifndef MANTID_ALGORITHMS_PHASEQUADMUONTEST_H_ +#define MANTID_ALGORITHMS_PHASEQUADMUONTEST_H_ + +#include <cxxtest/TestSuite.h> +#include "MantidDataHandling/LoadMuonNexus2.h" +#include "MantidAlgorithms/PhaseQuadMuon.h" +#include <Poco/File.h> +#include <stdexcept> + +using namespace Mantid::Algorithms; +using namespace Mantid::API; + +class PhaseQuadMuonTest : public CxxTest::TestSuite +{ +public: + + void testName() + { + TS_ASSERT_EQUALS( phaseQuadMuon.name(), "PhaseQuad" ); + } + + void testCategory() + { + TS_ASSERT_EQUALS( phaseQuadMuon.category(), "Muon" ) + } + + void testInit() + { + TS_ASSERT_THROWS_NOTHING( phaseQuadMuon.initialize() ); + TS_ASSERT( phaseQuadMuon.isInitialized() ) + } + + void testExec() + { + loader.initialize(); + loader.setPropertyValue("Filename", "emu00006473.nxs"); + loader.setPropertyValue("OutputWorkspace", "EMU6473"); + TS_ASSERT_THROWS_NOTHING( loader.execute() ); + TS_ASSERT_EQUALS(loader.isExecuted(),true); + + MatrixWorkspace_sptr inputWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("EMU6473"); + + std::string filename("TestPhaseTable.txt"); + generatePhaseTable(filename); + + TS_ASSERT_THROWS_NOTHING( phaseQuadMuon.setProperty("PhaseTable", "TestPhaseTable.txt") ); + TS_ASSERT_THROWS_NOTHING( phaseQuadMuon.setProperty("InputWorkspace", "EMU6473") ); + TS_ASSERT_THROWS_NOTHING( phaseQuadMuon.setProperty("OutputWorkspace", "EMU6473_out") ); + + TS_ASSERT_THROWS_NOTHING( phaseQuadMuon.execute() ); + TS_ASSERT( phaseQuadMuon.isExecuted() ); + + MatrixWorkspace_sptr outputWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("EMU6473_out"); + + TS_ASSERT_EQUALS( outputWs->getNumberHistograms(), 2); + TS_ASSERT_EQUALS( outputWs->getSpectrum(0)->readX(), inputWs->getSpectrum(0)->readX() ); // Check outputWs X values + TS_ASSERT_EQUALS( outputWs->getSpectrum(1)->readX(), inputWs->getSpectrum(1)->readX() ); + + // TODO add more tests + + AnalysisDataService::Instance().remove("EMU6473"); // remove inputWs + AnalysisDataService::Instance().remove("EMU6473_out"); // remove OutputWs + Poco::File("TestPhaseTable.txt").remove(); // remove phase table + } + + void generatePhaseTable (std::string filename) + { + std::ofstream ofile; + ofile.open(filename.c_str()); + + if (ofile.is_open()) + { + // Write header + ofile << "MuSR 64 det 12705-12715" << std::endl; + ofile << "Top row of numbers are:" << std::endl; + ofile << "#histos, typ. first good bin#, typ. bin# when pulse over, mean lag." << std::endl; + ofile << "Tabulated numbers are, per histogram:" << std::endl; + ofile << "det ok, asymmetry, phase, lag, deadtime_c, deadtime_m." << std::endl; + ofile << "32 2 0 0" << std::endl; + // Write data + for (int i=0; i<16; i++) + { + ofile << "1 50.0 0.00 0.0 0.0 1" << std::endl; + ofile << "1 50.0 1.57 0.0 0.0 1" << std::endl; + } + ofile.close(); + } + else + { + throw std::runtime_error("Unable to open file to write."); + } + } + +private: + PhaseQuadMuon phaseQuadMuon; + Mantid::DataHandling::LoadMuonNexus2 loader; +}; + +#endif /* MANTID_ALGORITHMS_PHASEQUADMUONTEST_H_ */ \ No newline at end of file -- GitLab