Do not read the oscillation width as the rotation step
SweepLayout rejected any inter-frame difference below half the header's oscillation width as read-back jitter. A series that steps by less than it exposes - overlapping wedges, or a writer that puts the whole sweep's range in that field - then had every difference rejected, no step was found, and the files fell into the "series that never turns" branch, which lays them out end to end and, unlike the gapped path, said nothing. The jitter bound is now absolute (1e-4 deg, below any step an instrument makes and above 32-bit float read-back noise), and the end-to-end fallback warns when the angles do span a rotation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nW6FNRP1bBJJ8pfHiByAT
This commit is contained in:
@@ -153,3 +153,24 @@ TEST_CASE("SweepLayout_RepeatedAngleRefused") {
|
||||
// Two sweeps of the same crystal concatenated: the second covers angles the first already has.
|
||||
CHECK_THROWS_AS(sweep::Place(Series({0.0, 0.1, 0.2, 0.1, 0.2}, 0.1), "test"), JFJochException);
|
||||
}
|
||||
|
||||
TEST_CASE("SweepLayout_StepFinerThanTheOscillationWidth") {
|
||||
// The header field is the oscillation WIDTH, and a series can step by far less than it exposes -
|
||||
// or, on some writers, hold the whole sweep's range in that field. Taking it for the step
|
||||
// rejected every inter-frame difference as jitter: the sweep then read as one that never turns
|
||||
// and was laid out end to end, every frame past the first at the wrong angle.
|
||||
std::vector<double> angles;
|
||||
for (int i = 0; i < 100; i++)
|
||||
angles.push_back(30.0 + 0.1 * i);
|
||||
|
||||
const auto wedges = sweep::Place(Series(angles, 1.0), "test"); // 1 deg wedges, 0.1 deg apart
|
||||
REQUIRE(wedges.files.size() == 100);
|
||||
CHECK(wedges.present == 100);
|
||||
CHECK(wedges.start_deg == Catch::Approx(30.0));
|
||||
CHECK(wedges.increment_deg == Catch::Approx(0.1));
|
||||
|
||||
const auto total = sweep::Place(Series(angles, 10.0), "test"); // the field holds the range
|
||||
REQUIRE(total.files.size() == 100);
|
||||
CHECK(total.present == 100);
|
||||
CHECK(total.increment_deg == Catch::Approx(0.1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user