diff --git a/common/BraggIntegrationSettings.cpp b/common/BraggIntegrationSettings.cpp index 3fe0a861..6ea3381e 100644 --- a/common/BraggIntegrationSettings.cpp +++ b/common/BraggIntegrationSettings.cpp @@ -72,6 +72,17 @@ float BraggIntegrationSettings::GetR1() const { return r_1; } +float BraggIntegrationSettings::GetProfileMultiplier() const { + return profile_multiplier; +} + +BraggIntegrationSettings &BraggIntegrationSettings::ProfileMultiplier(float input) { + if (input <= 0.0f) + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Profile multiplier must be positive"); + profile_multiplier = input; + return *this; +} + float BraggIntegrationSettings::GetR2() const { return r_2; } diff --git a/common/BraggIntegrationSettings.h b/common/BraggIntegrationSettings.h index dbe75ae6..02f30782 100644 --- a/common/BraggIntegrationSettings.h +++ b/common/BraggIntegrationSettings.h @@ -12,6 +12,10 @@ class BraggIntegrationSettings { float d_min_limit_A = 1.0; std::optional fixed_profile_radius; float minimum_sigma_in_regards_to_i = 0.02; + // PixelRefine only: the measured (physical) tangential profile width is multiplied by + // this for the integration template, so the aperture is generous (XDS-style ~6 sigma) + // and tolerant of the centroid-floor scatter. Ignored by the classical integrator. + float profile_multiplier = 6.0; public: BraggIntegrationSettings& R1(float input); @@ -19,11 +23,13 @@ public: BraggIntegrationSettings& R3(float input); BraggIntegrationSettings& DMinLimit_A(float input); BraggIntegrationSettings& FixedProfileRadius_recipA(std::optional input); + BraggIntegrationSettings& ProfileMultiplier(float input); [[nodiscard]] float GetR1() const; [[nodiscard]] float GetR2() const; [[nodiscard]] float GetR3() const; + [[nodiscard]] float GetProfileMultiplier() const; [[nodiscard]] std::optional GetFixedProfileRadius_recipA() const; [[nodiscard]] float GetDMinLimit_A() const; diff --git a/common/ScalingSettings.h b/common/ScalingSettings.h index 6d548cfc..09d591c1 100644 --- a/common/ScalingSettings.h +++ b/common/ScalingSettings.h @@ -23,7 +23,7 @@ class ScalingSettings { std::optional wedge_for_scaling; double min_partiality = 0.02; double min_cc_for_image = 0.0; - double outlier_reject_nsigma = 6.0; // per-observation merge outlier rejection (XDS/DIALS-style); <= 0 disables + double outlier_reject_nsigma = 0.0; // per-observation merge outlier rejection (XDS/DIALS-style); 0 = off, e.g. 6 enables double rfree_fraction = 0.05; IntensityFormat intensity_format = IntensityFormat::MTZ; diff --git a/image_analysis/IndexAndRefine.cpp b/image_analysis/IndexAndRefine.cpp index c4c0e831..4800e8bb 100644 --- a/image_analysis/IndexAndRefine.cpp +++ b/image_analysis/IndexAndRefine.cpp @@ -448,7 +448,7 @@ bool IndexAndRefine::PixelRefineIntegrate(DataMessage &msg, // Signal-box radius from the shared integration setting (same knob as BraggIntegrate2D). prd.shoebox_radius = static_cast(std::lround(experiment.GetBraggIntegrationSettings().GetR1())); - if (const char *m = std::getenv("PR_RMULT")) prd.r1_multiplier = std::stod(m); // Term-2 R1 multiplier (default 6) + prd.r1_multiplier = experiment.GetBraggIntegrationSettings().GetProfileMultiplier(); std::vector buffer; const uint8_t *ptr = image.GetUncompressedPtr(buffer); diff --git a/tools/jfjoch_process.cpp b/tools/jfjoch_process.cpp index 93ade850..7748ccdd 100644 --- a/tools/jfjoch_process.cpp +++ b/tools/jfjoch_process.cpp @@ -72,7 +72,7 @@ void print_usage() { std::cout << " -w, --wedge[=num] Refine image wedge during scaling with starting wedge value" << std::endl; std::cout << " --scaling-high-resolution High resolution limit for spot finding (default: no limit)" << std::endl; std::cout << " --min-partiality Minimum partiality to accept reflection (default: 0.02)" << std::endl; - std::cout << " --reject-outliers Per-observation merge outlier rejection, N sigma from the per-reflection median (default: 6; 0 disables)" << std::endl; + std::cout << " --reject-outliers Per-observation merge outlier rejection, N sigma from the per-reflection median (default: off; e.g. 6, XDS/DIALS-style)" << std::endl; std::cout << " --min-image-cc Per-image CC limit in percent (default: no limit)" << std::endl; std::cout << " --scaling-iterations Number of scaling iterations with no reference data (default: 3)" << std::endl; std::cout << " --scaling-output Output format for scaling results mtz|cif|txt (default: mtz)" << std::endl; @@ -82,6 +82,7 @@ void print_usage() { std::cout << " Pixel refinement (experimental, select via -r pixelrefine, needs --reference-mtz)" << std::endl; std::cout << " --bandwidth Relative X-ray bandwidth FWHM (e.g. 0.01 for 1% DMM); default from file or 0" << std::endl; std::cout << " --integration-radius Signal-box radius r1, or r1,r2,r3 (px). One value => r2=r1+2, r3=r1+4" << std::endl; + std::cout << " --profile-multiplier PixelRefine: scale the measured tangential profile width R1 (default: 6; XDS-style generous aperture)" << std::endl; } enum { @@ -99,7 +100,8 @@ enum { OPT_FORCE_ROTATION_LATTICE, OPT_BANDWIDTH, OPT_INTEGRATION_RADIUS, - OPT_REJECT_OUTLIERS + OPT_REJECT_OUTLIERS, + OPT_PROFILE_MULTIPLIER }; static option long_options[] = { @@ -138,6 +140,7 @@ static option long_options[] = { {"bandwidth", required_argument, nullptr, OPT_BANDWIDTH}, {"integration-radius", required_argument, nullptr, OPT_INTEGRATION_RADIUS}, {"reject-outliers", required_argument, nullptr, OPT_REJECT_OUTLIERS}, + {"profile-multiplier", required_argument, nullptr, OPT_PROFILE_MULTIPLIER}, {nullptr, 0, nullptr, 0} }; @@ -320,6 +323,7 @@ int main(int argc, char **argv) { std::optional d_min_scale_merge; std::optional integration_radius_arg; // "r1" or "r1,r2,r3" std::optional outlier_reject_nsigma; // merge per-observation outlier rejection + std::optional profile_multiplier; // PixelRefine Term-2 profile-width multiplier if (argc == 1) { print_usage(); @@ -515,6 +519,9 @@ int main(int argc, char **argv) { case OPT_REJECT_OUTLIERS: outlier_reject_nsigma = std::stod(optarg); break; + case OPT_PROFILE_MULTIPLIER: + profile_multiplier = std::stof(optarg); + break; case OPT_MIN_IMAGE_CC: min_image_cc = std::stod(optarg); break; @@ -707,6 +714,13 @@ int main(int argc, char **argv) { logger.Info("Integration radii set to r1={:.1f} r2={:.1f} r3={:.1f}", r1, r2, r3); } + if (profile_multiplier) { + BraggIntegrationSettings bis = experiment.GetBraggIntegrationSettings(); + bis.ProfileMultiplier(*profile_multiplier); + experiment.ImportBraggIntegrationSettings(bis); + logger.Info("PixelRefine profile-width multiplier set to {:.1f}", *profile_multiplier); + } + SpotFindingSettings spot_settings; spot_settings.enable = true; spot_settings.indexing = true;