Integration radius: default r1=4, CLI flag, PixelRefine shares the knob

Bumped the default signal-box radius to r1=4 (r2=6, r3=8): on the lysozyme jet
(1% DMM) it lifts CCref 50.1->52.2% and CC1/2 90.8->92.5% (its broadened spots
spill past a radius-3 box), is neutral on the mono crystal and on the classical
integrator. Added 'jfjoch_process --integration-radius <r1|r1,r2,r3>' (a single
value derives r2=r1+2, r3=r1+4) and wired PixelRefine's shoebox radius to
BraggIntegrationSettings::GetR1() so it shares the classical integrator's knob.

(Explored but rejected: an elliptical/anisotropic Term-2 profile. The jet's
tangential spots are mildly anisotropic - axis ratio 1.15->1.44 low->high res,
azimuthal mosaic, separate from the radial DMM bandwidth - but using the measured
2x2 covariance as the profile DEGRADED the jet, CC1/2 92.5->83.5: the tight
measured width loses to a generous aperture, same lesson as the radius bump.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 23:27:36 +02:00
co-authored by Claude Opus 4.8
parent 100fe7b7e7
commit bf6efc7fe9
3 changed files with 33 additions and 3 deletions
+28 -1
View File
@@ -80,6 +80,7 @@ void print_usage() {
std::cout << " Pixel refinement (experimental, select via -r pixelrefine, needs --reference-mtz)" << std::endl;
std::cout << " --bandwidth <num> Relative X-ray bandwidth FWHM (e.g. 0.01 for 1% DMM); default from file or 0" << std::endl;
std::cout << " --integration-radius <r> Signal-box radius r1, or r1,r2,r3 (px). One value => r2=r1+2, r3=r1+4" << std::endl;
}
enum {
@@ -95,7 +96,8 @@ enum {
OPT_SINGLE_PASS_ROTATION,
OPT_REDO_ROTATION_SPOTS,
OPT_FORCE_ROTATION_LATTICE,
OPT_BANDWIDTH
OPT_BANDWIDTH,
OPT_INTEGRATION_RADIUS
};
static option long_options[] = {
@@ -132,6 +134,7 @@ static option long_options[] = {
{"scaling-high-resolution", required_argument, nullptr, OPT_SCALING_HIGH_RESOLUTION},
{"scaling-output", required_argument, nullptr, OPT_SCALING_OUTPUT},
{"bandwidth", required_argument, nullptr, OPT_BANDWIDTH},
{"integration-radius", required_argument, nullptr, OPT_INTEGRATION_RADIUS},
{nullptr, 0, nullptr, 0}
};
@@ -312,6 +315,7 @@ int main(int argc, char **argv) {
float d_min_spot_finding = 1.5;
std::optional<float> d_min_scale_merge;
std::optional<std::string> integration_radius_arg; // "r1" or "r1,r2,r3"
if (argc == 1) {
print_usage();
@@ -501,6 +505,9 @@ int main(int argc, char **argv) {
case OPT_MIN_PARTIALITY:
min_partiality = std::stod(optarg);
break;
case OPT_INTEGRATION_RADIUS:
integration_radius_arg = optarg;
break;
case OPT_MIN_IMAGE_CC:
min_image_cc = std::stod(optarg);
break;
@@ -671,6 +678,26 @@ int main(int argc, char **argv) {
experiment.ImportScalingSettings(scaling_settings);
// Integration radii: r1 (signal box), r2/r3 (background annulus). PixelRefine reads
// r1 as its shoebox radius; the classical integrator uses all three.
if (integration_radius_arg) {
std::vector<float> rr;
std::stringstream ss(*integration_radius_arg);
std::string tok;
while (std::getline(ss, tok, ',')) {
trim_in_place(tok);
if (!tok.empty()) rr.push_back(std::stof(tok));
}
float r1, r2, r3;
if (rr.size() == 1) { r1 = rr[0]; r2 = r1 + 2.0f; r3 = r1 + 4.0f; }
else if (rr.size() == 3) { r1 = rr[0]; r2 = rr[1]; r3 = rr[2]; }
else { logger.Error("--integration-radius expects r1 or r1,r2,r3"); return 1; }
BraggIntegrationSettings bis = experiment.GetBraggIntegrationSettings();
bis.R1(r1).R2(r2).R3(r3);
experiment.ImportBraggIntegrationSettings(bis);
logger.Info("Integration radii set to r1={:.1f} r2={:.1f} r3={:.1f}", r1, r2, r3);
}
SpotFindingSettings spot_settings;
spot_settings.enable = true;
spot_settings.indexing = true;