From 18c0d0cf6fb8317eec28e3a154585aee22dfa1df Mon Sep 17 00:00:00 2001 From: leonarski_f Date: Wed, 20 May 2026 08:25:43 +0200 Subject: [PATCH] Merge: More printing is done directly, --- image_analysis/scale_merge/Merge.cpp | 69 +++++++++++++++------------- image_analysis/scale_merge/Merge.h | 5 +- tools/jfjoch_process.cpp | 47 +++++++++++++------ tools/jfjoch_scale.cpp | 2 +- 4 files changed, 74 insertions(+), 49 deletions(-) diff --git a/image_analysis/scale_merge/Merge.cpp b/image_analysis/scale_merge/Merge.cpp index 66942a78..4a7c5fba 100644 --- a/image_analysis/scale_merge/Merge.cpp +++ b/image_analysis/scale_merge/Merge.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include #include "../../common/CorrelationCoefficient.h" @@ -440,41 +442,42 @@ MergeStatistics MergeStats(const DiffractionExperiment &x, return out; } -void MergeStatistics::Print(Logger &logger) const { - logger.Info(""); - logger.Info(" {:>8s} {:>8s} {:>8s} {:>8s} {:>8s} {:>8s} {:>8s} {:>8s}", "d_min", "N_obs", "N_uniq", "N_possib", "Compl","", "CC1/2", "CCref"); - logger.Info(" {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s}", "", "", "", "", "", "", "", ""); - for (const auto &sh: shells) { + +std::ostream &operator<<(std::ostream &output, const MergeStatisticsShell &in) { + double completeness = in.possible_unique_reflections > 0 + ? static_cast(in.unique_reflections) / in.possible_unique_reflections * 100.0 : 0.0; + + output << fmt::format("{:8d} {:8d} {:8d} {:7.1f}% {:8.1f} {:7.1f}% {:7.1f}%", + in.total_observations, + in.unique_reflections, + in.possible_unique_reflections, + completeness, + in.mean_i_over_sigma, + in.cc_half*100.0, + in.cc_ref*100.0); + return output; +} + +std::ostream &operator<<(std::ostream &output, const MergeStatistics &in) { + output << std::endl; + output << fmt::format(" {:>8s} {:>8s} {:>8s} {:>8s} {:>8s} {:>8s} {:>8s} {:>8s}", + "d_min", "N_obs", "N_uniq", "N_possib", "Compl","", "CC1/2", "CCref") + << std::endl;; + output << fmt::format(" {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s}", + "", "", "", "", "", "", "", "") << std::endl; + for (const auto &sh: in.shells) { if (sh.unique_reflections == 0) continue; - double completeness = sh.possible_unique_reflections > 0 - ? static_cast(sh.unique_reflections) / sh.possible_unique_reflections * 100.0 : 0.0; - - logger.Info(" {:8.2f} {:8d} {:8d} {:8d} {:7.1f}% {:8.1f} {:7.1f}% {:7.1f}%", - sh.d_min, - sh.total_observations, - sh.unique_reflections, - sh.possible_unique_reflections, - completeness, - sh.mean_i_over_sigma, - sh.cc_half*100.0, - sh.cc_ref*100.0); + output << fmt::format(" {:8.2f} ", sh.d_min); + output << sh; + output << std::endl; } - { - const auto &ov = overall; - double completeness = ov.possible_unique_reflections > 0 - ? static_cast(ov.unique_reflections) / ov.possible_unique_reflections * 100.0 : 0.0; + output << fmt::format(" {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s}", + "", "", "", "", "", "", "", "") << std::endl; - logger.Info(" {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s} {:->8s}", "", "", "", "", "", "", "", ""); - logger.Info(" {:>8s} {:8d} {:8d} {:8d} {:7.1f}% {:8.1f} {:7.1f}% {:7.1f}%", - "Overall", - ov.total_observations, - ov.unique_reflections, - ov.possible_unique_reflections, - completeness, - ov.mean_i_over_sigma, - ov.cc_half*100.0, - ov.cc_ref*100.0); - } - logger.Info(""); + output << fmt::format(" {:>8s} ", "Overall"); + output << in.overall; + output << std::endl; + output << std::endl; + return output; } diff --git a/image_analysis/scale_merge/Merge.h b/image_analysis/scale_merge/Merge.h index 9f3e671e..31a05da3 100644 --- a/image_analysis/scale_merge/Merge.h +++ b/image_analysis/scale_merge/Merge.h @@ -31,9 +31,12 @@ struct MergeStatisticsShell { struct MergeStatistics { std::vector shells; MergeStatisticsShell overall; - void Print(Logger &logger) const; }; + +std::ostream &operator<<(std::ostream &output, const MergeStatisticsShell &in); +std::ostream &operator<<(std::ostream &output, const MergeStatistics &in); + struct MergeAccum { int32_t h = 0; int32_t k = 0; diff --git a/tools/jfjoch_process.cpp b/tools/jfjoch_process.cpp index 0f57c359..591f7840 100644 --- a/tools/jfjoch_process.cpp +++ b/tools/jfjoch_process.cpp @@ -60,8 +60,8 @@ void print_usage(Logger &logger) { std::cout << std::endl; std::cout << " Scaling and merging" << std::endl; - std::cout << " --scale-merge Scale and merge (refine mosaicity) and write scaled.hkl + image.dat" << std::endl; - std::cout << " --partiality Partiality refinement fixed|rot|unity (default: fixed)" << std::endl; + std::cout << " -M, --scale-merge Scale and merge (refine mosaicity) and write scaled.hkl + image.dat" << std::endl; + std::cout << " -P, --partiality Partiality refinement fixed|rot|unity (default: fixed)" << std::endl; std::cout << " -A, --anomalous Anomalous mode (don't merge Friedel pairs)" << std::endl; std::cout << " -B, --refine-bfactor Refine per image B-factor" << std::endl; std::cout << " -w, --wedge[=num] Refine image wedge during scaling with starting wedge value" << std::endl; @@ -77,7 +77,6 @@ enum { OPT_SPOT_RESOLUTION, OPT_MAX_SPOTS, OPT_NO_BEAM_CENTER_REFINE, - OPT_SCALE_MERGE, OPT_MIN_PARTIALITY, OPT_MIN_IMAGE_CC, OPT_SCALING_ITERATIONS @@ -99,13 +98,13 @@ static option long_options[] = { {"anomalous", no_argument, nullptr, 'A'}, {"refine-bfactor", no_argument, nullptr, 'B'}, {"wedge", optional_argument, nullptr, 'w'}, + {"scale-merge", no_argument, nullptr, 'M'}, {"spot-sigma", required_argument, nullptr, OPT_SPOT_SIGMA}, {"spot-threshold", required_argument, nullptr, OPT_SPOT_THRESHOLD}, {"spot-resolution", required_argument, nullptr, OPT_SPOT_RESOLUTION}, {"max-spots", required_argument, nullptr, OPT_MAX_SPOTS}, {"no-beam-center-refine", no_argument, nullptr, OPT_NO_BEAM_CENTER_REFINE}, - {"scale-merge", no_argument, nullptr, OPT_SCALE_MERGE}, {"min-partiality", required_argument, nullptr, OPT_MIN_PARTIALITY}, {"min-image-cc", required_argument, nullptr, OPT_MIN_IMAGE_CC}, {"scaling-iterations", required_argument, nullptr, OPT_SCALING_ITERATIONS}, @@ -174,6 +173,12 @@ std::optional parse_unit_cell_arg(const char *arg) { }; int main(int argc, char **argv) { + for (int i = 0; i < argc; i++) { + std::cout << argv[i] << " "; + } + std::cout << std::endl << std::endl; + + RegisterHDF5Filter(); print_license("jfjoch_analysis"); @@ -220,7 +225,7 @@ int main(int argc, char **argv) { int opt; int option_index = 0; - const char *short_opts = "vo:N:s:e:t:R::X:C:z:FABw::S:"; + const char *short_opts = "vo:N:s:e:t:R::X:C:z:FABw::S:MP:"; while ((opt = getopt_long(argc, argv, short_opts, long_options, &option_index)) != -1) { switch (opt) { @@ -303,6 +308,19 @@ int main(int argc, char **argv) { case 'S': space_group_number = atoi(optarg); break; + case 'P': + if (strcmp(optarg, "unity") == 0) + partiality_model = PartialityModel::Unity; + else if (strcmp(optarg, "fixed") == 0) + partiality_model = PartialityModel::Fixed; + else if (strcmp(optarg, "rot") == 0) + partiality_model = PartialityModel::Rotation; + else { + logger.Error("Invalid partiality mode: {}", optarg); + print_usage(logger); + exit(EXIT_FAILURE); + } + break; case OPT_SPOT_SIGMA: sigma_spot_finding = atof(optarg); logger.Info("Noise threshold level for spot finding set to {:.2f} sigma", sigma_spot_finding); @@ -323,7 +341,7 @@ int main(int argc, char **argv) { case OPT_NO_BEAM_CENTER_REFINE: refine_beam_center = false; break; - case OPT_SCALE_MERGE: + case 'M': run_scaling = true; break; case OPT_MIN_PARTIALITY: @@ -761,7 +779,7 @@ int main(int argc, char **argv) { } */ } - merged_statistics.Print(logger); + std::cout << merged_statistics; if (consensus_cell && !output_prefix.empty()) WriteReflections(merged_reflections, *consensus_cell, experiment, output_prefix); @@ -778,18 +796,18 @@ int main(int argc, char **argv) { double throughput_MBs = static_cast(total_uncompressed_bytes) / (processing_time * 1e6); double frame_rate = static_cast(images_to_process) / processing_time; - logger.Info(""); - logger.Info("Processing time: {:.2f} s", processing_time); - logger.Info("Frame rate: {:.2f} Hz", frame_rate); - logger.Info("Total throughput:{:.2f} MB/s", throughput_MBs); + + std::cout << fmt::format("Processing time: {:.2f} s", processing_time) << std::endl; + std::cout << fmt::format("Frame rate: {:.2f} Hz", frame_rate) << std::endl; + std::cout << fmt::format("Total throughput:{:.2f} MB/s", throughput_MBs) << std::endl; // Print extended stats similar to Receiver if (end_msg.indexing_rate.has_value()) { - logger.Info("Indexing rate: {:.2f}%", end_msg.indexing_rate.value() * 100.0); + std::cout << fmt::format("Indexing rate: {:.2f}%", end_msg.indexing_rate.value() * 100.0) << std::endl; } auto image_mean_time = plots.GetMeanProcessingTime(); - logger.Info( + std::cout << fmt::format( "Per-image time: (mean; milliseconds): decompress {:.2f} preprocess {:.2f} azint {:.2f} spot finding {:.2f} indexing {:.2f} refinement {:.2f} indexing analysis {:.2f} prediction {:.2f} integration {:.2f} scaling {:.2f} total {:.2f}", image_mean_time.compression * 1e3, image_mean_time.preprocessing * 1e3, @@ -801,5 +819,6 @@ int main(int argc, char **argv) { image_mean_time.bragg_prediction * 1e3, image_mean_time.integration * 1e3, image_mean_time.image_scale * 1e3, - image_mean_time.processing * 1e3); + image_mean_time.processing * 1e3) + << std::endl; } diff --git a/tools/jfjoch_scale.cpp b/tools/jfjoch_scale.cpp index d2b975e5..4a8c9a87 100644 --- a/tools/jfjoch_scale.cpp +++ b/tools/jfjoch_scale.cpp @@ -331,7 +331,7 @@ int main(int argc, char **argv) { } // Print resolution-shell statistics table - merge_stats.Print(logger); + std::cout << merge_stats; if (!output_prefix.empty()) WriteReflections(merge_result, *experiment.GetUnitCell(), experiment, output_prefix);