Skip to content
Snippets Groups Projects
LoadNexusProcessedTest.h 50.7 KiB
Newer Older
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
//     NScD Oak Ridge National Laboratory, European Spallation Source
//     & Institut Laue - Langevin
// SPDX - License - Identifier: GPL - 3.0 +
#ifndef LOADNEXUSPROCESSEDTEST_H_
#define LOADNEXUSPROCESSEDTEST_H_

#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/FileFinder.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/NumericAxis.h"
#include "MantidAPI/WorkspaceGroup.h"
#include "MantidAPI/WorkspaceHistory.h"
#include "MantidDataHandling/Load.h"
#include "MantidDataHandling/LoadInstrument.h"
#include "MantidDataHandling/LoadNexusProcessed.h"
#include "MantidDataHandling/SaveNexusProcessed.h"
#include "MantidDataObjects/Peak.h"
#include "MantidDataObjects/PeakShapeSpherical.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidGeometry/IDTypes.h"
#include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"

#include "SaveNexusProcessedTest.h"

Campbell, Stuart's avatar
Campbell, Stuart committed
#include <Poco/File.h>
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
using namespace Mantid::Geometry;
Janik Zikovsky's avatar
Janik Zikovsky committed
using namespace Mantid::Kernel;
using namespace Mantid::DataObjects;
// Note that this suite tests an old version of Nexus processed files that we
// continue to support.
// LoadRawSaveNxsLoadNxs tests the current version of Nexus processed by loading
// a newly created Nexus processed file.
// LoadRawSaveNxsLoadNxs should be run when making any changes to
// LoadNexusProcessed
// in addition to this test.

class LoadNexusProcessedTest : public CxxTest::TestSuite {
  static LoadNexusProcessedTest *createSuite() {
Owen Arnold's avatar
Owen Arnold committed
    return new LoadNexusProcessedTest();
  }
  static void destroySuite(LoadNexusProcessedTest *suite) { delete suite; }
  LoadNexusProcessedTest()
      : testFile("GEM38370_Focussed_Legacy.nxs"), output_ws("nxstest"),
        m_savedTmpEventFile("") {}
  ~LoadNexusProcessedTest() override {
    AnalysisDataService::Instance().clear();
  void testFastMultiPeriodDefault() {
    LoadNexusProcessed alg;
    alg.initialize();
    TS_ASSERT(alg.isInitialized());
    const bool bFastMultiPeriod = alg.getProperty("FastMultiPeriod");
    TSM_ASSERT("Should defalt to offering fast multiperiod loading",
               bFastMultiPeriod);
  void testProcessedFile() {
    LoadNexusProcessed alg;

    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
    alg.setPropertyValue("Filename", testFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);

    TS_ASSERT_THROWS_NOTHING(alg.execute());
    // Test some aspects of the file
    TS_ASSERT_THROWS_NOTHING(
        workspace = AnalysisDataService::Instance().retrieve(output_ws));
    TS_ASSERT(workspace.get());
    MatrixWorkspace_sptr matrix_ws =
        boost::dynamic_pointer_cast<MatrixWorkspace>(workspace);
    TS_ASSERT(matrix_ws.get());

    // Test proton charge from the sample block
    TS_ASSERT_DELTA(matrix_ws->run().getProtonCharge(), 30.14816, 1e-5);
    boost::shared_ptr<const Mantid::Geometry::Instrument> inst =
        matrix_ws->getInstrument();
    TS_ASSERT_EQUALS(inst->getName(), "GEM");
    TS_ASSERT_EQUALS(inst->getSource()->getPos().Z(), -17);
  void testNexusProcessed_Min_Max() {

    LoadNexusProcessed alg;

    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
Owen Arnold's avatar
Owen Arnold committed
    testFile = "focussed.nxs";
    alg.setPropertyValue("Filename", testFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("SpectrumMin", "2");
    alg.setPropertyValue("SpectrumMax", "4");
    const std::vector<int> expectedSpectra = {3, 4, 5};
    doSpectrumListTests(alg, expectedSpectra);
  void testNexusProcessed_List() {
    LoadNexusProcessed alg;

    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
Owen Arnold's avatar
Owen Arnold committed
    testFile = "focussed.nxs";
    alg.setPropertyValue("Filename", testFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("SpectrumList", "1,2,3,4");
    const std::vector<int> expectedSpectra = {2, 3, 4, 5};
    doSpectrumListTests(alg, expectedSpectra);
  void testNexusProcessed_Min_Max_List() {
    LoadNexusProcessed alg;

    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
Owen Arnold's avatar
Owen Arnold committed
    testFile = "focussed.nxs";
    alg.setPropertyValue("Filename", testFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("SpectrumMin", "1");
    alg.setPropertyValue("SpectrumMax", "3");
    alg.setPropertyValue("SpectrumList", "4,5");
    const std::vector<int> expectedSpectra = {2, 3, 4, 5, 6};
    doSpectrumListTests(alg, expectedSpectra);
  void testNexusProcessed_Min() {
    LoadNexusProcessed alg;

    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
Owen Arnold's avatar
Owen Arnold committed
    testFile = "focussed.nxs";
    alg.setPropertyValue("Filename", testFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("SpectrumMin", "4");

    doSpectrumMinOrMaxTest(alg, 3);
  void testNexusProcessed_Max() {
    LoadNexusProcessed alg;

    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
Owen Arnold's avatar
Owen Arnold committed
    testFile = "focussed.nxs";
    alg.setPropertyValue("Filename", testFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("SpectrumMax", "3");

    doSpectrumMinOrMaxTest(alg, 3);
Owen Arnold's avatar
Owen Arnold committed
  }

  // Saving and reading masking correctly
  void testMasked() {
Owen Arnold's avatar
Owen Arnold committed
    LoadNexusProcessed alg;

    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
Owen Arnold's avatar
Owen Arnold committed
    testFile = "focussed.nxs";
    alg.setPropertyValue("Filename", testFile);
    testFile = alg.getPropertyValue("Filename");

    alg.setPropertyValue("OutputWorkspace", output_ws);

    TS_ASSERT_THROWS_NOTHING(alg.execute());

    // Test some aspects of the file
Owen Arnold's avatar
Owen Arnold committed
    MatrixWorkspace_sptr workspace;
    workspace = boost::dynamic_pointer_cast<MatrixWorkspace>(
        AnalysisDataService::Instance().retrieve(output_ws));
    TS_ASSERT(workspace.get());
    for (size_t si = 0; si < workspace->getNumberHistograms(); ++si) {
Owen Arnold's avatar
Owen Arnold committed
      workspace->maskBin(si, 0, 1.0);
      workspace->maskBin(si, 1, 1.0);
      workspace->maskBin(si, 2, 1.0);
    }

    SaveNexusProcessed save;
    save.initialize();
    save.setPropertyValue("InputWorkspace", output_ws);
    std::string filename = "LoadNexusProcessed_tmp.nxs";
    save.setPropertyValue("Filename", filename);
    filename = save.getPropertyValue("Filename");
    save.execute();
    LoadNexusProcessed load;
    load.initialize();
    load.setPropertyValue("Filename", filename);
    load.setPropertyValue("OutputWorkspace", output_ws);
    load.execute();

    workspace = boost::dynamic_pointer_cast<MatrixWorkspace>(
        AnalysisDataService::Instance().retrieve(output_ws));
    TS_ASSERT(workspace.get());
Owen Arnold's avatar
Owen Arnold committed

    TS_ASSERT_EQUALS(workspace->getNumberHistograms(), 6);

    TS_ASSERT(workspace->hasMaskedBins(0));
    TS_ASSERT(workspace->hasMaskedBins(1));
    TS_ASSERT(workspace->hasMaskedBins(2));
    TS_ASSERT(workspace->hasMaskedBins(3));
    TS_ASSERT(workspace->hasMaskedBins(4));
    TS_ASSERT(workspace->hasMaskedBins(5));

    if (Poco::File(filename).exists())
      Poco::File(filename).remove();
  }

  void dotest_LoadAnEventFile(EventType type) {
Owen Arnold's avatar
Owen Arnold committed
    std::string filename_root = "LoadNexusProcessed_ExecEvent_";

    // Call a function that writes out the file
    std::string outputFile;
    EventWorkspace_sptr origWS =
        SaveNexusProcessedTest::do_testExec_EventWorkspaces(
            filename_root, type, outputFile, false, false);
Owen Arnold's avatar
Owen Arnold committed

    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("Filename", outputFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);

    TS_ASSERT_THROWS_NOTHING(alg.execute());

    // Test some aspects of the file
Owen Arnold's avatar
Owen Arnold committed
    Workspace_sptr workspace;
    TS_ASSERT_THROWS_NOTHING(
        workspace = AnalysisDataService::Instance().retrieve(output_ws));
    TS_ASSERT(workspace.get());
    EventWorkspace_sptr ws =
        boost::dynamic_pointer_cast<EventWorkspace>(workspace);
    TS_ASSERT(ws);
Owen Arnold's avatar
Owen Arnold committed
    if (!ws)
      return;

    // Testing the number of histograms
Owen Arnold's avatar
Owen Arnold committed
    TS_ASSERT_EQUALS(ws->getNumberHistograms(), 5);

    TS_ASSERT_EQUALS(ws->x(0).size(), 100);
    for (size_t wi = 0; wi < 5; wi++) {
      const EventList &el = ws->getSpectrum(wi);
      TS_ASSERT_EQUALS(el.getEventType(), type);
      TS_ASSERT(el.hasDetectorID(detid_t(wi + 1) * 10));
    TS_ASSERT_EQUALS(ws->getSpectrum(0).getNumberEvents(), 300);
    TS_ASSERT_EQUALS(ws->getSpectrum(1).getNumberEvents(), 100);
    TS_ASSERT_EQUALS(ws->getSpectrum(2).getNumberEvents(), 200);
    TS_ASSERT_EQUALS(ws->getSpectrum(3).getNumberEvents(), 0);
    TS_ASSERT_EQUALS(ws->getSpectrum(4).getNumberEvents(), 100);
Owen Arnold's avatar
Owen Arnold committed

    // Do the comparison algo to check that they really are the same
    origWS->sortAll(TOF_SORT, nullptr);
    ws->sortAll(TOF_SORT, nullptr);
    IAlgorithm_sptr alg2 =
        AlgorithmManager::Instance().createUnmanaged("CompareWorkspaces");
Owen Arnold's avatar
Owen Arnold committed
    alg2->initialize();
    alg2->setProperty<MatrixWorkspace_sptr>("Workspace1", origWS);
    alg2->setProperty<MatrixWorkspace_sptr>("Workspace2", ws);
    alg2->setProperty<double>("Tolerance", 1e-5);
    alg2->setProperty<bool>("CheckAxes", false);
    alg2->execute();
    if (alg2->isExecuted()) {
      TS_ASSERT(alg2->getProperty("Result"));
    } else {
      TS_ASSERT(false);
    // Clear old file
Owen Arnold's avatar
Owen Arnold committed
    if (Poco::File(outputFile).exists())
      Poco::File(outputFile).remove();
  }

  void test_LoadEventNexus_TOF() { dotest_LoadAnEventFile(TOF); }
  void test_LoadEventNexus_WEIGHTED() { dotest_LoadAnEventFile(WEIGHTED); }
  void test_LoadEventNexus_WEIGHTED_NOTIME() {
Owen Arnold's avatar
Owen Arnold committed
    dotest_LoadAnEventFile(WEIGHTED_NOTIME);
  }

  void test_loadEventNexus_Min() {
    writeTmpEventNexus();

    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());

    alg.setPropertyValue("Filename", m_savedTmpEventFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
    alg.setPropertyValue("SpectrumMin", "3");
    // this should imply 4==ws->getNumberHistograms()

    // expected number of spectra and length of the alg history
    doCommonEventLoadChecks(alg, 4, 2);
  void test_loadEventNexus_Max() {
    writeTmpEventNexus();

    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());

    alg.setPropertyValue("Filename", m_savedTmpEventFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
    alg.setPropertyValue("SpectrumMax", "2");
    // this should imply 3==ws->getNumberHistograms()

    // expected number of spectra and length of the alg history
    doCommonEventLoadChecks(alg, 2, 2);
  void test_loadEventNexus_Min_Max() {

    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
    alg.setPropertyValue("Filename", m_savedTmpEventFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
    alg.setPropertyValue("SpectrumMin", "2");
    alg.setPropertyValue("SpectrumMax", "4");
    // this should imply 3==ws->getNumberHistograms()

    // expected number of spectra and length of the alg history
    // in history, expect: load + LoadInst (child)
    doCommonEventLoadChecks(alg, 3, 2);
  void test_loadEventNexus_Fail() {
    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());

    alg.setPropertyValue("Filename", m_savedTmpEventFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
    alg.setPropertyValue("SpectrumList", "1,3,5,89");
    // the 89 should cause trouble, but gracefully...

    TS_ASSERT_THROWS_NOTHING(alg.execute());
    TS_ASSERT(!alg.isExecuted());
  void test_loadEventNexus_List() {
    writeTmpEventNexus();

    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());

    alg.setPropertyValue("Filename", m_savedTmpEventFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
    alg.setPropertyValue("SpectrumList", "1,3,5");
    // this should imply 3==ws->getNumberHistograms()

    // expected number of spectra and length of the alg history
    doCommonEventLoadChecks(alg, 3, 2);
  void test_loadEventNexus_Min_List() {
    writeTmpEventNexus();

    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());

    alg.setPropertyValue("Filename", m_savedTmpEventFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
    alg.setPropertyValue("SpectrumList", "5");
    alg.setPropertyValue("SpectrumMin", "4");
    // this should imply 2==ws->getNumberHistograms()

    // expected number of spectra and length of the alg history
    doCommonEventLoadChecks(alg, 3, 2);
  void test_loadEventNexus_Max_List() {
    writeTmpEventNexus();

    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());

    alg.setPropertyValue("Filename", m_savedTmpEventFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
    alg.setPropertyValue("SpectrumMax", "2");
    alg.setPropertyValue("SpectrumList", "3,5");
    // this should imply 4==ws->getNumberHistograms()

    // expected number of spectra and length of the alg history
    doCommonEventLoadChecks(alg, 4, 2);
  void test_loadEventNexus_Min_Max_List() {
    writeTmpEventNexus();

    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());

    alg.setPropertyValue("Filename", m_savedTmpEventFile);
    alg.setPropertyValue("OutputWorkspace", output_ws);
    alg.setPropertyValue("SpectrumMin", "3");
    alg.setPropertyValue("SpectrumMax", "5");
    alg.setPropertyValue("SpectrumList", "1,2,3,5");
    // this should imply 5(all)==ws->getNumberHistograms()

    // expected number of spectra and length of the alg history
    doCommonEventLoadChecks(alg, 5, 2);
  void test_load_saved_workspace_group() {
Owen Arnold's avatar
Owen Arnold committed
    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("Filename", "WorkspaceGroup.nxs");
    alg.setPropertyValue("OutputWorkspace", "group");

    TS_ASSERT_THROWS_NOTHING(alg.execute());

    Workspace_sptr workspace;
    TS_ASSERT_THROWS_NOTHING(
        workspace = AnalysisDataService::Instance().retrieve("group"));
    WorkspaceGroup_sptr group =
        boost::dynamic_pointer_cast<WorkspaceGroup>(workspace);
    TS_ASSERT(group);
Owen Arnold's avatar
Owen Arnold committed
    int groupSize = group->getNumberOfEntries();
    TS_ASSERT_EQUALS(groupSize, 12);
    for (int i = 0; i < groupSize; ++i) {
      MatrixWorkspace_sptr ws =
          boost::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(i));
      TS_ASSERT(ws);
      TS_ASSERT_EQUALS(ws->getNumberHistograms(), 1);
      TS_ASSERT_EQUALS(ws->blocksize(), 10);
      TS_ASSERT_EQUALS(ws->getName(), "group_" + std::to_string(i + 1));
  void test_load_workspace_group_unique_names() {
Owen Arnold's avatar
Owen Arnold committed
    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
    // Group two uses unique names for each workspace
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("Filename", "WorkspaceGroup2.nxs");
    alg.setPropertyValue("OutputWorkspace", "group");

    const char *suffix[] = {"eq2", "eq1", "elf"};
Owen Arnold's avatar
Owen Arnold committed
    TS_ASSERT_THROWS_NOTHING(alg.execute());

    Workspace_sptr workspace;
    TS_ASSERT_THROWS_NOTHING(
        workspace = AnalysisDataService::Instance().retrieve("group"));
    WorkspaceGroup_sptr group =
        boost::dynamic_pointer_cast<WorkspaceGroup>(workspace);
    TS_ASSERT(group);
Owen Arnold's avatar
Owen Arnold committed
    int groupSize = group->getNumberOfEntries();
    TS_ASSERT_EQUALS(groupSize, 3);
    for (int i = 0; i < groupSize; ++i) {
      MatrixWorkspace_sptr ws =
          boost::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(i));
      TS_ASSERT(ws);
      TS_ASSERT_EQUALS(ws->getNumberHistograms(), 1);
      TS_ASSERT_EQUALS(ws->blocksize(), 2);
      TS_ASSERT_EQUALS(ws->getName(), "irs55125_graphite002_to_55131_" +
                                          std::string(suffix[i]));
  void test_load_workspace_group_unique_names_two_workspaces() {
Owen Arnold's avatar
Owen Arnold committed
    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
    // Group two uses unique names for each workspace
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("Filename", "WorkspaceGroup2.nxs");
    alg.setPropertyValue("OutputWorkspace", "group");

    const char *suffix[] = {"eq2", "eq1", "elf"};
Owen Arnold's avatar
Owen Arnold committed
    TS_ASSERT_THROWS_NOTHING(alg.execute());

    Workspace_sptr workspace;
    TS_ASSERT_THROWS_NOTHING(
        workspace = AnalysisDataService::Instance().retrieve("group"));
    WorkspaceGroup_sptr group =
        boost::dynamic_pointer_cast<WorkspaceGroup>(workspace);
    TS_ASSERT(group);
Owen Arnold's avatar
Owen Arnold committed
    int groupSize = group->getNumberOfEntries();
    TS_ASSERT_EQUALS(groupSize, 3);
    for (int i = 0; i < groupSize; ++i) {
      MatrixWorkspace_sptr ws =
          boost::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(i));
      TS_ASSERT(ws);
      TS_ASSERT_EQUALS(ws->getNumberHistograms(), 1);
      TS_ASSERT_EQUALS(ws->blocksize(), 2);
      TS_ASSERT_EQUALS(ws->getName(), "irs55125_graphite002_to_55131_" +
                                          std::string(suffix[i]));
    // load same file again, but to a different group
    // this checks that the names will be unique
Owen Arnold's avatar
Owen Arnold committed

    LoadNexusProcessed alg2;
    TS_ASSERT_THROWS_NOTHING(alg2.initialize());
    TS_ASSERT(alg2.isInitialized());
    // Group two uses unique names for each workspace
Owen Arnold's avatar
Owen Arnold committed
    alg2.setPropertyValue("Filename", "WorkspaceGroup2.nxs");
    alg2.setPropertyValue("OutputWorkspace", "group2");

    TS_ASSERT_THROWS_NOTHING(alg2.execute());
    TS_ASSERT_THROWS_NOTHING(
        workspace = AnalysisDataService::Instance().retrieve("group2"));
Owen Arnold's avatar
Owen Arnold committed
    group = boost::dynamic_pointer_cast<WorkspaceGroup>(workspace);
    TS_ASSERT(group);
Owen Arnold's avatar
Owen Arnold committed
    groupSize = group->getNumberOfEntries();
    TS_ASSERT_EQUALS(groupSize, 3);

    for (int i = 0; i < groupSize; ++i) {
      MatrixWorkspace_sptr ws =
          boost::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(i));
      TS_ASSERT(ws);
      TS_ASSERT_EQUALS(ws->getNumberHistograms(), 1);
      TS_ASSERT_EQUALS(ws->blocksize(), 2);
      TS_ASSERT_EQUALS(ws->getName(), "irs55125_graphite002_to_55131_" +
                                          std::string(suffix[i]) + "_1");
  void test_load_fit_parameters() {
Owen Arnold's avatar
Owen Arnold committed
    LoadNexusProcessed alg;
    TS_ASSERT_THROWS_NOTHING(alg.initialize());
    TS_ASSERT(alg.isInitialized());
Owen Arnold's avatar
Owen Arnold committed
    alg.setPropertyValue("Filename", "HRP38692a.nxs");
    alg.setPropertyValue("OutputWorkspace", "HRPDparameters");

    TS_ASSERT_THROWS_NOTHING(alg.execute());
    ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
        "HRPDparameters");

    // test to see if parameters are loaded
    std::vector<boost::shared_ptr<const Mantid::Geometry::IComponent>>
        bankComp = ws->getInstrument()->getAllComponentsWithName("bank_bsk");
    TS_ASSERT(bankComp[0]->getParameterNames().size() == 3);
  void testTableWorkspace() {
Owen Arnold's avatar
Owen Arnold committed
    Load alg;
    alg.initialize();
    alg.setPropertyValue("Filename", "SavedTableWorkspace.nxs");
    const std::string wsName("SavedTableWorkspace");
    alg.setPropertyValue("OutputWorkspace", wsName);
    TS_ASSERT(alg.execute());
    TableWorkspace_const_sptr ws =
        AnalysisDataService::Instance().retrieveWS<TableWorkspace>(wsName);
    TS_ASSERT_EQUALS(ws->columnCount(), 10);
    TS_ASSERT_EQUALS(ws->rowCount(), 4);
      {
        ConstColumnVector<std::string> column = ws->getVector("Name");
        TS_ASSERT_EQUALS(column[0], "Height");
        TS_ASSERT_EQUALS(column[1], "PeakCentre");
        TS_ASSERT_EQUALS(column[2], "Sigma");
        TS_ASSERT_EQUALS(column[3], "Cost function value");
      }
      {
        ConstColumnVector<double> column = ws->getVector("Value");
        TS_ASSERT_DELTA(column[0], 79.2315, 0.0001);
        TS_ASSERT_DELTA(column[1], 2.3979, 0.0001);
        TS_ASSERT_DELTA(column[2], 0.3495, 0.0001);
        TS_ASSERT_DELTA(column[3], 35.6841, 0.0001);
      }
      {
        ConstColumnVector<double> column = ws->getVector("Error");
        TS_ASSERT_DELTA(column[0], 0.814478, 0.0001);
        TS_ASSERT_DELTA(column[1], 0.00348291, 0.000001);
        TS_ASSERT_DELTA(column[2], 0.00342847, 0.000001);
        TS_ASSERT_EQUALS(column[3], 0);
        TS_ASSERT_THROWS(ConstColumnVector<int64_t> column =
                             ws->getVector("Integer"),
                         const std::runtime_error &);
        ConstColumnVector<int> column = ws->getVector("Integer");
        TS_ASSERT_EQUALS(column[0], 5);
        TS_ASSERT_EQUALS(column[1], 3);
        TS_ASSERT_EQUALS(column[2], 2);
        TS_ASSERT_EQUALS(column[3], 4);
      {
        ConstColumnVector<uint32_t> column = ws->getVector("UInteger");
        TS_ASSERT_EQUALS(column[0], 35);
        TS_ASSERT_EQUALS(column[1], 33);
        TS_ASSERT_EQUALS(column[2], 32);
        TS_ASSERT_EQUALS(column[3], 34);
      {
        ConstColumnVector<int64_t> column = ws->getVector("Integer64");
        TS_ASSERT_EQUALS(column[0], 15);
        TS_ASSERT_EQUALS(column[1], 13);
        TS_ASSERT_EQUALS(column[2], 12);
        TS_ASSERT_EQUALS(column[3], 14);
      }
      {
        ConstColumnVector<float> column = ws->getVector("Float");
        TS_ASSERT_DELTA(column[0], 0.5, 0.000001);
        TS_ASSERT_DELTA(column[1], 0.3, 0.000001);
        TS_ASSERT_DELTA(column[2], 0.2, 0.000001);
        TS_ASSERT_DELTA(column[3], 0.4, 0.000001);
        ConstColumnVector<size_t> column = ws->getVector("Size");
        TS_ASSERT_EQUALS(column[0], 25);
        TS_ASSERT_EQUALS(column[1], 23);
        TS_ASSERT_EQUALS(column[2], 22);
        TS_ASSERT_EQUALS(column[3], 24);
      {
        ConstColumnVector<Boolean> column = ws->getVector("Bool");
        TS_ASSERT(column[0]);
        TS_ASSERT(column[1]);
        TS_ASSERT(!column[2]);
        TS_ASSERT(column[3]);
        ConstColumnVector<Mantid::Kernel::V3D> column =
            ws->getVector("3DVector");
        TS_ASSERT_EQUALS(column[0], Mantid::Kernel::V3D(1, 2, 3));
        TS_ASSERT_EQUALS(column[1], Mantid::Kernel::V3D(4, 5, 6));
        TS_ASSERT_EQUALS(column[2], Mantid::Kernel::V3D(7, 8, 9));
        TS_ASSERT_EQUALS(column[3], Mantid::Kernel::V3D(11, 12, 13));
    } catch (std::exception &e) {
      TS_FAIL(e.what());
Owen Arnold's avatar
Owen Arnold committed

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

  void test_peaks_workspace_with_shape_format() {
    LoadNexusProcessed loadAlg;
    loadAlg.setChild(true);
    loadAlg.initialize();
    loadAlg.setPropertyValue("Filename", "SingleCrystalPeakTable.nxs");
    loadAlg.setPropertyValue("OutputWorkspace", "dummy");
    loadAlg.execute();

    Workspace_sptr ws = loadAlg.getProperty("OutputWorkspace");
    auto peakWS =
        boost::dynamic_pointer_cast<Mantid::DataObjects::PeaksWorkspace>(ws);
    TS_ASSERT(peakWS);

    TS_ASSERT_EQUALS(3, peakWS->getNumberPeaks());
    // In this peaks workspace one of the peaks has been marked as spherically
    // integrated.
    TS_ASSERT_EQUALS("spherical",
                     peakWS->getPeak(0).getPeakShape().shapeName());
    TS_ASSERT_EQUALS("none", peakWS->getPeak(1).getPeakShape().shapeName());
    TS_ASSERT_EQUALS("none", peakWS->getPeak(2).getPeakShape().shapeName());
  /* The nexus format for this type of workspace has a legacy format with no
   * shape information
Owen Arnold's avatar
Owen Arnold committed
   * We should still be able to load that */
  void test_peaks_workspace_no_shape_format() {
    LoadNexusProcessed loadAlg;
    loadAlg.setChild(true);
    loadAlg.initialize();
    loadAlg.setPropertyValue("Filename", "SingleCrystalPeakTableLegacy.nxs");
    loadAlg.setPropertyValue("OutputWorkspace", "dummy");
    loadAlg.execute();

    Workspace_sptr ws = loadAlg.getProperty("OutputWorkspace");
    auto peakWS =
        boost::dynamic_pointer_cast<Mantid::DataObjects::PeaksWorkspace>(ws);
    TS_ASSERT(peakWS);
  void test_coordinates_saved_and_loaded_on_peaks_workspace() {
    auto peaksTestWS = WorkspaceCreationHelper::createPeaksWorkspace();
    // Loading a peaks workspace without a instrument from an IDF doesn't work
    // ...
    const std::string filename = FileFinder::Instance().getFullPath(
        "unit_testing/MINITOPAZ_Definition.xml");
    InstrumentDefinitionParser parser(filename, "MINITOPAZ",
                                      Strings::loadFile(filename));
    auto instrument = parser.parseXML(nullptr);
    peaksTestWS->populateInstrumentParameters();
    peaksTestWS->setInstrument(instrument);

    const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
    peaksTestWS->setCoordinateSystem(appliedCoordinateSystem);

    SaveNexusProcessed saveAlg;
    saveAlg.setChild(true);
    saveAlg.initialize();
    saveAlg.setProperty("InputWorkspace", peaksTestWS);
    saveAlg.setPropertyValue("Filename",
                             "LoadAndSaveNexusProcessedCoordinateSystem.nxs");
    saveAlg.execute();
    std::string filePath = saveAlg.getPropertyValue("Filename");

    LoadNexusProcessed loadAlg;
    loadAlg.setChild(true);
    loadAlg.initialize();
    loadAlg.setPropertyValue("Filename", filePath);
    loadAlg.setPropertyValue("OutputWorkspace", "__unused");
    loadAlg.execute();

    Mantid::API::Workspace_sptr loadedWS =
        loadAlg.getProperty("OutputWorkspace");
    auto loadedPeaksWS =
        boost::dynamic_pointer_cast<Mantid::API::IPeaksWorkspace>(loadedWS);
    Poco::File testFile(filePath);
    if (testFile.exists()) {

    TS_ASSERT_EQUALS(appliedCoordinateSystem,
                     loadedPeaksWS->getSpecialCoordinateSystem());
  }

  // backwards compatability check
  void test_coordinates_saved_and_loaded_on_peaks_workspace_from_expt_info() {
    auto peaksTestWS = WorkspaceCreationHelper::createPeaksWorkspace();
    // Loading a peaks workspace without a instrument from an IDF doesn't work
    // ...
    const std::string filename = FileFinder::Instance().getFullPath(
        "unit_testing/MINITOPAZ_Definition.xml");
    InstrumentDefinitionParser parser(filename, "MINITOPAZ",
                                      Strings::loadFile(filename));
    auto instrument = parser.parseXML(nullptr);
    peaksTestWS->populateInstrumentParameters();
    peaksTestWS->setInstrument(instrument);

    // simulate old-style file with "CoordinateSystem" log
    const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
    peaksTestWS->logs()->addProperty("CoordinateSystem",
                                     static_cast<int>(appliedCoordinateSystem));

    SaveNexusProcessed saveAlg;
    saveAlg.setChild(true);
    saveAlg.initialize();
    saveAlg.setProperty("InputWorkspace", peaksTestWS);
    saveAlg.setPropertyValue(
        "Filename", "LoadAndSaveNexusProcessedCoordinateSystemOldFormat.nxs");
    saveAlg.execute();
    std::string filePath = saveAlg.getPropertyValue("Filename");

    // Remove the coordinate_system entry so it falls back on the log. NeXus
    // can't do this so use the HDF5 API directly
    auto fid = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
    auto mantid_id = H5Gopen(fid, "mantid_workspace_1", H5P_DEFAULT);
    auto peaks_id = H5Gopen(mantid_id, "peaks_workspace", H5P_DEFAULT);
    if (peaks_id > 0) {
      H5Ldelete(peaks_id, "coordinate_system", H5P_DEFAULT);
      H5Gclose(peaks_id);
      H5Gclose(mantid_id);
    } else {
      TS_FAIL("Cannot unlink coordinate_system group. Test file has unexpected "
              "structure.");
    }
    H5Fclose(fid);
    LoadNexusProcessed loadAlg;
    loadAlg.setChild(true);
    loadAlg.initialize();
    loadAlg.setPropertyValue("Filename", filePath);
    loadAlg.setPropertyValue("OutputWorkspace", "__unused");
    loadAlg.execute();

    Mantid::API::Workspace_sptr loadedWS =
        loadAlg.getProperty("OutputWorkspace");
    auto loadedPeaksWS =
        boost::dynamic_pointer_cast<Mantid::API::IPeaksWorkspace>(loadedWS);
    Poco::File testFile(filePath);
    if (testFile.exists()) {

    TS_ASSERT_EQUALS(appliedCoordinateSystem,
                     loadedPeaksWS->getSpecialCoordinateSystem());
  void testTableWorkspace_vectorColumn() {
Owen Arnold's avatar
Owen Arnold committed
    // Create a table we will save
    ITableWorkspace_sptr table = WorkspaceFactory::Instance().createTable();
    table->addColumn("vector_int", "IntVectorColumn");
    table->addColumn("vector_double", "DoubleVectorColumn");

    std::vector<double> d1, d2, d3;
    d1.push_back(0.5);
    d2.push_back(1.0);
    d2.push_back(2.5);
    d3.push_back(4.0);

    std::vector<int> i1(Strings::parseRange("1"));
    std::vector<int> i2(Strings::parseRange("2,3,"));
    std::vector<int> i3(Strings::parseRange("4,5,6,7"));

    // Add some rows of different sizes
    TableRow row1 = table->appendRow();
    row1 << i1 << d1;
    TableRow row2 = table->appendRow();
    row2 << i2 << d2;
    TableRow row3 = table->appendRow();
    row3 << i3 << d3;

    ScopedWorkspace inTableEntry(table);
    std::string savedFileName(
        "LoadNexusProcessedTest_testTableWorkspace_vectorColumn.nxs");
Owen Arnold's avatar
Owen Arnold committed
    SaveNexusProcessed saveAlg;
    saveAlg.initialize();
    saveAlg.setPropertyValue("InputWorkspace", inTableEntry.name());
    saveAlg.setPropertyValue("Filename", savedFileName);

    TS_ASSERT_THROWS_NOTHING(saveAlg.execute());
    TS_ASSERT(saveAlg.isExecuted());
Owen Arnold's avatar
Owen Arnold committed
    if (!saveAlg.isExecuted())
      return; // Nothing to check
Owen Arnold's avatar
Owen Arnold committed
    // Get absolute path to the saved file
    savedFileName = saveAlg.getPropertyValue("Filename");
Owen Arnold's avatar
Owen Arnold committed
    ScopedWorkspace outTableEntry;

    LoadNexusProcessed loadAlg;
    loadAlg.initialize();
    loadAlg.setPropertyValue("Filename", savedFileName);
    loadAlg.setPropertyValue("OutputWorkspace", outTableEntry.name());

    TS_ASSERT_THROWS_NOTHING(loadAlg.execute());
    TS_ASSERT(loadAlg.isExecuted());
Owen Arnold's avatar
Owen Arnold committed

    // The file is not needed anymore
    Poco::File(savedFileName).remove();

    if (!loadAlg.isExecuted())
      return; // Nothing to check

    auto outTable = boost::dynamic_pointer_cast<const TableWorkspace>(
        outTableEntry.retrieve());
    TS_ASSERT(outTable);
Owen Arnold's avatar
Owen Arnold committed

    if (!outTable)
      return; // Nothing to check

    TS_ASSERT_EQUALS(outTable->columnCount(), 2);
    TS_ASSERT_EQUALS(outTable->rowCount(), 3);
Owen Arnold's avatar
Owen Arnold committed

    Column_const_sptr column; // Column we are currently checking

    TS_ASSERT_THROWS_NOTHING(column = outTable->getColumn("IntVectorColumn"));
    TS_ASSERT(column->isType<std::vector<int>>());
    if (column->isType<std::vector<int>>()) {
      TS_ASSERT_EQUALS(column->cell<std::vector<int>>(0), i1);
      TS_ASSERT_EQUALS(column->cell<std::vector<int>>(1), i2);
      TS_ASSERT_EQUALS(column->cell<std::vector<int>>(2), i3);
    TS_ASSERT_THROWS_NOTHING(column =
                                 outTable->getColumn("DoubleVectorColumn"));
    TS_ASSERT(column->isType<std::vector<double>>());
    if (column->isType<std::vector<double>>()) {
      TS_ASSERT_EQUALS(column->cell<std::vector<double>>(0), d1);
      TS_ASSERT_EQUALS(column->cell<std::vector<double>>(1), d2);
      TS_ASSERT_EQUALS(column->cell<std::vector<double>>(2), d3);
  void test_SaveAndLoadOnHistogramWS() { doTestLoadAndSaveHistogramWS(false); }
  void test_SaveAndLoadOnHistogramWSWithNumericAxis() {
    doTestLoadAndSaveHistogramWS(false, true);
  }

  void test_SaveAndLoadOnHistogramWSwithXErrors() {
  void test_SaveAndLoadOnHistogramWSwithLegacyXErrors() {
    doTestLoadAndSaveHistogramWS(true, false, true);
  }

  void test_SaveAndLoadOnPointLikeWS() { doTestLoadAndSavePointWS(false); }
  void test_SaveAndLoadOnPointLikeWSWithXErrors() {
    doTestLoadAndSavePointWS(true);
  void test_that_workspace_name_is_loaded() {
    // Arrange
    LoadNexusProcessed loader;
    loader.setChild(false);
    loader.initialize();
    loader.setPropertyValue("Filename", "POLREF00004699_nexus.nxs");
    loader.setPropertyValue("OutputWorkspace", "ws");
    loader.setProperty("FastMultiPeriod", true);
    // Act
    TS_ASSERT(loader.execute());
    // Assert
    TSM_ASSERT(
        "Can access workspace via name which was set in file",
        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("y_1"));
    TSM_ASSERT(
        "Can access workspace via name which was set in file",
        AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("y_2"));
    // Clean up
    AnalysisDataService::Instance().remove("y_1");
    AnalysisDataService::Instance().remove("y_2");
  }

  void test_that_workspace_name_is_not_loaded_when_is_duplicate() {
    // Arrange
    SaveNexusProcessed alg;
    alg.initialize();
    std::string tempFile = "LoadNexusProcessed_TmpTestWorkspace.nxs";
    alg.setPropertyValue("Filename", tempFile);

    std::string workspaceName = "test_workspace_name";
    for (size_t index = 0; index < 2; ++index) {
      // Create a sample workspace and add it to the ADS, so it gets a name.
      auto ws = WorkspaceCreationHelper::create1DWorkspaceConstant(
          3, static_cast<double>(index), static_cast<double>(index), true);
      AnalysisDataService::Instance().addOrReplace(workspaceName, ws);
      alg.setProperty("InputWorkspace",
                      boost::dynamic_pointer_cast<MatrixWorkspace>(ws));
      if (index == 0) {
        alg.setProperty("Append", false);
      } else {
        alg.setProperty("Append", true);
      }
      alg.execute();
    }
    // Delete the workspace
    AnalysisDataService::Instance().remove(workspaceName);

    tempFile = alg.getPropertyValue("Filename");

    // Load the data
    LoadNexusProcessed loader;
    loader.setChild(false);
    loader.initialize();
    loader.setPropertyValue("Filename", tempFile);
    loader.setPropertyValue("OutputWorkspace", "ws_loaded");
    // Act
    loader.execute();

    // Assert
    TSM_ASSERT("Can access workspace via name which is the name of the file "
               "with an index",