Files
Jungfraujoch/broker/gen/model/Dataset_settings.h
T
leonarski_fandClaude Opus 5 1f4f77fe42 Choose images_per_file from the acquisition when it is not given
The value means three different things at once. It is the unit of writer
parallelism - whole files go round-robin to the writers,
(image_number / images_per_file) % socket.size() in ZMQStream2Pusher::SendImage
and TCPStreamPusher - it multiplies writer memory linearly, since every data-file
plugin reserves per file, and it decides whether a legacy master is readable at
all, because dxtbx follows only the first data file of one.

That last point is what makes a flat default wrong. Measured with DIALS on a
2500-image rotation sweep written as legacy: split into five files it reports
2500 images and then raises IndexError beyond image 499, so it half-works
silently; in one file all 2500 read. AutoPROC does not read VDS, so legacy has to
stay the default, which leaves the file count as the only lever.

So make it optional and resolve it from the acquisition. A rotation sweep of at
most 20000 images goes into one data file - rotation datasets are small enough,
and one writer keeps up with them. A grid scan splits on whole fast-axis rows, so
a file is a meaningful piece of the grid. Stills and serial keep 1000, where the
image count far exceeds it and the parallelism and the bounded writer memory are
what matter. An explicit value is always taken literally.

GetImagesPerFile is the single place this is resolved, and it must always return
a fixed non-zero number, because everything downstream - receiver, pusher, puller,
writer - requires one. That was already true of the old 0 = "one file" spelling;
0 is now gone from the API and omitting the field says the same thing better.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-22 21:57:12 +02:00

420 lines
18 KiB
C++

/**
* Jungfraujoch
* API to control Jungfraujoch developed by the Paul Scherrer Institute (Switzerland). Jungfraujoch is a data acquisition and analysis system for pixel array detectors, primarly PSI JUNGFRAU. Jungfraujoch uses FPGA boards to acquire data at high data rates. # License Clarification While this API definition is licensed under GPL-3.0, **the GPL copyleft provisions do not apply** when this file is used solely to generate OpenAPI clients or when implementing applications that interact with the API. Generated client code and applications using this API definition are not subject to the GPL license requirements and may be distributed under terms of your choosing. This exception is similar in spirit to the Linux Kernel's approach to userspace API headers and the GCC Runtime Library Exception. The Linux Kernel developers have explicitly stated that user programs that merely use the kernel interfaces (syscalls, ioctl definitions, etc.) are not derivative works of the kernel and are not subject to the terms of the GPL. This exception is intended to allow wider use of this API specification without imposing GPL requirements on applications that merely interact with the API, regardless of whether they communicate through network calls or other mechanisms.
*
* The version of the OpenAPI document: 1.0.0-rc.162
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* Dataset_settings.h
*
*
*/
#ifndef Dataset_settings_H_
#define Dataset_settings_H_
#include "Grid_scan.h"
#include <nlohmann/json.hpp>
#include "Dataset_settings_smargon.h"
#include "Rotation_axis.h"
#include "Unit_cell.h"
#include <string>
#include "Dataset_settings_xray_fluorescence_spectrum.h"
#include <nlohmann/json.hpp>
namespace org::openapitools::server::model
{
/// <summary>
///
/// </summary>
class Dataset_settings
{
public:
Dataset_settings();
virtual ~Dataset_settings() = default;
/// <summary>
/// Validate the current data in the model. Throws a ValidationException on failure.
/// </summary>
void validate() const;
/// <summary>
/// Validate the current data in the model. Returns false on error and writes an error
/// message into the given stringstream.
/// </summary>
bool validate(std::stringstream& msg) const;
/// <summary>
/// Helper overload for validate. Used when one model stores another model and calls it's validate.
/// Not meant to be called outside that case.
/// </summary>
bool validate(std::stringstream& msg, const std::string& pathPrefix) const;
bool operator==(const Dataset_settings& rhs) const;
bool operator!=(const Dataset_settings& rhs) const;
/////////////////////////////////////////////
/// Dataset_settings members
/// <summary>
/// For standard synchrotron data collection - this is number of images collected per one TTL trigger For XFEL (pulsed source) - this number is ignored and set to 1 For storage cell mode - this number is ignored and set to number of storage cells
/// </summary>
int64_t getImagesPerTrigger() const;
void setImagesPerTrigger(int64_t const value);
bool imagesPerTriggerIsSet() const;
void unsetImages_per_trigger();
/// <summary>
/// Number of TTL trigger that the detector is expected to receive during data collection
/// </summary>
int64_t getNtrigger() const;
void setNtrigger(int64_t const value);
bool ntriggerIsSet() const;
void unsetNtrigger();
/// <summary>
/// Image time. If not provided (or zero value) the frame time is assumed as default. For JUNGFRAU image time must be multiple of frame time and max value is 256 * frame_time. In XFEL mode: summation happens for frames collected with multiple triggers. Ignored for storage cells and if raw data are saved.
/// </summary>
int64_t getImageTimeUs() const;
void setImageTimeUs(int64_t const value);
bool imageTimeUsIsSet() const;
void unsetImage_time_us();
/// <summary>
/// /entry/detector/beam_center_x in NXmx Beam center in X direction [pixels]
/// </summary>
float getBeamXPxl() const;
void setBeamXPxl(float const value);
/// <summary>
/// /entry/detector/beam_center_y in NXmx Beam center in X direction [pixels]
/// </summary>
float getBeamYPxl() const;
void setBeamYPxl(float const value);
/// <summary>
/// /entry/detector/distance in NXmx Detector distance [mm]
/// </summary>
float getDetectorDistanceMm() const;
void setDetectorDistanceMm(float const value);
/// <summary>
/// Used to calculate /entry/beam/incident_wavelength in NXmx Incident particle (photon, electron) energy in keV
/// </summary>
float getIncidentEnergyKeV() const;
void setIncidentEnergyKeV(float const value);
/// <summary>
/// Prefix for filenames. If left empty, no file will be saved.
/// </summary>
std::string getFilePrefix() const;
void setFilePrefix(std::string const& value);
bool filePrefixIsSet() const;
void unsetFile_prefix();
/// <summary>
/// Number of images in a single HDF5 data file, taken literally when given. If omitted, it is chosen from the acquisition: a rotation sweep of at most 20000 images goes into a single data file, so the dataset stays readable by programs that follow only the first data file of a legacy master; a grid scan is split on a whole number of fast-axis rows; anything else (stills, serial) uses 1000.
/// </summary>
int64_t getImagesPerFile() const;
void setImagesPerFile(int64_t const value);
bool imagesPerFileIsSet() const;
void unsetImages_per_file();
/// <summary>
/// Number of space group for the crystal. Currently used solely as metadata, not relevant for image processing done in Jungfraujoch.
/// </summary>
int64_t getSpaceGroupNumber() const;
void setSpaceGroupNumber(int64_t const value);
bool spaceGroupNumberIsSet() const;
void unsetSpace_group_number();
/// <summary>
/// /entry/sample/name in NXmx Sample name
/// </summary>
std::string getSampleName() const;
void setSampleName(std::string const& value);
bool sampleNameIsSet() const;
void unsetSample_name();
/// <summary>
/// Compression type for the images transferred over ZeroMQ and saved to HDF5 file.
/// </summary>
std::string getCompression() const;
void setCompression(std::string const& value);
bool compressionIsSet() const;
void unsetCompression();
/// <summary>
/// /entry/beam/total_flux in NXmx Flux incident on beam plane in photons per second. In other words this is the flux integrated over area. [photons/s]
/// </summary>
float getTotalFlux() const;
void setTotalFlux(float const value);
bool totalFluxIsSet() const;
void unsetTotal_flux();
/// <summary>
/// /entry/instrument/attenuator/attenuator_transmission Transmission of attenuator (filter) [no units]
/// </summary>
float getTransmission() const;
void setTransmission(float const value);
bool transmissionIsSet() const;
void unsetTransmission();
/// <summary>
///
/// </summary>
org::openapitools::server::model::Rotation_axis getGoniometer() const;
void setGoniometer(org::openapitools::server::model::Rotation_axis const& value);
bool goniometerIsSet() const;
void unsetGoniometer();
/// <summary>
///
/// </summary>
org::openapitools::server::model::Grid_scan getGridScan() const;
void setGridScan(org::openapitools::server::model::Grid_scan const& value);
bool gridScanIsSet() const;
void unsetGrid_scan();
/// <summary>
/// Header appendix, added as user_data/user to start ZeroMQ message (can be any valid JSON) In general, it is not saved in HDF5 file. However, if values are placed in \&quot;hdf5\&quot; object, &#x60;jfjoch_writer&#x60; will write them in /entry/user of the HDF5 file. This applies solely to string and number (double floating-point). No arrays/sub-objects is allowed. For example {\&quot;hdf5\&quot;: {\&quot;val1\&quot;:1, \&quot;val2\&quot;:\&quot;xyz\&quot;}}, will write /entry/user/val1 and /entry/user/val2.
/// </summary>
nlohmann::json getHeaderAppendix() const;
void setHeaderAppendix(nlohmann::json const& value);
bool headerAppendixIsSet() const;
void unsetHeader_appendix();
/// <summary>
/// Image appendix, added as user_data to image ZeroMQ message (can be any valid JSON) Not saved in HDF5 file
/// </summary>
nlohmann::json getImageAppendix() const;
void setImageAppendix(nlohmann::json const& value);
bool imageAppendixIsSet() const;
void unsetImage_appendix();
/// <summary>
/// Rate at which non-indexed images are accepted to be forwarded to writer. Value of 1.0 (default) means that all images are written. Values below zero mean that non-indexed images will be accepted with a given probability.
/// </summary>
float getDataReductionFactorSerialmx() const;
void setDataReductionFactorSerialmx(float const value);
bool dataReductionFactorSerialmxIsSet() const;
void unsetData_reduction_factor_serialmx();
/// <summary>
/// Set all counts lower than the value to zero. When the value is set, negative numbers other than error pixel value are always set to zero. Setting to zero is equivalent to turning the option off.
/// </summary>
int64_t getPixelValueLowThreshold() const;
void setPixelValueLowThreshold(int64_t const value);
bool pixelValueLowThresholdIsSet() const;
void unsetPixel_value_low_threshold();
/// <summary>
/// Number of run within an experimental session. Transferred over CBOR stream as \&quot;series ID\&quot;, though not saved in HDF5 file. It is highly recommended to keep this number unique for each data collection during experimental series. If not provided, the number will be automatically incremented.
/// </summary>
int64_t getRunNumber() const;
void setRunNumber(int64_t const value);
bool runNumberIsSet() const;
void unsetRun_number();
/// <summary>
/// Unique ID of run. Transferred over CBOR stream as \&quot;unique series ID\&quot;, though not saved in HDF5 file. It is highly recommended to keep this name unique for each data collection during experimental series. If not provided, the name will be automatically generated as number + colon + file_prefix.
/// </summary>
std::string getRunName() const;
void setRunName(std::string const& value);
bool runNameIsSet() const;
void unsetRun_name();
/// <summary>
/// Name of group owning the data (e.g. p-group or proposal number). Transferred over CBOR stream, though not saved in HDF5 file.
/// </summary>
std::string getExperimentGroup() const;
void setExperimentGroup(std::string const& value);
bool experimentGroupIsSet() const;
void unsetExperiment_group();
/// <summary>
/// Enable lossy compression of pixel values that preserves Poisson statistics. Requires to provide a numerical factor SQ. Pixel value P will be transformed to round(sqrt(P) * SQ), with rounding to the closest integer. Compression is turned off if the value is missing or it is set to zero.
/// </summary>
int64_t getPoissonCompression() const;
void setPoissonCompression(int64_t const value);
bool poissonCompressionIsSet() const;
void unsetPoisson_compression();
/// <summary>
/// Write NXmx formatted HDF5 master file. Recommended to use for macromolecular crystallography experiments and to turn off for other experiments.
/// </summary>
bool isWriteNxmxHdf5Master() const;
void setWriteNxmxHdf5Master(bool const value);
bool writeNxmxHdf5MasterIsSet() const;
void unsetWrite_nxmx_hdf5_master();
/// <summary>
/// Forward image calibration (at the moment pedestal and pedestal RMS for JUNGFRAU) using the ZeroMQ stream to writer. If parameter is not provided calibration will be saved only if more than 4 images are recorded.
/// </summary>
bool isSaveCalibration() const;
void setSaveCalibration(bool const value);
bool saveCalibrationIsSet() const;
void unsetSave_calibration();
/// <summary>
/// Polarization factor for integration; 1.0 is horizontal polarization; -1.0 is vertical polarization
/// </summary>
float getPolarizationFactor() const;
void setPolarizationFactor(float const value);
bool polarizationFactorIsSet() const;
void unsetPolarization_factor();
/// <summary>
/// Ring current at the beginning of the data collection
/// </summary>
float getRingCurrentMA() const;
void setRingCurrentMA(float const value);
bool ringCurrentMAIsSet() const;
void unsetRing_current_mA();
/// <summary>
/// Sample temperature in Kelvin
/// </summary>
float getSampleTemperatureK() const;
void setSampleTemperatureK(float const value);
bool sampleTemperatureKIsSet() const;
void unsetSample_temperature_K();
/// <summary>
/// PONI angle rot1 (see PyFAI documentation for details) in radians
/// </summary>
float getPoniRot1Rad() const;
void setPoniRot1Rad(float const value);
bool poniRot1RadIsSet() const;
void unsetPoni_rot1_rad();
/// <summary>
/// PONI angle rot2 (see PyFAI documentation for details) in radians
/// </summary>
float getPoniRot2Rad() const;
void setPoniRot2Rad(float const value);
bool poniRot2RadIsSet() const;
void unsetPoni_rot2_rad();
/// <summary>
/// PONI angle rot3 (see PyFAI documentation for details) in radians
/// </summary>
float getPoniRot3Rad() const;
void setPoniRot3Rad(float const value);
bool poniRot3RadIsSet() const;
void unsetPoni_rot3_rad();
/// <summary>
///
/// </summary>
org::openapitools::server::model::Unit_cell getUnitCell() const;
void setUnitCell(org::openapitools::server::model::Unit_cell const& value);
bool unitCellIsSet() const;
void unsetUnit_cell();
/// <summary>
/// Enable spot finding and save spots
/// </summary>
bool isSpotFinding() const;
void setSpotFinding(bool const value);
bool spotFindingIsSet() const;
void unsetSpot_finding();
/// <summary>
///
/// </summary>
org::openapitools::server::model::Dataset_settings_smargon getSmargon() const;
void setSmargon(org::openapitools::server::model::Dataset_settings_smargon const& value);
bool smargonIsSet() const;
void unsetSmargon();
/// <summary>
/// Maximum number of spots that are saved/used for indexing; spots with highest intensity are selected
/// </summary>
int32_t getMaxSpotCount() const;
void setMaxSpotCount(int32_t const value);
bool maxSpotCountIsSet() const;
void unsetMax_spot_count();
/// <summary>
/// Flag spots as ice rings and reduce their effect on indexing
/// </summary>
bool isDetectIceRings() const;
void setDetectIceRings(bool const value);
bool detectIceRingsIsSet() const;
void unsetDetect_ice_rings();
/// <summary>
/// When set to true, &#x60;/start&#x60; will not wait for detector and Jungfraujoch to be ready for the measurement.
/// </summary>
bool isAsyncStart() const;
void setAsyncStart(bool const value);
bool asyncStartIsSet() const;
void unsetAsync_start();
/// <summary>
///
/// </summary>
org::openapitools::server::model::Dataset_settings_xray_fluorescence_spectrum getXrayFluorescenceSpectrum() const;
void setXrayFluorescenceSpectrum(org::openapitools::server::model::Dataset_settings_xray_fluorescence_spectrum const& value);
bool xrayFluorescenceSpectrumIsSet() const;
void unsetXray_fluorescence_spectrum();
friend void to_json(nlohmann::json& j, const Dataset_settings& o);
friend void from_json(const nlohmann::json& j, Dataset_settings& o);
protected:
int64_t m_Images_per_trigger;
bool m_Images_per_triggerIsSet;
int64_t m_Ntrigger;
bool m_NtriggerIsSet;
int64_t m_Image_time_us;
bool m_Image_time_usIsSet;
float m_Beam_x_pxl;
float m_Beam_y_pxl;
float m_Detector_distance_mm;
float m_Incident_energy_keV;
std::string m_File_prefix;
bool m_File_prefixIsSet;
int64_t m_Images_per_file;
bool m_Images_per_fileIsSet;
int64_t m_Space_group_number;
bool m_Space_group_numberIsSet;
std::string m_Sample_name;
bool m_Sample_nameIsSet;
std::string m_Compression;
bool m_CompressionIsSet;
float m_Total_flux;
bool m_Total_fluxIsSet;
float m_Transmission;
bool m_TransmissionIsSet;
org::openapitools::server::model::Rotation_axis m_Goniometer;
bool m_GoniometerIsSet;
org::openapitools::server::model::Grid_scan m_Grid_scan;
bool m_Grid_scanIsSet;
nlohmann::json m_Header_appendix;
bool m_Header_appendixIsSet;
nlohmann::json m_Image_appendix;
bool m_Image_appendixIsSet;
float m_Data_reduction_factor_serialmx;
bool m_Data_reduction_factor_serialmxIsSet;
int64_t m_Pixel_value_low_threshold;
bool m_Pixel_value_low_thresholdIsSet;
int64_t m_Run_number;
bool m_Run_numberIsSet;
std::string m_Run_name;
bool m_Run_nameIsSet;
std::string m_Experiment_group;
bool m_Experiment_groupIsSet;
int64_t m_Poisson_compression;
bool m_Poisson_compressionIsSet;
bool m_Write_nxmx_hdf5_master;
bool m_Write_nxmx_hdf5_masterIsSet;
bool m_Save_calibration;
bool m_Save_calibrationIsSet;
float m_Polarization_factor;
bool m_Polarization_factorIsSet;
float m_Ring_current_mA;
bool m_Ring_current_mAIsSet;
float m_Sample_temperature_K;
bool m_Sample_temperature_KIsSet;
float m_Poni_rot1_rad;
bool m_Poni_rot1_radIsSet;
float m_Poni_rot2_rad;
bool m_Poni_rot2_radIsSet;
float m_Poni_rot3_rad;
bool m_Poni_rot3_radIsSet;
org::openapitools::server::model::Unit_cell m_Unit_cell;
bool m_Unit_cellIsSet;
bool m_Spot_finding;
bool m_Spot_findingIsSet;
org::openapitools::server::model::Dataset_settings_smargon m_Smargon;
bool m_SmargonIsSet;
int32_t m_Max_spot_count;
bool m_Max_spot_countIsSet;
bool m_Detect_ice_rings;
bool m_Detect_ice_ringsIsSet;
bool m_Async_start;
bool m_Async_startIsSet;
org::openapitools::server::model::Dataset_settings_xray_fluorescence_spectrum m_Xray_fluorescence_spectrum;
bool m_Xray_fluorescence_spectrumIsSet;
};
} // namespace org::openapitools::server::model
#endif /* Dataset_settings_H_ */