// SPDX-FileCopyrightText: 2025 Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include #include #include "../common/Reflection.h" #include "../common/UnitCell.h" #include "../common/DiffractionExperiment.h" #include "IntegrationOutcome.h" 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 &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 &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 &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 Lorentz-polarization factor and nothing else - 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 &outcomes, const UnitCell &unitCell, const DiffractionExperiment &experiment, bool sum_partials, const std::string &filename); void WriteReflections(const std::vector &reflections, const UnitCell &unitCell, const DiffractionExperiment &experiment, const MergeStatistics &statistics, const ErrorModelReport &error_model, const TwinningAnalysisResult &twinning, const std::string &filename, size_t nthreads);