jfjoch_process: Print statistics moved to Merge.h/Merge.cpp and ScalingResult.cpp/ScalingResult.h
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 14m10s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 14m51s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 15m28s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 15m49s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m8s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 16m40s
Build Packages / build:rpm (rocky8) (push) Successful in 11m55s
Build Packages / XDS test (durin plugin) (push) Successful in 10m54s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 12m7s
Build Packages / build:rpm (rocky9) (push) Successful in 13m36s
Build Packages / Generate python client (push) Successful in 26s
Build Packages / Create release (push) Skipped
Build Packages / build:rpm (ubuntu2204) (push) Successful in 13m31s
Build Packages / Build documentation (push) Successful in 1m7s
Build Packages / DIALS test (push) Successful in 14m53s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m6s
Build Packages / XDS test (neggia plugin) (push) Successful in 6m9s
Build Packages / Unit tests (push) Successful in 58m34s

This commit is contained in:
2026-05-11 10:37:39 +02:00
parent 486310fd87
commit b53f0d6474
9 changed files with 89 additions and 70 deletions
+4
View File
@@ -77,6 +77,10 @@ double ScalingSettings::GetMaxWedge() const {
return 10.0;
}
double ScalingSettings::GetDefaultMosaicity() const {
return 0.1;
}
ScalingSettings &ScalingSettings::RotationWedgeForScaling(std::optional<double> input) {
if (input) {
// TODO: Use fmt
+2 -1
View File
@@ -6,7 +6,7 @@
#include <optional>
#include "JFJochException.h"
enum class PartialityModel { Fixed, Rotation, Unity, Still };
enum class PartialityModel { Fixed, Rotation, Unity };
class ScalingSettings {
std::optional<PartialityModel> partiality_mode;
@@ -35,6 +35,7 @@ public:
[[nodiscard]] double GetMaxB() const;
[[nodiscard]] double GetMinMosaicity() const;
[[nodiscard]] double GetDefaultMosaicity() const;
[[nodiscard]] double GetMaxMosaicity() const;
[[nodiscard]] double GetMinWedge() const;
+2 -1
View File
@@ -7,5 +7,6 @@ ADD_LIBRARY(JFJochScaleMerge FrenchWilson.cpp FrenchWilson.h
ScaleOnTheFly.h
HKLKey.cpp
HKLKey.h
ScalingResult.h)
ScalingResult.h
ScalingResult.cpp)
TARGET_LINK_LIBRARIES(JFJochScaleMerge Ceres::ceres Eigen3::Eigen JFJochCommon)
+21
View File
@@ -293,3 +293,24 @@ MergeResult MergeReflections(const std::vector<std::vector<Reflection> > &observ
return out;
}
void MergeStatistics::Print(Logger &logger) const {
logger.Info("");
logger.Info(" {:>8s} {:>8s} {:>8s} {:>8s}", "d_min", "N_obs", "N_uniq", "<I/sig>");
logger.Info(" {:->8s} {:->8s} {:->8s} {:->8s}", "", "", "", "", "", "");
for (const auto &sh: shells) {
if (sh.unique_reflections == 0)
continue;
logger.Info(" {:8.2f} {:8d} {:8d} {:8.1f}",
sh.d_min, sh.total_observations, sh.unique_reflections,
sh.mean_i_over_sigma);
}
{
const auto &ov = overall;
logger.Info(" {:->8s} {:->8s} {:->8s} {:->8s}", "", "", "", "");
logger.Info(" {:>8s} {:8d} {:8d} {:8.1f}",
"Overall", ov.total_observations, ov.unique_reflections,
ov.mean_i_over_sigma);
}
logger.Info("");
}
+2
View File
@@ -7,6 +7,7 @@
#include <optional>
#include <vector>
#include "../../common/Logger.h"
#include "../../common/DiffractionExperiment.h"
#include "../../common/Reflection.h"
#include "gemmi/symmetry.hpp"
@@ -26,6 +27,7 @@ struct MergeStatisticsShell {
struct MergeStatistics {
std::vector<MergeStatisticsShell> shells;
MergeStatisticsShell overall;
void Print(Logger &logger) const;
};
struct MergeResult {
+10 -5
View File
@@ -96,8 +96,6 @@ bool ScaleOnTheFly::Accept(const Reflection &r) {
switch (model) {
case PartialityModel::Rotation:
return std::isfinite(r.zeta) && r.zeta > 0.0f;
case PartialityModel::Still:
return std::isfinite(r.dist_ewald);
case PartialityModel::Fixed:
case PartialityModel::Unity:
return true;
@@ -113,11 +111,17 @@ ScaleOnTheFlyResult ScaleOnTheFly::Scale(std::vector<Reflection> &reflections, s
ScaleOnTheFlyResult result{
.B = 0.0,
.G = 1.0,
.mos = mosaicity_deg.value_or(0.0),
.wedge = rot_wedge_deg.value_or(0.0)
.G = 1.0
};
if (model == PartialityModel::Rotation) {
result.mos = mosaicity_deg.value_or(s.GetDefaultMosaicity());
result.wedge = rot_wedge_deg.value_or(0.0);
} else {
result.mos = NAN;
result.wedge = NAN;
}
size_t n_reflections = 0;
HKLKeyGenerator key_generator(s.GetMergeFriedel(), sg);
for (const auto &r: reflections) {
@@ -207,6 +211,7 @@ ScaleOnTheFlyResult ScaleOnTheFly::Scale(std::vector<Reflection> &reflections, s
break;
}
default:
// For fixed partiality there is no need to change anything
break;
}
r.scaling_correction = static_cast<float>(r.rlp / (B_term * r.partiality * result.G));
@@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "ScalingResult.h"
#include <cmath>
#include <fstream>
#include "../../common/JFJochException.h"
ScalingResult::ScalingResult(size_t n)
: image_scale_g(n, NAN),
mosaicity_deg(n, NAN),
image_bfactor_Ang2(n, NAN),
rotation_wedge_deg(n, NAN) {
}
void ScalingResult::SaveToFile(const std::string &filename) {
const std::string img_path = filename + "_image.dat";
std::ofstream img_file(img_path);
if (!img_file) {
throw JFJochException(JFJochExceptionCategory::FileWriteError
, "Cannot open {} for writing");
}
img_file << "# image_id G B mosaicity_deg wedge_deg\n";
for (size_t i = 0; i < image_scale_g.size(); ++i) {
img_file << i
<< " " << image_scale_g[i]
<< " " << image_bfactor_Ang2[i]
<< " " << mosaicity_deg[i]
<< " " << rotation_wedge_deg[i]
<< "\n";
}
img_file.close();
}
+3 -6
View File
@@ -4,6 +4,7 @@
#pragma once
#include <vector>
#include <string>
struct ScalingResult {
std::vector<float> image_scale_g;
@@ -11,10 +12,6 @@ struct ScalingResult {
std::vector<float> image_bfactor_Ang2;
std::vector<float> rotation_wedge_deg;
explicit ScalingResult(size_t n)
: image_scale_g(n, NAN),
mosaicity_deg(n, NAN),
image_bfactor_Ang2(n, NAN),
rotation_wedge_deg(n, NAN) {
}
explicit ScalingResult(size_t n);
void SaveToFile(const std::string &filename);
};
+7 -57
View File
@@ -581,7 +581,7 @@ int main(int argc, char **argv) {
auto merge_result = indexer.Merge();
auto scale_end = std::chrono::steady_clock::now();
double scale_time = std::chrono::duration<double>(scale_end - scale_start).count();
/*
if (!fixed_space_group) {
logger.Info("Searching for space group from P1-merged reflections ...");
@@ -608,7 +608,7 @@ int main(int argc, char **argv) {
}
}
logger.Info("");
/*
if (sg_search.best_space_group.has_value()) {
logger.Info("Re-running scaling in detected space group {}", sg_search.best_space_group->short_name());
@@ -626,8 +626,8 @@ int main(int argc, char **argv) {
}
} else {
logger.Warning("No space group accepted; keeping P1-merged result");
}
} */
} */
}
end_msg.image_scale_factor = scale_result.image_scale_g;
@@ -635,59 +635,9 @@ int main(int argc, char **argv) {
scale_time, merge_result.merged.size());
// Print resolution-shell statistics table
{
const auto &stats = merge_result.statistics;
logger.Info("");
logger.Info(" {:>8s} {:>8s} {:>8s} {:>8s}",
"d_min", "N_obs", "N_uniq", "<I/sig>");
logger.Info(" {:->8s} {:->8s} {:->8s} {:->8s}",
"", "", "", "", "", "");
for (const auto &sh: stats.shells) {
if (sh.unique_reflections == 0)
continue;
logger.Info(" {:8.2f} {:8d} {:8d} {:8.1f}",
sh.d_min, sh.total_observations, sh.unique_reflections,
sh.mean_i_over_sigma);
}
{
const auto &ov = stats.overall;
logger.Info(" {:->8s} {:->8s} {:->8s} {:->8s}",
"", "", "", "");
logger.Info(" {:>8s} {:8d} {:8d} {:8.1f}",
"Overall", ov.total_observations, ov.unique_reflections,
ov.mean_i_over_sigma);
}
logger.Info("");
}
{
const std::string img_path = output_prefix + "_image.dat";
std::ofstream img_file(img_path);
if (!img_file) {
logger.Error("Cannot open {} for writing", img_path);
} else {
if (experiment.GetPartialityModel() == PartialityModel::Rotation) {
img_file << "# image_id G B mosaicity_deg wedge_deg\n";
for (size_t i = 0; i < scale_result.image_scale_g.size(); ++i) {
img_file << i
<< " " << scale_result.image_scale_g[i]
<< " " << scale_result.image_bfactor_Ang2[i]
<< " " << scale_result.mosaicity_deg[i]
<< " " << scale_result.rotation_wedge_deg[i]
<< "\n";
}
} else {
img_file << "# image_id G B\n";
for (size_t i = 0; i < scale_result.image_scale_g.size(); ++i) {
img_file << i
<< " " << scale_result.image_scale_g[i]
<< " " << scale_result.image_bfactor_Ang2[i]
<< "\n";
}
}
img_file.close();
}
}
const auto &stats = merge_result.statistics;
stats.Print(logger);
scale_result.SaveToFile(output_prefix + "_scale.dat");
{
FrenchWilsonOptions fw_opts;