A pure move. ModelValidation, RigidBodyRefine, RigidBodyGPU, ModelFFT, ModelGrid, ModelScaling, ModelMaskGPU, ModelScaleGPU and SigmaA - everything that works on an atomic model - become the JFJochStructureRefinement library, linked by JFJochImageAnalysis. WriteModel (the placed-model mmCIF/PDB writer) goes to writer/ as its own small JFJochModelWriter target, so JFJochWriter, which a writer-only build compiles, does not gain a gemmi dependency. Only include paths and CMake lists change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SVmAWnzCmRKAXVUCdc4iNi
39 lines
1.9 KiB
C
39 lines
1.9 KiB
C
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#pragma once
|
|
|
|
#include <cstddef>
|
|
|
|
#include "gemmi/scaling.hpp"
|
|
|
|
// Fit the overall scale, the anisotropic B and the flat bulk solvent of a model to observed
|
|
// amplitudes, writing the answer into `scaling` (k_overall, b_star, k_sol, b_sol) so that
|
|
// gemmi's own scale_data() can then apply it.
|
|
//
|
|
// The caller decides which reflections are fitted: FitModelScale reads scaling.points, which
|
|
// prepare_points() filled. Pass the WORKING set to keep the free reflections out of the scale
|
|
// model - that is a property of the call site, not of this function.
|
|
//
|
|
// Replaces gemmi's fit_isotropic_b_approximately() + fit_parameters(), which is an unbounded
|
|
// Levenberg-Marquardt: nothing there stops k_sol and b_sol reaching values a flat solvent model
|
|
// is meaningless at (b_sol of 1707 A^2 was measured on this corpus). Here k_sol and b_sol come
|
|
// from a grid search over the physical ranges, so an unphysical answer cannot be represented.
|
|
// The box the solvent parameters are searched in. The defaults are the physically reasonable
|
|
// range reported by Fokine & Urzhumtsev and adopted as phenix's default grid: k_sol in (0.1, 0.8)
|
|
// and b_sol in (10, 80) A^2, of which phenix searches b_sol 10-80 in steps of 5.
|
|
struct ModelScaleBox {
|
|
double k_lo = 0.10, k_hi = 0.60;
|
|
double b_lo = 10.0, b_hi = 80.0;
|
|
};
|
|
|
|
struct ModelScaleReport {
|
|
int n_points = 0; // reflections the fit actually used
|
|
int n_grid = 0; // grid points evaluated
|
|
double r_work_fit = 1.0; // R on the fitted reflections, at the chosen solution
|
|
};
|
|
|
|
// nthreads: the grid points are fitted in parallel on up to this many threads; the answer does not
|
|
// depend on it.
|
|
ModelScaleReport FitModelScale(gemmi::Scaling<float> &scaling, ModelScaleBox box = {}, size_t nthreads = 1);
|