Updates March 2023

This commit is contained in:
2024-03-14 20:26:03 +01:00
parent affb8d1380
commit 59aacf516d
59 changed files with 1637 additions and 792 deletions

View File

@@ -1,6 +1,7 @@
// Copyright (2019-2023) Paul Scherrer Institute
#include <cmath>
#include <utility>
#include "NetworkAddressConvert.h"
#include "JFJochCompressor.h" // For ZSTD_USE_JFJOCH_RLE
@@ -10,36 +11,18 @@
#define check_max(param, val, max) if ((val) > (max)) throw JFJochException(JFJochExceptionCategory::InputParameterAboveMax, param)
#define check_min(param, val, min) if ((val) < (min)) throw JFJochException(JFJochExceptionCategory::InputParameterBelowMin, param)
#define check_finite(param, val) if (!std::isfinite(val)) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, param)
DiffractionExperiment::DiffractionExperiment() : DiffractionExperiment(DetectorGeometry(8, 2)) {}
DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : detector(det_setup) {
default_omega_axis = {1, 0, 0};
dataset.photon_energy_keV = WVL_1A_IN_KEV;
dataset.detector_distance_mm = 100;
dataset.beam_x_pxl = 0.0;
dataset.beam_y_pxl = 0.0;
dataset.data_file_count = 1;
dataset.file_prefix = "test";
dataset.ntrigger = 1;
dataset.images_per_trigger = 1;
dataset.summation = 1;
dataset.fpga_pixel_output = FPGAPixelOutput::Auto;
dataset.space_group_number = 0; // not set
dataset.compression = CompressionAlgorithm::BSHUF_LZ4;
dataset.rad_int_polarization_corr = false;
dataset.rad_int_solid_angle_corr = true;
dataset.save_calibration = false;
dataset.omega_rotation_axis = default_omega_axis;
dataset.photon_energy_multiplier = 1.0f;
rad_int_polarization_corr = false;
rad_int_solid_angle_corr = true;
internal_fpga_packet_generator = false;
internal_fpga_packet_generator_images = 1;
debug_pixel_mask = false;
@@ -79,7 +62,7 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : d
conversion_on_fpga = true;
pulsed_source = false;
Mode(DetectorMode::Conversion);
mode = DetectorMode::Conversion;
}
// setter functions
@@ -101,16 +84,12 @@ DiffractionExperiment &DiffractionExperiment::DataStreams(int64_t input) {
}
DiffractionExperiment &DiffractionExperiment::ImagesPerTrigger(int64_t input) {
check_max("Total number of images", input, 10*1000*1000);
check_min("Total number of images", input, 0);
dataset.images_per_trigger = input;
dataset.ImagesPerTrigger(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::NumTriggers(int64_t input) {
check_max("Total number of triggers", input, 10*1000*1000);
check_min("Total number of triggers", input, 1);
dataset.ntrigger = input;
dataset.NumTriggers(input);
return *this;
}
@@ -158,51 +137,32 @@ DiffractionExperiment &DiffractionExperiment::PedestalG2Frames(int64_t input) {
DiffractionExperiment &DiffractionExperiment::PhotonEnergy_keV(float input) {
check_min("Energy (keV)", input, MIN_ENERGY);
check_max("Energy (keV)", input, MAX_ENERGY);
dataset.photon_energy_keV = input;
dataset.PhotonEnergy_keV(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::BeamX_pxl(float input) {
dataset.beam_x_pxl = input;
dataset.BeamX_pxl(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::BeamY_pxl(float input) {
dataset.beam_y_pxl = input;
dataset.BeamY_pxl(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::DetectorDistance_mm(float input) {
check_min("Detector distance (mm)", input, 1);
dataset.detector_distance_mm = input;
dataset.DetectorDistance_mm(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::FilePrefix(std::string input) {
// File prefix with front slash is not allowed for security reasons
if (input.front() == '/')
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Path cannot start with slash");
if (input.substr(0,3) == "../")
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Path cannot start with ../");
if (input.find("/../") != std::string::npos)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Path cannot contain /../");
if ((input.find("_master.h5") == input.length() - 10) && (input.length() > 10))
dataset.file_prefix = input.substr(0, input.length() - 10);
else
dataset.file_prefix = input;
dataset.FilePrefix(std::move(input));
return *this;
}
DiffractionExperiment &DiffractionExperiment::DataFileCount(int64_t input) {
check_min("File count", input, 1);
check_max("File count", input, 1000);
dataset.data_file_count = input;
dataset.DataFileCount(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::UseInternalPacketGenerator(bool input) {
@@ -221,16 +181,7 @@ DiffractionExperiment &DiffractionExperiment::MaskModuleEdges(bool input) {
}
DiffractionExperiment &DiffractionExperiment::Compression(CompressionAlgorithm input) {
switch (input) {
case CompressionAlgorithm::NO_COMPRESSION:
case CompressionAlgorithm::BSHUF_LZ4:
case CompressionAlgorithm::BSHUF_ZSTD:
case CompressionAlgorithm::BSHUF_ZSTD_RLE:
dataset.compression = input;
break;
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Invalid value for enum parameter");
}
dataset.Compression(input);
return *this;
}
@@ -240,6 +191,7 @@ DiffractionExperiment &DiffractionExperiment::MaskChipEdges(bool input) {
}
DiffractionExperiment& DiffractionExperiment::LowResForAzimInt_A(float input) {
check_finite("Low Resolution for azimuthal integration", input);
check_min("Low Resolution for azimuthal integration", input, 0.1);
check_max("Low Resolution for azimuthal integration", input, 500.0);
low_q = 2 * static_cast<float>(M_PI) / input;
@@ -247,6 +199,7 @@ DiffractionExperiment& DiffractionExperiment::LowResForAzimInt_A(float input) {
}
DiffractionExperiment& DiffractionExperiment::HighResForAzimInt_A(float input) {
check_finite("High Resolution for azimuthal integration", input);
check_min("High Resolution for azimuthal integration", input, 0.1);
check_max("High Resolution for azimuthal integration", input, 500.0);
high_q = 2 * static_cast<float>(M_PI) / input;
@@ -254,6 +207,7 @@ DiffractionExperiment& DiffractionExperiment::HighResForAzimInt_A(float input) {
}
DiffractionExperiment& DiffractionExperiment::LowQForAzimInt_recipA(float input) {
check_finite("Low Q for azimuthal integration", input);
check_min("Low Q for azimuthal integration", input, 0.001);
check_max("Low Q for azimuthal integration", input, 10.0);
low_q = input;
@@ -261,6 +215,7 @@ DiffractionExperiment& DiffractionExperiment::LowQForAzimInt_recipA(float input)
}
DiffractionExperiment& DiffractionExperiment::HighQForAzimInt_recipA(float input) {
check_finite("High Q for azimuthal integration", input);
check_min("High Q for azimuthal integration", input, 0.001);
check_max("High Q for azimuthal integration", input, 10.0);
high_q = input;
@@ -268,13 +223,14 @@ DiffractionExperiment& DiffractionExperiment::HighQForAzimInt_recipA(float input
}
DiffractionExperiment& DiffractionExperiment::QSpacingForAzimInt_recipA(float input) {
check_finite("Q spacing for azimuthal integration", input);
check_min("Q spacing for azimuthal integration", input, 0.01);
q_spacing = input;
return *this;
}
DiffractionExperiment &DiffractionExperiment::SetUnitCell(const std::optional<UnitCell> &cell) {
dataset.unit_cell = cell;
dataset.SetUnitCell(cell);
return *this;
}
@@ -285,9 +241,7 @@ DiffractionExperiment &DiffractionExperiment::PreviewPeriod(std::chrono::microse
}
DiffractionExperiment &DiffractionExperiment::SpaceGroupNumber(int64_t input) {
check_min("Space group number", input, 0);
check_max("Space group number", input, 230);
dataset.space_group_number = input;
dataset.SpaceGroupNumber(input);
return *this;
}
@@ -309,7 +263,7 @@ DiffractionExperiment &DiffractionExperiment::StorageCellStart(int64_t input) {
}
DiffractionExperiment &DiffractionExperiment::SampleName(std::string input) {
dataset.sample_name = input;
dataset.SampleName(input);
return *this;
}
@@ -318,7 +272,7 @@ int64_t DiffractionExperiment::GetNumTriggers() const {
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
case DetectorMode::Raw:
return dataset.ntrigger;
return dataset.GetNumTriggers();
case DetectorMode::PedestalG0:
if (IsPulsedSource())
return pedestal_g0_frames;
@@ -406,7 +360,7 @@ int64_t DiffractionExperiment::GetFrameNumPerTrigger() const {
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
case DetectorMode::Raw:
return dataset.images_per_trigger * GetSummation();
return dataset.GetImageNumPerTrigger() * GetSummation();
case DetectorMode::PedestalG0:
return pedestal_g0_frames * GetStorageCellNumber();
case DetectorMode::PedestalG1:
@@ -427,50 +381,56 @@ std::chrono::microseconds DiffractionExperiment::GetImageCountTime() const {
}
int64_t DiffractionExperiment::GetPedestalG0Frames() const {
if (detector.GetDetectorType() == DetectorType::EIGER)
return 0;
return pedestal_g0_frames;
}
int64_t DiffractionExperiment::GetPedestalG1Frames() const {
if (detector.GetDetectorType() == DetectorType::EIGER)
return 0;
return pedestal_g1_frames;
}
int64_t DiffractionExperiment::GetPedestalG2Frames() const {
if (detector.GetDetectorType() == DetectorType::EIGER)
return 0;
return pedestal_g2_frames;
}
float DiffractionExperiment::GetPhotonEnergy_keV() const {
return dataset.photon_energy_keV;
return dataset.GetPhotonEnergy_keV();
}
float DiffractionExperiment::GetWavelength_A() const {
return WVL_1A_IN_KEV / dataset.photon_energy_keV;
return WVL_1A_IN_KEV / dataset.GetPhotonEnergy_keV();
}
float DiffractionExperiment::GetBeamX_pxl() const {
return dataset.beam_x_pxl;
return dataset.GetBeamX_pxl();
}
float DiffractionExperiment::GetBeamY_pxl() const {
return dataset.beam_y_pxl;
return dataset.GetBeamY_pxl();
}
float DiffractionExperiment::GetDetectorDistance_mm() const {
return dataset.detector_distance_mm;
return dataset.GetDetectorDistance_mm();
}
Coord DiffractionExperiment::GetScatteringVector() const {
return {0,0,dataset.photon_energy_keV / WVL_1A_IN_KEV};
return dataset.GetScatteringVector();
}
std::string DiffractionExperiment::GetFilePrefix() const {
return dataset.file_prefix;
return dataset.GetFilePrefix();
}
int64_t DiffractionExperiment::GetDataFileCount() const {
if (GetStorageCellNumber() > 1)
return GetStorageCellNumber();
else
return dataset.data_file_count;
return dataset.GetDataFileCount();
}
CompressionAlgorithm DiffractionExperiment::GetCompressionAlgorithm() const {
@@ -478,7 +438,7 @@ CompressionAlgorithm DiffractionExperiment::GetCompressionAlgorithm() const {
// Compression not supported for raw data and pedestal
return CompressionAlgorithm::NO_COMPRESSION;
return dataset.compression;
return dataset.GetCompressionAlgorithm();
}
int64_t DiffractionExperiment::GetPixelDepth() const {
@@ -640,7 +600,7 @@ bool DiffractionExperiment::GetMaskChipEdges() const {
}
std::optional<UnitCell> DiffractionExperiment::GetUnitCell() const {
return dataset.unit_cell;
return dataset.GetUnitCell();
}
Coord DiffractionExperiment::LabCoord(float detector_x, float detector_y) const {
@@ -651,7 +611,7 @@ Coord DiffractionExperiment::LabCoord(float detector_x, float detector_y) const
}
int64_t DiffractionExperiment::GetSpaceGroupNumber() const {
return dataset.space_group_number;
return dataset.GetSpaceGroupNumber();
}
int64_t DiffractionExperiment::GetStorageCellNumber() const {
@@ -687,7 +647,7 @@ int64_t DiffractionExperiment::GetMaxSpotCount() const {
}
std::string DiffractionExperiment::GetSampleName() const {
return dataset.sample_name;
return dataset.GetSampleName();
}
void DiffractionExperiment::CheckDataProcessingSettings(const SpotFindingSettings &settings) {
@@ -854,39 +814,42 @@ std::string DiffractionExperiment::GetDetectorDescription() const {
}
DiffractionExperiment &DiffractionExperiment::ApplySolidAngleCorr(bool input) {
dataset.rad_int_solid_angle_corr = input;
rad_int_solid_angle_corr = input;
return *this;
}
DiffractionExperiment &DiffractionExperiment::ApplyPolarizationCorr(bool input) {
dataset.rad_int_polarization_corr = input;
rad_int_polarization_corr = input;
return *this;
}
DiffractionExperiment &DiffractionExperiment::PolarizationFactor(float input) {
dataset.rad_int_polarization_factor = input;
check_finite("Polarization factor", input);
check_min("Polarization factor", input, -1.0);
check_max("Polarization factor", input, 1.0);
rad_int_polarization_factor = input;
return *this;
}
bool DiffractionExperiment::GetApplySolidAngleCorr() const {
return dataset.rad_int_solid_angle_corr;
return rad_int_solid_angle_corr;
}
bool DiffractionExperiment::GetApplyPolarizationCorr() const {
return dataset.rad_int_polarization_corr;
return rad_int_polarization_corr;
}
float DiffractionExperiment::GetPolarizationFactor() const {
return dataset.rad_int_polarization_factor;
return rad_int_polarization_factor;
}
DiffractionExperiment &DiffractionExperiment::SaveCalibration(bool input) {
dataset.save_calibration = input;
dataset.SaveCalibration(input);
return *this;
}
bool DiffractionExperiment::GetSaveCalibration() const {
return dataset.save_calibration;
return dataset.GetSaveCalibration();
}
DiffractionExperiment &DiffractionExperiment::StorageCellDelay(std::chrono::nanoseconds input) {
@@ -900,9 +863,7 @@ std::chrono::nanoseconds DiffractionExperiment::GetStorageCellDelay() const {
}
DiffractionExperiment &DiffractionExperiment::Summation(int64_t input) {
check_min("Summation", input, 1);
check_max("Summation", input, MAX_FPGA_SUMMATION);
dataset.summation = input;
dataset.Summation(input);
return *this;
}
@@ -916,28 +877,18 @@ int64_t DiffractionExperiment::GetSummation() const {
case DetectorMode::Conversion:
case DetectorMode::Raw:
// FPGA summation for raw data makes zero sense - but it is still available as a means for debug, etc.
return dataset.summation;
return dataset.GetSummation();
}
}
DiffractionExperiment &DiffractionExperiment::FPGAOutputMode(FPGAPixelOutput input) {
switch (input) {
case FPGAPixelOutput::Auto:
case FPGAPixelOutput::Int16:
case FPGAPixelOutput::Uint16:
case FPGAPixelOutput::Int32:
case FPGAPixelOutput::Uint32:
dataset.fpga_pixel_output = input;
break;
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Invalid value for enum parameter");
}
dataset.FPGAOutputMode(input);
return *this;
}
FPGAPixelOutput DiffractionExperiment::GetFPGAOutputMode() const {
return dataset.fpga_pixel_output;
return dataset.GetFPGAOutputMode();
}
int64_t DiffractionExperiment::GetUDPInterfaceCount() const {
@@ -979,42 +930,39 @@ float DiffractionExperiment::GetHighQForBkgEstimate_recipA() const {
}
DiffractionExperiment &DiffractionExperiment::AttenuatorTransmission(const std::optional<float> &input) {
dataset.attenuator_transmission = input;
dataset.AttenuatorTransmission(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::TotalFlux(const std::optional<float> &input) {
dataset.total_flux = input;
dataset.TotalFlux(input);
return *this;
}
std::optional<float> DiffractionExperiment::GetAttenuatorTransmission() const {
return dataset.attenuator_transmission;
return dataset.GetAttenuatorTransmission();
}
std::optional<float> DiffractionExperiment::GetTotalFlux() const {
return dataset.total_flux;
return dataset.GetTotalFlux();
}
DiffractionExperiment &DiffractionExperiment::OmegaStep(const std::optional<float> &input) {
if (input && (input == 0.0f))
dataset.omega_step.reset();
else
dataset.omega_step = input;
dataset.OmegaStep(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::OmegaStart(float input) {
dataset.omega_start = input;
dataset.OmegaStart(input);
return *this;
}
std::optional<float> DiffractionExperiment::GetOmegaStep() const {
return dataset.omega_step;
return dataset.GetOmegaStep();
}
float DiffractionExperiment::GetOmegaStart() const {
return dataset.omega_start;
return dataset.GetOmegaStart();
}
DiffractionExperiment &DiffractionExperiment::UsingGainHG0(bool input) {
@@ -1036,38 +984,39 @@ bool DiffractionExperiment::IsUsingGainHG0() const {
}
DiffractionExperiment &DiffractionExperiment::HeaderAppendix(const std::string &input) {
dataset.header_appendix = input;
dataset.HeaderAppendix(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::ImageAppendix(const std::string &input) {
dataset.image_appendix = input;
dataset.ImageAppendix(input);
return *this;
}
std::string DiffractionExperiment::GetHeaderAppendix() const {
return dataset.header_appendix;
return dataset.GetHeaderAppendix();
}
std::string DiffractionExperiment::GetImageAppendix() const {
return dataset.image_appendix;
return dataset.GetImageAppendix();
}
DiffractionExperiment &DiffractionExperiment::OmegaAxis(const Coord &c) {
if (c.Length() == 0.0)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Cannot use empty vector for omega");
dataset.omega_rotation_axis = c.Normalize();
dataset.OmegaAxis(c);
return *this;
}
DiffractionExperiment &DiffractionExperiment::OmegaAxis() {
dataset.omega_rotation_axis = default_omega_axis;
dataset.OmegaAxis({});
return *this;
}
Coord DiffractionExperiment::GetOmegaAxis() const {
return dataset.omega_rotation_axis;
auto tmp = dataset.GetOmegaAxis();
if (tmp)
return tmp.value();
else
return default_omega_axis;
}
DiffractionExperiment &DiffractionExperiment::DefaultOmegaAxis(const Coord &c) {
@@ -1087,7 +1036,7 @@ uint64_t DiffractionExperiment::GetSeriesID() const {
}
std::string DiffractionExperiment::GetSeriesIDString() const {
return std::to_string(series_id) + ": " + dataset.file_prefix;
return std::to_string(series_id) + ": " + dataset.GetFilePrefix();
}
DiffractionExperiment &DiffractionExperiment::IncrementSeriesID() {
@@ -1104,19 +1053,12 @@ Coord DiffractionExperiment::GetModuleSlowDirection(uint16_t module_number) cons
}
DiffractionExperiment &DiffractionExperiment::ROISummation(const std::optional<ROIRectangle> &input) {
if (input) {
check_max("Max X for ROI summation", input->x_max, GetXPixelsNum() - 1);
check_max("Max Y for ROI summation", input->y_max, GetYPixelsNum() - 1);
check_max("Min X for ROI summation", input->x_min, input->x_max);
check_max("Min Y for ROI summation", input->y_min, input->y_max);
}
dataset.roi_sum = input;
dataset.ROISummation(input);
return *this;
}
std::optional<ROIRectangle> DiffractionExperiment::GetROISummation() const {
return dataset.roi_sum;
return dataset.GetROISummation();
}
DiffractionExperiment &DiffractionExperiment::ConversionOnFPGA(bool input) {
@@ -1174,13 +1116,7 @@ bool DiffractionExperiment::IsSpotFindingEnabled() const {
}
DiffractionExperiment &DiffractionExperiment::PhotonEnergyMultiplayer(float input) {
check_min("Photon energy multiplier", input, 1/64.f);
check_max("Photon energy multiplier", input, 4.f);
if ((GetDetectorSetup().GetDetectorType() == DetectorType::EIGER)
&& (input != 1.0f))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"For EIGER cannot set photon energy multiplier");
dataset.photon_energy_multiplier = input;
dataset.PhotonEnergyMultiplayer(input);
return *this;
}
@@ -1191,7 +1127,27 @@ float DiffractionExperiment::GetPhotonEnergyForConversion_keV() const {
float DiffractionExperiment::GetPhotonEnergyMultiplier() const {
if ((GetDetectorSetup().GetDetectorType() == DetectorType::JUNGFRAU)
&& (GetDetectorMode() == DetectorMode::Conversion))
return dataset.photon_energy_multiplier;
return dataset.GetPhotonEnergyMultiplier();
else
return 1.0f;
}
DiffractionExperiment &DiffractionExperiment::InternalPacketGeneratorImages(int64_t input) {
check_min("Internal packet generator images", input, 1);
check_max("Internal packet generator images", input, 128);
internal_fpga_packet_generator_images = input;
return *this;
}
int64_t DiffractionExperiment::GetInternalPacketGeneratorImages() const {
return internal_fpga_packet_generator_images;
}
DiffractionExperiment &DiffractionExperiment::ImportDatasetSettings(const DatasetSettings &input) {
dataset = input;
return *this;
}
DatasetSettings DiffractionExperiment::GetDatasetSettings() const {
return dataset;
}