Newer
Older
#ifndef MANTID_MDEVENTS_MDTRANSF_MODQTEST_H_
#define MANTID_MDEVENTS_MDTRANSF_MODQTEST_H_
#include "MantidMDAlgorithms/MDTransfQ3D.h"
#include "MantidKernel/DeltaEMode.h"
#include "MantidTestHelpers/WorkspaceCreationHelper.h"
#include "MantidTestHelpers/MDEventsTestHelper.h"
using namespace Mantid;
class MDTransfModQTest : public CxxTest::TestSuite {
Mantid::API::MatrixWorkspace_sptr ws2D;
static MDTransfModQTest *createSuite() { return new MDTransfModQTest(); }
static void destroySuite(MDTransfModQTest *suite) { delete suite; }
MDTransfModQ ModQTransformer;
TS_ASSERT_EQUALS("|Q|", ModQTransformer.transfID());
TS_ASSERT_EQUALS(
2, ModQTransformer.getNMatrixDimensions(Kernel::DeltaEMode::Direct));
TS_ASSERT_EQUALS(
1, ModQTransformer.getNMatrixDimensions(Kernel::DeltaEMode::Elastic));
TS_ASSERT_EQUALS(
2, ModQTransformer.getNMatrixDimensions(Kernel::DeltaEMode::Indirect));
MDTransfModQ ModQTransformer;
std::vector<std::string> outputDimUnits;
TS_ASSERT_THROWS_NOTHING(outputDimUnits = ModQTransformer.outputUnitID(
Kernel::DeltaEMode::Direct));
TS_ASSERT_EQUALS(2, outputDimUnits.size());
TS_ASSERT_EQUALS("MomentumTransfer", outputDimUnits[0]);
TS_ASSERT_EQUALS("DeltaE", outputDimUnits[1]);
TS_ASSERT_THROWS_NOTHING(outputDimUnits = ModQTransformer.outputUnitID(
Kernel::DeltaEMode::Elastic));
TS_ASSERT_EQUALS(1, outputDimUnits.size());
MDTransfModQ ModQTransformer;
std::vector<std::string> outputDimID;
TS_ASSERT_THROWS_NOTHING(outputDimID = ModQTransformer.getDefaultDimID(
Kernel::DeltaEMode::Direct));
TS_ASSERT_EQUALS(2, outputDimID.size());
TS_ASSERT_EQUALS("|Q|", outputDimID[0]);
TS_ASSERT_EQUALS("DeltaE", outputDimID[1]);
TS_ASSERT_THROWS_NOTHING(outputDimID = ModQTransformer.getDefaultDimID(
Kernel::DeltaEMode::Elastic));
TS_ASSERT_EQUALS(1, outputDimID.size());
TS_ASSERT_EQUALS("|Q|", outputDimID[0]);
MDTransfModQ ModQTransformer;
std::string inputUnitID;
TS_ASSERT_THROWS_NOTHING(
inputUnitID = ModQTransformer.inputUnitID(Kernel::DeltaEMode::Direct));
TS_ASSERT_EQUALS("DeltaE", inputUnitID);
TS_ASSERT_THROWS_NOTHING(inputUnitID = ModQTransformer.inputUnitID(
Kernel::DeltaEMode::Indirect));
TS_ASSERT_EQUALS("DeltaE", inputUnitID);
TS_ASSERT_THROWS_NOTHING(
inputUnitID = ModQTransformer.inputUnitID(Kernel::DeltaEMode::Elastic));
TS_ASSERT_EQUALS("Momentum", inputUnitID);
std::string checkMinMaxRangesCorrect(MDWSDescription &WSDescr,
Mantid::API::MatrixWorkspace_sptr &ws2D,
MDTransfInterface &MDTransf) {
std::string result("");
// auxiliary variables not used here
unsigned int nDims = WSDescr.nDimensions();
auto detIDMap = WSDescr.m_PreprDetTable->getColVector<size_t>("detIDMap");
std::vector<coord_t> locCoord(nDims);
std::vector<coord_t> minCoord(nDims, FLT_MAX);
std::vector<coord_t> maxCoord(nDims, -FLT_MAX);
const size_t specSize = ws2D->blocksize();
size_t nDetectors = ws2D->getNumberHistograms();
MDTransf.calcGenericVariables(locCoord, nDims);
for (size_t i = 0; i < nDetectors; i++) {
size_t iSpctr = detIDMap[i];
const MantidVec &X = ws2D->readX(iSpctr);
auto range = MDTransf.getExtremumPoints(X[0], X[specSize], i);
// calculate the coordinates which depend on detector posision and set up
// the detectors parameters
MDTransf.calcYDepCoordinates(locCoord, i);
for (size_t k = 0; k < range.size(); k++) {
MDTransf.calcMatrixCoord(range[k], locCoord, signal, errorSq);
for (size_t j = 0; j < nDims; j++) {
if (locCoord[j] < minCoord[j])
minCoord[j] = locCoord[j];
if (locCoord[j] > maxCoord[j])
maxCoord[j] = locCoord[j];
}
}
//=> START INTERNAL LOOP OVER THE "TIME"
for (size_t j = 0; j < specSize; ++j) {
MDTransf.calcMatrixCoordinates(X, i, j, locCoord, signal, errorSq);
for (size_t j = 0; j < nDims; j++) {
if (locCoord[j] < minCoord[j]) {
result = "Local transformed coordinate in direction " +
boost::lexical_cast<std::string>(j) + " at bin N: " +
boost::lexical_cast<std::string>(i) +
" is smaller then identified conversion range";
return result;
}
if (locCoord[j] > maxCoord[j]) {
result = "Local transformed coordinate in direction " +
boost::lexical_cast<std::string>(j) + " at bin N: " +
boost::lexical_cast<std::string>(i) +
" is bigger then identified conversion range";
return result;
}
}
}
}
return result;
MDTransfModQ ModQTransf;
size_t nDims = 4;
std::vector<double> L2, polar, azimuthal;
WorkspaceCreationHelper::create2DAngles(L2, polar, azimuthal);
MDWSDescription WSDescr(static_cast<unsigned int>(nDims));
std::string QMode = ModQTransf.transfID();
std::string dEMode =
Kernel::DeltaEMode::asString(Kernel::DeltaEMode::Direct);
std::vector<std::string> dimPropNames(2, "T");
dimPropNames[1] = "Ei";
auto ws2Dbig = WorkspaceCreationHelper::createProcessedInelasticWS(
L2, polar, azimuthal, 100, -11, 9.9, 10);
ws2Dbig->mutableRun().mutableGoniometer().setRotationAngle(0, 20);
ws2Dbig->mutableRun().addProperty("Ei", 13., "meV", true);
ws2Dbig->mutableRun().addProperty("T", 70., "K", true);
WSDescr.buildFromMatrixWS(ws2Dbig, QMode, dEMode, dimPropNames);
std::vector<double> minVal(nDims, -FLT_MAX), maxVal(nDims, FLT_MAX);
WSDescr.setMinMax(minVal, maxVal);
TSM_ASSERT_THROWS(
"No detectors yet defined, so should thow run time error: ",
ModQTransf.initialize(WSDescr), std::runtime_error);
// let's preprocess detectors positions to go any further
WSDescr.m_PreprDetTable =
WorkspaceCreationHelper::buildPreprocessedDetectorsWorkspace(ws2Dbig);
TSM_ASSERT_THROWS_NOTHING("should initialize properly: ",
ModQTransf.initialize(WSDescr));
std::vector<coord_t> coord(4);
TSM_ASSERT("Generic coordinates should be in range, so should be true ",
ModQTransf.calcGenericVariables(coord, 4));
TSM_ASSERT_DELTA("3th Generic coordinates should be temperature ", 70,
coord[2], 2.e-8);
TSM_ASSERT_DELTA("4th Generic coordinates should be Ei ", 13, coord[3],
2.e-8);
TSM_ASSERT(
" Y-dependent coordinates should be in range so it should be true: ",
ModQTransf.calcYDepCoordinates(coord, 0));
auto convResult = checkMinMaxRangesCorrect(WSDescr, ws2Dbig, ModQTransf);
TSM_ASSERT_EQUALS(convResult, 0, convResult.size());
// Check if the correct display normalization is set
auto mdEventWorkspace =
Mantid::DataObjects::MDEventsTestHelper::makeMDEW<3>(4, 0.0, 4.0, 1);
ModQTransf.setDisplayNormalization(mdEventWorkspace, ws2Dbig);
TSM_ASSERT_EQUALS("Should be set to number events normalization",
mdEventWorkspace->displayNormalization(),
Mantid::API::VolumeNormalization);
TSM_ASSERT_EQUALS("Should be set to number events normalization",
mdEventWorkspace->displayNormalizationHisto(),
Mantid::API::NumEventsNormalization);
ws2D = WorkspaceCreationHelper::
createProcessedWorkspaceWithCylComplexInstrument(4, 10, true);
// rotate the crystal by twenty degrees back;
ws2D->mutableRun().mutableGoniometer().setRotationAngle(0, 20);
ws2D->mutableRun().addProperty("Ei", 13., "meV", true);
ws2D->mutableRun().addProperty("T", 70., "K", true);