Build Packages / Create release (push) Successful in 24s
Build Packages / build:viewer:macos-arm64:nocuda (push) Successful in 3m29s
Build Packages / build:rugnux:macos-arm64:nocuda (push) Successful in 2m43s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 8m27s
Build Packages / build:rugnux:linux-x86_64:cuda (push) Successful in 9m53s
Build Packages / build:viewer:linux-x86_64:nocuda (push) Successful in 9m58s
Build Packages / build:viewer:linux-x86_64:cuda (push) Successful in 11m22s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 13m39s
Build Packages / build:viewer:windows-x86_64:nocuda (push) Successful in 18m37s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 16m32s
Build Packages / build:viewer:windows-x86_64:cuda (push) Successful in 24m11s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m30s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 19m3s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 20m23s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 19m41s
Build Packages / Generate python client (push) Successful in 50s
Build Packages / Build documentation (push) Successful in 1m16s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 21m0s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 18m38s
Build Packages / build:rugnux:windows-x86_64:cuda (push) Successful in 14m33s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 17m55s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 20m50s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 18m38s
Build Packages / Unit tests (push) Successful in 1h46m14s
* jfjoch_broker: Optional per-dataset authentication - statistics, images and plots can require a bearer token, which jfjoch_viewer supports. * jfjoch_viewer: Dark mode and a theme-matched colour scheme, a magnifier panel, and simpler contrast and background controls. * Rugnux: Multiple performance improvements on GPU and CPU (CPU-only processing up to 40% faster, faster image decoding on ARM), with unchanged results. * Rugnux: `--model` rigid-body refinement runs on the GPU, and the model-validation check is faster and more reliable. * Rugnux: Improved scaling and merging - error model, outlier rejection, absorption correction and French-Wilson amplitudes now agree more closely with XDS and ctruncate. * Rugnux: Improved integration - radial background on powder and ice rings, crowded rotation data keep their reflections, and CPU-only builds integrate large unit cells as GPU builds do. * Rugnux: More robust detector geometry - measured beam centre, X-ray bandwidth and goniometer rate, and geometry refinement accepted only on significant evidence. * Rugnux: Merged files are written in the standard setting, or in the setting of a reference MTZ, structure-factor mmCIF or model, with its free-R flags. * Rugnux: Richer report - ice and powder rings, further lattices, superstructure candidates and mosaicity, with warnings worded as prompts to check. * Rugnux: Clear error messages when a data set needs more GPU or host memory than is available. Reviewed-on: #83 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
91 lines
4.8 KiB
C++
91 lines
4.8 KiB
C++
// SPDX-FileCopyrightText: 2025 Paul Scherrer Institute
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "../common/Reflection.h"
|
|
#include "../common/UnitCell.h"
|
|
#include "../common/DiffractionExperiment.h"
|
|
#include "IntegrationOutcome.h"
|
|
|
|
#include <gemmi/mtz.hpp>
|
|
|
|
struct MergeStatistics;
|
|
struct TwinningAnalysisResult;
|
|
|
|
// The error model as it is reported, already formatted. `isa` is the whole-range 1/sqrt(a*b), the
|
|
// same quantity XDS's ISa denotes, so a file written here is directly comparable with a CORRECT.LP;
|
|
// `isa_asymptotic` is the strong-reflection tier, which only the rotation path has. `a` and `b` are
|
|
// in XDS's convention, sigma^2 = a*(sigma0^2 + b*I^2). Empty strings are written as unknown.
|
|
struct ErrorModelReport {
|
|
std::string isa;
|
|
std::string isa_asymptotic;
|
|
std::string a;
|
|
std::string b;
|
|
};
|
|
|
|
// nthreads: workers for the per-reflection row formatting, which is the bulk of the file.
|
|
void WriteMmcifReflections(const std::vector<MergedReflection> &reflections,
|
|
const UnitCell &unitCell,
|
|
const DiffractionExperiment &experiment,
|
|
const MergeStatistics &statistics,
|
|
const ErrorModelReport &error_model,
|
|
const TwinningAnalysisResult &twinning,
|
|
const std::string &filename,
|
|
size_t nthreads);
|
|
|
|
void WriteMtzReflections(const std::vector<MergedReflection> &reflections,
|
|
const UnitCell &unitCell,
|
|
const DiffractionExperiment &experiment,
|
|
const std::string &filename);
|
|
|
|
// SHELX HKLF-4 text file (h k l I sigma(I), Bijvoet mates separate) for SHELXC / ANODE.
|
|
// nthreads: workers for the per-reflection row formatting, as for the mmCIF.
|
|
void WriteShelxHklReflections(const std::vector<MergedReflection> &reflections,
|
|
const DiffractionExperiment &experiment,
|
|
const std::string &filename,
|
|
size_t nthreads);
|
|
|
|
// Unmerged observations in the column and batch-header layout POINTLESS writes: aimless, pointless,
|
|
// careless and iotbx.merging_statistics all read that layout. H K L are the ASU indices and M/ISYM
|
|
// recovers the index the reflection was measured at (which is what careless needs to see the crystal
|
|
// frame) and says whether the observation is a partial.
|
|
// sum_partials: add the partials of each rocking event into one full, written at the batch of the
|
|
// event's centroid with the summed rocking-curve fraction in FRACTIONCALC - the plain sum every
|
|
// rotation program writes, over the events the combine would assemble (--min-partiality). False
|
|
// writes one row per integrated box instead, flagged as partials for the reading program to sum.
|
|
// Stills have no rocking events and are unaffected either way.
|
|
// The intensities carry the deterministic per-reflection corrections and nothing else - Lorentz
|
|
// and polarization in LP, the sensor's angle-dependent efficiency in QE, and the attenuation of the
|
|
// flight-path medium in FLIGHT - so raw counts are I / LP * QE * FLIGHT. The partiality and the
|
|
// per-image scale are left for the reading program to fit, since every program this file is for
|
|
// fits a scale model of its own.
|
|
void WriteUnmergedMtzReflections(const std::vector<IntegrationOutcome> &outcomes,
|
|
const UnitCell &unitCell,
|
|
const DiffractionExperiment &experiment,
|
|
bool sum_partials,
|
|
const std::string &filename,
|
|
size_t nthreads = 1);
|
|
|
|
// The same file in two steps, for a caller that builds it while the outcomes' per-image scale fields
|
|
// are still being written: UnmergedMtz reads everything but mosaicity_deg, which
|
|
// SetUnmergedMtzMosaicity then copies into the batch headers. The Mtz points at the experiment's space
|
|
// group, so the experiment has to outlive it.
|
|
gemmi::Mtz UnmergedMtz(const std::vector<IntegrationOutcome> &outcomes,
|
|
const UnitCell &unitCell,
|
|
const DiffractionExperiment &experiment,
|
|
bool sum_partials,
|
|
size_t nthreads = 1);
|
|
void SetUnmergedMtzMosaicity(gemmi::Mtz &mtz, const std::vector<IntegrationOutcome> &outcomes);
|
|
|
|
void WriteReflections(const std::vector<MergedReflection> &reflections,
|
|
const UnitCell &unitCell,
|
|
const DiffractionExperiment &experiment,
|
|
const MergeStatistics &statistics,
|
|
const ErrorModelReport &error_model,
|
|
const TwinningAnalysisResult &twinning,
|
|
const std::string &filename,
|
|
size_t nthreads); |