Newer
Older
#ifndef OBSERVATIONTEST_H_
#define OBSERVATIONTEST_H_
#include "MantidMDAlgorithms/Quantification/CachedExperimentInfo.h"
#include "MantidKernel/DeltaEMode.h"
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidGeometry/Instrument/ReferenceFrame.h"
#include "MantidAPI/Run.h"
#include "MantidAPI/Sample.h"
#include "MantidTestHelpers/ComponentCreationHelper.h"
#include <cxxtest/TestSuite.h>
#include <boost/make_shared.hpp>
using Mantid::MDAlgorithms::CachedExperimentInfo;
using Mantid::Kernel::DeltaEMode;
using Mantid::Kernel::V3D;
class CachedExperimentInfoTest : public CxxTest::TestSuite {
private:
// Avoiding booleans
enum TestObjectType {
NoChopper,
WithChopper,
NoAperture,
WithAperture,
NoDetShape,
WithDetShape
};
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static CachedExperimentInfoTest *createSuite() {
return new CachedExperimentInfoTest();
}
static void destroySuite(CachedExperimentInfoTest *suite) { delete suite; }
CachedExperimentInfoTest()
: m_test_ei(12.1), m_test_ef(15.5), m_sourcePos(0.0, 0.0, -10.0),
m_chopperPos(0, 0, -3.), m_aperturePos(0., 0., -8.) {}
void test_trying_to_construct_object_with_unknown_id_throws_exception() {
// createEmptyExptInfo();
auto expt = boost::make_shared<Mantid::API::ExperimentInfo>();
TS_ASSERT_THROWS(CachedExperimentInfo(*expt, 1000), std::out_of_range);
}
void test_trying_to_construct_object_with_no_chopper_throws() {
TS_ASSERT_THROWS(createTestCachedExperimentInfo(NoChopper),
std::invalid_argument);
}
void test_trying_to_construct_object_with_no_aperature_throws() {
TS_ASSERT_THROWS(createTestCachedExperimentInfo(WithChopper, NoAperture),
std::invalid_argument);
}
void test_trying_to_construct_object_with_no_det_shape_throws() {
TS_ASSERT_THROWS(createTestCachedExperimentInfo(WithChopper, WithAperture,
DeltaEMode::Direct,
V3D(1, 1, 1), NoDetShape),
std::invalid_argument);
}
void test_efixed_returns_Ei_for_direct_mode() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo(WithChopper, WithAperture,
DeltaEMode::Direct);
TS_ASSERT_EQUALS(event->getEFixed(), m_test_ei);
}
void test_efixed_returns_EFixed_for_indirect_mode() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo(WithChopper, WithAperture,
DeltaEMode::Indirect);
TS_ASSERT_EQUALS(event->getEFixed(), m_test_ef);
}
void test_theta_angle_from_beam_is_correct() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo();
TS_ASSERT_DELTA(event->twoTheta(), 0.440510663, 1e-09);
}
void test_phi_angle_from_beam_is_correct() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo();
TS_ASSERT_DELTA(event->phi(), M_PI / 4., 1e-09);
}
void test_sample_to_detector_distance_gives_expected_results() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo();
TS_ASSERT_DELTA(event->sampleToDetectorDistance(), std::sqrt(11.), 1e-12);
}
void test_moderator_to_first_chopper_distance_gives_expected_result() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo(WithChopper);
const double expectedDistance = m_chopperPos.distance(m_sourcePos);
TS_ASSERT_DELTA(event->moderatorToFirstChopperDistance(), expectedDistance,
1e-12);
}
void test_first_chopper_to_sample_distance_gives_expected_result() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo(WithChopper);
const double expectedDistance = m_chopperPos.distance(V3D());
TS_ASSERT_DELTA(event->firstChopperToSampleDistance(), expectedDistance,
1e-12);
}
void test_first_aperture_to_first_chopper_distance_gives_expected_result() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo(WithChopper, WithAperture);
const double expectedDistance = m_chopperPos.distance(m_aperturePos);
TS_ASSERT_DELTA(event->firstApertureToFirstChopperDistance(),
expectedDistance, 1e-12);
}
void test_aperture_size_is_expected() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo(WithChopper, WithAperture);
const double expectedWidth(0.08), expectedHeight(0.05);
std::pair<double, double> apSize = event->apertureSize();
TS_ASSERT_DELTA(apSize.first, expectedWidth, 1e-4);
TS_ASSERT_DELTA(apSize.second, expectedHeight, 1e-4);
}
void test_sample_widths_are_expected() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo(WithChopper, WithAperture);
const Mantid::Kernel::V3D &sampleWidths = event->sampleCuboid();
TS_ASSERT_DELTA(sampleWidths.X(), 0.2, 1e-5);
TS_ASSERT_DELTA(sampleWidths.Y(), 0.4, 1e-5);
TS_ASSERT_DELTA(sampleWidths.Z(), 0.6, 1e-5);
}
void test_detector_volume_gives_expected_pos() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo(WithChopper, WithAperture,
DeltaEMode::Direct, V3D(1, 1, 1));
Mantid::Kernel::V3D volume;
TS_ASSERT_THROWS_NOTHING(volume = event->detectorVolume());
TS_ASSERT_DELTA(volume[0], 0.0240, 1e-6);
TS_ASSERT_DELTA(volume[1], 0.0100, 1e-6);
TS_ASSERT_DELTA(volume[2], 0.0240, 1e-6);
}
void test_labToDetTransformation_Yields_Expected_Matrix() {
boost::shared_ptr<CachedExperimentInfo> event =
createTestCachedExperimentInfo(WithChopper, WithAperture,
DeltaEMode::Direct, V3D(1, 1, 1));
const double sintheta = std::sqrt(2. / 3.);
const double costheta = 1. / std::sqrt(3.);
const double sinphi = 0.5 * M_SQRT2;
const double cosphi = 0.5 * M_SQRT2;
double expectedMatrix[3][3] = {{costheta * cosphi, -sinphi, costheta},
{costheta * cosphi, cosphi, costheta},
{-sintheta, 0.0, costheta}};
Mantid::Kernel::DblMatrix labToDet = event->labToDetectorTransform();
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
std::ostringstream os;
os << "Mismatch at row=" << i << ", col=" << j;
TSM_ASSERT_DELTA(os.str(), labToDet[i][j], expectedMatrix[i][j], 1e-12);
}
}
}
private:
m_expt = boost::make_shared<Mantid::API::ExperimentInfo>();
}
boost::shared_ptr<CachedExperimentInfo> createTestCachedExperimentInfo(
const TestObjectType addChopper = WithChopper,
const TestObjectType addAperture = WithAperture,
const DeltaEMode::Type emode = DeltaEMode::Direct,
const V3D &detPos = V3D(1, 1, 3),
const TestObjectType addDetShape = WithDetShape) {
using namespace Mantid::API;
using namespace Mantid::Geometry;
createEmptyExptInfo();
Instrument_sptr instrument(new Instrument("test-inst"));
instrument->setReferenceFrame(boost::make_shared<ReferenceFrame>(
Mantid::Geometry::Y, Mantid::Geometry::Z, Mantid::Geometry::Right,
"frame"));
Detector *det1 = new Detector("det1", g_test_id, instrument.get());
if (addDetShape == WithDetShape) {
auto shape = ComponentCreationHelper::createCappedCylinder(
0.012, 0.01, detPos, V3D(0, 1, 0), "cyl");
det1->setShape(shape);
}
instrument->add(det1);
det1->setPos(detPos);
instrument->markAsDetector(det1);
ObjComponent *source = new ObjComponent("source");
source->setPos(m_sourcePos);
instrument->add(source);
instrument->markAsSource(source);
ObjComponent *samplePos = new ObjComponent("samplePos");
instrument->add(samplePos);
instrument->markAsSamplePos(samplePos);
auto sampleShape = ComponentCreationHelper::createCuboid(0.1, 0.2, 0.3);
m_expt->mutableSample().setShape(sampleShape);
if (addChopper == WithChopper) {
ObjComponent *chopper = new ObjComponent("firstChopperPos");
chopper->setPos(m_chopperPos);
instrument->add(chopper);
instrument->markAsChopperPoint(chopper);
}
if (addAperture == WithAperture) {
ObjComponent *aperture = new ObjComponent("aperture");
aperture->setPos(m_aperturePos);
auto shape = ComponentCreationHelper::createCuboid(0.04, 0.025, 0.05);
aperture->setShape(shape);
instrument->add(aperture);
}
m_expt->setInstrument(instrument);
m_expt->mutableRun().addProperty("deltaE-mode",
DeltaEMode::asString(emode));
Mantid::Geometry::OrientedLattice latt(5.57, 5.51, 12.298);
m_expt->mutableSample().setOrientedLattice(&latt);
if (emode == DeltaEMode::Direct) // Direct
{
// Add log entry
m_expt->mutableRun().addProperty("Ei", m_test_ei);
} else if (emode == DeltaEMode::Indirect) // Indirect
{
m_expt->instrumentParameters().addDouble(det1, "EFixed", m_test_ef);
} else {
}
return boost::make_shared<CachedExperimentInfo>(
*m_expt, static_cast<Mantid::detid_t>(g_test_id));
}
enum { g_test_id = 1 };
const double m_test_ei;
const double m_test_ef;
const V3D m_sourcePos;
const V3D m_chopperPos;
const V3D m_aperturePos;
Mantid::API::ExperimentInfo_sptr m_expt;
};
#endif /* OBSERVATIONTEST_H_ */