Skip to content
Snippets Groups Projects
ConjoinWorkspacesTest.h 9 KiB
Newer Older
#ifndef CONJOINWORKSPACESTEST_H_
#define CONJOINWORKSPACESTEST_H_

#include <cxxtest/TestSuite.h>

#include "MantidAlgorithms/ConjoinWorkspaces.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"

using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::Algorithms;
using namespace Mantid::DataObjects;
class ConjoinWorkspacesTest : public CxxTest::TestSuite {
  // This pair of boilerplate methods prevent the suite being created statically
  // This means the constructor isn't called when running other tests
  static ConjoinWorkspacesTest *createSuite() {
    return new ConjoinWorkspacesTest();
  static void destroySuite(ConjoinWorkspacesTest *suite) { delete suite; }
  ConjoinWorkspacesTest()
      : ws1Name("ConjoinWorkspacesTest_grp1"),
        ws2Name("ConjoinWorkspacesTest_grp2") {}
  void setupWS() {
    IAlgorithm *loader;
    loader = new Mantid::DataHandling::LoadRaw3;
    loader->initialize();
    loader->setPropertyValue("Filename", "OSI11886.raw");
    loader->setPropertyValue("OutputWorkspace", "top");
    loader->setPropertyValue("SpectrumMin", "1");
    loader->setPropertyValue("SpectrumMax", "10");
    TS_ASSERT_THROWS_NOTHING(loader->execute());
    TS_ASSERT(loader->isExecuted());
    delete loader;

    loader = new Mantid::DataHandling::LoadRaw3;
    loader->initialize();
    loader->setPropertyValue("Filename", "OSI11886.raw");
    loader->setPropertyValue("OutputWorkspace", "bottom");
    loader->setPropertyValue("SpectrumMin", "11");
    loader->setPropertyValue("SpectrumMax", "25");
    TS_ASSERT_THROWS_NOTHING(loader->execute());
    TS_ASSERT(loader->isExecuted());
  void testTheBasics() {
    ConjoinWorkspaces conj;
    TS_ASSERT_EQUALS(conj.name(), "ConjoinWorkspaces");
    TS_ASSERT_EQUALS(conj.version(), 1);
    TS_ASSERT_THROWS_NOTHING(conj.initialize());
    TS_ASSERT(conj.isInitialized());
  }

  //----------------------------------------------------------------------------------------------
  void testExec() {
    ConjoinWorkspaces conj;
    if (!conj.isInitialized())
      conj.initialize();
    // Get the two input workspaces for later
    MatrixWorkspace_sptr in1 = boost::dynamic_pointer_cast<MatrixWorkspace>(
        AnalysisDataService::Instance().retrieve("top"));
    MatrixWorkspace_sptr in2 = boost::dynamic_pointer_cast<MatrixWorkspace>(
        AnalysisDataService::Instance().retrieve("bottom"));
    // Mask a spectrum and check it is carried over
    const size_t maskTop(5), maskBottom(10);
    in1->maskWorkspaceIndex(maskTop);
    in2->maskWorkspaceIndex(maskBottom);

    // Check it fails if properties haven't been set
    TS_ASSERT_THROWS(conj.execute(), std::runtime_error);
    TS_ASSERT(!conj.isExecuted());

    // Check it fails if input overlap
    TS_ASSERT_THROWS_NOTHING(conj.setPropertyValue("InputWorkspace1", "top"));
    TS_ASSERT_THROWS_NOTHING(conj.setPropertyValue("InputWorkspace2", "top"));
    TS_ASSERT_THROWS_NOTHING(conj.execute());
    TS_ASSERT(!conj.isExecuted());
    TS_ASSERT_THROWS_NOTHING(conj.setPropertyValue("InputWorkspace1", "top"));
    TS_ASSERT_THROWS_NOTHING(
        conj.setPropertyValue("InputWorkspace2", "bottom"));
    TS_ASSERT_THROWS_NOTHING(conj.execute());
    TS_ASSERT(conj.isExecuted());
    TS_ASSERT_THROWS_NOTHING(
        output = boost::dynamic_pointer_cast<MatrixWorkspace>(
            AnalysisDataService::Instance().retrieve("top")));
    TS_ASSERT_EQUALS(output->getNumberHistograms(), 25);
    TS_ASSERT_EQUALS(output->readX(0)[0], in1->readX(0)[0]);
    TS_ASSERT_EQUALS(output->readX(15)[444], in2->readX(5)[444]);
    TS_ASSERT_EQUALS(output->readY(3)[99], in1->readY(3)[99]);
    TS_ASSERT_EQUALS(output->readE(7)[700], in1->readE(7)[700]);
    TS_ASSERT_EQUALS(output->readY(19)[55], in2->readY(9)[55]);
    TS_ASSERT_EQUALS(output->readE(10)[321], in2->readE(0)[321]);
    TS_ASSERT_EQUALS(output->getAxis(1)->spectraNo(5),
                     in1->getAxis(1)->spectraNo(5));
    TS_ASSERT_EQUALS(output->getAxis(1)->spectraNo(12),
                     in2->getAxis(1)->spectraNo(2));

    // Check masking
    TS_ASSERT_EQUALS(output->getDetector(maskTop)->isMasked(), true);
    TS_ASSERT_EQUALS(output->getDetector(10 + maskBottom)->isMasked(), true);
    // Check that 2nd input workspace no longer exists
    TS_ASSERT_THROWS(AnalysisDataService::Instance().retrieve("bottom"),
                     Exception::NotFoundError);

    // Check that th workspace has the correct number of history entries
    TS_ASSERT_EQUALS(output->getHistory().size(), 3);
  //----------------------------------------------------------------------------------------------
  void testExecMismatchedWorkspaces() {
    MatrixWorkspace_sptr ews =
        WorkspaceCreationHelper::CreateEventWorkspace(10, 10);

    // Check it fails if input overlap
    ConjoinWorkspaces conj;
    conj.initialize();
    TS_ASSERT_THROWS_NOTHING(conj.setProperty("InputWorkspace1", ews));
    TS_ASSERT_THROWS_NOTHING(conj.setProperty("InputWorkspace2", ews));
    TS_ASSERT(!conj.isExecuted());

    // Check it fails if mixing event workspaces and workspace 2Ds
    TS_ASSERT_THROWS_NOTHING(conj.setProperty("InputWorkspace1", ews));
    TS_ASSERT_THROWS_NOTHING(conj.setProperty(
        "InputWorkspace2", WorkspaceCreationHelper::Create2DWorkspace(10, 10)));
    TS_ASSERT(!conj.isExecuted());
  void testDoCheckForOverlap() {
    MatrixWorkspace_sptr ws1, ws2;
    int numPixels = 10;
    int numBins = 20;
    ws1 = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins);
    const std::string ws1_name = "ConjoinWorkspaces_testDoCheckForOverlap";
    AnalysisDataService::Instance().add(ws1_name, ws1);
    ws2 = WorkspaceCreationHelper::CreateEventWorkspace(5, numBins);

    ConjoinWorkspaces conj;
    conj.initialize();
    TS_ASSERT_THROWS_NOTHING(
        conj.setPropertyValue("InputWorkspace1", ws1_name));
    TS_ASSERT_THROWS_NOTHING(conj.setProperty("InputWorkspace2", ws2));
    TS_ASSERT_THROWS_NOTHING(conj.setProperty("CheckOverlapping", true));
    TS_ASSERT_THROWS_NOTHING(conj.execute());
    // Falls over as they overlap
    TS_ASSERT(!conj.isExecuted());
    Mantid::specid_t start =
        ws1->getSpectrum(numPixels - 1)->getSpectrumNo() + 10;
    for (int i = 0; i < 5; ++i) {
      Mantid::API::ISpectrum *spec = ws2->getSpectrum(i);
      spec->setSpectrumNo(start + i);
      spec->clearDetectorIDs();
      spec->addDetectorID(start + i);
    }

    TS_ASSERT_THROWS_NOTHING(conj.setProperty("InputWorkspace2", ws2));
    TS_ASSERT_THROWS_NOTHING(conj.execute());
    TS_ASSERT(conj.isExecuted());
    MatrixWorkspace_sptr output = boost::dynamic_pointer_cast<MatrixWorkspace>(
        AnalysisDataService::Instance().retrieve(ws1_name));
    TS_ASSERT(output);
    // Check the first spectrum has the correct ID
    TS_ASSERT_EQUALS(output->getNumberHistograms(), 15);
    TS_ASSERT_EQUALS(output->getSpectrum(0)->getSpectrumNo(),
                     ws1->getSpectrum(0)->getSpectrumNo());
    // and the joining point
    TS_ASSERT_EQUALS(output->getSpectrum(10)->getSpectrumNo(), start);
    TS_ASSERT(!output->getSpectrum(11)->getDetectorIDs().empty());

    AnalysisDataService::Instance().remove(ws1_name);
  }

  void performTestNoOverlap(bool event) {
    MatrixWorkspace_sptr ws1, ws2, out;
    int numBins = 20;

    if (event) {
      ws1 = WorkspaceCreationHelper::CreateEventWorkspace2(
          10, numBins); // 2 events per bin
      ws2 = WorkspaceCreationHelper::CreateEventWorkspace2(5, numBins);
      ws1 = WorkspaceCreationHelper::Create2DWorkspace(10, numBins);
      ws2 = WorkspaceCreationHelper::Create2DWorkspace(5, numBins);
    }
    AnalysisDataService::Instance().addOrReplace(ws1Name, ws1);
    AnalysisDataService::Instance().addOrReplace(ws2Name, ws2);

    ConjoinWorkspaces conj;
    conj.initialize();
    TS_ASSERT_THROWS_NOTHING(conj.setPropertyValue("InputWorkspace1", ws1Name));
    TS_ASSERT_THROWS_NOTHING(conj.setPropertyValue("InputWorkspace2", ws2Name));
    TS_ASSERT_THROWS_NOTHING(conj.setProperty("CheckOverlapping", false));
    TS_ASSERT_THROWS_NOTHING(conj.execute();)
    TS_ASSERT(conj.isExecuted());

    TS_ASSERT_THROWS_NOTHING(
        out = boost::dynamic_pointer_cast<MatrixWorkspace>(
            AnalysisDataService::Instance().retrieve(ws1Name));)
    TS_ASSERT_EQUALS(out->getNumberHistograms(), 15);
    TS_ASSERT_EQUALS(out->blocksize(), numBins);
    for (size_t wi = 0; wi < out->getNumberHistograms(); wi++)
      for (size_t x = 0; x < out->blocksize(); x++)
        TS_ASSERT_DELTA(out->readY(wi)[x], 2.0, 1e-5);
  }

  void test_DONTCheckForOverlap_Events() { performTestNoOverlap(true); }
  void test_DONTCheckForOverlap_2D() { performTestNoOverlap(false); }

private:
  const std::string ws1Name;
  const std::string ws2Name;