CorrelationCoefficient: Separate class

This commit is contained in:
2026-05-18 20:23:13 +02:00
parent 371a69c5b8
commit c90e4facce
7 changed files with 81 additions and 40 deletions
+2
View File
@@ -130,6 +130,8 @@ ADD_LIBRARY(JFJochCommon STATIC
ScalingSettings.h
UnitCell.cpp
UnitCell.h
CorrelationCoefficient.cpp
CorrelationCoefficient.h
)
TARGET_LINK_LIBRARIES(JFJochCommon JFJochLogger Compression JFCalibration gemmi Threads::Threads -lrt )
+33
View File
@@ -0,0 +1,33 @@
//
// Created by leonarski_f on 18.05.2026.
//
#include <cmath>
#include "CorrelationCoefficient.h"
void CorrelationCoefficient::Add(double x, double y) {
sum_x += x;
sum_y += y;
sum_x2 += x * x;
sum_y2 += y * y;
sum_xy += x * y;
n_cc++;
}
double CorrelationCoefficient::GetCC() const {
if (n_cc < 2)
return NAN;
const double n = static_cast<double>(n_cc);
const double mean_x = sum_x / n;
const double mean_y = sum_y / n;
const double cov = sum_xy / n - mean_x * mean_y;
const double var_x = sum_x2 / n - mean_x * mean_x;
const double var_y = sum_y2 / n - mean_y * mean_y;
if (!(var_x > 0.0 && var_y > 0.0))
return NAN;
return cov / std::sqrt(var_x * var_y);
}
+17
View File
@@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
class CorrelationCoefficient {
double sum_x = 0.0;
double sum_y = 0.0;
double sum_x2 = 0.0;
double sum_y2 = 0.0;
double sum_xy = 0.0;
int n_cc = 0;
public:
void Add(double x, double y);
[[nodiscard]] double GetCC() const;
};
+6 -39
View File
@@ -11,6 +11,7 @@
#include <gemmi/reciproc.hpp>
#include "../../common/CorrelationCoefficient.h"
#include "../../common/ResolutionShells.h"
#include "HKLKey.h"
@@ -170,39 +171,6 @@ std::vector<MergedReflection> MergeAll(const DiffractionExperiment &x,
return out;
}
struct CCAccum {
double sum_x = 0.0;
double sum_y = 0.0;
double sum_x2 = 0.0;
double sum_y2 = 0.0;
double sum_xy = 0.0;
int n_cc = 0;
void Add(double x, double y) {
sum_x += x;
sum_y += y;
sum_x2 += x * x;
sum_y2 += y * y;
sum_xy += x * y;
n_cc++;
}
double GetCC() const {
if (n_cc < 2)
return NAN;
const double n = static_cast<double>(n_cc);
const double mean_x = sum_x / n;
const double mean_y = sum_y / n;
const double cov = sum_xy / n - mean_x * mean_y;
const double var_x = sum_x2 / n - mean_x * mean_x;
const double var_y = sum_y2 / n - mean_y * mean_y;
if (!(var_x > 0.0 && var_y > 0.0))
return NAN;
return cov / std::sqrt(var_x * var_y);
}
};
struct ShellAccum {
int total_obs = 0;
@@ -212,8 +180,8 @@ struct ShellAccum {
double sum_i_over_sigma = 0.0;
int n_i_over_sigma = 0;
CCAccum cc_half;
CCAccum cc_ref;
CorrelationCoefficient cc_half;
CorrelationCoefficient cc_ref;
};
void CalcPossibleReflections(const DiffractionExperiment &x,
@@ -303,8 +271,8 @@ MergeStatistics MergeStats(const DiffractionExperiment &x,
CalcPossibleReflections(x, cell, d_min_pad, d_max_pad, shells, acc);
CCAccum cc_half_overall;
CCAccum cc_ref_overall;
CorrelationCoefficient cc_half_overall;
CorrelationCoefficient cc_ref_overall;
for (const auto &m: merged) {
const auto shell = shells.GetShell(m.d);
@@ -326,6 +294,7 @@ MergeStatistics MergeStats(const DiffractionExperiment &x,
cc_ref_overall.Add(m.I, ref_it->second);
}
}
if (std::isfinite(m.I_half[0]) && std::isfinite(m.I_half[1])) {
acc[s].cc_half.Add(m.I_half[0], m.I_half[1]);
cc_half_overall.Add(m.I_half[0], m.I_half[1]);
@@ -342,10 +311,8 @@ MergeStatistics MergeStats(const DiffractionExperiment &x,
for (const auto &r: reflections[i]) {
if (key_generator.IsSystematicallyAbsent(r))
continue;
if (r.image_scale_corr <= 0.0 || !std::isfinite(r.image_scale_corr))
continue;
if (!AcceptReflection(r, d_min_limit_A))
continue;
if (r.partiality < min_partiality)
-1
View File
@@ -10,7 +10,6 @@
#include "../../common/Reflection.h"
struct MergeStatisticsShell {
float d_min = 0.0f;
float d_max = 0.0f;
float mean_one_over_d2 = 0;
+22
View File
@@ -0,0 +1,22 @@
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include <catch2/catch_all.hpp>
#include "../common/CorrelationCoefficient.h"
TEST_CASE("CorrelationCoefficient") {
CorrelationCoefficient cc;
CHECK(std::isnan(cc.GetCC()));
cc.Add(100.0, 500.0);
CHECK(std::isnan(cc.GetCC()));
cc.Add(200.0, 1000.0);
CHECK(cc.GetCC() == Catch::Approx(1.0));
cc.Add(300.0, 1500.0);
CHECK(cc.GetCC() == Catch::Approx(1.0));
cc.Add(400.0, 2000.0);
CHECK(cc.GetCC() == Catch::Approx(1.0));
}
+1
View File
@@ -69,6 +69,7 @@ ADD_EXECUTABLE(jfjoch_test
XDSPluginTest.cpp
MergeScaleTest.cpp
UnitCellTest.cpp
CCTest.cpp
)
target_link_libraries(jfjoch_test Catch2WithMain JFJochBroker JFJochReceiver JFJochReader JFJochWriter