Files
Jungfraujoch/writer/RugnuxReflectionFile.h
T
leonarski_f a218c0bec8 rugnux --mode refine: refine a model against merged structure factors, nothing processed
rugnux --mode refine --model model.cif -o out data.mtz

The input is an MTZ or a structure-factor mmCIF, gzipped or not, by content
(writer/RugnuxReflectionFile: parsing in the file layer, the library reads no file). Columns are
found, not named: F/SIGF-like amplitudes (calculated amplitudes and map coefficients passed over),
else intensities made into amplitudes by French-Wilson, else the mean of the anomalous pairs; the
free set from a FreeR_flag-like column (0 the test set, or the minority value), else rugnux's own
5 % set. RunRefineOnly (rugnux/RugnuxRefine) runs RefineModel; the outputs are --refine's
(_refined_model.cif, _refined_maps.mtz, _blobs.json) and a report with the REFINE_ keys, the input's
REFINE_FRENCH_WILSON / REFINE_FREE_FLAGS, and every term of the start score under REFINE_SCORE_
(also in --refine's section). --refine-score-only scores the model as given; --refine-d-min cuts
the resolution.

tools/battery/refine_parity.py runs REFMAC 5.8 at 0 cycles and rugnux --refine-score-only on the
same files and prints the terms side by side, with R by resolution from both programs' model
amplitudes on the same reflections.

Tests: [refine_only] - column choice (observed over map coefficients, intensities, 1-marks-free
flags, no flags, no usable column), an MTZ read from its bytes, and the mode end to end on a
synthetic cell (French-Wilson, generated flags, score-only, the report keys).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu
(cherry picked from commit 63ee830c39c988588cffb8c9d4638a678815ec2c)
(cherry picked from commit d7397311e6ce0d3bb37ac91e8973b6052e38589f)
2026-10-26 01:38:24 +01:00

51 lines
2.8 KiB
C++

// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <string>
#include <vector>
#include "gemmi/mtz.hpp"
#include "gemmi/unitcell.hpp"
#include "../common/Reflection.h"
// Merged reflections a refinement is given (rugnux --mode refine), as their file held them: an MTZ or a
// structure-factor mmCIF (as the PDB holds them), gzipped or not, the format taken from the content. The
// columns are found, not named: amplitudes with their sigmas where the file has them, else intensities (the
// caller turns those into amplitudes), and the free-set flags where there are any. The caller parses; the
// analysis reads no file.
struct RugnuxReflections {
std::string name; // what the report calls the file
std::string source; // "MTZ" or "mmCIF block <name>"
gemmi::UnitCell cell;
std::string space_group; // extended Hermann-Mauguin symbol
double wavelength_A = 0; // 0: the file does not say
// h, k, l and d, with F/sigmaF where amplitudes were read, I/sigma where intensities were; rfree_flag
// where the file has free-set flags.
std::vector<MergedReflection> reflections;
bool amplitudes = true; // false: intensities, no amplitudes in the file
std::string value_column, sigma_column;
std::string free_column; // empty: the file has no free-set flags
int n_free = 0;
};
// The columns of `mtz` (an MTZ, or an mmCIF converted to one), found as RugnuxReflections describes:
// - amplitudes: a type-F column followed by its type-Q sigma, by the usual names first (F, FP, FOBS, F-obs,
// FMEAN, ...), then any such pair that is not a calculated or map coefficient (FC, FWT, DELFWT, F-model ...);
// - else intensities: a type-J column with its type-Q sigma (IMEAN, I, IOBS, I-obs, ... first); the
// anomalous pairs F(+)/F(-) (G/L) or I(+)/I(-) (K/M) averaged where there is nothing else;
// - free flags: a type-I column named as a free set (FreeR_flag, FREE, R-free-flags, ...: any with "free" in
// its name). The test set is flag 0 in the CCP4 convention (0-19 thin shells included); where 0 marks the
// majority (1 marks the test set, as phenix and CNS write it), the minority is taken.
// Throws where there is neither.
RugnuxReflections RugnuxReflectionsFromMtz(const gemmi::Mtz &mtz, const std::string &name);
// The reflections of a file's bytes, the format from the content (MTZ by its magic, else mmCIF: the first
// merged block that holds amplitudes or intensities). Throws where the bytes hold none.
RugnuxReflections ParseRugnuxReflections(const std::string &bytes, const std::string &name);
// The file at `path`, named by it.
RugnuxReflections ReadRugnuxReflectionFile(const std::string &path);