Newer
Older
#ifndef WORKSPACETEST_H_
#define WORKSPACETEST_H_
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/ISpectrum.h"
Roman Tolchenov
committed
#include "MantidAPI/MatrixWorkspace.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/Crystal/OrientedLattice.h"
#include "MantidGeometry/Instrument/ComponentInfo.h"
#include "MantidGeometry/Instrument/Detector.h"
#include "MantidGeometry/Instrument/DetectorInfo.h"
#include "MantidGeometry/Instrument/ReferenceFrame.h"
#include "MantidKernel/TimeSeriesProperty.h"
#include "MantidKernel/VMD.h"
#include "MantidKernel/make_cow.h"
#include "MantidTestHelpers/ComponentCreationHelper.h"
#include "MantidTestHelpers/FakeObjects.h"
#include "MantidTestHelpers/InstrumentCreationHelper.h"
#include "MantidTestHelpers/NexusTestHelper.h"
#include "MantidTestHelpers/ParallelRunner.h"
#include <cxxtest/TestSuite.h>
#include <boost/make_shared.hpp>
#include <atomic>
using namespace Mantid;
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::Geometry;
using Mantid::Indexing::IndexInfo;
using Mantid::Types::Core::DateAndTime;
Janik Zikovsky
committed
// Declare into the factory.
Janik Zikovsky
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);
Gigg, Martyn Anthony
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) {
Janik Zikovsky
committed
// Create a detector for each spectra
Detector *det = new Detector("pixel", static_cast<detid_t>(i), inst.get());
det->setShape(
ComponentCreationHelper::createSphere(0.01, V3D(0, 0, 0), "1"));
Janik Zikovsky
committed
inst->add(det);
inst->markAsDetector(det);
ws2->getSpectrum(i).addDetectorID(static_cast<detid_t>(i));
Gigg, Martyn Anthony
committed
}
ws2->setInstrument(inst);
Janik Zikovsky
committed
return ws2;
Gigg, Martyn Anthony
committed
}
Janik Zikovsky
committed
void run_legacy_setting_spectrum_numbers_with_MPI(
const Parallel::Communicator &comm) {
using namespace Parallel;
for (const auto storageMode : {StorageMode::MasterOnly, StorageMode::Cloned,
StorageMode::Distributed}) {
WorkspaceTester ws;
if (comm.rank() == 0 || storageMode != StorageMode::MasterOnly) {
Indexing::IndexInfo indexInfo(1000, storageMode, comm);
ws.initialize(indexInfo,
HistogramData::Histogram(HistogramData::Points(1)));
}
if (storageMode == StorageMode::Distributed && comm.size() > 1) {
TS_ASSERT_THROWS_EQUALS(ws.getSpectrum(0).setSpectrumNo(42),
const std::logic_error &e, std::string(e.what()),
"Setting spectrum numbers in MatrixWorkspace via "
"ISpectrum::setSpectrumNo is not possible in MPI "
"runs for distributed workspaces. Use "
"IndexInfo.");
} else {
if (comm.rank() == 0 || storageMode != StorageMode::MasterOnly) {
TS_ASSERT_THROWS_NOTHING(ws.getSpectrum(0).setSpectrumNo(42));
}
}
}
}
class MatrixWorkspaceTest : public CxxTest::TestSuite {
Russell Taylor
committed
// 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();
Russell Taylor
committed
}
static void destroySuite(MatrixWorkspaceTest *suite) { delete suite; }
MatrixWorkspaceTest() : ws(boost::make_shared<WorkspaceTester>()) {
ws->initialize(1, 1, 1);
}
void test_indexInfo() {
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()),
Loading
Loading full blame...