-z (now also --reference; --reference-mtz still works) takes an SF-mmCIF (e.g. a deposited -sf.cif, gzipped or not) as well as an MTZ. The format is recognised by content: a file starting with "MTZ " is an MTZ, anything else is parsed as CIF. The first merged reflection block with the requested column (or, by default, one the auto choice accepts) is converted to a gemmi::Mtz in memory with GEMMI's CifToMtz and then read by the unchanged MTZ loader, so the in-memory reference is exactly what the MTZ path yields. Unmerged (_diffrn_refln) and anomalous-only blocks are passed over; the log names the block used. The R-free set comes from _refln.status (f -> FreeR_flag 0, o -> 1: the CCP4 convention the loader already reads) and is preferred to _refln.pdbx_r_free_flag, whose convention varies by program; a status column with no 'f' is ignored and pdbx_r_free_flag is used instead. Checked on two open-arm sets in the deposited setting (one with F_meas_au only, one with intensity_meas): reference loaded with the deposited cell and group, the inherited free set agrees with the deposited status 'f' on every common reflection, and the merge correlates at CC 0.99 with the deposition. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D1G8gJVAy6gp1K5Dz3NE5C
67 lines
3.9 KiB
C++
67 lines
3.9 KiB
C++
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#pragma once
|
|
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "../common/Reflection.h"
|
|
#include "../common/UnitCell.h"
|
|
|
|
// A column an MTZ offers as reference intensities/structure factors (type 'J' mean intensity or
|
|
// 'F' amplitude). Surfaced so the caller (CLI flag / viewer combo) can pick which one to scale
|
|
// against and report the choice, rather than the loader silently guessing.
|
|
struct ReferenceMtzColumn {
|
|
std::string label;
|
|
char type = '\0'; // 'J' = mean intensity, 'F' = structure-factor amplitude
|
|
};
|
|
|
|
// Reference reflections loaded from an MTZ, plus the metadata a user needs to judge whether the
|
|
// reference matches the data being scaled: which column was used, the cell / space group it was
|
|
// recorded in, its resolution range and reflection count.
|
|
struct ReferenceMtzData {
|
|
std::vector<MergedReflection> reflections; // h,k,l,I,d set (sigma stays NaN)
|
|
std::optional<UnitCell> cell;
|
|
std::optional<int> space_group_number;
|
|
std::string space_group_name; // Hermann-Mauguin short symbol, for display
|
|
std::string space_group_xhm; // the full symbol, which names the setting too
|
|
std::string point_group; // point-group symbol, for the consistency check
|
|
std::string used_column;
|
|
char used_column_type = '\0';
|
|
bool squared = false; // an 'F' column was squared to an intensity
|
|
bool default_column = true; // column was auto-selected, not user-specified
|
|
std::vector<ReferenceMtzColumn> candidate_columns;
|
|
double d_min = 0.0;
|
|
double d_max = 0.0;
|
|
|
|
// Cross-validation (free-R) flags, if the MTZ carried a FreeR_flag column. When present, the
|
|
// per-reflection rfree_flag above is set from it and a whole campaign can inherit one test set.
|
|
bool has_free_flags = false;
|
|
std::string free_column; // the FreeR column label used, for display
|
|
int n_free = 0; // number of reflections flagged free (test set)
|
|
|
|
std::string source; // "MTZ" or "SF-mmCIF block <name>", for display
|
|
};
|
|
|
|
// Load reference reflections from an MTZ or a PDB structure-factor mmCIF (SF-mmCIF), gzipped or not;
|
|
// the format is recognised by content. An SF-mmCIF block is converted to an MTZ in memory (FreeR_flag
|
|
// from _refln.status f/o, else _refln.pdbx_r_free_flag) and then read exactly like one. With no column requested the smart default is used:
|
|
// a calculated structure factor F-model (squared to an intensity), else a merged/observed
|
|
// intensity column (IMEAN/I/IOBS/...), else any mean-intensity (J) column - this also lets
|
|
// reference-based scaling be self-seeded from the data's own previous merge. A requested column overrides
|
|
// the default (an 'F'-type column is squared, a 'J'-type used directly). Throws if the requested
|
|
// column is missing or no usable column exists.
|
|
ReferenceMtzData LoadReferenceMtz(const std::string& path,
|
|
const std::optional<std::string>& column = std::nullopt);
|
|
|
|
// Compare a loaded reference against the data it will scale. Returns an empty string when they are
|
|
// consistent (or when the data cell / space group is unknown, so nothing can be said); otherwise a
|
|
// one-line, human-readable description of the mismatch to warn the user about. Reference intensities
|
|
// keyed in a different point group or cell do not correspond to the data, so this is the check that
|
|
// makes reference-based scaling and CCref trustworthy.
|
|
std::string ReferenceConsistencyWarning(const ReferenceMtzData& reference,
|
|
const std::optional<UnitCell>& data_cell,
|
|
std::optional<int> data_space_group_number);
|