diff --git a/rugnux/RugnuxJointSweeps.cpp b/rugnux/RugnuxJointSweeps.cpp index c6a6253e0..db0a59943 100644 --- a/rugnux/RugnuxJointSweeps.cpp +++ b/rugnux/RugnuxJointSweeps.cpp @@ -574,11 +574,24 @@ JointMergeInput BuildJointMergeInput(const std::vector &sweeps out.outcomes.resize(first + sweep.n_frames); for (int64_t f = 0; f < sweep.n_frames; ++f) out.outcomes[first + f].latt = lattice; + const auto usable = [](const ScaledFull &full) { + return std::isfinite(full.I) && std::isfinite(full.var_bkg) && full.var_per_I > 0.0f && full.d > 0.0f; + }; + const auto frame_of = [&](const ScaledFull &full) { + return std::clamp(std::llround(full.image_number), 0, sweep.n_frames - 1); + }; + // Each frame's reflections reserved at their count first: grown one by one, a large cell's + // sweeps held up to twice their size in spare capacity. + std::vector count(sweep.n_frames, 0); + for (const ScaledFull &full : sweep.fulls) + if (usable(full)) + count[frame_of(full)]++; + for (int64_t f = 0; f < sweep.n_frames; ++f) + out.outcomes[first + f].reflections.reserve(count[f]); for (const ScaledFull &full : sweep.fulls) { - if (!std::isfinite(full.I) || !std::isfinite(full.var_bkg) || !(full.var_per_I > 0.0f) - || !(full.d > 0.0f)) + if (!usable(full)) continue; - const auto frame = std::clamp(std::llround(full.image_number), 0, sweep.n_frames - 1); + const auto frame = frame_of(full); const gemmi::Op::Miller hkl = rel.cob.apply_to_hkl({{full.h, full.k, full.l}}); // A full as the merge takes a pre-combined observation, so that the combine rebuilds the variance // its own sweep's merge gave it: a count c of intensity I/c at correction c = var_per_I is a diff --git a/rugnux/rugnux_cli.cpp b/rugnux/rugnux_cli.cpp index 675567094..9ca68f76a 100644 --- a/rugnux/rugnux_cli.cpp +++ b/rugnux/rugnux_cli.cpp @@ -4262,9 +4262,10 @@ int RugnuxCli::RunJointSweeps(const RugnuxSweepPlan &plan) { JointMergeInput input = BuildJointMergeInput(members, relation); // The joint merge works on its own copy of the fulls (input.outcomes): the members' go, so that a large // cell's sweeps are not held twice. + // (Assigned an empty vector, not {}: that is an assignment from an empty list, which keeps the memory.) for (JointMemberSweep &m : members) { - m.fulls = {}; - m.merged = {}; + m.fulls = std::vector(); + m.merged = std::vector(); } if (input.segments.size() < 2) logger.Warning("Only {} sweep goes into the joint merge", input.segments.size());