api: record the beam size at the sample, and write it where NXmx puts it
dataset_settings gains beam_size_x_um and beam_size_y_um, the horizontal and vertical size of the X-ray beam where it meets the sample. They follow the same route total_flux takes - OpenAPI, DatasetSettings, the CBOR start message, the HDF5 master, and back out of a stored file - and nothing consumes them; this is metadata a beamline can state and a downstream program can read. NXmx puts this in the application definition rather than the base class: not NXbeam's extent (rank 2, nP x 2, per scan point, always FWHM of a rectangular aperture) but NXmx's own incident_beam_size, a recommended rank-1 two-element array in the order x, y. Both are live and neither is deprecated, so the choice matters; the MX definition wins in an MX file. Written as one array with a units attribute of "m", like every other length in the master, so the settings hold micrometres and FillMessage converts once. The unit table of ReadLength_m becomes LengthUnitFactor so the array read can share it: a master written elsewhere may state this in millimetres. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EFEJG6WBQv8th4UJFNe53N
This commit is contained in:
@@ -665,6 +665,12 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
|
||||
if (const auto bw = GetBandwidthFWHM())
|
||||
message.incident_wavelength_spread = bw.value() * GetWavelength_A();
|
||||
message.incident_energy = GetIncidentEnergy_keV() * 1e3f;
|
||||
// NXmx incident_beam_size is a length like every other in this message, so micrometres in
|
||||
// the settings become metres here.
|
||||
if (const auto beam_size_x = GetBeamSizeX_um())
|
||||
message.beam_size_x = beam_size_x.value() * 1e-6f;
|
||||
if (const auto beam_size_y = GetBeamSizeY_um())
|
||||
message.beam_size_y = beam_size_y.value() * 1e-6f;
|
||||
message.image_size_x = GetXPixelsNum();
|
||||
message.image_size_y = GetYPixelsNum();
|
||||
message.mirror_y = IsDetectorMirroredY();
|
||||
@@ -920,6 +926,16 @@ DiffractionExperiment &DiffractionExperiment::TotalFlux(const std::optional<floa
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::BeamSizeX_um(const std::optional<float> &input) {
|
||||
dataset.BeamSizeX_um(input);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::BeamSizeY_um(const std::optional<float> &input) {
|
||||
dataset.BeamSizeY_um(input);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::optional<float> DiffractionExperiment::GetAttenuatorTransmission() const {
|
||||
return dataset.GetAttenuatorTransmission();
|
||||
}
|
||||
@@ -928,6 +944,14 @@ std::optional<float> DiffractionExperiment::GetTotalFlux() const {
|
||||
return dataset.GetTotalFlux();
|
||||
}
|
||||
|
||||
std::optional<float> DiffractionExperiment::GetBeamSizeX_um() const {
|
||||
return dataset.GetBeamSizeX_um();
|
||||
}
|
||||
|
||||
std::optional<float> DiffractionExperiment::GetBeamSizeY_um() const {
|
||||
return dataset.GetBeamSizeY_um();
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::Goniometer(const std::optional<GoniometerAxis> &input) {
|
||||
dataset.Goniometer(input);
|
||||
return *this;
|
||||
|
||||
Reference in New Issue
Block a user