diff --git a/acquisition_device/AcquisitionDevice.cpp b/acquisition_device/AcquisitionDevice.cpp index 00fecac8..a422fb58 100644 --- a/acquisition_device/AcquisitionDevice.cpp +++ b/acquisition_device/AcquisitionDevice.cpp @@ -320,9 +320,14 @@ void AcquisitionDevice::RunInternalGenerator(const DiffractionExperiment &experi void AcquisitionDevice::SetSpotFinderParameters(const SpotFindingSettings &settings) { SpotFinderParameters fpga_parameters{}; + // The FPGA compares d against these as xray_d_t = ap_ufixed<16,9> (hls_jfjoch.h), which tops out just + // below 512 A and WRAPS above it - so "no low-resolution limit" is that ceiling, not infinity. Sending + // a larger number would wrap to a small d and mask the whole image. The high end needs no such care: + // no pixel has d < 0. + constexpr float FPGA_MAX_D_A = 511.0f; fpga_parameters.snr_threshold = settings.signal_to_noise_threshold; fpga_parameters.count_threshold = settings.photon_count_threshold; - fpga_parameters.max_d = settings.low_resolution_limit; + fpga_parameters.max_d = settings.low_resolution_limit.value_or(FPGA_MAX_D_A); fpga_parameters.min_d = settings.high_resolution_limit.value_or(0.0f); fpga_parameters.min_pix_per_spot = settings.min_pix_per_spot.value_or(2); HW_SetSpotFinderParameters(fpga_parameters); diff --git a/broker/OpenAPIConvert.cpp b/broker/OpenAPIConvert.cpp index 50a2bf06..7fe98181 100644 --- a/broker/OpenAPIConvert.cpp +++ b/broker/OpenAPIConvert.cpp @@ -16,9 +16,13 @@ SpotFindingSettings Convert(const org::openapitools::server::model::Spot_finding ret.photon_count_threshold = input.getPhotonCountThreshold(); ret.min_pix_per_spot = input.getMinPixPerSpot(); ret.max_pix_per_spot = input.getMaxPixPerSpot(); - if (input.highResolutionLimitIsSet()) + // Both limits are optional and unset means "no limit at that end". A value of 0 has meant the same + // thing since rc.161 and clients still send it that way, so fold it into the unset case here - the + // analysis code then has exactly one spelling for "no limit" and no zero to special-case. + if (input.highResolutionLimitIsSet() && input.getHighResolutionLimit() > 0) ret.high_resolution_limit = input.getHighResolutionLimit(); - ret.low_resolution_limit = input.getLowResolutionLimit(); + if (input.lowResolutionLimitIsSet() && input.getLowResolutionLimit() > 0) + ret.low_resolution_limit = input.getLowResolutionLimit(); ret.enable = input.isEnable(); ret.indexing = input.isIndexing(); ret.quick_integration = input.isQuickIntegration(); @@ -41,7 +45,8 @@ org::openapitools::server::model::Spot_finding_settings Convert(const SpotFindin ret.setMaxPixPerSpot(input.max_pix_per_spot); if (input.high_resolution_limit.has_value()) ret.setHighResolutionLimit(input.high_resolution_limit.value()); - ret.setLowResolutionLimit(input.low_resolution_limit); + if (input.low_resolution_limit.has_value()) + ret.setLowResolutionLimit(input.low_resolution_limit.value()); ret.setEnable(input.enable); ret.setIndexing(input.indexing); ret.setHighResolutionLimitForSpotCountLowRes(input.cutoff_spot_count_low_res); diff --git a/broker/gen/model/Spot_finding_settings.cpp b/broker/gen/model/Spot_finding_settings.cpp index d85be081..e96079f1 100644 --- a/broker/gen/model/Spot_finding_settings.cpp +++ b/broker/gen/model/Spot_finding_settings.cpp @@ -30,6 +30,7 @@ Spot_finding_settings::Spot_finding_settings() m_High_resolution_limit = 0.0f; m_High_resolution_limitIsSet = false; m_Low_resolution_limit = 0.0f; + m_Low_resolution_limitIsSet = false; m_High_resolution_limit_for_spot_count_low_res = 0.0f; m_Quick_integration = false; m_Ice_ring_width_q_recipA = 0.03f; @@ -223,8 +224,8 @@ bool Spot_finding_settings::operator==(const Spot_finding_settings& rhs) const ((!highResolutionLimitIsSet() && !rhs.highResolutionLimitIsSet()) || (highResolutionLimitIsSet() && rhs.highResolutionLimitIsSet() && getHighResolutionLimit() == rhs.getHighResolutionLimit())) && - (getLowResolutionLimit() == rhs.getLowResolutionLimit()) - && + + ((!lowResolutionLimitIsSet() && !rhs.lowResolutionLimitIsSet()) || (lowResolutionLimitIsSet() && rhs.lowResolutionLimitIsSet() && getLowResolutionLimit() == rhs.getLowResolutionLimit())) && (getHighResolutionLimitForSpotCountLowRes() == rhs.getHighResolutionLimitForSpotCountLowRes()) && @@ -263,7 +264,8 @@ void to_json(nlohmann::json& j, const Spot_finding_settings& o) j["max_pix_per_spot"] = o.m_Max_pix_per_spot; if(o.highResolutionLimitIsSet()) j["high_resolution_limit"] = o.m_High_resolution_limit; - j["low_resolution_limit"] = o.m_Low_resolution_limit; + if(o.lowResolutionLimitIsSet()) + j["low_resolution_limit"] = o.m_Low_resolution_limit; j["high_resolution_limit_for_spot_count_low_res"] = o.m_High_resolution_limit_for_spot_count_low_res; j["quick_integration"] = o.m_Quick_integration; j["ice_ring_width_q_recipA"] = o.m_Ice_ring_width_q_recipA; @@ -289,7 +291,11 @@ void from_json(const nlohmann::json& j, Spot_finding_settings& o) j.at("high_resolution_limit").get_to(o.m_High_resolution_limit); o.m_High_resolution_limitIsSet = true; } - j.at("low_resolution_limit").get_to(o.m_Low_resolution_limit); + if(j.find("low_resolution_limit") != j.end()) + { + j.at("low_resolution_limit").get_to(o.m_Low_resolution_limit); + o.m_Low_resolution_limitIsSet = true; + } j.at("high_resolution_limit_for_spot_count_low_res").get_to(o.m_High_resolution_limit_for_spot_count_low_res); j.at("quick_integration").get_to(o.m_Quick_integration); j.at("ice_ring_width_q_recipA").get_to(o.m_Ice_ring_width_q_recipA); @@ -383,6 +389,15 @@ float Spot_finding_settings::getLowResolutionLimit() const void Spot_finding_settings::setLowResolutionLimit(float const value) { m_Low_resolution_limit = value; + m_Low_resolution_limitIsSet = true; +} +bool Spot_finding_settings::lowResolutionLimitIsSet() const +{ + return m_Low_resolution_limitIsSet; +} +void Spot_finding_settings::unsetLow_resolution_limit() +{ + m_Low_resolution_limitIsSet = false; } float Spot_finding_settings::getHighResolutionLimitForSpotCountLowRes() const { diff --git a/broker/gen/model/Spot_finding_settings.h b/broker/gen/model/Spot_finding_settings.h index 63838b1b..873d2d09 100644 --- a/broker/gen/model/Spot_finding_settings.h +++ b/broker/gen/model/Spot_finding_settings.h @@ -95,10 +95,12 @@ public: bool highResolutionLimitIsSet() const; void unsetHigh_resolution_limit(); /// - /// Low resolution limit for spot finding [Angstrom] + /// Low resolution limit for spot finding [Angstrom]. Optional: if omitted, spot finding is not clipped at the low-resolution end. A value of 0 is accepted and means the same thing. /// float getLowResolutionLimit() const; void setLowResolutionLimit(float const value); + bool lowResolutionLimitIsSet() const; + void unsetLow_resolution_limit(); /// /// High resolution threshold to consider spot \"low resolution\" [Angstrom] /// @@ -154,7 +156,7 @@ protected: float m_High_resolution_limit; bool m_High_resolution_limitIsSet; float m_Low_resolution_limit; - + bool m_Low_resolution_limitIsSet; float m_High_resolution_limit_for_spot_count_low_res; bool m_Quick_integration; diff --git a/broker/jfjoch_api.yaml b/broker/jfjoch_api.yaml index eb75e3ea..236eee22 100644 --- a/broker/jfjoch_api.yaml +++ b/broker/jfjoch_api.yaml @@ -1038,7 +1038,6 @@ components: - photon_count_threshold - max_pix_per_spot - min_pix_per_spot - - low_resolution_limit - quick_integration - high_resolution_limit_for_spot_count_low_res - ice_ring_width_q_recipA @@ -1079,7 +1078,9 @@ components: low_resolution_limit: type: number format: float - description: Low resolution limit for spot finding [Angstrom] + description: | + Low resolution limit for spot finding [Angstrom]. Optional: if omitted, spot finding is not + clipped at the low-resolution end. A value of 0 is accepted and means the same thing. high_resolution_limit_for_spot_count_low_res: type: number format: float diff --git a/broker/redoc-static.html b/broker/redoc-static.html index 7d084587..f40ccb83 100644 --- a/broker/redoc-static.html +++ b/broker/redoc-static.html @@ -710,7 +710,8 @@ Even if disabled spot finding information will still be send and written, though indexing
required
boolean
Default: true

Enable indexing. This is temporary setting, i.e. can be changed anytime during data collection.

signal_to_noise_threshold
required
number <float> >= 0
photon_count_threshold
required
integer <int64> >= 0
min_pix_per_spot
required
integer <int64> >= 1
max_pix_per_spot
required
integer <int64> >= 1
high_resolution_limit
number <float>

High resolution limit for spot finding [Angstrom]. Optional: if omitted, spot finding extends as far as the detector reaches, i.e. the detection is not clipped in resolution.

-
low_resolution_limit
required
number <float>

Low resolution limit for spot finding [Angstrom]

+
low_resolution_limit
number <float>

Low resolution limit for spot finding [Angstrom]. Optional: if omitted, spot finding is not +clipped at the low-resolution end. A value of 0 is accepted and means the same thing.

high_resolution_limit_for_spot_count_low_res
required
number <float> [ 2 .. 8 ]

High resolution threshold to consider spot "low resolution" [Angstrom]

quick_integration
required
boolean
Default: false

Quick integration of Bragg spots in diffraction images. If enabled it will likely reduce performance of Jungfraujoch for datasets with a very high indexing rate. @@ -976,7 +977,7 @@ then image might be replaced in the buffer between calling /images and /image.cb