Commit 7187a1b0 authored by Peterson, Peter's avatar Peterson, Peter
Browse files

Change behavior to generate exception for negative d

This also shuffles the code around a little more to cluster the error
checking and separately cluster the returns
parent ffd01776
......@@ -685,39 +685,46 @@ double dSpacing::singleFromTOF(const double tof) const {
// force the assumption that difc is positive in debug builds
assert(difc > 0.);
// handle special cases first...
// don't need to solve a quadratic when difa==0
if (difa == 0.)
return (tof - tzero) / difc;
// non-physical result
if (tzero > tof) {
if (difa > 0.) {
throw std::runtime_error("Cannot convert to imaginary d spacing because tzero > time-of-flight and difa is "
"positive. Quadratic doesn't have a positive root");
} else if (difa == 0.) {
throw std::runtime_error("Cannot convert to d spacing because tzero > time-of-flight");
}
}
// citardauq formula hides non-zero root if tof==tzero
// wich means that the constantTerm == 0
if (tof == tzero) {
if (difa < 0.)
return -difc / difa;
else
return 0.;
}
// non-physical result
if ((difa > 0.) && (tzero > tof)) {
throw std::runtime_error("Cannot convert to d spacing. Quadratic doesn't "
"have a positive root");
}
// general equation
const double linearTerm = tzero - tof;
const double sqrtTerm = 1 - 4 * difa * linearTerm / (difc * difc);
// this is with the opposite sign from the equation above
// as it reduces number of individual flops
const double negativeConstantTerm = tof - tzero;
// don't need to solve a quadratic when difa==0
if (difa == 0.)
return negativeConstantTerm / difc;
// general citarqauq equation
const double sqrtTerm = 1 + 4 * difa * negativeConstantTerm / (difc * difc);
if (sqrtTerm < 0.) {
throw std::runtime_error("Cannot convert to d spacing. Quadratic doesn't have real roots");
}
// pick smallest positive root. Since difc is positive it just depends on sign of c
// Note - c is generally negative
if (linearTerm > 0)
// pick smallest positive root. Since difc is positive it just depends on sign of constantTerm
// Note - constantTerm is generally negative
if (negativeConstantTerm < 0)
// single positive root
return linearTerm / (0.5 * difc * (-1 + sqrt(sqrtTerm)));
return negativeConstantTerm / (0.5 * difc * (1 - sqrt(sqrtTerm)));
else
// two positive roots. pick most negative denominator to get smallest root
return linearTerm / (0.5 * difc * (-1 - sqrt(sqrtTerm)));
return negativeConstantTerm / (0.5 * difc * (1 + sqrt(sqrtTerm)));
}
double dSpacing::conversionTOFMin() const {
......
......@@ -577,8 +577,8 @@ public:
}
void testdSpacing_fromTOF() {
const std::vector<double> x_in{-1., 0., 1001.1, 16000.};
const std::vector<double> y_in{1., 2., 3., 4.};
const std::vector<double> x_in{0., 1001.1, 16000.};
const std::vector<double> y_in{2., 3., 4.};
std::vector<double> x(x_in.begin(), x_in.end());
std::vector<double> y(y_in.begin(), y_in.end());
double difc =
......@@ -589,6 +589,10 @@ public:
for (size_t i = 0; i < x.size(); ++i)
TS_ASSERT_DELTA(x[i], x_in[i] / difc, 0.000001);
// test for exception thrown for negative tof
x[0] = -1.0;
TS_ASSERT_THROWS(d.fromTOF(x, y, 1.0, 1, {{UnitParams::difc, difc}}), const std::runtime_error &);
// test for exception thrown
x[0] = 1.0;
TS_ASSERT_THROWS(d.fromTOF(x, y, 1.0, 1, {{UnitParams::difc, -1.0}}), const std::runtime_error &)
......
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