Commit a28fc710 authored by Danny Hindson's avatar Danny Hindson Committed by Zhang, Chen
Browse files

Various changes

Update some more unit tests to cope with changes MomentumTransfer unit
to make it use the diff constants
Improve validation on the L2\ttheta params in dSpacing unit
Allow negative DIFCs in conversions to TOF -
do this by setting up validation on to FromTOF direction only
Revert some files now that I'm doing more "input" averaging in DIFC
calculation on spectra with more than one detector
parent 27914e9a
......@@ -1232,8 +1232,8 @@ void IFunction::convertValue(std::vector<double> &values, Kernel::Unit_sptr &out
wsUnit->toTOF(values, emptyVec, l1, emode, pmap);
outUnit->fromTOF(values, emptyVec, l1, emode, pmap);
} catch (std::exception &) {
throw std::runtime_error("Unable to retrieve detector properties "
"required for unit conversion");
throw std::runtime_error("Unable to perform unit conversion to " +
outUnit->unitID());
}
}
}
......
......@@ -90,6 +90,7 @@ void ConvertSpectrumAxis::exec() {
const double l1 = spectrumInfo.l1();
const std::string emodeStr = getProperty("EMode");
auto emode = Kernel::DeltaEMode::fromString(emodeStr);
int nfailures = 0;
for (size_t i = 0; i < nHist; i++) {
std::vector<double> xval{inputWS->x(i).front(), inputWS->x(i).back()};
UnitParametersMap pmap{};
......@@ -102,16 +103,24 @@ void ConvertSpectrumAxis::exec() {
}
spectrumInfo.getDetectorValues(*fromUnit, *toUnit, emode, false, i, pmap);
double value = 0.;
try {
fromUnit->toTOF(xval, emptyVector, l1, emode, pmap);
toUnit->fromTOF(xval, emptyVector, l1, emode, pmap);
} catch (std::exception &) {
throw std::runtime_error("Unable to retrieve detector properties "
"required for unit conversion");
value = (xval.front() + xval.back()) / 2;
} catch (std::runtime_error &) {
nfailures++;
g_log.warning(
"Unable to calculate new spectrum axis value for workspace index " +
i);
value = inputWS->getAxis(1)->getValue(i);
}
double value = (xval.front() + xval.back()) / 2;
indexMap.emplace(value, i);
}
if (nfailures == nHist) {
throw std::runtime_error(
"Unable to convert spectrum axis values on all spectra");
}
} else {
// Set up binding to memeber funtion. Avoids condition as part of loop over
// nHistograms.
......
......@@ -390,7 +390,7 @@ public:
// setup the peak postions based on transformation from detID=155
// allow refining DIFA, but don't set the transformation to require it
// setup the peak postions based on transformation from detID=155
std::vector<double> dValues(PEAK_TOFS.size());
std::vector<double> dValues(PEAK_TOFS);
Mantid::Kernel::Units::dSpacing dSpacingUnit;
std::vector<double> unusedy;
dSpacingUnit.fromTOF(
......
......@@ -31,7 +31,8 @@ public:
private:
struct CalibrationParams {
CalibrationParams(const double _difa, const double _difc, const double _tzero);
CalibrationParams(const double _difc, const double _difa,
const double _tzero);
const double difa;
const double difc;
const double tzero;
......
......@@ -81,7 +81,9 @@ boost::optional<std::vector<std::string>> getParamLinesFromGSASFile(const std::s
DECLARE_ALGORITHM(SaveGDA)
SaveGDA::CalibrationParams::CalibrationParams(const double _difa, const double _difc, const double _tzero)
SaveGDA::CalibrationParams::CalibrationParams(const double _difc,
const double _difa,
const double _tzero)
: difa(_difa), difc(_difc), tzero(_tzero) {}
const std::string SaveGDA::name() const { return "SaveGDA"; }
......@@ -142,7 +144,7 @@ void SaveGDA::exec() {
const auto ws = inputWS->getItem(i);
const auto matrixWS = std::dynamic_pointer_cast<MatrixWorkspace>(ws);
auto &x = matrixWS->dataX(0);
auto x = matrixWS->dataX(0);
const size_t bankIndex(groupingScheme[i] - 1);
if (bankIndex >= calibParams.size()) {
throw Kernel::Exception::IndexError(bankIndex, calibParams.size(), "Bank number out of range");
......@@ -157,7 +159,7 @@ void SaveGDA::exec() {
std::vector<double> yunused;
dSpacingUnit.toTOF(x, yunused, 0., Kernel::DeltaEMode::Elastic,
{{Kernel::UnitParams::difa, bankCalibParams.difa},
{Kernel::UnitParams::difa, bankCalibParams.difc},
{Kernel::UnitParams::difc, bankCalibParams.difc},
{Kernel::UnitParams::tzero, bankCalibParams.tzero}});
std::transform(x.begin(), x.end(), std::back_inserter(tofScaled),
[](const double tofVal) { return tofVal * tofScale; });
......
......@@ -431,6 +431,7 @@ public:
protected:
void validateUnitParams(const int emode,
const UnitParametersMap &params) override;
std::string toDSpacingError;
double difa;
double difc;
double tzero;
......
......@@ -594,22 +594,33 @@ double tofToDSpacingFactor(const double l1, const double l2,
dSpacingBase::dSpacingBase()
: Unit(), difa(0), difc(DBL_MIN), tzero(0),
valueThatGivesLargestTOF(DBL_MAX), valueThatGivesSmallestTOF(0.) {}
valueThatGivesLargestTOF(DBL_MAX), valueThatGivesSmallestTOF(0.),
toDSpacingError("") {}
void dSpacingBase::validateUnitParams(const int,
const UnitParametersMap &params) {
double difc;
double difc = 0.;
if (!ParamPresentAndSet(&params, UnitParams::difc, difc)) {
if (!ParamPresent(params, UnitParams::twoTheta) ||
(!ParamPresent(params, UnitParams::l2)))
throw std::runtime_error("A difc value or L2\two theta must be supplied "
throw std::runtime_error("A difc value or L2/two theta must be supplied "
"in the extra parameters when initialising " +
this->unitID() + " for conversion via TOF");
} else if (difc < 0.) {
throw std::runtime_error(
"A positive difc value must be supplied in the extra parameters when "
"initialising " +
this->unitID() + " for conversion via TOF");
} else {
// check validations only applicable to fromTOF
toDSpacingError = "";
double difa = 0.;
ParamPresentAndSet(&params, UnitParams::difa, difa);
if ((difa == 0) && (difc == 0)) {
toDSpacingError = "Cannot convert to d spacing with DIFA=0 and DIFC=0";
};
// singleFromTOF currently assuming difc not negative
if (difc < 0.) {
toDSpacingError =
"A positive difc value must be supplied in the extra parameters when "
"initialising " +
this->unitID() + " for conversion via TOF";
}
}
}
......@@ -647,19 +658,18 @@ double dSpacingBase::singleToTOF(const double x) const {
"has been initialized.");
return difa * x * x + difc * x + tzero;
}
double dSpacingBase::singleFromTOF(const double tof) const {
if (!isInitialized())
throw std::runtime_error("dSpacingBase::singleFromTOF called before object "
"has been initialized.");
if (!toDSpacingError.empty())
throw std::runtime_error(toDSpacingError);
// handle special cases first...
if (tof == tzero) {
if (difa != 0)
return -difc / difa;
}
if ((difa == 0) && (difc == 0)) {
throw std::runtime_error(
"Cannot convert to d spacing with DIFA=0 and DIFC=0");
}
if ((difc * difc - 4 * difa * (tzero - tof)) < 0) {
throw std::runtime_error(
"Cannot convert to d spacing. Quadratic doesn't have real roots");
......
......@@ -166,8 +166,8 @@ public:
pAlg->setPropertyValue("MaxValues", " 10,20,40");
pAlg->setRethrows(true);
TS_ASSERT_THROWS_NOTHING(pAlg->execute());
checkHistogramsHaveBeenStored("WS3DmodQ", 7000, 6489.55858391694,
7300.75340690656);
checkHistogramsHaveBeenStored("WS3DmodQ", 7000, 6489.5591101441796,
7300.7539989122024);
auto outWS = AnalysisDataService::Instance().retrieveWS<IMDWorkspace>("WS3DmodQ");
TS_ASSERT_EQUALS(Mantid::Kernel::None, outWS->getSpecialCoordinateSystem());
......
......@@ -15,11 +15,11 @@ class EnggFocusTest(unittest.TestCase):
_van_curves_ws = None
_van_integ_tbl = None
_expected_yvals_bank1 = [0.01671889741296237, 0.016036458905862805, 0.04757112365349549,
0.1566982298749516, 0.11047168569414788, 0.017336154388340106]
_expected_yvals_bank1 = [0.016676032919961604, 0.015995344072536975, 0.047449159145519233,
0.15629648148139513, 0.11018845452876322, 0.017291707350351286]
_expected_yvals_bank2 = [0.0, 0.01835793983891016, 0.07157114331736783,
0.06194238438581619, 0.13136628929521785, 0.0017714987522226692]
_expected_yvals_bank2 = [0.0, 0.018310873111703541, 0.071387646720910913,
0.061783574337739511, 0.13102948781549345, 0.001766956921862095]
# Note not using @classmethod setUpClass / tearDownClass because that's not supported in the old
# unittest of rhel6
......@@ -129,7 +129,7 @@ class EnggFocusTest(unittest.TestCase):
self.assertEqual(wks.getNumDims(), 2)
self.assertEqual(wks.YUnit(), 'Counts')
dimX = wks.getXDimension()
self.assertAlmostEqual( dimX.getMaximum(), 36843.375)
self.assertAlmostEqual( dimX.getMaximum(), 36938.078125)
self.assertEqual(dimX.name, 'Time-of-flight')
self.assertEqual(dimX.getUnits(), 'microsecond')
dimY = wks.getYDimension()
......@@ -139,8 +139,8 @@ class EnggFocusTest(unittest.TestCase):
if yvalues is None:
raise ValueError("No y-vals provided for test")
xvals = [10834.11037667225, 12161.113671020974, 13488.116965369696,
14815.12025971842, 24104.14332015949, 34720.16967494928]
xvals = [10861.958645540433, 12192.372902418168, 13522.787159295902,
14853.201416173637, 24166.101214317776, 34809.415269339654]
p_charge = wks.getRun().getProtonCharge()
for i, bin_idx in enumerate([0, 5, 10, 15, 50, 90]):
self.assertAlmostEqual(wks.readX(0)[bin_idx], xvals[i])
......
......@@ -109,9 +109,9 @@ public:
docheckEventInputWksp();
// Test the output
TS_ASSERT_DELTA(m_outWS->x(0)[423], 1634.3727, 0.0001);
TS_ASSERT_DELTA(m_outWS->x(0)[423], 1634.3791, 0.0001);
TS_ASSERT_EQUALS(m_outWS->y(0)[423], 2702);
TS_ASSERT_DELTA(m_outWS->x(0)[970], 14719.7702, 0.0001);
TS_ASSERT_DELTA(m_outWS->x(0)[970], 14719.8272, 0.0001);
TS_ASSERT_EQUALS(m_outWS->y(0)[970], 149165);
}
......@@ -153,9 +153,9 @@ public:
docheckEventInputWksp();
// Test the output
TS_ASSERT_DELTA(m_outWS->x(0)[423], 1634.3727, 0.0001);
TS_ASSERT_DELTA(m_outWS->x(0)[423], 1634.3791, 0.0001);
TS_ASSERT_DELTA(m_outWS->y(0)[423], 2419.5680, 0.0001);
TS_ASSERT_DELTA(m_outWS->x(0)[970], 14719.7702, 0.0001);
TS_ASSERT_DELTA(m_outWS->x(0)[970], 14719.8272, 0.0001);
TS_ASSERT_DELTA(m_outWS->y(0)[970], 148503.3853, 0.0001);
}
......@@ -499,15 +499,15 @@ public:
TS_ASSERT_EQUALS(m_outWS->getNumberHistograms(), 1);
// Maximum of peak near TOF approx. equal to 22,000 (micro-seconds)
TS_ASSERT_DELTA(m_outWS->x(0)[333], 21989.8543, 0.0001);
TS_ASSERT_DELTA(m_outWS->x(0)[333], 21990.0502, 0.0001);
TS_ASSERT_DELTA(m_outWS->y(0)[333], 770.2515, 0.0001);
// Maximum of peak near TOF approx. equal to 25,800 (micro-seconds)
TS_ASSERT_DELTA(m_outWS->x(0)[398], 25750.0819, 0.0001);
TS_ASSERT_DELTA(m_outWS->x(0)[398], 25750.3113, 0.0001);
TS_ASSERT_DELTA(m_outWS->y(0)[398], 1522.3778, 0.0001);
// Maximum of peak near TOF approx. equal to 42,000 (micro-seconds)
TS_ASSERT_DELTA(m_outWS->x(0)[600], 42056.2345, 0.0001);
TS_ASSERT_DELTA(m_outWS->x(0)[600], 42056.6091, 0.0001);
TS_ASSERT_DELTA(m_outWS->y(0)[600], 7283.29652, 0.0001);
}
......
......@@ -162,7 +162,7 @@ public:
const auto expectedUnitsNoGroups =
expectedUnitsInfo("2.6862", "14.1501", "40.1274", "0.1566", "-38.6633");
const auto expectedUnitsWithGroup =
expectedUnitsInfo("2.6860", "14.1541", "34.4100", "0.1826", "-38.6614");
expectedUnitsInfo("2.6860", "14.1541", "34.4103", "0.1826", "-38.6614");
for (const auto &paramName : {"Efixed", "EFixed-val"}) {
bool includeGrouping(false);
const auto expectedInfoNoGroups = expectedCommonTOFInfo() << expectedUnitsNoGroups;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment