From 9fe5fc7e4c490b2488bb7f5560445306fa2fda4a Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Tue, 28 Apr 2026 13:59:39 +0200 Subject: [PATCH] Detector read-out time can be in nanoseconds (this is work in progress, need to adapt count time and frame time to serious units) --- broker/JFJochBrokerParser.cpp | 4 +- broker/JFJochStateMachine.h | 2 +- broker/OpenAPIConvert.cpp | 2 +- broker/gen/model/Detector.cpp | 40 +++++++++---------- broker/gen/model/Detector.h | 14 +++---- broker/gen/model/Detector_list_element.cpp | 16 ++++---- broker/gen/model/Detector_list_element.h | 6 +-- broker/jfjoch_api.yaml | 8 ++-- broker/redoc-static.html | 6 +-- common/DetectorSetup.cpp | 4 +- common/DetectorSetup.h | 6 +-- common/DiffractionExperiment.cpp | 16 +++++--- common/DiffractionExperiment.h | 4 +- detector_control/DectrisSimplonClient.cpp | 24 +++++------ detector_control/SLSDetectorWrapper.cpp | 4 +- docs/python_client/docs/Detector.md | 2 +- .../python_client/docs/DetectorListElement.md | 2 +- frontend/package-lock.json | 4 +- frontend/src/components/DetectorSelection.tsx | 4 +- frontend/src/openapi/models/detector.ts | 4 +- .../openapi/models/detector_list_element.ts | 2 +- reader/JFJochHDF5Reader.cpp | 11 +++-- .../widgets/JFJochViewerImageStatistics.cpp | 5 ++- 23 files changed, 100 insertions(+), 90 deletions(-) diff --git a/broker/JFJochBrokerParser.cpp b/broker/JFJochBrokerParser.cpp index 76f3e376..7a9b24af 100644 --- a/broker/JFJochBrokerParser.cpp +++ b/broker/JFJochBrokerParser.cpp @@ -124,8 +124,8 @@ DetectorSetup ParseDetectorSetup(const org::openapitools::server::model::Detecto .SerialNumber(d.getSerialNumber()) .ModuleSync(d.isModuleSync()); - if (d.readoutTimeUsIsSet()) - setup.ReadOutTime(std::chrono::microseconds(d.getReadoutTimeUs())); + if (d.readoutTimeNsIsSet()) + setup.ReadOutTime(std::chrono::nanoseconds(d.getReadoutTimeNs())); if (d.baseDataIpv4AddressIsSet()) setup.BaseIPv4Addr(d.getBaseDataIpv4Address()); diff --git a/broker/JFJochStateMachine.h b/broker/JFJochStateMachine.h index b2f0413a..01a4ce6d 100644 --- a/broker/JFJochStateMachine.h +++ b/broker/JFJochStateMachine.h @@ -25,7 +25,7 @@ struct DetectorListElement { int64_t nmodules; int64_t width; int64_t height; - std::chrono::microseconds readout_time; + std::chrono::nanoseconds readout_time; std::chrono::microseconds min_frame_time; std::chrono::microseconds min_count_time; DetectorType detector_type; diff --git a/broker/OpenAPIConvert.cpp b/broker/OpenAPIConvert.cpp index 6cfb7aa7..ebb7a378 100644 --- a/broker/OpenAPIConvert.cpp +++ b/broker/OpenAPIConvert.cpp @@ -372,7 +372,7 @@ org::openapitools::server::model::Detector_list Convert(const DetectorList &inpu d.setUdpInterfaceCount(input.detector[i].udp_interface_count); d.setMinFrameTimeUs(input.detector[i].min_frame_time.count()); d.setMinCountTimeUs(input.detector[i].min_count_time.count()); - d.setReadoutTimeUs(input.detector[i].readout_time.count()); + d.setReadoutTimeNs(input.detector[i].readout_time.count()); d.setPixelSizeMm(input.detector[i].pixel_size_mm); d.setType(Convert(input.detector[i].detector_type)); dets.emplace_back(std::move(d)); diff --git a/broker/gen/model/Detector.cpp b/broker/gen/model/Detector.cpp index 5907b30d..0e72ed16 100644 --- a/broker/gen/model/Detector.cpp +++ b/broker/gen/model/Detector.cpp @@ -33,8 +33,8 @@ Detector::Detector() m_Module_syncIsSet = false; m_Sensor_thickness_um = 320.0f; m_Sensor_thickness_umIsSet = false; - m_Readout_time_us = 0L; - m_Readout_time_usIsSet = false; + m_Readout_time_ns = 0L; + m_Readout_time_nsIsSet = false; m_Minimum_count_time_us = 0L; m_Minimum_count_time_usIsSet = false; m_Minimum_frame_time_us = 0L; @@ -158,10 +158,10 @@ bool Detector::validate(std::stringstream& msg, const std::string& pathPrefix) c } - if (readoutTimeUsIsSet()) + if (readoutTimeNsIsSet()) { - const int64_t& value = m_Readout_time_us; - const std::string currentValuePath = _pathPrefix + ".readoutTimeUs"; + const int64_t& value = m_Readout_time_ns; + const std::string currentValuePath = _pathPrefix + ".readoutTimeNs"; if (value < 1ll) @@ -333,7 +333,7 @@ bool Detector::operator==(const Detector& rhs) const ((!sensorThicknessUmIsSet() && !rhs.sensorThicknessUmIsSet()) || (sensorThicknessUmIsSet() && rhs.sensorThicknessUmIsSet() && getSensorThicknessUm() == rhs.getSensorThicknessUm())) && - ((!readoutTimeUsIsSet() && !rhs.readoutTimeUsIsSet()) || (readoutTimeUsIsSet() && rhs.readoutTimeUsIsSet() && getReadoutTimeUs() == rhs.getReadoutTimeUs())) && + ((!readoutTimeNsIsSet() && !rhs.readoutTimeNsIsSet()) || (readoutTimeNsIsSet() && rhs.readoutTimeNsIsSet() && getReadoutTimeNs() == rhs.getReadoutTimeNs())) && ((!minimumCountTimeUsIsSet() && !rhs.minimumCountTimeUsIsSet()) || (minimumCountTimeUsIsSet() && rhs.minimumCountTimeUsIsSet() && getMinimumCountTimeUs() == rhs.getMinimumCountTimeUs())) && @@ -398,8 +398,8 @@ void to_json(nlohmann::json& j, const Detector& o) j["module_sync"] = o.m_Module_sync; if(o.sensorThicknessUmIsSet()) j["sensor_thickness_um"] = o.m_Sensor_thickness_um; - if(o.readoutTimeUsIsSet()) - j["readout_time_us"] = o.m_Readout_time_us; + if(o.readoutTimeNsIsSet()) + j["readout_time_ns"] = o.m_Readout_time_ns; if(o.minimumCountTimeUsIsSet()) j["minimum_count_time_us"] = o.m_Minimum_count_time_us; if(o.minimumFrameTimeUsIsSet()) @@ -462,10 +462,10 @@ void from_json(const nlohmann::json& j, Detector& o) j.at("sensor_thickness_um").get_to(o.m_Sensor_thickness_um); o.m_Sensor_thickness_umIsSet = true; } - if(j.find("readout_time_us") != j.end()) + if(j.find("readout_time_ns") != j.end()) { - j.at("readout_time_us").get_to(o.m_Readout_time_us); - o.m_Readout_time_usIsSet = true; + j.at("readout_time_ns").get_to(o.m_Readout_time_ns); + o.m_Readout_time_nsIsSet = true; } if(j.find("minimum_count_time_us") != j.end()) { @@ -645,22 +645,22 @@ void Detector::unsetSensor_thickness_um() { m_Sensor_thickness_umIsSet = false; } -int64_t Detector::getReadoutTimeUs() const +int64_t Detector::getReadoutTimeNs() const { - return m_Readout_time_us; + return m_Readout_time_ns; } -void Detector::setReadoutTimeUs(int64_t const value) +void Detector::setReadoutTimeNs(int64_t const value) { - m_Readout_time_us = value; - m_Readout_time_usIsSet = true; + m_Readout_time_ns = value; + m_Readout_time_nsIsSet = true; } -bool Detector::readoutTimeUsIsSet() const +bool Detector::readoutTimeNsIsSet() const { - return m_Readout_time_usIsSet; + return m_Readout_time_nsIsSet; } -void Detector::unsetReadout_time_us() +void Detector::unsetReadout_time_ns() { - m_Readout_time_usIsSet = false; + m_Readout_time_nsIsSet = false; } int64_t Detector::getMinimumCountTimeUs() const { diff --git a/broker/gen/model/Detector.h b/broker/gen/model/Detector.h index 6bfd2322..2b919d12 100644 --- a/broker/gen/model/Detector.h +++ b/broker/gen/model/Detector.h @@ -111,12 +111,12 @@ public: bool sensorThicknessUmIsSet() const; void unsetSensor_thickness_um(); /// - /// Minimum difference between frame time and count time in microseconds Defaults are 3 us for EIGER and 20 us for JUNGFRAU + /// Minimum difference between frame time and count time in microseconds Defaults are 3'000 ns for EIGER and 20'000 ns for JUNGFRAU /// - int64_t getReadoutTimeUs() const; - void setReadoutTimeUs(int64_t const value); - bool readoutTimeUsIsSet() const; - void unsetReadout_time_us(); + int64_t getReadoutTimeNs() const; + void setReadoutTimeNs(int64_t const value); + bool readoutTimeNsIsSet() const; + void unsetReadout_time_ns(); /// /// Minimum count time available for the detector. /// @@ -226,8 +226,8 @@ protected: bool m_Module_syncIsSet; float m_Sensor_thickness_um; bool m_Sensor_thickness_umIsSet; - int64_t m_Readout_time_us; - bool m_Readout_time_usIsSet; + int64_t m_Readout_time_ns; + bool m_Readout_time_nsIsSet; int64_t m_Minimum_count_time_us; bool m_Minimum_count_time_usIsSet; int64_t m_Minimum_frame_time_us; diff --git a/broker/gen/model/Detector_list_element.cpp b/broker/gen/model/Detector_list_element.cpp index da668d80..13e8e588 100644 --- a/broker/gen/model/Detector_list_element.cpp +++ b/broker/gen/model/Detector_list_element.cpp @@ -31,7 +31,7 @@ Detector_list_element::Detector_list_element() m_Height = 0L; m_Pixel_size_mm = 0.0f; m_Pixel_size_mmIsSet = false; - m_Readout_time_us = 0L; + m_Readout_time_ns = 0L; m_Min_frame_time_us = 0L; m_Min_count_time_us = 0L; m_TypeIsSet = false; @@ -107,7 +107,7 @@ bool Detector_list_element::operator==(const Detector_list_element& rhs) const ((!pixelSizeMmIsSet() && !rhs.pixelSizeMmIsSet()) || (pixelSizeMmIsSet() && rhs.pixelSizeMmIsSet() && getPixelSizeMm() == rhs.getPixelSizeMm())) && - (getReadoutTimeUs() == rhs.getReadoutTimeUs()) + (getReadoutTimeNs() == rhs.getReadoutTimeNs()) && (getMinFrameTimeUs() == rhs.getMinFrameTimeUs()) @@ -140,7 +140,7 @@ void to_json(nlohmann::json& j, const Detector_list_element& o) j["height"] = o.m_Height; if(o.pixelSizeMmIsSet()) j["pixel_size_mm"] = o.m_Pixel_size_mm; - j["readout_time_us"] = o.m_Readout_time_us; + j["readout_time_ns"] = o.m_Readout_time_ns; j["min_frame_time_us"] = o.m_Min_frame_time_us; j["min_count_time_us"] = o.m_Min_count_time_us; if(o.typeIsSet()) @@ -163,7 +163,7 @@ void from_json(const nlohmann::json& j, Detector_list_element& o) j.at("pixel_size_mm").get_to(o.m_Pixel_size_mm); o.m_Pixel_size_mmIsSet = true; } - j.at("readout_time_us").get_to(o.m_Readout_time_us); + j.at("readout_time_ns").get_to(o.m_Readout_time_ns); j.at("min_frame_time_us").get_to(o.m_Min_frame_time_us); j.at("min_count_time_us").get_to(o.m_Min_count_time_us); if(j.find("type") != j.end()) @@ -255,13 +255,13 @@ void Detector_list_element::unsetPixel_size_mm() { m_Pixel_size_mmIsSet = false; } -int64_t Detector_list_element::getReadoutTimeUs() const +int64_t Detector_list_element::getReadoutTimeNs() const { - return m_Readout_time_us; + return m_Readout_time_ns; } -void Detector_list_element::setReadoutTimeUs(int64_t const value) +void Detector_list_element::setReadoutTimeNs(int64_t const value) { - m_Readout_time_us = value; + m_Readout_time_ns = value; } int64_t Detector_list_element::getMinFrameTimeUs() const { diff --git a/broker/gen/model/Detector_list_element.h b/broker/gen/model/Detector_list_element.h index 51b52dbe..2fb5508c 100644 --- a/broker/gen/model/Detector_list_element.h +++ b/broker/gen/model/Detector_list_element.h @@ -109,8 +109,8 @@ public: /// /// /// - int64_t getReadoutTimeUs() const; - void setReadoutTimeUs(int64_t const value); + int64_t getReadoutTimeNs() const; + void setReadoutTimeNs(int64_t const value); /// /// /// @@ -150,7 +150,7 @@ protected: float m_Pixel_size_mm; bool m_Pixel_size_mmIsSet; - int64_t m_Readout_time_us; + int64_t m_Readout_time_ns; int64_t m_Min_frame_time_us; diff --git a/broker/jfjoch_api.yaml b/broker/jfjoch_api.yaml index 8674cb75..9c2ceb43 100644 --- a/broker/jfjoch_api.yaml +++ b/broker/jfjoch_api.yaml @@ -1083,7 +1083,7 @@ components: - serial_number - base_ipv4_addr - udp_interface_count - - readout_time_us + - readout_time_ns - min_frame_time_us - min_count_time_us properties: @@ -1121,7 +1121,7 @@ components: type: number format: float example: 0.075 - readout_time_us: + readout_time_ns: type: integer format: int64 min_frame_time_us: @@ -2060,13 +2060,13 @@ components: format: float minimum: 0 default: 320 - readout_time_us: + readout_time_ns: type: integer format: int64 minimum: 1 description: | Minimum difference between frame time and count time in microseconds - Defaults are 3 us for EIGER and 20 us for JUNGFRAU + Defaults are 3'000 ns for EIGER and 20'000 ns for JUNGFRAU minimum_count_time_us: type: integer format: int64 diff --git a/broker/redoc-static.html b/broker/redoc-static.html index 3066543d..a33bb302 100644 --- a/broker/redoc-static.html +++ b/broker/redoc-static.html @@ -733,7 +733,7 @@ Changing detector will set detector to Inactive state and will requ
http://localhost:5232/config/select_detector

Request samples

Content type
application/json
{
  • "id": 1
}

Response samples

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

List available detectors

Configured detectors that can be selected by used

Responses

Response samples

Content type
application/json
{
  • "detectors": [
    ],
  • "current_id": 0
}

Set ZeroMQ preview settings

Jungfraujoch can generate preview message stream on ZeroMQ SUB socket. +

http://localhost:5232/config/select_detector

Response samples

Content type
application/json
{
  • "detectors": [
    ],
  • "current_id": 0
}

Set ZeroMQ preview settings

Jungfraujoch can generate preview message stream on ZeroMQ SUB socket. Here settings of the socket can be adjusted. While the data structure contains also socket_address, this cannot be changed via HTTP and is ignore in PUT request. Options set with this PUT request have no effect on HTTP based preview.

@@ -811,7 +811,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": {
    },
  • "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": {
    },
  • "image_pusher": {
    }
}

Get data collection statistics

Results of the last data collection

Responses