WriteReflections: write merging statistics + ISa to the mmCIF output
Build Packages / build:windows:cuda (push) Failing after 2m40s
Build Packages / build:windows:nocuda (push) Failing after 2m40s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 13m47s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 14m42s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 14m46s
Build Packages / build:rpm (rocky8) (push) Successful in 14m52s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 15m10s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 15m5s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 15m47s
Build Packages / Unit tests (push) Failing after 19m1s
Build Packages / Generate python client (push) Successful in 32s
Build Packages / Build documentation (push) Successful in 1m0s
Build Packages / Create release (push) Skipped
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m54s
Build Packages / XDS test (durin plugin) (push) Successful in 8m7s
Build Packages / XDS test (neggia plugin) (push) Successful in 8m24s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 11m5s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 12m4s
Build Packages / build:rpm (rocky9) (push) Successful in 12m58s
Build Packages / DIALS test (push) Successful in 12m32s
Build Packages / build:windows:cuda (push) Failing after 2m40s
Build Packages / build:windows:nocuda (push) Failing after 2m40s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 13m47s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 14m42s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 14m46s
Build Packages / build:rpm (rocky8) (push) Successful in 14m52s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 15m10s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 15m5s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 15m47s
Build Packages / Unit tests (push) Failing after 19m1s
Build Packages / Generate python client (push) Successful in 32s
Build Packages / Build documentation (push) Successful in 1m0s
Build Packages / Create release (push) Skipped
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m54s
Build Packages / XDS test (durin plugin) (push) Successful in 8m7s
Build Packages / XDS test (neggia plugin) (push) Successful in 8m24s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 11m5s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 12m4s
Build Packages / build:rpm (rocky9) (push) Successful in 12m58s
Build Packages / DIALS test (push) Successful in 12m32s
The .cif (--scaling-output cif) now carries the per-shell and overall merging statistics in the standard _reflns / _reflns_shell categories (resolution, redundancy, completeness, <I/sigma>, R-rim/R-meas, CC1/2) plus the Diederichs asymptotic I/sigma (ISa) as a free-text _reflns.pdbx_diffrn_ISa item (no standard CIF tag exists). The MergeStatistics and the ISa string are threaded through WriteReflections to the mmCIF writer; jfjoch_process and jfjoch_scale pass them. Values match the text statistics table. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include "WriteReflections.h"
|
||||
#include "scale_merge/Merge.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
@@ -59,6 +60,8 @@ std::string CifStr(const std::string& s) {
|
||||
void WriteMmcifReflections(const std::vector<MergedReflection> &reflections,
|
||||
const UnitCell &unitCell,
|
||||
const DiffractionExperiment &experiment,
|
||||
const MergeStatistics &statistics,
|
||||
const std::string &isa,
|
||||
const std::string &filename) {
|
||||
|
||||
std::ofstream out(filename);
|
||||
@@ -110,6 +113,51 @@ void WriteMmcifReflections(const std::vector<MergedReflection> &reflections,
|
||||
|
||||
out << "_diffrn_radiation_wavelength.wavelength " << Fmt(experiment.GetWavelength_A(), 5) << "\n";
|
||||
out << "_diffrn_detector.detector " << CifStr(experiment.GetDetectorDescription()) << "\n";
|
||||
out << "#\n";
|
||||
|
||||
// ---------- merging statistics (_reflns overall + _reflns_shell loop) ----------
|
||||
// cc_half and r_meas are stored as fractions (0-1), which is the mmCIF convention. ISa (the
|
||||
// Diederichs asymptotic I/sigma, 1/b of the a*sigma^2 + (b*I)^2 error model) has no standard CIF
|
||||
// item, so it is written as a free-text pdbx value.
|
||||
const auto mult = [](const MergeStatisticsShell &s) {
|
||||
return s.unique_reflections > 0 ? static_cast<double>(s.total_observations) / s.unique_reflections : 0.0; };
|
||||
const auto compl_pct = [](const MergeStatisticsShell &s) {
|
||||
return s.possible_unique_reflections > 0
|
||||
? 100.0 * static_cast<double>(s.unique_reflections) / s.possible_unique_reflections : 0.0; };
|
||||
if (!statistics.shells.empty()) {
|
||||
const auto &ov = statistics.overall;
|
||||
out << "_reflns.d_resolution_high " << Fmt(ov.d_min, 2) << "\n";
|
||||
out << "_reflns.d_resolution_low " << Fmt(ov.d_max, 2) << "\n";
|
||||
out << "_reflns.number_obs " << ov.unique_reflections << "\n";
|
||||
out << "_reflns.pdbx_number_measured_all " << ov.total_observations << "\n";
|
||||
out << "_reflns.pdbx_redundancy " << Fmt(mult(ov), 2) << "\n";
|
||||
out << "_reflns.percent_possible_obs " << Fmt(compl_pct(ov), 1) << "\n";
|
||||
out << "_reflns.pdbx_netI_over_sigmaI " << Fmt(ov.mean_i_over_sigma, 2) << "\n";
|
||||
out << "_reflns.pdbx_Rrim_I_all " << Fmt(ov.r_meas, 4) << "\n";
|
||||
out << "_reflns.pdbx_CC_half " << Fmt(ov.cc_half, 4) << "\n";
|
||||
out << "_reflns.pdbx_diffrn_ISa " << CifStr(isa) << " # asymptotic I/sigma (Diederichs)\n";
|
||||
out << "#\n";
|
||||
|
||||
out << "loop_\n";
|
||||
out << "_reflns_shell.d_res_high\n";
|
||||
out << "_reflns_shell.d_res_low\n";
|
||||
out << "_reflns_shell.number_measured_obs\n";
|
||||
out << "_reflns_shell.number_unique_obs\n";
|
||||
out << "_reflns_shell.pdbx_redundancy\n";
|
||||
out << "_reflns_shell.percent_possible_obs\n";
|
||||
out << "_reflns_shell.meanI_over_sigI_obs\n";
|
||||
out << "_reflns_shell.pdbx_Rrim_I_all\n";
|
||||
out << "_reflns_shell.pdbx_CC_half\n";
|
||||
for (const auto &s : statistics.shells) {
|
||||
if (s.unique_reflections == 0)
|
||||
continue;
|
||||
out << Fmt(s.d_min, 2) << " " << Fmt(s.d_max, 2) << " "
|
||||
<< s.total_observations << " " << s.unique_reflections << " "
|
||||
<< Fmt(mult(s), 2) << " " << Fmt(compl_pct(s), 1) << " "
|
||||
<< Fmt(s.mean_i_over_sigma, 2) << " " << Fmt(s.r_meas, 4) << " " << Fmt(s.cc_half, 4) << "\n";
|
||||
}
|
||||
out << "#\n";
|
||||
}
|
||||
|
||||
// ---------- _refln loop ----------
|
||||
out << "loop_\n";
|
||||
@@ -199,13 +247,15 @@ void WriteHKLReflections(const std::vector<MergedReflection> &reflections,
|
||||
void WriteReflections(const std::vector<MergedReflection> &reflections,
|
||||
const UnitCell &unitCell,
|
||||
const DiffractionExperiment &experiment,
|
||||
const MergeStatistics &statistics,
|
||||
const std::string &isa,
|
||||
const std::string &filename) {
|
||||
switch (experiment.GetScalingSettings().GetFileFormat()) {
|
||||
case IntensityFormat::Text:
|
||||
WriteHKLReflections(reflections, filename + ".hkl");
|
||||
break;
|
||||
case IntensityFormat::mmCIF:
|
||||
WriteMmcifReflections(reflections, unitCell, experiment, filename + ".cif");
|
||||
WriteMmcifReflections(reflections, unitCell, experiment, statistics, isa, filename + ".cif");
|
||||
break;
|
||||
case IntensityFormat::MTZ:
|
||||
WriteMtzReflections(reflections, unitCell, experiment, filename + ".mtz");
|
||||
|
||||
Reference in New Issue
Block a user