Skip to content
Snippets Groups Projects
MatrixWorkspaceTest.h 64.8 KiB
Newer Older
#ifndef WORKSPACETEST_H_
#define WORKSPACETEST_H_

#include "MantidAPI/DetectorInfo.h"
#include "MantidAPI/NumericAxis.h"
#include "MantidAPI/Run.h"
#include "MantidAPI/SpectraAxis.h"
#include "MantidAPI/SpectrumDetectorMapping.h"
#include "MantidAPI/SpectrumInfo.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidGeometry/Instrument/ComponentHelper.h"
#include "MantidGeometry/Instrument/Detector.h"
#include "MantidKernel/make_cow.h"
#include "MantidKernel/TimeSeriesProperty.h"
#include "MantidKernel/VMD.h"
#include "MantidTypes/SpectrumDefinition.h"
#include "MantidIndexing/IndexInfo.h"
#include "MantidTestHelpers/FakeObjects.h"
#include "MantidTestHelpers/InstrumentCreationHelper.h"
#include "MantidTestHelpers/ComponentCreationHelper.h"
#include "MantidTestHelpers/NexusTestHelper.h"
#include "PropertyManagerHelper.h"
#include <boost/make_shared.hpp>
#include <algorithm>
#include <cmath>
#include <functional>
#include <numeric>
Peterson, Peter's avatar
Peterson, Peter committed
using std::size_t;
using namespace Mantid::Kernel;
using namespace Mantid::API;
using Mantid::Indexing::IndexInfo;
DECLARE_WORKSPACE(WorkspaceTester)
Russell Taylor's avatar
Russell Taylor committed

/** Create a workspace with numSpectra, with
 * each spectrum having one detector, at id = workspace index.
 * @param numSpectra
 * @return
 */
boost::shared_ptr<MatrixWorkspace> makeWorkspaceWithDetectors(size_t numSpectra,
                                                              size_t numBins) {
  boost::shared_ptr<MatrixWorkspace> ws2 =
      boost::make_shared<WorkspaceTester>();
  ws2->initialize(numSpectra, numBins, numBins);
Hahn, Steven's avatar
Hahn, Steven committed
  auto inst = boost::make_shared<Instrument>("TestInstrument");
  // We get a 1:1 map by default so the detector ID should match the spectrum
  // number
  for (size_t i = 0; i < ws2->getNumberHistograms(); ++i) {
    Detector *det = new Detector("pixel", static_cast<detid_t>(i), inst.get());
    det->setShape(
        ComponentCreationHelper::createSphere(0.01, V3D(0, 0, 0), "1"));
    inst->add(det);
    inst->markAsDetector(det);
    ws2->getSpectrum(i).addDetectorID(static_cast<detid_t>(i));
class MatrixWorkspaceTest : 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 MatrixWorkspaceTest *createSuite() {
    return new MatrixWorkspaceTest();
  static void destroySuite(MatrixWorkspaceTest *suite) { delete suite; }

Hahn, Steven's avatar
Hahn, Steven committed
  MatrixWorkspaceTest() : ws(boost::make_shared<WorkspaceTester>()) {
    ws->initialize(1, 1, 1);
  }
    WorkspaceTester ws;
    ws.initialize(3, 1, 1);
    const auto &indexInfo = ws.indexInfo();
    // IndexInfo contains spectrum numbers generated by WorkspaceTester.
    TS_ASSERT_EQUALS(indexInfo.spectrumNumber(0), 1);
    TS_ASSERT_EQUALS(indexInfo.spectrumNumber(1), 2);
    TS_ASSERT_EQUALS(indexInfo.spectrumNumber(2), 3);
    // Workspace tester contains detector IDs...
    TS_ASSERT_EQUALS(ws.getSpectrum(0).getDetectorIDs().size(), 1);
    TS_ASSERT_EQUALS(ws.getSpectrum(1).getDetectorIDs().size(), 1);
    TS_ASSERT_EQUALS(ws.getSpectrum(2).getDetectorIDs().size(), 1);
    // ... but spectrum definitions in IndexInfo are empty...
    TS_ASSERT_EQUALS((*indexInfo.spectrumDefinitions())[0],
                     SpectrumDefinition{});
    TS_ASSERT_EQUALS((*indexInfo.spectrumDefinitions())[1],
                     SpectrumDefinition{});
    TS_ASSERT_EQUALS((*indexInfo.spectrumDefinitions())[2],
                     SpectrumDefinition{});
    // ... since there is no instrument, i.e., all detector IDs are invalid.
    TS_ASSERT_EQUALS(ws.detectorInfo().size(), 0);
  void test_setIndexInfo_size_failure() {
    WorkspaceTester ws;
    ws.initialize(3, 1, 1);
    IndexInfo bad(2);
    TS_ASSERT_THROWS_EQUALS(ws.setIndexInfo(std::move(bad)),
                            const std::invalid_argument &e,
                            std::string(e.what()),
                            "MatrixWorkspace::setIndexInfo: IndexInfo size "
                            "does not match number of histograms in workspace");
  }
  void test_setIndexInfo_bad_detector_index() {
    WorkspaceTester ws;
    ws.initialize(1, 1, 1);
    IndexInfo indices(1);
    indices.setSpectrumNumbers({2});
    std::vector<SpectrumDefinition> specDefs(1);
    specDefs[0].add(0);
    indices.setSpectrumDefinitions(specDefs);
    TS_ASSERT_THROWS_EQUALS(ws.setIndexInfo(std::move(indices)),
                            const std::invalid_argument &e,
                            std::string(e.what()),
                            "MatrixWorkspace: SpectrumDefinition contains an "
                            "out-of-range detector index, i.e., the spectrum "
                            "definition does not match the instrument in the "
                            "workspace.");
  void test_setIndexInfo_bad_detector_time_index() {
    WorkspaceTester ws;
    ws.initialize(1, 1, 1);
    ws.setInstrument(
        ComponentCreationHelper::createTestInstrumentRectangular(1, 1));
    IndexInfo indices(1);
    indices.setSpectrumNumbers({2});
    std::vector<SpectrumDefinition> specDefs(1);
    specDefs[0].add(0, 1);
    indices.setSpectrumDefinitions(specDefs);
    TS_ASSERT_THROWS_EQUALS(ws.setIndexInfo(std::move(indices)),
                            const std::invalid_argument &e,
                            std::string(e.what()),
                            "MatrixWorkspace: SpectrumDefinition contains an "
                            "out-of-range time index for a detector, i.e., the "
                            "spectrum definition does not match the instrument "
                            "in the workspace.");
  }

  void test_setIndexInfo_default_mapping_failure() {
    WorkspaceTester ws;
    ws.initialize(3, 1, 1);
    // 2x2 = 4 pixels
    ws.setInstrument(
        ComponentCreationHelper::createTestInstrumentRectangular(1, 2));
    IndexInfo indices(3);
    TS_ASSERT_THROWS_EQUALS(ws.setIndexInfo(std::move(indices)),
                            const std::invalid_argument &e,
                            std::string(e.what()),
                            "MatrixWorkspace: IndexInfo does not contain "
                            "spectrum definitions so building a 1:1 mapping "
                            "from spectra to detectors was attempted, but the "
                            "number of spectra in the workspace is not equal "
                            "to the number of detectors in the instrument.");
  }

  void test_setIndexInfo_default_mapping() {
    WorkspaceTester ws;
    ws.initialize(4, 1, 1);
    // 2x2 = 4 pixels
    ws.setInstrument(
        ComponentCreationHelper::createTestInstrumentRectangular(1, 2));
    IndexInfo indices(4);

    TS_ASSERT_THROWS_NOTHING(ws.setIndexInfo(std::move(indices)));

    const auto &info = ws.indexInfo();
    TS_ASSERT(info.spectrumDefinitions());
    std::vector<SpectrumDefinition> specDefs(4);
    specDefs[0].add(0);
    specDefs[1].add(1);
    specDefs[2].add(2);
    specDefs[3].add(3);
    TS_ASSERT_EQUALS(*info.spectrumDefinitions(), specDefs);
    TS_ASSERT_EQUALS(ws.getSpectrum(0).getSpectrumNo(), 1);
    TS_ASSERT_EQUALS(ws.getSpectrum(1).getSpectrumNo(), 2);
    TS_ASSERT_EQUALS(ws.getSpectrum(2).getSpectrumNo(), 3);
    TS_ASSERT_EQUALS(ws.getSpectrum(3).getSpectrumNo(), 4);
    TS_ASSERT_EQUALS(ws.getSpectrum(0).getDetectorIDs(),
                     (std::set<detid_t>{4}));
    TS_ASSERT_EQUALS(ws.getSpectrum(1).getDetectorIDs(),
                     (std::set<detid_t>{5}));
    TS_ASSERT_EQUALS(ws.getSpectrum(2).getDetectorIDs(),
                     (std::set<detid_t>{6}));
Loading
Loading full blame...