v1.0.0-rc.166 (#76)
Build Packages / Unit tests (push) Successful in 1h22m15s
Build Packages / build:windows:nocuda (push) Successful in 18m0s
Build Packages / build:windows:cuda (push) Successful in 20m30s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m32s
Build Packages / build:viewer-tgz:cuda (push) Successful in 11m39s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 8m55s
Build Packages / build:rugnux:windows (push) Successful in 11m25s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 20m6s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m27s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 20m19s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 15m34s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 20m25s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m36s
Build Packages / build:rpm (rocky8) (push) Successful in 17m43s
Build Packages / build:rpm (rocky9) (push) Successful in 13m34s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 21m28s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 18m19s
Build Packages / DIALS test (push) Successful in 12m36s
Build Packages / XDS test (durin plugin) (push) Successful in 6m56s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 6m48s
Build Packages / XDS test (neggia plugin) (push) Successful in 6m7s
Build Packages / Generate python client (push) Successful in 11s
Build Packages / Build documentation (push) Successful in 36s
Build Packages / Create release (push) Skipped
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 5m11s
Build Packages / Unit tests (push) Successful in 1h22m15s
Build Packages / build:windows:nocuda (push) Successful in 18m0s
Build Packages / build:windows:cuda (push) Successful in 20m30s
Build Packages / build:viewer-tgz:cpu (push) Successful in 10m32s
Build Packages / build:viewer-tgz:cuda (push) Successful in 11m39s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 8m55s
Build Packages / build:rugnux:windows (push) Successful in 11m25s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 20m6s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m27s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 20m19s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 15m34s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 20m25s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 19m36s
Build Packages / build:rpm (rocky8) (push) Successful in 17m43s
Build Packages / build:rpm (rocky9) (push) Successful in 13m34s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 21m28s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 18m19s
Build Packages / DIALS test (push) Successful in 12m36s
Build Packages / XDS test (durin plugin) (push) Successful in 6m56s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 6m48s
Build Packages / XDS test (neggia plugin) (push) Successful in 6m7s
Build Packages / Generate python client (push) Successful in 11s
Build Packages / Build documentation (push) Successful in 36s
Build Packages / Create release (push) Skipped
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 5m11s
* `rugnux --mode calibration` writes `<prefix>.json` beside the `.poni`, whose `dataset_settings` member is a `jfjoch_broker` `dataset_settings` body as it stands. * `rugnux` and `jfjoch_viewer` read PILATUS miniCBF sweeps natively, without conversion. * Masters written by other facilities open, including Eiger 1.x and third-party NXmx variants. * `rugnux` measures the beam centre on every run, and indexes with it when the file's value indexes nothing. * A detector swung out on a 2theta arm is placed where the file says it stands, and the calibration can hold the tilt fixed. * `rugnux` writes the unmerged MTZ by default, and a P1 merge beside it, so a wrong space group can be re-merged without reprocessing. * Significant improvements to symmetry handling in `rugnux`: the lattice, the point group, the setting and the systematic absences. * The `rugnux` report gives the resolution the CC1/2 fit reached, beside the range the reflections were written to. * The `rugnux` report gives the twinning statistics measured before the space group was decided, beside the ones measured after. * The `rugnux` report gives the strong-direction diffraction limit, and warns when CC1/2 is not monotone with resolution. * `rugnux` ranks screw axes on the evidence their absences carry, rather than on how many control reflections a candidate happens to have. * Twinning is no longer reported when the L-test contradicts it. * The `rugnux` report gives the detector tilt, the measured tilt and the direct beam beside the beam centre, and a post-refined beam centre is judged against the run's own measurement rather than the file's. * `--no-refine-tilt` holds the detector tilt at the value in the file, instead of zeroing it, when the calibration starts from the spots. * The `jfjoch_viewer` grid scan view draws the cells in the proportion of the scan steps, so the map has the shape of the scanned area. Reviewed-on: #76 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
This commit was merged in pull request #76.
This commit is contained in:
@@ -669,5 +669,75 @@ TEST_CASE("XtalOptimizer_refine_rotation_axis") {
|
||||
CHECK(fabsf(xtal_opt.axis->GetAxis().z) < 0.01f);
|
||||
}
|
||||
|
||||
// The rotation residual applies `angle_rad * |rot_vec|`, so the goniometer axis block must be
|
||||
// constrained to unit length or the solve also fits a rotation SCALE that GoniometerAxis::Axis()
|
||||
// then normalises away. Generate spots whose true rotation is k times the angles the optimizer is
|
||||
// handed - k = 1 for a healthy goniometer, k = 1.01 for a stage that turned 1 % further than it was
|
||||
// commanded - and check the axis DIRECTION and the cell come back either way. (Before the axis block
|
||||
// was put on the unit sphere, the free length absorbed part of that 1 %: on this noise-free data it
|
||||
// reached only 1.00538 of the 1.01 it would have had to reach to be a measurement.)
|
||||
TEST_CASE("XtalOptimizer_rotation_axis_direction_only") {
|
||||
DiffractionExperiment exp_i;
|
||||
exp_i.IncidentEnergy_keV(WVL_1A_IN_KEV)
|
||||
.BeamX_pxl(1000).BeamY_pxl(1000)
|
||||
.DetectorDistance_mm(200);
|
||||
|
||||
const CrystalLattice latt_base(40, 50, 80, 90, 95, 90);
|
||||
const auto uc_ref = latt_base.GetUnitCell();
|
||||
|
||||
const double k_true = GENERATE(1.000, 1.010);
|
||||
|
||||
// The angles the FILE records. The stage actually turned k_true times as far.
|
||||
GoniometerAxis nominal("omega", 0.0f, 3.0f, Coord(1, 0, 0), std::nullopt);
|
||||
|
||||
BraggPredictionSettings prediction_settings{.high_res_A = 1.5, .ewald_dist_cutoff = 0.002};
|
||||
BraggPrediction prediction;
|
||||
|
||||
const size_t nimages = 40;
|
||||
std::vector<std::vector<SpotToSave>> spots(nimages);
|
||||
for (size_t img = 0; img < nimages; ++img) {
|
||||
const float nominal_deg = nominal.GetAngle_deg(img) + nominal.GetWedge_deg() / 2.0f;
|
||||
const RotMatrix rot = nominal.GetTransformationAngle(static_cast<float>(nominal_deg * k_true));
|
||||
const CrystalLattice latt_img = latt_base.Multiply(rot.transpose());
|
||||
const auto n = prediction.Calc(exp_i, latt_img, prediction_settings);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
const auto &r = prediction.GetReflections().at(i);
|
||||
SpotToSave s{};
|
||||
s.x = r.predicted_x;
|
||||
s.y = r.predicted_y;
|
||||
s.image = static_cast<int32_t>(img);
|
||||
s.intensity = 1.0f;
|
||||
s.phi = nominal_deg;
|
||||
s.indexed = true;
|
||||
spots.at(img).push_back(s);
|
||||
}
|
||||
}
|
||||
|
||||
XtalOptimizerData xtal_opt{};
|
||||
xtal_opt.latt = latt_base;
|
||||
xtal_opt.geom.BeamX_pxl(1000).BeamY_pxl(1000).DetectorDistance_mm(200.0);
|
||||
xtal_opt.crystal_system = gemmi::CrystalSystem::Monoclinic;
|
||||
xtal_opt.axis = GoniometerAxis("omega", 0.0f, 3.0f, Coord(0.999, 0.02, 0.02).Normalize(),
|
||||
std::nullopt);
|
||||
xtal_opt.min_spots = 200;
|
||||
xtal_opt.refine_beam_center = true;
|
||||
xtal_opt.refine_detector_angles = true;
|
||||
xtal_opt.refine_rotation_axis = true;
|
||||
xtal_opt.max_iterations = 200;
|
||||
|
||||
REQUIRE(XtalOptimizer(xtal_opt, spots));
|
||||
|
||||
const Coord axis_out = xtal_opt.axis->GetAxis();
|
||||
CHECK(std::fabs(axis_out.Length() - 1.0f) < 1e-5f);
|
||||
CHECK(std::fabs(axis_out.x - 1.0f) < 0.01f);
|
||||
CHECK(std::fabs(axis_out.y) < 0.01f);
|
||||
CHECK(std::fabs(axis_out.z) < 0.01f);
|
||||
|
||||
const auto uc_out = xtal_opt.latt.GetUnitCell();
|
||||
CHECK(std::fabs(uc_ref.a - uc_out.a) < 0.2f);
|
||||
CHECK(std::fabs(uc_ref.b - uc_out.b) < 0.2f);
|
||||
CHECK(std::fabs(uc_ref.c - uc_out.c) < 0.3f);
|
||||
}
|
||||
|
||||
// --- helpers for lattice sanity tests ---
|
||||
#include <Eigen/Dense>
|
||||
|
||||
Reference in New Issue
Block a user