diff --git a/broker/OpenAPIConvert.cpp b/broker/OpenAPIConvert.cpp index 3d6378e0..f41a145d 100644 --- a/broker/OpenAPIConvert.cpp +++ b/broker/OpenAPIConvert.cpp @@ -1073,6 +1073,11 @@ BraggIntegrationSettings Convert(const org::openapitools::server::model::Bragg_i default: throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown integration model"); } + // Always a concrete number online, never "derive it from the crystal": the generated model holds + // the schema's default when the request omits the field, so an absent max_hkl arrives here as that + // default rather than as an absent value. Deriving per crystal would make a live acquisition's + // per-image cost depend on whichever sample is mounted. + ret.MaxHKL(input.getMaxHkl()); return ret; } @@ -1091,6 +1096,8 @@ org::openapitools::server::model::Bragg_integration_settings Convert(const Bragg break; } ret.setIntegrationModel(tmp); + if (const auto max_hkl = input.GetMaxHKL()) + ret.setMaxHkl(*max_hkl); return ret; } diff --git a/broker/gen/model/Bragg_integration_settings.cpp b/broker/gen/model/Bragg_integration_settings.cpp index 8b1328bf..30ab9d26 100644 --- a/broker/gen/model/Bragg_integration_settings.cpp +++ b/broker/gen/model/Bragg_integration_settings.cpp @@ -21,6 +21,8 @@ namespace org::openapitools::server::model Bragg_integration_settings::Bragg_integration_settings() { + m_Max_hkl = 100; + m_Max_hklIsSet = false; } @@ -43,7 +45,26 @@ bool Bragg_integration_settings::validate(std::stringstream& msg, const std::str bool success = true; const std::string _pathPrefix = pathPrefix.empty() ? "Bragg_integration_settings" : pathPrefix; + + if (maxHklIsSet()) + { + const int32_t& value = m_Max_hkl; + const std::string currentValuePath = _pathPrefix + ".maxHkl"; + + if (value < 1) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 1;"; + } + if (value > 511) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 511;"; + } + + } + return success; } @@ -53,8 +74,11 @@ bool Bragg_integration_settings::operator==(const Bragg_integration_settings& rh (getIntegrationModel() == rhs.getIntegrationModel()) + && + ((!maxHklIsSet() && !rhs.maxHklIsSet()) || (maxHklIsSet() && rhs.maxHklIsSet() && getMaxHkl() == rhs.getMaxHkl())) + ; } @@ -67,12 +91,19 @@ void to_json(nlohmann::json& j, const Bragg_integration_settings& o) { j = nlohmann::json::object(); j["integration_model"] = o.m_Integration_model; + if(o.maxHklIsSet()) + j["max_hkl"] = o.m_Max_hkl; } void from_json(const nlohmann::json& j, Bragg_integration_settings& o) { j.at("integration_model").get_to(o.m_Integration_model); + if(j.find("max_hkl") != j.end()) + { + j.at("max_hkl").get_to(o.m_Max_hkl); + o.m_Max_hklIsSet = true; + } } @@ -84,6 +115,23 @@ void Bragg_integration_settings::setIntegrationModel(org::openapitools::server:: { m_Integration_model = value; } +int32_t Bragg_integration_settings::getMaxHkl() const +{ + return m_Max_hkl; +} +void Bragg_integration_settings::setMaxHkl(int32_t const value) +{ + m_Max_hkl = value; + m_Max_hklIsSet = true; +} +bool Bragg_integration_settings::maxHklIsSet() const +{ + return m_Max_hklIsSet; +} +void Bragg_integration_settings::unsetMax_hkl() +{ + m_Max_hklIsSet = false; +} } // namespace org::openapitools::server::model diff --git a/broker/gen/model/Bragg_integration_settings.h b/broker/gen/model/Bragg_integration_settings.h index b82dc5c0..53f9f678 100644 --- a/broker/gen/model/Bragg_integration_settings.h +++ b/broker/gen/model/Bragg_integration_settings.h @@ -63,12 +63,21 @@ public: /// org::openapitools::server::model::Integration_model getIntegrationModel() const; void setIntegrationModel(org::openapitools::server::model::Integration_model const& value); + /// + /// How far the Bragg predictor walks the lattice: reflections with |h|,|k|,|l| above this are never predicted. An axis is truncated once a/d_min exceeds it, so a long axis - or a short one taken to high resolution - loses its outermost reflections. The cost grows as the cube (2n+1)^3 of candidates per image, which is why online keeps a fixed, predictable value instead of taking it from whichever crystal is mounted. Omitting the field selects the default above; it is never interpreted as \"choose per crystal\". The offline tools (rugnux, viewer) do derive it from the refined cell when it is left unset there, but that is their own default and is not reachable through this API. + /// + int32_t getMaxHkl() const; + void setMaxHkl(int32_t const value); + bool maxHklIsSet() const; + void unsetMax_hkl(); friend void to_json(nlohmann::json& j, const Bragg_integration_settings& o); friend void from_json(const nlohmann::json& j, Bragg_integration_settings& o); protected: org::openapitools::server::model::Integration_model m_Integration_model; + int32_t m_Max_hkl; + bool m_Max_hklIsSet; }; diff --git a/broker/jfjoch_api.yaml b/broker/jfjoch_api.yaml index e4c174f3..f880c728 100644 --- a/broker/jfjoch_api.yaml +++ b/broker/jfjoch_api.yaml @@ -2348,6 +2348,21 @@ components: properties: integration_model: $ref: '#/components/schemas/integration_model' + max_hkl: + type: integer + minimum: 1 + maximum: 511 + default: 100 + description: | + How far the Bragg predictor walks the lattice: reflections with |h|,|k|,|l| above this are + never predicted. An axis is truncated once a/d_min exceeds it, so a long axis - or a short + one taken to high resolution - loses its outermost reflections. The cost grows as the cube + (2n+1)^3 of candidates per image, which is why online keeps a fixed, predictable value + instead of taking it from whichever crystal is mounted. + + Omitting the field selects the default above; it is never interpreted as "choose per + crystal". The offline tools (rugnux, viewer) do derive it from the refined cell when it is + left unset there, but that is their own default and is not reachable through this API. jfjoch_settings: type: object required: diff --git a/broker/redoc-static.html b/broker/redoc-static.html index 434419cc..973da47c 100644 --- a/broker/redoc-static.html +++ b/broker/redoc-static.html @@ -609,19 +609,27 @@ If set to true, the thread pool will block until a thread is available.

Responses

Response samples

Content type
application/json
{
  • "algorithm": "FFBIDX",
  • "fft_max_unit_cell_A": 250,
  • "fft_min_unit_cell_A": 10,
  • "fft_high_resolution_A": 2,
  • "fft_num_vectors": 16384,
  • "tolerance": 0.5,
  • "thread_count": 1,
  • "geom_refinement_algorithm": "BeamCenter",
  • "unit_cell_dist_tolerance": 0.05,
  • "viable_cell_min_spots": 10,
  • "index_ice_rings": false,
  • "rotation_indexing": false,
  • "rotation_indexing_min_angular_range_deg": 20,
  • "rotation_indexing_angular_stride_deg": 0.5,
  • "blocking": true
}

Change Bragg integration settings

This can only be done when detector is Idle, Error or Inactive states.

-
Request Body schema: application/json
integration_model
required
string (integration_model)
Default: "ProfileGaussian"
Enum: "ProfileGaussian" "ProfileEmpirical" "BoxSum"

Bragg spot integration model. +

Request Body schema: application/json
integration_model
required
string (integration_model)
Default: "ProfileGaussian"
Enum: "ProfileGaussian" "ProfileEmpirical" "BoxSum"

Bragg spot integration model. ProfileGaussian - profile fit with a measured-width Gaussian (Kabsch-style), the default; more accurate intensities than box summation. ProfileEmpirical - profile fit with a per-resolution-shell empirical profile learned from strong spots. BoxSum - classical uniform box summation minus a ring-mean background; the simpler, faster fallback.

+
max_hkl
integer [ 1 .. 511 ]
Default: 100

How far the Bragg predictor walks the lattice: reflections with |h|,|k|,|l| above this are +never predicted. An axis is truncated once a/d_min exceeds it, so a long axis - or a short +one taken to high resolution - loses its outermost reflections. The cost grows as the cube +(2n+1)^3 of candidates per image, which is why online keeps a fixed, predictable value +instead of taking it from whichever crystal is mounted.

+

Omitting the field selects the default above; it is never interpreted as "choose per +crystal". The offline tools (rugnux, viewer) do derive it from the refined cell when it is +left unset there, but that is their own default and is not reachable through this API.

Responses

Request samples

Content type
application/json
{
  • "integration_model": "ProfileGaussian"
}

Response samples

Content type
application/json
{
  • "msg": "Detector in wrong state",
  • "reason": "WrongDAQState"
}

Get Bragg integration configuration

Can be done anytime

+
http://localhost:5232/config/bragg_integration

Request samples

Content type
application/json
{
  • "integration_model": "ProfileGaussian",
  • "max_hkl": 100
}

Response samples

Content type
application/json
{
  • "msg": "Detector in wrong state",
  • "reason": "WrongDAQState"
}

Get Bragg integration configuration

Can be done anytime

Responses

Response samples

Content type
application/json
{
  • "integration_model": "ProfileGaussian"
}

Change file writer settings

This can only be done when detector is Idle, Error or Inactive states.

+
http://localhost:5232/config/bragg_integration

Response samples

Content type
application/json
{
  • "integration_model": "ProfileGaussian",
  • "max_hkl": 100
}

Change file writer settings

This can only be done when detector is Idle, Error or Inactive states.

Request Body schema: application/json
overwrite
boolean
Default: false

Inform jfjoch_write to overwrite existing files. Otherwise files would be saved with .h5.{timestamp}.tmp suffix.

format
string (file_writer_format)
Default: "NXmxLegacy"
Enum: "NXmxOnlyData" "NXmxLegacy" "NXmxVDS" "NXmxIntegrated" "CBF" "TIFF" "NoFileWritten"

NoFileWritten - no files are written at all NXmxOnlyData - only data files are written, no master file @@ -836,7 +844,7 @@ This can only be done when detector is Idle, Error or

Request samples

Content type
application/json
{
  • "box": {
    },
  • "circle": {
    },
  • "azim": {
    }
}

Response samples

Content type
application/json
{
  • "msg": "Detector in wrong state",
  • "reason": "WrongDAQState"
}

Get general statistics

Responses

Response samples

Content type
application/json
{
  • "detector": {
    },
  • "detector_list": {
    },
  • "detector_settings": {
    },
  • "image_format_settings": {
    },
  • "instrument_metadata": {
    },
  • "file_writer_settings": {
    },
  • "data_processing_settings": {
    },
  • "measurement": {
    },
  • "broker": {
    },
  • "fpga": [
    ],
  • "calibration": [
    ],
  • "zeromq_preview": {
    },
  • "zeromq_metadata": {
    },
  • "dark_mask": {
    },
  • "pixel_mask": {
    },
  • "roi": {
    },
  • "az_int": {
    },
  • "buffer": {
    },
  • "indexing": {
    },
  • "bragg_integration": {
    },
  • "image_pusher": {
    }
}

Get data collection statistics

Results of the last data collection

+
http://localhost:5232/statistics

Response samples

Content type
application/json
{
  • "detector": {
    },
  • "detector_list": {
    },
  • "detector_settings": {
    },
  • "image_format_settings": {
    },
  • "instrument_metadata": {
    },
  • "file_writer_settings": {
    },
  • "data_processing_settings": {
    },
  • "measurement": {
    },
  • "broker": {
    },
  • "fpga": [
    ],
  • "calibration": [
    ],
  • "zeromq_preview": {
    },
  • "zeromq_metadata": {
    },
  • "dark_mask": {
    },
  • "pixel_mask": {
    },
  • "roi": {
    },
  • "az_int": {
    },
  • "buffer": {
    },
  • "indexing": {
    },
  • "bragg_integration": {
    },
  • "image_pusher": {
    }
}

Get data collection statistics

Results of the last data collection

Responses