rugnux: sum each rotation reflection's partials into one full on export
--export-unmerged now writes one row per reflection with its partials summed, which is how a rotation dataset is normally handed to a scaling program. The previous behaviour is still available as --export-unmerged-partials. Partials made the file's usefulness depend on the reading program's partial-assembly settings. On an orthorhombic case only 31% of partial sets passed aimless's default PARTIALS test, so it merged 2% of the file: multiplicity 4.7 against our own 12.4, CC1/2 0.788, and CC against our merged intensities 0.806. Summed, aimless uses 89% of the file and rejects nothing: multiplicity 12.5, CC1/2 0.931, completeness 96.1 to 98.0, pointless Laue confidence 0.669 to 0.792, CC 0.848. The other two test crystals are ties overall and win their outer shells, and the anomalous signal comes out stronger from the fulls. iotbx.merging_statistics, which never assembled partials at all, now reports real merging statistics rather than statistics of parts. Events are grouped by Combine()'s own rule so the file and the merge assemble exactly the same reflections; the sum is plain with variances in quadrature and no partiality division, which reproduces the merge's full times FRACTIONCALC to a few percent. Per-part metadata is combined on a partiality-weighted centroid rather than an intensity-weighted one: 8-41% of events have parts summing to zero or less, where intensity weights are undefined or sign-flipped, and 10-21% of intensity-weighted centroids fall outside the event's own frame range. Events below --min-partiality are not written. Declaring a reflection whose rocking curve caught a thousandth of itself as a complete measurement gives a scaling program noise with a small sigma and it weights it heavily; there is no partial test to catch it once it is a full. This is the same constant already applied to the same quantity in the merge, and it is what takes the orthorhombic case from CC 0.219 to 0.848. --min-partiality 0 writes every event. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CHMmeM1d489zvNFT7ZMN2P
This commit is contained in:
@@ -47,17 +47,22 @@ void WriteShelxHklReflections(const std::vector<MergedReflection> &reflections,
|
||||
const std::string &filename,
|
||||
size_t nthreads);
|
||||
|
||||
// Unmerged observations, one row per integrated reflection, 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.
|
||||
// One observation per integrated box, so on a rotation run a reflection arrives as a run of partials
|
||||
// over consecutive batches, for the reader to sum. 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.
|
||||
// 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<IntegrationOutcome> &outcomes,
|
||||
const UnitCell &unitCell,
|
||||
const DiffractionExperiment &experiment,
|
||||
bool sum_partials,
|
||||
const std::string &filename);
|
||||
|
||||
void WriteReflections(const std::vector<MergedReflection> &reflections,
|
||||
|
||||
Reference in New Issue
Block a user