jfjoch_writer writes rugnux's .mtz, _maps.mtz and _model.cif from the END blocks
New gemmi-only library JFJochRugnuxFiles (writer/), linked by JFJochWriter, so the writer needs no analysis library and builds with JFJOCH_WRITER_ONLY: - WriteMergedMtz / WriteMapCoefficientsMtz / PlacedModelStructure make the files from the structured blocks; WriteRugnuxResultFiles writes whichever blocks END carries beside the master, each under a temporary name and renamed into place, an existing file replaced only when the run's overwrite is set. A file that fails costs only itself (logged), not the run. - FillRugnuxResultBlocks reads the blocks back from the files rugnux wrote at a prefix (p.mtz, p_maps.mtz, p_model.cif), for the broker to fill END. WriteMtzReflections now goes through WriteMergedMtz (MergedReflectionsForWriter builds the block); its output is byte-identical to before, checked by md5 on a synthetic set in both the Friedel-merged and the anomalous layout. StreamWriter writes the files after the master and before the END ACK, so the ACK means they are in place; END receipt and each rename are logged at INFO with the wall-clock time, for last-frame-to-files latency. The broker's direct HDF5 pusher writes them too. Test: rugnux's three files -> blocks -> CBOR -> writer reproduces all of them (and _model.pdb) byte for byte; a ~25k-reflection END is 2.7 MB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
91f6563953
commit
aca27be862
14 files changed
+706
-85
No files matched your search
@@ -4,6 +4,7 @@
|
||||
#include "../common/JFJochException.h"
|
||||
#include "StreamWriter.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <utility>
|
||||
#include "FileWriter.h"
|
||||
|
||||
@@ -203,14 +204,16 @@ void StreamWriter::ProcessEndMessage() {
|
||||
if (state == StreamWriterState::Idle || state == StreamWriterState::Finalized)
|
||||
return;
|
||||
|
||||
if (verbose)
|
||||
logger.Info("Received end message");
|
||||
logger.Info("Received end message at wall clock {:.3f} s",
|
||||
std::chrono::duration<double>(std::chrono::system_clock::now().time_since_epoch()).count());
|
||||
|
||||
if (state != StreamWriterState::Error) {
|
||||
try {
|
||||
if ((image_puller_output.cbor->end_message->max_image_number == 0) && (max_image_number > 0))
|
||||
image_puller_output.cbor->end_message->max_image_number = max_image_number;
|
||||
file_writer->WriteHDF5(*image_puller_output.cbor->end_message);
|
||||
// Before the END ACK below, so that the ACK says these files are in place too.
|
||||
file_writer->WriteResultFiles(*image_puller_output.cbor->end_message, logger);
|
||||
} catch (const std::exception &e) {
|
||||
// std::exception for the same reason as in ProcessDataImage. Here the cost of a leak is the
|
||||
// highest: the END ACK and the notification below are never sent, the state never reaches
|
||||
|
||||
Reference in new issue
Block a user