* Enhancements for XFEL

* Enhancements for EIGER
* Writer is more flexible and capable of handling DECTRIS data
This commit is contained in:
2024-03-05 20:41:47 +01:00
parent 71d862b706
commit d315506633
165 changed files with 5440 additions and 2230 deletions
+85 -46
View File
@@ -18,6 +18,8 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : d
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";
@@ -35,6 +37,8 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : d
dataset.save_calibration = false;
dataset.omega_rotation_axis = default_omega_axis;
dataset.photon_energy_multiplier = 1.0f;
internal_fpga_packet_generator = false;
debug_pixel_mask = false;
@@ -73,6 +77,7 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup) : d
series_id = 0;
conversion_on_fpga = true;
pulsed_source = false;
Mode(DetectorMode::Conversion);
}
@@ -315,17 +320,17 @@ int64_t DiffractionExperiment::GetNumTriggers() const {
case DetectorMode::Raw:
return dataset.ntrigger;
case DetectorMode::PedestalG0:
if (GetPedestalWithExternalTrigger())
if (IsPulsedSource())
return pedestal_g0_frames;
else
return 1;
case DetectorMode::PedestalG1:
if (GetPedestalWithExternalTrigger())
if (IsPulsedSource())
return pedestal_g1_frames;
else
return 1;
case DetectorMode::PedestalG2:
if (GetPedestalWithExternalTrigger())
if (IsPulsedSource())
return pedestal_g2_frames;
else
return 1;
@@ -382,8 +387,6 @@ int64_t DiffractionExperiment::GetImageNumPerTrigger() const {
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
case DetectorMode::Raw:
if (GetStorageCellNumber() > 1)
return GetStorageCellNumber();
return GetFrameNumPerTrigger() / GetSummation();
case DetectorMode::PedestalG0:
case DetectorMode::PedestalG1:
@@ -398,24 +401,17 @@ int64_t DiffractionExperiment::GetFrameNum() const {
}
int64_t DiffractionExperiment::GetFrameNumPerTrigger() const {
if (IsPulsedSource())
return GetStorageCellNumber() * GetSummation();
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
case DetectorMode::Raw:
if (GetStorageCellNumber() > 1)
return GetStorageCellNumber();
else
return dataset.images_per_trigger * GetSummation();
return dataset.images_per_trigger * GetSummation();
case DetectorMode::PedestalG0:
if (GetPedestalWithExternalTrigger())
return GetStorageCellNumber();
return pedestal_g0_frames * GetStorageCellNumber();
case DetectorMode::PedestalG1:
if (GetPedestalWithExternalTrigger())
return GetStorageCellNumber();
return pedestal_g1_frames * GetStorageCellNumber();
case DetectorMode::PedestalG2:
if (GetPedestalWithExternalTrigger())
return GetStorageCellNumber();
return pedestal_g2_frames * GetStorageCellNumber();
default:
return 0;
@@ -512,7 +508,8 @@ bool DiffractionExperiment::IsPixelSigned() const {
return false;
default:
case FPGAPixelOutput::Auto:
if (GetDetectorMode() == DetectorMode::Conversion)
if ((GetDetectorMode() == DetectorMode::Conversion)
&& (detector.GetDetectorType() == DetectorType::JUNGFRAU))
return true;
else
return false;
@@ -577,12 +574,15 @@ int64_t DiffractionExperiment::GetPixel0OfModule(uint16_t module_number) const {
int64_t DiffractionExperiment::GetOverflow() const {
if (GetPixelDepth() == 2)
return INT16_MAX;
return IsPixelSigned() ? INT16_MAX : UINT16_MAX;
else
return INT32_MAX;
return IsPixelSigned() ? INT32_MAX : UINT32_MAX;
}
int64_t DiffractionExperiment::GetUnderflow() const {
if (!IsPixelSigned())
return -1;
if (GetPixelDepth() == 2)
return INT16_MIN;
else
@@ -590,11 +590,10 @@ int64_t DiffractionExperiment::GetUnderflow() const {
}
std::chrono::microseconds DiffractionExperiment::GetPreviewPeriod() const {
return preview_period;
}
int64_t DiffractionExperiment::GetPreviewStride() const {
return GetPreviewStride(GetPreviewPeriod());
if (GetDetectorMode() == DetectorMode::Conversion)
return preview_period;
else
return std::chrono::microseconds(0);
}
int64_t DiffractionExperiment::GetSpotFindingBin() const {
@@ -604,15 +603,6 @@ int64_t DiffractionExperiment::GetSpotFindingBin() const {
return 200*1000 / GetImageTime().count(); // 1 bin = 1 second
}
int64_t DiffractionExperiment::GetPreviewStride(std::chrono::microseconds period) const {
switch (GetDetectorMode()) {
case DetectorMode::Conversion:
return CalculateStride(GetImageTime(), period);
default:
return 0;
}
}
bool DiffractionExperiment::IsUsingInternalPacketGen() const {
return internal_fpga_packet_generator;
}
@@ -620,10 +610,10 @@ bool DiffractionExperiment::IsUsingInternalPacketGen() const {
uint32_t DiffractionExperiment::GetSrcIPv4Address(uint32_t data_stream, uint32_t half_module) const {
if (data_stream >= GetDataStreamsNum())
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Non existing data stream");
if (half_module >= 2 * GetModulesNum(data_stream))
if (half_module >= detector.GetUDPInterfaceCount() * GetModulesNum(data_stream))
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Non existing module");
uint32_t host = half_module + 2 * GetFirstModuleOfDataStream(data_stream);
uint32_t host = half_module + detector.GetUDPInterfaceCount() * GetFirstModuleOfDataStream(data_stream);
return ipv4_base_addr + (host << 24);
}
@@ -747,8 +737,6 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
message.pixel_size_y = GetPixelSize_mm() * 1e-3f;
message.sensor_material = detector.GetSensorMaterial();
message.sensor_thickness = detector.GetSensorThickness_um() * 1e-6f;
message.compression_algorithm = GetCompressionAlgorithm();
message.compression_block_size = JFJochBitShuffleCompressor::DefaultBlockSize;
message.pixel_bit_depth = GetPixelDepth() * 8;
message.storage_cell_number = GetStorageCellNumber();
message.storage_cell_delay_ns = GetStorageCellDelay().count();
@@ -776,12 +764,19 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
message.user_data = GetHeaderAppendix();
message.roi_summation_area = GetROISummation();
message.countrate_correction_enabled = false;
message.flatfield_enabled = false;
if (GetOmegaStep())
message.goniometer["omega"] = GoniometerAxis{.increment = GetOmegaStep().value(), .start = GetOmegaStart(),
.axis = {GetOmegaAxis().x, GetOmegaAxis().y, GetOmegaAxis().z}};
message.omega = GoniometerAxis{.increment = GetOmegaStep().value(), .start = GetOmegaStart(),
.axis = {GetOmegaAxis().x, GetOmegaAxis().y, GetOmegaAxis().z}};
else
message.omega = GoniometerAxis{.increment = 0.0f};
message.series_id = GetSeriesID();
message.series_unique_id = GetSeriesIDString();
message.gain_file_names = detector.GetGainFileNames();
}
DiffractionExperiment &DiffractionExperiment::ApplyPixelMaskInFPGA(bool input) {
@@ -858,10 +853,6 @@ std::string DiffractionExperiment::GetDetectorDescription() const {
return detector.GetDescription();
}
bool DiffractionExperiment::GetPedestalWithExternalTrigger() const {
return (GetStorageCellNumber() > 1);
}
DiffractionExperiment &DiffractionExperiment::ApplySolidAngleCorr(bool input) {
dataset.rad_int_solid_angle_corr = input;
return *this;
@@ -961,8 +952,13 @@ DiffractionExperiment::GetDetectorModuleConfig(const std::vector<AcquisitionDevi
DetectorModuleConfig mod_cfg;
mod_cfg.udp_dest_port_1 = net_config[d].udp_port;
mod_cfg.udp_dest_port_2 = net_config[d].udp_port;
mod_cfg.ipv4_src_addr_1 = IPv4AddressToStr(GetSrcIPv4Address(d, 2 * m));
mod_cfg.ipv4_src_addr_2 = IPv4AddressToStr(GetSrcIPv4Address(d, 2 * m + 1));
if (detector.GetUDPInterfaceCount() == 2) {
mod_cfg.ipv4_src_addr_1 = IPv4AddressToStr(GetSrcIPv4Address(d, 2 * m));
mod_cfg.ipv4_src_addr_2 = IPv4AddressToStr(GetSrcIPv4Address(d, 2 * m + 1));
} else {
mod_cfg.ipv4_src_addr_1 = IPv4AddressToStr(GetSrcIPv4Address(d, m));
mod_cfg.ipv4_src_addr_2 = IPv4AddressToStr(GetSrcIPv4Address(d, m)); // not used, settings just in case
}
mod_cfg.ipv4_dest_addr_1 = net_config[d].ipv4_addr;
mod_cfg.ipv4_dest_addr_2 = net_config[d].ipv4_addr;
mod_cfg.mac_addr_dest_1 = net_config[d].mac_addr;
@@ -1008,7 +1004,7 @@ DiffractionExperiment &DiffractionExperiment::OmegaStep(const std::optional<floa
return *this;
}
DiffractionExperiment &DiffractionExperiment::OmegaStart(const float input) {
DiffractionExperiment &DiffractionExperiment::OmegaStart(float input) {
dataset.omega_start = input;
return *this;
}
@@ -1129,7 +1125,8 @@ DiffractionExperiment &DiffractionExperiment::ConversionOnFPGA(bool input) {
}
bool DiffractionExperiment::IsConversionOnFPGA() const {
if (GetDetectorMode() == DetectorMode::Conversion)
if ((GetDetectorMode() == DetectorMode::Conversion)
&& (detector.GetDetectorType() == DetectorType::JUNGFRAU))
return conversion_on_fpga;
else
return false;
@@ -1156,3 +1153,45 @@ DiffractionExperiment &DiffractionExperiment::NeuralNetModelPath(const std::stri
std::string DiffractionExperiment::GetNeuralNetModelPath() const {
return neural_net_model_path;
}
DiffractionExperiment &DiffractionExperiment::PulsedSource(bool input) {
pulsed_source = input;
return *this;
}
bool DiffractionExperiment::IsPulsedSource() const {
if (GetStorageCellNumber() > 1)
return true;
else
return pulsed_source;
}
bool DiffractionExperiment::IsSpotFindingEnabled() const {
if (GetDetectorMode() == DetectorMode::Conversion)
return true;
else
return false;
}
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;
return *this;
}
float DiffractionExperiment::GetPhotonEnergyForConversion_keV() const {
return GetPhotonEnergyMultiplier() * GetPhotonEnergy_keV();
}
float DiffractionExperiment::GetPhotonEnergyMultiplier() const {
if ((GetDetectorSetup().GetDetectorType() == DetectorType::JUNGFRAU)
&& (GetDetectorMode() == DetectorMode::Conversion))
return dataset.photon_energy_multiplier;
else
return 1.0f;
}