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

@@ -291,6 +291,7 @@ void AcquisitionDevice::RunInternalGenerator(const DiffractionExperiment &experi
config.debug = INT_PKT_GEN_DEBUG;
config.dest_mac_addr = MacAddressFromStr(GetMACAddress());
config.dest_ipv4_addr = IPv4AddressFromStr(GetIPv4Address());
config.images_in_memory = experiment.GetInternalPacketGeneratorImages() - 1;
switch (experiment.GetDetectorSetup().GetDetectorType()) {
case DetectorType::JUNGFRAU:
config.detector_type = SLS_DETECTOR_TYPE_JUNGFRAU;

View File

@@ -85,10 +85,12 @@ inline DetectorSettings Convert(const org::openapitools::server::model::Detector
ret.pedestal_g1_frames = input.getPedestalG1Frames();
if (input.pedestalG2FramesIsSet())
ret.pedestal_g2_frames = input.getPedestalG2Frames();
if (input.storageCellDelayNsIsSet())
ret.storage_cell_delay_ns = input.getStorageCellDelayNs();
if (input.detectorTriggerDelayNsIsSet())
ret.detector_delay_ns = input.getDetectorTriggerDelayNs();
if (input.storageCellDelayUsIsSet() && std::isfinite(input.getStorageCellDelayUs()))
ret.storage_cell_delay_ns = std::round(input.getStorageCellDelayUs() * 1000.0f);
if (input.detectorTriggerDelayUsIsSet() && std::isfinite(input.getDetectorTriggerDelayUs()))
ret.detector_delay_ns = std::round(input.getDetectorTriggerDelayUs() * 1000.0f);
if (input.internalFrameGeneratorImagesIsSet())
ret.internal_packet_generator_images = input.getInternalFrameGeneratorImages();
return ret;
}
@@ -97,20 +99,28 @@ inline org::openapitools::server::model::Detector_settings Convert(const Detecto
org::openapitools::server::model::Detector_settings ret{};
ret.setFrameTimeUs(input.frame_time_us);
ret.setCountTimeUs(input.count_time_us.value());
if (input.count_time_us)
ret.setCountTimeUs(input.count_time_us.value());
ret.setStorageCellCount(input.storage_cell_count);
ret.setInternalFrameGenerator(input.use_internal_packet_generator);
ret.setCollectRawData(input.collect_raw_data);
ret.setFixedGainG1(input.fixed_gain_g1);
ret.setUseGainHg0(input.use_gain_hg0);
ret.setPedestalG0Frames(input.pedestal_g0_frames.value());
ret.setPedestalG1Frames(input.pedestal_g1_frames.value());
ret.setPedestalG2Frames(input.pedestal_g2_frames.value());
ret.setStorageCellDelayNs(input.storage_cell_delay_ns.value());
ret.setDetectorTriggerDelayNs(input.detector_delay_ns.value());
if (input.pedestal_g0_frames)
ret.setPedestalG0Frames(input.pedestal_g0_frames.value());
if (input.pedestal_g1_frames)
ret.setPedestalG1Frames(input.pedestal_g1_frames.value());
if (input.pedestal_g2_frames)
ret.setPedestalG2Frames(input.pedestal_g2_frames.value());
if (input.storage_cell_delay_ns)
ret.setStorageCellDelayUs(static_cast<float>(input.storage_cell_delay_ns.value()) / 1000.0f);
if (input.detector_delay_ns)
ret.setDetectorTriggerDelayUs(static_cast<float>(input.detector_delay_ns.value()) / 1000.0f);
if (input.internal_packet_generator_images)
ret.setInternalFrameGeneratorImages(input.internal_packet_generator_images.value());
return ret;
}
@@ -276,92 +286,91 @@ inline org::openapitools::server::model::Preview_settings Convert(const PreviewJ
inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_settings& input) {
DatasetSettings ret;
ret.images_per_trigger = input.getImagesPerTrigger();
ret.ntrigger = input.ntriggerIsSet() ? input.getNtrigger() : 1;
ret.ImagesPerTrigger(input.getImagesPerTrigger());
ret.NumTriggers(input.getNtrigger());
if (!input.fpgaOutputIsSet())
ret.fpga_pixel_output = FPGAPixelOutput::Auto;
ret.FPGAOutputMode(FPGAPixelOutput::Auto);
else {
std::string out = str_tolower(input.getFpgaOutput());
if (out == "auto")
ret.fpga_pixel_output = FPGAPixelOutput::Auto;
ret.FPGAOutputMode(FPGAPixelOutput::Auto);
else if (out == "int16")
ret.fpga_pixel_output = FPGAPixelOutput::Int16;
ret.FPGAOutputMode(FPGAPixelOutput::Int16);
else if (out == "uint16")
ret.fpga_pixel_output = FPGAPixelOutput::Uint16;
ret.FPGAOutputMode(FPGAPixelOutput::Uint16);
else if (out == "int32")
ret.fpga_pixel_output = FPGAPixelOutput::Int32;
ret.FPGAOutputMode(FPGAPixelOutput::Int32);
else if (out == "uint32")
ret.fpga_pixel_output = FPGAPixelOutput::Uint32;
ret.FPGAOutputMode(FPGAPixelOutput::Uint32);
else
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown output format");
}
ret.summation = input.summationIsSet() ? input.getSummation() : 1;
ret.beam_x_pxl = input.getBeamXPxl();
ret.beam_y_pxl = input.getBeamYPxl();
ret.detector_distance_mm = input.getDetectorDistanceMm();
ret.photon_energy_keV = input.getPhotonEnergyKeV();
ret.Summation(input.getSummation());
ret.BeamX_pxl(input.getBeamXPxl());
ret.BeamY_pxl(input.getBeamYPxl());
ret.DetectorDistance_mm(input.getDetectorDistanceMm());
ret.PhotonEnergy_keV(input.getPhotonEnergyKeV());
ret.photon_energy_multiplier = input.getPhotonEnergyMultiplier();
ret.PhotonEnergyMultiplayer(input.getPhotonEnergyMultiplier());
ret.file_prefix = input.filePrefixIsSet() ? input.getFilePrefix() : "";
ret.data_file_count = input.dataFileCountIsSet() ? input.getDataFileCount() : 1;
ret.FilePrefix(input.getFilePrefix());
ret.DataFileCount(input.getDataFileCount());
if (!input.compressionIsSet())
ret.compression = CompressionAlgorithm::BSHUF_LZ4;
ret.Compression(CompressionAlgorithm::BSHUF_LZ4);
else {
std::string compr = str_tolower(input.getCompression());
if (compr == "bslz4")
ret.compression = CompressionAlgorithm::BSHUF_LZ4;
ret.Compression(CompressionAlgorithm::BSHUF_LZ4);
else if (compr == "bszstd")
ret.compression = CompressionAlgorithm::BSHUF_ZSTD;
ret.Compression(CompressionAlgorithm::BSHUF_ZSTD);
else if (compr == "bszstd_rle")
ret.compression = CompressionAlgorithm::BSHUF_ZSTD_RLE;
ret.Compression(CompressionAlgorithm::BSHUF_ZSTD_RLE);
else if (compr == "none")
ret.compression = CompressionAlgorithm::NO_COMPRESSION;
ret.Compression(CompressionAlgorithm::NO_COMPRESSION);
else
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown compression");
}
if (input.unitCellIsSet())
ret.unit_cell = UnitCell{
ret.SetUnitCell(UnitCell{
.a = input.getUnitCell().getA(),
.b = input.getUnitCell().getB(),
.c = input.getUnitCell().getC(),
.alpha = input.getUnitCell().getAlpha(),
.beta = input.getUnitCell().getBeta(),
.gamma = input.getUnitCell().getGamma()
};
});
if (input.totalFluxIsSet())
ret.total_flux = input.getTotalFlux();
ret.TotalFlux(input.getTotalFlux());
if (input.transmissionIsSet())
ret.attenuator_transmission = input.getTransmission();
ret.AttenuatorTransmission(input.getTransmission());
if (input.omegaIsSet()) {
ret.omega_step = input.getOmega().getStep();
ret.omega_start = input.getOmega().getStart();
ret.OmegaStep(input.getOmega().getStep());
ret.OmegaStart(input.getOmega().getStart());
if (input.getOmega().getVector().size() == 3) {
auto v = input.getOmega().getVector();
ret.omega_axis = Coord(v[0], v[1], v[2]);
} else
ret.omega_axis = Coord(0, 0, 0);
ret.OmegaAxis(Coord(v[0], v[1], v[2]));
}
}
if (input.roiSumAreaIsSet()) {
ret.roi_sum_area = ROIRectangle{
ret.ROISummation(ROIRectangle{
.x_min = static_cast<size_t>(input.getRoiSumArea().getXMin()),
.x_max = static_cast<size_t>(input.getRoiSumArea().getXMax()),
.y_min = static_cast<size_t>(input.getRoiSumArea().getYMin()),
.y_max = static_cast<size_t>(input.getRoiSumArea().getYMax())
};
});
}
ret.space_group_number = input.spaceGroupNumberIsSet() ? input.getSpaceGroupNumber() : 0;
ret.sample_name = input.getSampleName();
ret.header_appendix = input.getHeaderAppendix();
ret.image_appendix = input.getImageAppendix();
ret.save_calibration = input.saveCalibrationIsSet() && input.isSaveCalibration();
ret.SpaceGroupNumber(input.getSpaceGroupNumber());
ret.SampleName(input.getSampleName());
ret.HeaderAppendix(input.getHeaderAppendix());
ret.ImageAppendix(input.getImageAppendix());
ret.SaveCalibration(input.isSaveCalibration());
return ret;
}
@@ -712,3 +721,18 @@ void JFJochBrokerHttp::plot_resolution_estimate_histogram_get(Pistache::Http::Re
auto plot = state_machine.GetPlots(req);
ProcessOutput(Convert(plot), response);
}
void JFJochBrokerHttp::config_internal_generator_image_put(const Pistache::Rest::Request &request,
Pistache::Http::ResponseWriter &response) {
int64_t image_number = 0;
auto number_query = request.query().get("number");
if (number_query)
image_number = std::stoi(number_query.value());
if ((image_number < 0) || (image_number > 127))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "image_number must be in range 0-127");
state_machine.LoadInternalGeneratorImage(request.body().data(), request.body().size(), image_number);
logger.Info("Internal generator image #{} loaded", image_number);
response.send(Pistache::Http::Code::Ok);
}

View File

@@ -104,6 +104,8 @@ class JFJochBrokerHttp : public org::openapitools::server::api::DefaultApi {
void preview_jpeg_settings_put(const org::openapitools::server::model::Preview_settings &previewSettings,
Pistache::Http::ResponseWriter &response) override;
void config_internal_generator_image_put(const Pistache::Rest::Request &request,
Pistache::Http::ResponseWriter &response) override;
void GetStaticFile(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
std::pair<Pistache::Http::Code, std::string> handleOperationException(const std::exception &ex) const noexcept override;

View File

@@ -294,6 +294,9 @@ void ParseFacilityConfiguration(const nlohmann::json &input, const std::string&
experiment.DetectorDelay(GET_TIME(j, "detector_trigger_delay_us"));
experiment.FrameTime(GET_TIME(j, "frame_time_us"), GET_TIME(j, "count_time_us"));
experiment.PreviewPeriod(GET_TIME(j, "preview_period_us"));
experiment.UseInternalPacketGenerator(GET_BOOL(j, "internal_frame_generator", false));
if (experiment.IsUsingInternalPacketGen())
experiment.ConversionOnFPGA(false);
experiment.IPv4BaseAddr(GET_STR(j, "detector_ipv4"));
} else
@@ -306,22 +309,20 @@ void ParseAcquisitionDeviceGroup(const nlohmann::json &input, const std::string&
const auto &j = input[tag];
std::string dev_type = GET_STR(j, "type");
bool use_4x10g = GET_BOOL(j, "use_4x10g", false);
int64_t buffer_size = GET_I64(j, "buffer_size", 1024);
int64_t dev_count = GET_I64(j, "count", 1);
if ((dev_count < 1) || (dev_count > 8))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Device count must be between 1 to 8");
if ((buffer_size < 16) || (buffer_size > 65536))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Buffer size must be in range 16-65536");
if (dev_type == "pcie") {
for (int i = 0; i < dev_count; i++)
aq_devices.AddPCIeDevice("/dev/jfjoch" + std::to_string(i));
std::vector<std::string> devices = GET_STR_ARR(j, "devices");
if (devices.empty())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"At least one PCIe device must be provided");
for (auto &d: devices)
aq_devices.AddPCIeDevice(d);
} else if (dev_type == "hls") {
if (dev_count > 1)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Device count must be 1 for HLS");
int64_t buffer_size = GET_I64(j, "buffer_size", 1024);
if ((buffer_size < 16) || (buffer_size > 65536))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Buffer size must be in range 16-65536");
aq_devices.AddHLSDevice(buffer_size);
} else
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Device type unknown");

View File

@@ -30,12 +30,17 @@ void JFJochServices::Off() {
}
void JFJochServices::On(const DiffractionExperiment &x) {
logger.Info("Detector on");
if (x.IsUsingInternalPacketGen() || (receiver == nullptr)) {
detector.reset();
} else {
logger.Info("Detector on");
if (detector && (receiver != nullptr))
if (!detector)
detector = std::make_unique<DetectorWrapper>();
detector->Initialize(x, receiver->GetNetworkConfig());
logger.Info(" ... done");
logger.Info(" ... done");
}
}
JFJochServicesOutput JFJochServices::Stop() {
@@ -105,12 +110,6 @@ JFJochServices &JFJochServices::Receiver(JFJochReceiverService *input) {
return *this;
}
JFJochServices &JFJochServices::Detector() {
detector = std::make_unique<DetectorWrapper>();
logger.Info("Using detector service");
return *this;
}
std::optional<JFJochReceiverStatus> JFJochServices::GetReceiverStatus() {
if (receiver == nullptr)
return {};
@@ -174,3 +173,10 @@ void JFJochServices::ConfigureDetector(const DiffractionExperiment &experiment)
if (detector)
detector->Configure(experiment);
}
void JFJochServices::LoadInternalGeneratorImage(const DiffractionExperiment &experiment,
const std::vector<uint16_t> &image,
uint64_t image_number) {
if (receiver)
receiver->LoadInternalGeneratorImage(experiment, image, image_number);
}

View File

@@ -28,13 +28,15 @@ public:
void Cancel();
void Trigger();
void LoadInternalGeneratorImage(const DiffractionExperiment &experiment,
const std::vector<uint16_t> &image,
uint64_t image_number);
std::optional<JFJochReceiverStatus> GetReceiverStatus();
Plot GetPlots(const PlotRequest &request);
RadialIntegrationProfiles GetRadialIntegrationProfiles();
void SetSpotFindingSettings(const SpotFindingSettings &settings);
JFJochServices& Receiver(JFJochReceiverService *input);
JFJochServices& Detector();
std::optional<DetectorStatus> GetDetectorStatus() const;

View File

@@ -4,50 +4,6 @@
#include "JFJochStateMachine.h"
void LoadDatasetSettings(DiffractionExperiment& experiment, const DatasetSettings &settings) {
// Save DatasetSettings - if something goes wrong, restore old settings
auto tmp = experiment;
try {
if (experiment.IsPulsedSource() && (settings.images_per_trigger != 1))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"No point to set image_per_trigger for a pulsed source");
experiment.ImagesPerTrigger(settings.images_per_trigger);
experiment.NumTriggers(settings.ntrigger);
experiment.BeamX_pxl(settings.beam_x_pxl);
experiment.BeamY_pxl(settings.beam_y_pxl);
experiment.DetectorDistance_mm(settings.detector_distance_mm);
experiment.PhotonEnergy_keV(settings.photon_energy_keV);
experiment.PhotonEnergyMultiplayer(settings.photon_energy_multiplier);
experiment.FilePrefix(settings.file_prefix);
experiment.DataFileCount(settings.data_file_count);
experiment.SetUnitCell(settings.unit_cell);
experiment.AttenuatorTransmission(settings.attenuator_transmission);
experiment.TotalFlux(settings.total_flux);
experiment.SpaceGroupNumber(settings.space_group_number);
experiment.SampleName(settings.sample_name);
experiment.Compression(settings.compression);
experiment.SaveCalibration(settings.save_calibration);
experiment.OmegaStart(settings.omega_start).OmegaStep(settings.omega_step);
if (settings.omega_axis.Length() == 0.0f)
experiment.OmegaAxis();
else
experiment.OmegaAxis(settings.omega_axis);
experiment.ImageAppendix(settings.image_appendix);
experiment.HeaderAppendix(settings.header_appendix);
if (settings.summation == 0)
experiment.Summation(1);
else
experiment.Summation(settings.summation);
experiment.FPGAOutputMode(settings.fpga_pixel_output);
experiment.ROISummation(settings.roi_sum_area);
} catch (...) {
experiment = tmp;
throw;
}
}
void ApplyDetectorSettings(DiffractionExperiment& experiment, const DetectorSettings &settings) {
auto tmp = experiment;
try {
@@ -58,7 +14,10 @@ void ApplyDetectorSettings(DiffractionExperiment& experiment, const DetectorSett
experiment.FrameTime(std::chrono::microseconds(settings.frame_time_us));
experiment.StorageCells(settings.storage_cell_count);
experiment.UseInternalPacketGenerator(settings.use_internal_packet_generator);
// If internal packet generator is used --> no conversion on FPGA
experiment.ConversionOnFPGA(!settings.use_internal_packet_generator);
if (settings.collect_raw_data)
experiment.Mode(DetectorMode::Raw);
@@ -78,6 +37,8 @@ void ApplyDetectorSettings(DiffractionExperiment& experiment, const DetectorSett
experiment.StorageCellDelay(std::chrono::nanoseconds(settings.storage_cell_delay_ns.value()));
if (settings.detector_delay_ns)
experiment.DetectorDelay(std::chrono::nanoseconds(settings.detector_delay_ns.value()));
if (settings.internal_packet_generator_images)
experiment.InternalPacketGeneratorImages(settings.internal_packet_generator_images.value());
} catch (...) {
experiment = tmp;
throw;
@@ -345,9 +306,7 @@ void JFJochStateMachine::Start(const DatasetSettings& settings) {
if (measurement.valid())
measurement.get(); // In case measurement was running - clear thread
auto mod_settings = settings;
SetDatasetDefaults(mod_settings);
LoadDatasetSettings(experiment, mod_settings);
experiment.ImportDatasetSettings(settings);
ClearAndSetMeasurementStatistics();
@@ -373,13 +332,6 @@ void JFJochStateMachine::Start(const DatasetSettings& settings) {
}
}
void JFJochStateMachine::SetDatasetDefaults(DatasetSettings &settings) {
if (settings.detector_distance_mm <= 0)
settings.detector_distance_mm = 100.0;
if (settings.ntrigger <= 0)
settings.ntrigger = 1;
}
void JFJochStateMachine::WaitTillMeasurementDone() {
std::unique_lock<std::mutex> ul(m);
@@ -530,6 +482,7 @@ DetectorSettings JFJochStateMachine::GetDetectorSettings() const {
ret.detector_delay_ns = experiment.GetDetectorDelay().count();
ret.fixed_gain_g1 = experiment.IsFixedGainG1();
ret.use_gain_hg0 = experiment.IsUsingGainHG0();
ret.internal_packet_generator_images = experiment.GetInternalPacketGeneratorImages();
return ret;
}
@@ -717,3 +670,23 @@ std::string JFJochStateMachine::GetPreviewJPEG() const {
std::string JFJochStateMachine::GetPreviewTIFF(bool calibration) const {
return services.GetPreviewTIFF(calibration);
}
void JFJochStateMachine::LoadInternalGeneratorImage(const void *data, size_t size, uint64_t image_number) {
std::unique_lock<std::mutex> ul(m);
if (state != JFJochState::Idle)
throw WrongDAQStateException ("Can change internal generator image only when detector in Idle state");
if ((size != experiment.GetPixelsNum() * sizeof(uint16_t))
&& (size != experiment.GetModulesNum() * RAW_MODULE_SIZE * sizeof(uint16_t)))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Image size doesn't match current detector");
if (image_number >= experiment.GetInternalPacketGeneratorImages())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Image for internal generator out of bounds");
std::vector<uint16_t> image(size / sizeof(uint16_t));
memcpy(image.data(), data, size);
services.LoadInternalGeneratorImage(experiment, image, image_number);
}

View File

@@ -55,43 +55,6 @@ struct MeasurementStatistics {
float bkg_estimate;
};
struct DatasetSettings {
int64_t images_per_trigger;
int64_t ntrigger;
FPGAPixelOutput fpga_pixel_output;
int64_t summation;
float beam_x_pxl;
float beam_y_pxl;
float detector_distance_mm;
float photon_energy_keV;
float photon_energy_multiplier;
std::string file_prefix;
int64_t data_file_count;
CompressionAlgorithm compression;
std::string sample_name;
std::optional<UnitCell> unit_cell;
int64_t space_group_number;
bool save_calibration;
std::optional<float> total_flux;
std::optional<float> attenuator_transmission;
std::optional<float> omega_step;
float omega_start;
Coord omega_axis;
std::string image_appendix;
std::string header_appendix;
std::optional<ROIRectangle> roi_sum_area;
};
struct DetectorSettings {
int64_t frame_time_us;
std::optional<int64_t> count_time_us;
@@ -107,6 +70,7 @@ struct DetectorSettings {
std::optional<int64_t> storage_cell_delay_ns;
std::optional<int64_t> detector_delay_ns;
std::optional<int64_t> internal_packet_generator_images;
};
@@ -118,8 +82,6 @@ struct RadialIntegrationSettings {
float q_spacing;
};
void LoadDatasetSettings(DiffractionExperiment& experiment, const DatasetSettings &settings);
class JFJochStateMachine {
Logger &logger;
JFJochServices &services;
@@ -156,7 +118,6 @@ class JFJochStateMachine {
PreviewJPEGSettings preview_jpeg_settings;
// Private functions assume that lock m is acquired
void SetDatasetDefaults(DatasetSettings& settings);
void MeasurementThread();
void PedestalThread(std::unique_lock<std::mutex> ul);
void InitializeThread(std::unique_lock<std::mutex> ul);
@@ -214,6 +175,8 @@ public:
std::string GetPreviewJPEG() const;
std::string GetPreviewTIFF(bool calibration) const;
void LoadInternalGeneratorImage(const void *data, size_t size, uint64_t image_number);
// Not thread safe - only for configuration in serial context
DiffractionExperiment& NotThreadSafe_Experiment();

View File

@@ -36,6 +36,7 @@ void DefaultApi::setupRoutes() {
Routes::Post(*router, base + "/cancel", Routes::bind(&DefaultApi::cancel_post_handler, this));
Routes::Get(*router, base + "/config/detector", Routes::bind(&DefaultApi::config_detector_get_handler, this));
Routes::Put(*router, base + "/config/detector", Routes::bind(&DefaultApi::config_detector_put_handler, this));
Routes::Put(*router, base + "/config/internal_generator_image", Routes::bind(&DefaultApi::config_internal_generator_image_put_handler, this));
Routes::Get(*router, base + "/config/rad_int", Routes::bind(&DefaultApi::config_rad_int_get_handler, this));
Routes::Put(*router, base + "/config/rad_int", Routes::bind(&DefaultApi::config_rad_int_put_handler, this));
Routes::Get(*router, base + "/config/select_detector", Routes::bind(&DefaultApi::config_select_detector_get_handler, this));
@@ -165,6 +166,25 @@ void DefaultApi::config_detector_put_handler(const Pistache::Rest::Request &requ
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
}
}
void DefaultApi::config_internal_generator_image_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
try {
try {
this->config_internal_generator_image_put(request, response);
} catch (Pistache::Http::HttpError &e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception &e) {
const std::pair<Pistache::Http::Code, std::string> errorInfo = this->handleOperationException(e);
response.send(errorInfo.first, errorInfo.second);
return;
}
} catch (std::exception &e) {
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
}
}
void DefaultApi::config_rad_int_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
try {

View File

@@ -60,6 +60,7 @@ private:
void cancel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void config_detector_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void config_detector_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void config_internal_generator_image_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void config_rad_int_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void config_rad_int_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void config_select_detector_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
@@ -135,6 +136,13 @@ private:
/// <param name="detectorSettings"> (optional)</param>
virtual void config_detector_put(const org::openapitools::server::model::Detector_settings &detectorSettings, Pistache::Http::ResponseWriter &response) = 0;
/// <summary>
/// Load binary image for internal FPGA generator
/// </summary>
/// <remarks>
/// Load image for internal FPGA generator. This can only happen in Idle state of the detector. Requires binary blob with 16-bit integer numbers of size of detector in raw/converted coordinates (depending on detector settings).
/// </remarks>
virtual void config_internal_generator_image_put(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter &response) = 0;
/// <summary>
/// Get radial integration configuration
/// </summary>
/// <remarks>

View File

@@ -28,6 +28,8 @@ Detector_settings::Detector_settings()
m_Storage_cell_countIsSet = false;
m_Internal_frame_generator = false;
m_Internal_frame_generatorIsSet = false;
m_Internal_frame_generator_images = 1L;
m_Internal_frame_generator_imagesIsSet = false;
m_Collect_raw_data = false;
m_Collect_raw_dataIsSet = false;
m_Pedestal_g0_frames = 0L;
@@ -36,10 +38,10 @@ Detector_settings::Detector_settings()
m_Pedestal_g1_framesIsSet = false;
m_Pedestal_g2_frames = 0L;
m_Pedestal_g2_framesIsSet = false;
m_Storage_cell_delay_ns = 0L;
m_Storage_cell_delay_nsIsSet = false;
m_Detector_trigger_delay_ns = 0L;
m_Detector_trigger_delay_nsIsSet = false;
m_Storage_cell_delay_us = 0.0f;
m_Storage_cell_delay_usIsSet = false;
m_Detector_trigger_delay_us = 0.0f;
m_Detector_trigger_delay_usIsSet = false;
m_Fixed_gain_g1 = false;
m_Fixed_gain_g1IsSet = false;
m_Use_gain_hg0 = false;
@@ -99,7 +101,26 @@ bool Detector_settings::validate(std::stringstream& msg, const std::string& path
}
}
if (internalFrameGeneratorImagesIsSet())
{
const int64_t& value = m_Internal_frame_generator_images;
const std::string currentValuePath = _pathPrefix + ".internalFrameGeneratorImages";
if (value < 1ll)
{
success = false;
msg << currentValuePath << ": must be greater than or equal to 1;";
}
if (value > 128ll)
{
success = false;
msg << currentValuePath << ": must be less than or equal to 128;";
}
}
if (pedestalG0FramesIsSet())
{
const int64_t& value = m_Pedestal_g0_frames;
@@ -163,6 +184,9 @@ bool Detector_settings::operator==(const Detector_settings& rhs) const
((!internalFrameGeneratorIsSet() && !rhs.internalFrameGeneratorIsSet()) || (internalFrameGeneratorIsSet() && rhs.internalFrameGeneratorIsSet() && isInternalFrameGenerator() == rhs.isInternalFrameGenerator())) &&
((!internalFrameGeneratorImagesIsSet() && !rhs.internalFrameGeneratorImagesIsSet()) || (internalFrameGeneratorImagesIsSet() && rhs.internalFrameGeneratorImagesIsSet() && getInternalFrameGeneratorImages() == rhs.getInternalFrameGeneratorImages())) &&
((!collectRawDataIsSet() && !rhs.collectRawDataIsSet()) || (collectRawDataIsSet() && rhs.collectRawDataIsSet() && isCollectRawData() == rhs.isCollectRawData())) &&
@@ -175,10 +199,10 @@ bool Detector_settings::operator==(const Detector_settings& rhs) const
((!pedestalG2FramesIsSet() && !rhs.pedestalG2FramesIsSet()) || (pedestalG2FramesIsSet() && rhs.pedestalG2FramesIsSet() && getPedestalG2Frames() == rhs.getPedestalG2Frames())) &&
((!storageCellDelayNsIsSet() && !rhs.storageCellDelayNsIsSet()) || (storageCellDelayNsIsSet() && rhs.storageCellDelayNsIsSet() && getStorageCellDelayNs() == rhs.getStorageCellDelayNs())) &&
((!storageCellDelayUsIsSet() && !rhs.storageCellDelayUsIsSet()) || (storageCellDelayUsIsSet() && rhs.storageCellDelayUsIsSet() && getStorageCellDelayUs() == rhs.getStorageCellDelayUs())) &&
((!detectorTriggerDelayNsIsSet() && !rhs.detectorTriggerDelayNsIsSet()) || (detectorTriggerDelayNsIsSet() && rhs.detectorTriggerDelayNsIsSet() && getDetectorTriggerDelayNs() == rhs.getDetectorTriggerDelayNs())) &&
((!detectorTriggerDelayUsIsSet() && !rhs.detectorTriggerDelayUsIsSet()) || (detectorTriggerDelayUsIsSet() && rhs.detectorTriggerDelayUsIsSet() && getDetectorTriggerDelayUs() == rhs.getDetectorTriggerDelayUs())) &&
((!fixedGainG1IsSet() && !rhs.fixedGainG1IsSet()) || (fixedGainG1IsSet() && rhs.fixedGainG1IsSet() && isFixedGainG1() == rhs.isFixedGainG1())) &&
@@ -204,6 +228,8 @@ void to_json(nlohmann::json& j, const Detector_settings& o)
j["storage_cell_count"] = o.m_Storage_cell_count;
if(o.internalFrameGeneratorIsSet())
j["internal_frame_generator"] = o.m_Internal_frame_generator;
if(o.internalFrameGeneratorImagesIsSet())
j["internal_frame_generator_images"] = o.m_Internal_frame_generator_images;
if(o.collectRawDataIsSet())
j["collect_raw_data"] = o.m_Collect_raw_data;
if(o.pedestalG0FramesIsSet())
@@ -212,10 +238,10 @@ void to_json(nlohmann::json& j, const Detector_settings& o)
j["pedestal_g1_frames"] = o.m_Pedestal_g1_frames;
if(o.pedestalG2FramesIsSet())
j["pedestal_g2_frames"] = o.m_Pedestal_g2_frames;
if(o.storageCellDelayNsIsSet())
j["storage_cell_delay_ns"] = o.m_Storage_cell_delay_ns;
if(o.detectorTriggerDelayNsIsSet())
j["detector_trigger_delay_ns"] = o.m_Detector_trigger_delay_ns;
if(o.storageCellDelayUsIsSet())
j["storage_cell_delay_us"] = o.m_Storage_cell_delay_us;
if(o.detectorTriggerDelayUsIsSet())
j["detector_trigger_delay_us"] = o.m_Detector_trigger_delay_us;
if(o.fixedGainG1IsSet())
j["fixed_gain_g1"] = o.m_Fixed_gain_g1;
if(o.useGainHg0IsSet())
@@ -241,6 +267,11 @@ void from_json(const nlohmann::json& j, Detector_settings& o)
j.at("internal_frame_generator").get_to(o.m_Internal_frame_generator);
o.m_Internal_frame_generatorIsSet = true;
}
if(j.find("internal_frame_generator_images") != j.end())
{
j.at("internal_frame_generator_images").get_to(o.m_Internal_frame_generator_images);
o.m_Internal_frame_generator_imagesIsSet = true;
}
if(j.find("collect_raw_data") != j.end())
{
j.at("collect_raw_data").get_to(o.m_Collect_raw_data);
@@ -261,15 +292,15 @@ void from_json(const nlohmann::json& j, Detector_settings& o)
j.at("pedestal_g2_frames").get_to(o.m_Pedestal_g2_frames);
o.m_Pedestal_g2_framesIsSet = true;
}
if(j.find("storage_cell_delay_ns") != j.end())
if(j.find("storage_cell_delay_us") != j.end())
{
j.at("storage_cell_delay_ns").get_to(o.m_Storage_cell_delay_ns);
o.m_Storage_cell_delay_nsIsSet = true;
j.at("storage_cell_delay_us").get_to(o.m_Storage_cell_delay_us);
o.m_Storage_cell_delay_usIsSet = true;
}
if(j.find("detector_trigger_delay_ns") != j.end())
if(j.find("detector_trigger_delay_us") != j.end())
{
j.at("detector_trigger_delay_ns").get_to(o.m_Detector_trigger_delay_ns);
o.m_Detector_trigger_delay_nsIsSet = true;
j.at("detector_trigger_delay_us").get_to(o.m_Detector_trigger_delay_us);
o.m_Detector_trigger_delay_usIsSet = true;
}
if(j.find("fixed_gain_g1") != j.end())
{
@@ -343,6 +374,23 @@ void Detector_settings::unsetInternal_frame_generator()
{
m_Internal_frame_generatorIsSet = false;
}
int64_t Detector_settings::getInternalFrameGeneratorImages() const
{
return m_Internal_frame_generator_images;
}
void Detector_settings::setInternalFrameGeneratorImages(int64_t const value)
{
m_Internal_frame_generator_images = value;
m_Internal_frame_generator_imagesIsSet = true;
}
bool Detector_settings::internalFrameGeneratorImagesIsSet() const
{
return m_Internal_frame_generator_imagesIsSet;
}
void Detector_settings::unsetInternal_frame_generator_images()
{
m_Internal_frame_generator_imagesIsSet = false;
}
bool Detector_settings::isCollectRawData() const
{
return m_Collect_raw_data;
@@ -411,39 +459,39 @@ void Detector_settings::unsetPedestal_g2_frames()
{
m_Pedestal_g2_framesIsSet = false;
}
int64_t Detector_settings::getStorageCellDelayNs() const
float Detector_settings::getStorageCellDelayUs() const
{
return m_Storage_cell_delay_ns;
return m_Storage_cell_delay_us;
}
void Detector_settings::setStorageCellDelayNs(int64_t const value)
void Detector_settings::setStorageCellDelayUs(float const value)
{
m_Storage_cell_delay_ns = value;
m_Storage_cell_delay_nsIsSet = true;
m_Storage_cell_delay_us = value;
m_Storage_cell_delay_usIsSet = true;
}
bool Detector_settings::storageCellDelayNsIsSet() const
bool Detector_settings::storageCellDelayUsIsSet() const
{
return m_Storage_cell_delay_nsIsSet;
return m_Storage_cell_delay_usIsSet;
}
void Detector_settings::unsetStorage_cell_delay_ns()
void Detector_settings::unsetStorage_cell_delay_us()
{
m_Storage_cell_delay_nsIsSet = false;
m_Storage_cell_delay_usIsSet = false;
}
int64_t Detector_settings::getDetectorTriggerDelayNs() const
float Detector_settings::getDetectorTriggerDelayUs() const
{
return m_Detector_trigger_delay_ns;
return m_Detector_trigger_delay_us;
}
void Detector_settings::setDetectorTriggerDelayNs(int64_t const value)
void Detector_settings::setDetectorTriggerDelayUs(float const value)
{
m_Detector_trigger_delay_ns = value;
m_Detector_trigger_delay_nsIsSet = true;
m_Detector_trigger_delay_us = value;
m_Detector_trigger_delay_usIsSet = true;
}
bool Detector_settings::detectorTriggerDelayNsIsSet() const
bool Detector_settings::detectorTriggerDelayUsIsSet() const
{
return m_Detector_trigger_delay_nsIsSet;
return m_Detector_trigger_delay_usIsSet;
}
void Detector_settings::unsetDetector_trigger_delay_ns()
void Detector_settings::unsetDetector_trigger_delay_us()
{
m_Detector_trigger_delay_nsIsSet = false;
m_Detector_trigger_delay_usIsSet = false;
}
bool Detector_settings::isFixedGainG1() const
{

View File

@@ -84,6 +84,13 @@ public:
bool internalFrameGeneratorIsSet() const;
void unsetInternal_frame_generator();
/// <summary>
///
/// </summary>
int64_t getInternalFrameGeneratorImages() const;
void setInternalFrameGeneratorImages(int64_t const value);
bool internalFrameGeneratorImagesIsSet() const;
void unsetInternal_frame_generator_images();
/// <summary>
/// Turn off conversion of pixel read-out to photon count
/// </summary>
bool isCollectRawData() const;
@@ -112,19 +119,19 @@ public:
bool pedestalG2FramesIsSet() const;
void unsetPedestal_g2_frames();
/// <summary>
/// Delay between two storage cells
/// Delay between two storage cells [us]
/// </summary>
int64_t getStorageCellDelayNs() const;
void setStorageCellDelayNs(int64_t const value);
bool storageCellDelayNsIsSet() const;
void unsetStorage_cell_delay_ns();
float getStorageCellDelayUs() const;
void setStorageCellDelayUs(float const value);
bool storageCellDelayUsIsSet() const;
void unsetStorage_cell_delay_us();
/// <summary>
/// Delay between TTL trigger and acquisition start
/// Delay between TTL trigger and acquisition start [us]
/// </summary>
int64_t getDetectorTriggerDelayNs() const;
void setDetectorTriggerDelayNs(int64_t const value);
bool detectorTriggerDelayNsIsSet() const;
void unsetDetector_trigger_delay_ns();
float getDetectorTriggerDelayUs() const;
void setDetectorTriggerDelayUs(float const value);
bool detectorTriggerDelayUsIsSet() const;
void unsetDetector_trigger_delay_us();
/// <summary>
/// Fix gain to G1 (can be useful for storage cells)
/// </summary>
@@ -151,6 +158,8 @@ protected:
bool m_Storage_cell_countIsSet;
bool m_Internal_frame_generator;
bool m_Internal_frame_generatorIsSet;
int64_t m_Internal_frame_generator_images;
bool m_Internal_frame_generator_imagesIsSet;
bool m_Collect_raw_data;
bool m_Collect_raw_dataIsSet;
int64_t m_Pedestal_g0_frames;
@@ -159,10 +168,10 @@ protected:
bool m_Pedestal_g1_framesIsSet;
int64_t m_Pedestal_g2_frames;
bool m_Pedestal_g2_framesIsSet;
int64_t m_Storage_cell_delay_ns;
bool m_Storage_cell_delay_nsIsSet;
int64_t m_Detector_trigger_delay_ns;
bool m_Detector_trigger_delay_nsIsSet;
float m_Storage_cell_delay_us;
bool m_Storage_cell_delay_usIsSet;
float m_Detector_trigger_delay_us;
bool m_Detector_trigger_delay_usIsSet;
bool m_Fixed_gain_g1;
bool m_Fixed_gain_g1IsSet;
bool m_Use_gain_hg0;

View File

@@ -238,18 +238,11 @@ components:
state:
type: string
description: Current state of the detector
enum:
- Idle
- Waiting
- Busy
- Error
enum: ["Idle", "Waiting", "Busy", "Error"]
powerchip:
type: string
description: Power on of ASICs
enum:
- On
- Off
- Partial
enum: ["On", "Off", "Partial"]
server_version:
type: string
description: Detector server (on read-out boards) version
@@ -293,6 +286,12 @@ components:
type: boolean
default: false
description: Use internal frame generator in FPGA instead of getting data from a real detector
internal_frame_generator_images:
type: integer
format: int64
default: 1
minimum: 1
maximum: 128
collect_raw_data:
type: boolean
default: false
@@ -309,14 +308,14 @@ components:
type: integer
format: int64
minimum: 0
storage_cell_delay_ns:
type: integer
format: int64
description: Delay between two storage cells
detector_trigger_delay_ns:
type: integer
format: int64
description: Delay between TTL trigger and acquisition start
storage_cell_delay_us:
type: number
format: float
description: Delay between two storage cells [us]
detector_trigger_delay_us:
type: number
format: float
description: Delay between TTL trigger and acquisition start [us]
fixed_gain_g1:
type: boolean
default: false
@@ -481,9 +480,7 @@ components:
detector_pixel_depth:
type: integer
format: int64
enum:
- 2
- 4
enum: [2, 4]
bkg_estimate:
type: number
format: float
@@ -494,13 +491,7 @@ components:
properties:
state:
type: string
enum:
- Inactive
- Idle
- Busy
- Measuring
- Pedestal
- Error
enum: ["Inactive", "Idle", "Busy", "Measuring", "Pedestal", "Error"]
progress:
type: number
format: float
@@ -626,10 +617,7 @@ components:
reason:
type: string
description: "Enumerate field for automated analysis"
enum:
- WrongDAQState
- Other
enum: ["WrongDAQState", "Other"]
paths:
/initialize:
@@ -865,7 +853,39 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/rad_int_settings'
/config/internal_generator_image:
put:
summary: Load binary image for internal FPGA generator
description: |
Load image for internal FPGA generator. This can only happen in Idle state of the detector.
Requires binary blob with 16-bit integer numbers of size of detector in raw/converted coordinates
(depending on detector settings).
parameters:
- name: number
in: query
description: Image number to upload
required: false
schema:
type: integer
format: int64
minimum: 0
maximum: 127
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
"200":
description: Everything OK
"400":
description: Input parsing or validation error
content:
text/plain:
schema:
type: string
description: Exception error
/config/select_detector:
put:
summary: Select detector

View File

@@ -79,7 +79,7 @@ int main (int argc, char **argv) {
experiment.MaskChipEdges(true).MaskModuleEdges(true);
AcquisitionDeviceGroup aq_devices;
ParseAcquisitionDeviceGroup(input, "devices", aq_devices);
ParseAcquisitionDeviceGroup(input, "receiver", aq_devices);
if (aq_devices.size() > 0) {
experiment.DataStreams(aq_devices.size());
image_pusher = std::make_unique<ZMQStream2PusherGroup>(context, ParseStringArray(input, "zmq_image_addr"));
@@ -112,7 +112,7 @@ int main (int argc, char **argv) {
auto router = std::make_shared<Pistache::Rest::Router>();
auto opts = Pistache::Http::Endpoint::options().threads(8);
auto opts = Pistache::Http::Endpoint::options().threads(8).maxRequestSize(64*1024*1024);
opts.flags(Pistache::Tcp::Options::ReuseAddr);
httpEndpoint->init(opts);
@@ -128,10 +128,8 @@ int main (int argc, char **argv) {
aq_devices.EnableLogging(&logger);
}
if (receiver) {
if (receiver)
broker.Services().Receiver(receiver.get());
broker.Services().Detector();
}
httpEndpoint->setHandler(router->handler());
httpEndpoint->serve();

File diff suppressed because one or more lines are too long

View File

@@ -44,6 +44,8 @@ ADD_LIBRARY( JFJochCommon STATIC
Plot.h
../fpga/include/jfjoch_fpga.h
ZMQWrappers.cpp ZMQWrappers.h
DatasetSettings.cpp
DatasetSettings.h
)
TARGET_LINK_LIBRARIES(JFJochCommon Compression JFCalibration "$<BUILD_INTERFACE:libzmq-static>" -lrt)

331
common/DatasetSettings.cpp Normal file
View File

@@ -0,0 +1,331 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include <cmath>
#include "DatasetSettings.h"
#include "Definitions.h"
#include "JFJochException.h"
#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)
DatasetSettings::DatasetSettings() {
photon_energy_keV = WVL_1A_IN_KEV;
detector_distance_mm = 100;
beam_x_pxl = 0.0;
beam_y_pxl = 0.0;
data_file_count = 1;
file_prefix = "test";
ntrigger = 1;
images_per_trigger = 1;
summation = 1;
fpga_pixel_output = FPGAPixelOutput::Auto;
space_group_number = 0; // not set
compression = CompressionAlgorithm::BSHUF_LZ4;
save_calibration = false;
photon_energy_multiplier = 1.0f;
omega_start = 0.0f;
}
DatasetSettings &DatasetSettings::ImagesPerTrigger(int64_t input) {
check_max("Total number of images", input, 10*1000*1000);
check_min("Total number of images", input, 0);
images_per_trigger = input;
return *this;
}
DatasetSettings &DatasetSettings::NumTriggers(int64_t input) {
check_max("Total number of triggers", input, 10*1000*1000);
check_min("Total number of triggers", input, 1);
ntrigger = input;
return *this;
}
DatasetSettings &DatasetSettings::PhotonEnergy_keV(float input) {
check_finite("Energy (keV)", input);
check_min("Energy (keV)", input, MIN_ENERGY);
check_max("Energy (keV)", input, MAX_ENERGY);
photon_energy_keV = input;
return *this;
}
DatasetSettings &DatasetSettings::BeamX_pxl(float input) {
check_finite("Beam center x", input);
beam_x_pxl = input;
return *this;
}
DatasetSettings &DatasetSettings::BeamY_pxl(float input) {
check_finite("Beam center y", input);
beam_y_pxl = input;
return *this;
}
DatasetSettings &DatasetSettings::DetectorDistance_mm(float input) {
check_finite("Detector distance (mm)", input);
check_min("Detector distance (mm)", input, 1);
detector_distance_mm = input;
return *this;
}
DatasetSettings &DatasetSettings::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))
file_prefix = input.substr(0, input.length() - 10);
else
file_prefix = input;
return *this;
}
DatasetSettings &DatasetSettings::DataFileCount(int64_t input) {
check_min("File count", input, 1);
check_max("File count", input, 1000);
data_file_count = input;
return *this;
}
DatasetSettings &DatasetSettings::Compression(CompressionAlgorithm input) {
switch (input) {
case CompressionAlgorithm::NO_COMPRESSION:
case CompressionAlgorithm::BSHUF_LZ4:
case CompressionAlgorithm::BSHUF_ZSTD:
case CompressionAlgorithm::BSHUF_ZSTD_RLE:
compression = input;
break;
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Invalid value for enum parameter");
}
return *this;
}
DatasetSettings &DatasetSettings::SetUnitCell(const std::optional<UnitCell> &cell) {
unit_cell = cell;
return *this;
}
DatasetSettings &DatasetSettings::SpaceGroupNumber(int64_t input) {
check_min("Space group number", input, 0);
check_max("Space group number", input, 230);
space_group_number = input;
return *this;
}
DatasetSettings &DatasetSettings::SampleName(std::string input) {
sample_name = input;
return *this;
}
DatasetSettings &DatasetSettings::AttenuatorTransmission(const std::optional<float> &input) {
if (input) {
check_finite("Attenuator transmission", input.value());
check_max("Attenuator transmission", input.value(), 1.0);
check_min("Attenuator transmission", input.value(), 0.0);
}
attenuator_transmission = input;
return *this;
}
DatasetSettings &DatasetSettings::TotalFlux(const std::optional<float> &input) {
if (input) {
check_finite("Total flux", input.value());
check_max("Total flux", input.value(), 1.0);
check_min("Total flux", input.value(), 0.0);
}
total_flux = input;
return *this;
}
DatasetSettings &DatasetSettings::OmegaStep(const std::optional<float> &input) {
if (input) {
check_finite("Omega step", input.value());
}
if (input && (input == 0.0f))
omega_step.reset();
else
omega_step = input;
return *this;
}
DatasetSettings &DatasetSettings::OmegaStart(float input) {
check_finite("Omega start", input);
omega_start = input;
return *this;
}
DatasetSettings &DatasetSettings::OmegaAxis(const std::optional<Coord> &c) {
if (c) {
if (c->Length() == 0.0)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Cannot use empty vector for omega");
omega_rotation_axis = c->Normalize();
} else
omega_rotation_axis = c;
return *this;
}
DatasetSettings &DatasetSettings::HeaderAppendix(const std::string &input) {
header_appendix = input;
return *this;
}
DatasetSettings &DatasetSettings::ImageAppendix(const std::string &input) {
image_appendix = input;
return *this;
}
DatasetSettings &DatasetSettings::ROISummation(const std::optional<ROIRectangle> &input) {
roi_sum = input;
return *this;
}
DatasetSettings &DatasetSettings::PhotonEnergyMultiplayer(float input) {
check_finite("Photon energy multiplier", input);
check_min("Photon energy multiplier", input, 1/64.f);
check_max("Photon energy multiplier", input, 4.f);
photon_energy_multiplier = input;
return *this;
}
DatasetSettings &DatasetSettings::SaveCalibration(bool input) {
save_calibration = input;
return *this;
}
DatasetSettings &DatasetSettings::Summation(int64_t input) {
check_min("Summation", input, 1);
check_max("Summation", input, MAX_FPGA_SUMMATION);
summation = input;
return *this;
}
DatasetSettings &DatasetSettings::FPGAOutputMode(FPGAPixelOutput input) {
switch (input) {
case FPGAPixelOutput::Auto:
case FPGAPixelOutput::Int16:
case FPGAPixelOutput::Uint16:
case FPGAPixelOutput::Int32:
case FPGAPixelOutput::Uint32:
fpga_pixel_output = input;
break;
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Invalid value for enum parameter");
}
return *this;
}
std::optional<float> DatasetSettings::GetAttenuatorTransmission() const {
return attenuator_transmission;
}
std::optional<float> DatasetSettings::GetTotalFlux() const {
return total_flux;
}
std::optional<float> DatasetSettings::GetOmegaStep() const {
return omega_step;
}
float DatasetSettings::GetOmegaStart() const {
return omega_start;
}
std::optional<Coord> DatasetSettings::GetOmegaAxis() const {
return omega_rotation_axis;
}
std::string DatasetSettings::GetHeaderAppendix() const {
return header_appendix;
}
std::string DatasetSettings::GetImageAppendix() const {
return image_appendix;
}
std::optional<ROIRectangle> DatasetSettings::GetROISummation() const {
return roi_sum;
}
float DatasetSettings::GetPhotonEnergyMultiplier() const {
return photon_energy_multiplier;
}
std::optional<UnitCell> DatasetSettings::GetUnitCell() const {
return unit_cell;
}
int64_t DatasetSettings::GetSpaceGroupNumber() const {
return space_group_number;
}
bool DatasetSettings::GetSaveCalibration() const {
return save_calibration;
}
int64_t DatasetSettings::GetSummation() const {
return summation;
}
FPGAPixelOutput DatasetSettings::GetFPGAOutputMode() const {
return fpga_pixel_output;
}
std::string DatasetSettings::GetSampleName() const {
return sample_name;
}
float DatasetSettings::GetPhotonEnergy_keV() const {
return photon_energy_keV;
}
float DatasetSettings::GetWavelength_A() const {
return WVL_1A_IN_KEV / photon_energy_keV;
}
float DatasetSettings::GetBeamX_pxl() const {
return beam_x_pxl;
}
float DatasetSettings::GetBeamY_pxl() const {
return beam_y_pxl;
}
float DatasetSettings::GetDetectorDistance_mm() const {
return detector_distance_mm;
}
Coord DatasetSettings::GetScatteringVector() const {
return {0, 0, photon_energy_keV / WVL_1A_IN_KEV};
}
std::string DatasetSettings::GetFilePrefix() const {
return file_prefix;
}
int64_t DatasetSettings::GetDataFileCount() const {
return data_file_count;
}
CompressionAlgorithm DatasetSettings::GetCompressionAlgorithm() const {
return compression;
}
int64_t DatasetSettings::GetNumTriggers() const {
return ntrigger;
}
int64_t DatasetSettings::GetImageNumPerTrigger() const {
return images_per_trigger;
}

111
common/DatasetSettings.h Normal file
View File

@@ -0,0 +1,111 @@
// Copyright (2019-2024) Paul Scherrer Institute
#ifndef JUNGFRAUJOCH_DATASETSETTINGS_H
#define JUNGFRAUJOCH_DATASETSETTINGS_H
#include <cstdint>
#include <string>
#include <optional>
#include "UnitCell.h"
#include "Coord.h"
#include "../compression/CompressionAlgorithmEnum.h"
#include "../frame_serialize/JFJochMessages.h"
enum class FPGAPixelOutput {
Auto, Int16, Uint16, Int32, Uint32
};
class DatasetSettings {
int64_t images_per_trigger;
int64_t ntrigger;
FPGAPixelOutput fpga_pixel_output;
int64_t summation;
float beam_x_pxl;
float beam_y_pxl;
float detector_distance_mm;
float photon_energy_keV;
float photon_energy_multiplier;
std::string file_prefix;
int64_t data_file_count;
CompressionAlgorithm compression;
std::string sample_name;
std::optional<UnitCell> unit_cell;
int64_t space_group_number;
bool save_calibration;
std::optional<float> total_flux;
std::optional<float> attenuator_transmission;
std::optional<float> omega_step;
float omega_start;
std::string image_appendix;
std::string header_appendix;
std::optional<Coord> omega_rotation_axis;
std::optional<ROIRectangle> roi_sum;
public:
DatasetSettings();
DatasetSettings& ImagesPerTrigger(int64_t input);
DatasetSettings& NumTriggers(int64_t triggers);
DatasetSettings& PhotonEnergy_keV(float input);
DatasetSettings& BeamX_pxl(float input);
DatasetSettings& BeamY_pxl(float input);
DatasetSettings& DetectorDistance_mm(float input);
DatasetSettings& FilePrefix(std::string input);
DatasetSettings& DataFileCount(int64_t input);
DatasetSettings& Compression(CompressionAlgorithm input);
DatasetSettings& SetUnitCell(const std::optional<UnitCell> &cell);
DatasetSettings& SpaceGroupNumber(int64_t input);
DatasetSettings& SampleName(std::string input);
DatasetSettings& AttenuatorTransmission(const std::optional<float> &input);
DatasetSettings& TotalFlux(const std::optional<float> &input);
DatasetSettings& OmegaStep(const std::optional<float> &input);
DatasetSettings& OmegaStart(float input);
DatasetSettings& OmegaAxis(const std::optional<Coord> &c);
DatasetSettings& HeaderAppendix(const std::string& input);
DatasetSettings& ImageAppendix(const std::string& input);
DatasetSettings& ROISummation(const std::optional<ROIRectangle>& input);
DatasetSettings& PhotonEnergyMultiplayer(float input);
DatasetSettings& SaveCalibration(bool input);
DatasetSettings& Summation(int64_t input);
DatasetSettings& FPGAOutputMode(FPGAPixelOutput input);
std::optional<float> GetAttenuatorTransmission() const;
std::optional<float> GetTotalFlux() const;
std::optional<float> GetOmegaStep() const;
float GetOmegaStart() const;
std::optional<Coord> GetOmegaAxis() const;
std::string GetHeaderAppendix() const;
std::string GetImageAppendix() const;
std::optional<ROIRectangle> GetROISummation() const;
float GetPhotonEnergyMultiplier() const;
std::optional<UnitCell> GetUnitCell() const;
int64_t GetSpaceGroupNumber() const;
bool GetSaveCalibration() const;
int64_t GetSummation() const;
FPGAPixelOutput GetFPGAOutputMode() const;
std::string GetSampleName() const;
float GetPhotonEnergy_keV() const;
float GetWavelength_A() const;
float GetBeamX_pxl() const;
float GetBeamY_pxl() const;
float GetDetectorDistance_mm() const;
Coord GetScatteringVector() const;
std::string GetFilePrefix() const;
int64_t GetDataFileCount() const;
CompressionAlgorithm GetCompressionAlgorithm() const;
int64_t GetNumTriggers() const;
int64_t GetImageNumPerTrigger() const;
};
#endif //JUNGFRAUJOCH_DATASETSETTINGS_H

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;
}

View File

@@ -15,15 +15,12 @@
#include "../frame_serialize/JFJochMessages.h"
#include "DetectorSetup.h"
#include "../image_analysis/SpotFindingSettings.h"
#include "DatasetSettings.h"
enum class DetectorMode {
Conversion, Raw, PedestalG0, PedestalG1, PedestalG2
};
enum class FPGAPixelOutput {
Auto, Int16, Uint16, Int32, Uint32
};
struct AcquisitionDeviceNetConfig {
std::string mac_addr;
std::string ipv4_addr;
@@ -44,27 +41,29 @@ struct DetectorModuleConfig {
class DiffractionExperiment {
// Internal detector settings
std::chrono::microseconds frame_time_pedestalG1G2;
std::chrono::microseconds frame_time_pedestalG1G2{};
// uint64 frame_time_pedestalG2_us = 2; reserved
std::chrono::microseconds frame_time;
std::chrono::microseconds count_time;
std::chrono::microseconds frame_time{};
std::chrono::microseconds count_time{};
DetectorSetup detector;
int64_t ndatastreams;
bool internal_fpga_packet_generator;
int64_t internal_fpga_packet_generator_images;
int64_t storage_cells;
int64_t storage_cell_start;
std::chrono::nanoseconds storage_cell_delay;
std::chrono::nanoseconds detector_delay;
std::chrono::nanoseconds storage_cell_delay{};
std::chrono::nanoseconds detector_delay{};
int64_t pedestal_g0_frames;
int64_t pedestal_g1_frames;
int64_t pedestal_g2_frames;
bool use_gain_hg0;
bool fix_gain_g1;
std::chrono::microseconds preview_period;
std::chrono::microseconds preview_period{};
DetectorMode mode;
bool mask_module_edges;
@@ -94,44 +93,12 @@ class DiffractionExperiment {
std::string neural_net_model_path;
bool rad_int_solid_angle_corr;
bool rad_int_polarization_corr;
float rad_int_polarization_factor{};
// Dataset settings
struct {
int64_t images_per_trigger;
int64_t ntrigger;
FPGAPixelOutput fpga_pixel_output;
int64_t summation;
float beam_x_pxl;
float beam_y_pxl;
float detector_distance_mm;
float photon_energy_keV;
float photon_energy_multiplier;
std::string file_prefix;
int64_t data_file_count;
CompressionAlgorithm compression;
std::string sample_name;
std::optional<UnitCell> unit_cell;
int64_t space_group_number;
bool rad_int_solid_angle_corr;
bool rad_int_polarization_corr;
float rad_int_polarization_factor;
bool save_calibration;
std::optional<float> total_flux;
std::optional<float> attenuator_transmission;
std::optional<float> omega_step;
float omega_start;
std::string image_appendix;
std::string header_appendix;
Coord omega_rotation_axis;
std::optional<ROIRectangle> roi_sum;
} dataset;
DatasetSettings dataset;
constexpr static const int64_t max_spot_count = 100;
public:
@@ -144,31 +111,20 @@ public:
DiffractionExperiment& Mode(DetectorMode input);
DiffractionExperiment& DataStreams(int64_t input);
DiffractionExperiment& ImagesPerTrigger(int64_t input);
DiffractionExperiment& NumTriggers(int64_t triggers);
DiffractionExperiment& PedestalG0Frames(int64_t input);
DiffractionExperiment& PedestalG1Frames(int64_t input);
DiffractionExperiment& PedestalG2Frames(int64_t input);
DiffractionExperiment& FrameTime(std::chrono::microseconds frame_time,
std::chrono::microseconds in_count_time = std::chrono::microseconds(0));
DiffractionExperiment& PedestalG1G2FrameTime(std::chrono::microseconds input);
DiffractionExperiment& PhotonEnergy_keV(float input);
DiffractionExperiment& BeamX_pxl(float input);
DiffractionExperiment& BeamY_pxl(float input);
DiffractionExperiment& DetectorDistance_mm(float input);
DiffractionExperiment& FilePrefix(std::string input);
DiffractionExperiment& DataFileCount(int64_t input);
DiffractionExperiment& Compression(CompressionAlgorithm input);
DiffractionExperiment& PreviewPeriod(std::chrono::microseconds input);
DiffractionExperiment& UseInternalPacketGenerator(bool input);
DiffractionExperiment& InternalPacketGeneratorImages(int64_t input);
DiffractionExperiment& IPv4BaseAddr(std::string input);
DiffractionExperiment& MaskModuleEdges(bool input);
DiffractionExperiment& MaskChipEdges(bool input);
DiffractionExperiment& SetUnitCell(const std::optional<UnitCell> &cell);
DiffractionExperiment& LowResForAzimInt_A(float input);
DiffractionExperiment& HighResForAzimInt_A(float input);
@@ -176,39 +132,57 @@ public:
DiffractionExperiment& HighQForAzimInt_recipA(float input);
DiffractionExperiment& QSpacingForAzimInt_recipA(float input);
DiffractionExperiment& SpaceGroupNumber(int64_t input);
DiffractionExperiment& StorageCells(int64_t input);
DiffractionExperiment& StorageCellStart(int64_t input = 15);
DiffractionExperiment& SampleName(std::string input);
DiffractionExperiment& SourceName(std::string input);
DiffractionExperiment& SourceNameShort(std::string input);
DiffractionExperiment& InstrumentName(std::string input);
DiffractionExperiment& InstrumentNameShort(std::string input);
DiffractionExperiment& ApplyPixelMaskInFPGA(bool input);
DiffractionExperiment& DefaultOmegaAxis(const Coord &c);
DiffractionExperiment& UsingGainHG0(bool input);
DiffractionExperiment& FixedGainG1(bool input);
DiffractionExperiment& IncrementSeriesID();
DiffractionExperiment& ConversionOnFPGA(bool input);
DiffractionExperiment& NeuralNetModelPath(const std::string& input);
DiffractionExperiment& PulsedSource(bool input);
DiffractionExperiment& ImagesPerTrigger(int64_t input);
DiffractionExperiment& NumTriggers(int64_t triggers);
DiffractionExperiment& PhotonEnergy_keV(float input);
DiffractionExperiment& BeamX_pxl(float input);
DiffractionExperiment& BeamY_pxl(float input);
DiffractionExperiment& DetectorDistance_mm(float input);
DiffractionExperiment& FilePrefix(std::string input);
DiffractionExperiment& DataFileCount(int64_t input);
DiffractionExperiment& Compression(CompressionAlgorithm input);
DiffractionExperiment& SetUnitCell(const std::optional<UnitCell> &cell);
DiffractionExperiment& SpaceGroupNumber(int64_t input);
DiffractionExperiment& SampleName(std::string input);
DiffractionExperiment& AttenuatorTransmission(const std::optional<float> &input);
DiffractionExperiment& TotalFlux(const std::optional<float> &input);
DiffractionExperiment& OmegaStep(const std::optional<float> &input);
DiffractionExperiment& OmegaStart(float input);
DiffractionExperiment& OmegaAxis(const Coord &c);
DiffractionExperiment& OmegaAxis();
DiffractionExperiment& DefaultOmegaAxis(const Coord &c);
DiffractionExperiment& UsingGainHG0(bool input);
DiffractionExperiment& FixedGainG1(bool input);
DiffractionExperiment& HeaderAppendix(const std::string& input);
DiffractionExperiment& ImageAppendix(const std::string& input);
DiffractionExperiment& IncrementSeriesID();
DiffractionExperiment& ROISummation(const std::optional<ROIRectangle>& input);
DiffractionExperiment& ConversionOnFPGA(bool input);
DiffractionExperiment& NeuralNetModelPath(const std::string& input);
DiffractionExperiment& PulsedSource(bool input);
DiffractionExperiment& PhotonEnergyMultiplayer(float input);
DiffractionExperiment& SaveCalibration(bool input);
DiffractionExperiment& Summation(int64_t input);
DiffractionExperiment& FPGAOutputMode(FPGAPixelOutput input);
DiffractionExperiment& ImportDatasetSettings(const DatasetSettings& input);
DatasetSettings GetDatasetSettings() const;
void FillMessage(StartMessage &message) const;
static void CheckDataProcessingSettings(const SpotFindingSettings& settings);
static SpotFindingSettings DefaultDataProcessingSettings();
DetectorMode GetDetectorMode() const;
int64_t GetPixelDepth() const;
@@ -216,14 +190,12 @@ public:
int64_t GetOverflow() const;
int64_t GetUnderflow() const;
int64_t GetNumTriggers() const;
int64_t GetImageNum() const;
int64_t GetImageNumPerTrigger() const;
int64_t GetPedestalG0Frames() const;
int64_t GetPedestalG1Frames() const;
int64_t GetPedestalG2Frames() const;
int64_t GetImageNum() const;
int64_t GetFrameNum() const;
int64_t GetFrameNumPerTrigger() const;
@@ -239,18 +211,7 @@ public:
DiffractionExperiment& DetectorDelay(std::chrono::nanoseconds input);
std::chrono::nanoseconds GetDetectorDelay() const;
float GetPhotonEnergy_keV() const;
float GetWavelength_A() const;
float GetBeamX_pxl() const;
float GetBeamY_pxl() const;
float GetDetectorDistance_mm() const;
Coord GetScatteringVector() const;
std::string GetFilePrefix() const;
int64_t GetDataFileCount() const;
CompressionAlgorithm GetCompressionAlgorithm() const;
int64_t GetMaxCompressedSize() const;
@@ -274,6 +235,7 @@ public:
int64_t GetSpotFindingBin() const;
bool IsUsingInternalPacketGen() const;
int64_t GetInternalPacketGeneratorImages() const;
uint32_t GetSrcIPv4Address(uint32_t data_stream, uint32_t half_module) const;
@@ -282,7 +244,6 @@ public:
bool GetMaskModuleEdges() const;
bool GetMaskChipEdges() const;
std::optional<UnitCell> GetUnitCell() const;
Coord LabCoord(float detector_x, float detector_y) const;
@@ -293,13 +254,10 @@ public:
float GetLowQForBkgEstimate_recipA() const;
float GetHighQForBkgEstimate_recipA() const;
int64_t GetSpaceGroupNumber() const;
int64_t GetStorageCellNumber() const;
int64_t GetStorageCellStart() const;
int64_t GetMaxSpotCount() const;
std::string GetSampleName() const;
bool GetApplyPixelMaskInFPGA() const;
float GetPixelSize_mm() const;
@@ -318,32 +276,15 @@ public:
bool GetApplyPolarizationCorr() const;
float GetPolarizationFactor() const;
DiffractionExperiment& SaveCalibration(bool input);
bool GetSaveCalibration() const;
DiffractionExperiment& Summation(int64_t input);
int64_t GetSummation() const;
DiffractionExperiment& FPGAOutputMode(FPGAPixelOutput input);
FPGAPixelOutput GetFPGAOutputMode() const;
int64_t GetUDPInterfaceCount() const;
std::vector<DetectorModuleConfig> GetDetectorModuleConfig(const std::vector<AcquisitionDeviceNetConfig>& net_config) const;
std::optional<float> GetAttenuatorTransmission() const;
std::optional<float> GetTotalFlux() const;
std::optional<float> GetOmegaStep() const;
float GetOmegaStart() const;
Coord GetOmegaAxis() const;
Coord GetDefaultOmegaAxis() const;
bool IsFixedGainG1() const;
bool IsUsingGainHG0() const;
std::string GetHeaderAppendix() const;
std::string GetImageAppendix() const;
uint64_t GetSeriesID() const;
std::string GetSeriesIDString() const;
std::optional<ROIRectangle> GetROISummation() const;
bool IsConversionOnFPGA() const;
const DetectorSetup& GetDetectorSetup() const;
@@ -354,8 +295,36 @@ public:
bool IsSpotFindingEnabled() const;
float GetPhotonEnergyForConversion_keV() const;
float GetPhotonEnergyMultiplier() const;
std::optional<float> GetAttenuatorTransmission() const;
std::optional<float> GetTotalFlux() const;
std::optional<float> GetOmegaStep() const;
float GetOmegaStart() const;
Coord GetOmegaAxis() const;
std::string GetHeaderAppendix() const;
std::string GetImageAppendix() const;
std::optional<ROIRectangle> GetROISummation() const;
float GetPhotonEnergyMultiplier() const;
std::optional<UnitCell> GetUnitCell() const;
int64_t GetSpaceGroupNumber() const;
bool GetSaveCalibration() const;
int64_t GetSummation() const;
FPGAPixelOutput GetFPGAOutputMode() const;
std::string GetSampleName() const;
float GetPhotonEnergy_keV() const;
float GetWavelength_A() const;
float GetBeamX_pxl() const;
float GetBeamY_pxl() const;
float GetDetectorDistance_mm() const;
Coord GetScatteringVector() const;
std::string GetFilePrefix() const;
int64_t GetDataFileCount() const;
CompressionAlgorithm GetCompressionAlgorithm() const;
int64_t GetNumTriggers() const;
int64_t GetImageNumPerTrigger() const;
};
inline int64_t CalculateStride(const std::chrono::microseconds &frame_time, const std::chrono::microseconds &preview_time) {

View File

@@ -81,9 +81,9 @@ inline void CalcAzIntCorrRawCoord(float *output, const DiffractionExperiment& ex
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
auto [x,y] = RawToConvertedCoordinate(experiment, module_number, i);
if (experiment.GetApplySolidAngleCorr())
output[i] *= CalcAzIntSolidAngleCorr(experiment, static_cast<float>(x), static_cast<float>(y));
output[i] /= CalcAzIntSolidAngleCorr(experiment, static_cast<float>(x), static_cast<float>(y));
if (experiment.GetApplyPolarizationCorr())
output[i] *= CalcAzIntPolarizationCorr(experiment, static_cast<float>(x), static_cast<float>(y));
output[i] /= CalcAzIntPolarizationCorr(experiment, static_cast<float>(x), static_cast<float>(y));
}
}

View File

@@ -55,7 +55,8 @@ void ConvertedToRawGeometry(const DiffractionExperiment &experiment, T *destinat
LineConvtToRaw<T>(destination + module_number * RAW_MODULE_SIZE + RAW_MODULE_COLS * line,
source + experiment.GetPixel0OfModule(module_number) +
experiment.GetModuleSlowDirectionStep(module_number) *
(line + ((line > 255) ? 2 : 0))
(line + ((line > 255) ? 2 : 0)),
experiment.GetModuleFastDirectionStep(module_number)
);
}
}

View File

@@ -140,10 +140,10 @@ void TransferModuleAdjustMultipixels(Td *destination, const Ts *source, int64_t
}
template<class T>
void LineConvtToRaw(T *destination, const T *source) {
void LineConvtToRaw(T *destination, const T *source, size_t fast_direction_step) {
for (int chip = 0; chip < 4; chip++) {
for (int i = 0; i < 256; i++)
destination[i + chip * 256] = source[i + chip * 258];
destination[i + chip * 256] = source[(i + chip * 258) * fast_direction_step];
}
}

View File

@@ -27,7 +27,7 @@ template <class Td, class Ts>
void JFJochDecompress(std::vector<Td> &output, CompressionAlgorithm algorithm, Ts *source_v, size_t source_size,
size_t nelements) {
size_t elem_size = sizeof(Td);
output.resize(nelements * elem_size);
output.resize(nelements);
auto source = (uint8_t *) source_v;
size_t block_size;

View File

@@ -19,10 +19,9 @@
"zmq_image_addr": ["tcp://0.0.0.0:5500", "tcp://0.0.0.0:5501", "tcp://0.0.0.0:5502", "tcp://0.0.0.0:5503"],
"zmq_preview_addr": "tcp://0.0.0.0:5400",
"receiver_threads": 64,
"send_buffer_count": 2048,
"devices": {
"receiver": {
"type": "pcie",
"count": 4,
"devices": ["/dev/jfjoch0","/dev/jfjoch1","/dev/jfjoch2","/dev/jfjoch3"],
"ipv4_addr": ["10.10.85.1", "10.10.85.2", "10.10.85.3" ,"10.10.85.4"]
},
"detectors": [

View File

@@ -19,10 +19,9 @@
"zmq_image_addr": ["tcp://0.0.0.0:5500"],
"zmq_preview_addr": "tcp://0.0.0.0:5400",
"receiver_threads": 64,
"send_buffer_count": 2048,
"devices": {
"receiver": {
"type": "pcie",
"count": 1,
"devices": ["/dev/jfjoch0"],
"ipv4_addr": ["10.3.30.200"]
},
"detectors": [

View File

@@ -1,21 +1,27 @@
{
"services": {},
"cfg": {
"source_name": "Swiss Light Source",
"source_name_short": "SLS",
"instrument_name": "X06SA VESPA",
"instrument_name_short": "VESPA",
"datastreams": 2,
"pedestal_g0_frames": 2000,
"pedestal_g1_frames": 300,
"pedestal_g2_frames": 300,
"datastreams": 1,
"pedestal_g0_frames": 0,
"pedestal_g1_frames": 0,
"pedestal_g2_frames": 0,
"frame_time_us": "1000 us",
"count_time_us": "980 us",
"spot_finding_period_us": "5 ms",
"preview_period_us": "1 s",
"detector_ipv4": "10.10.85.20"
"detector_ipv4": "10.10.85.20",
"internal_frame_generator": true
},
"receiver": {
"type": "hls",
"ipv4_addr": ["10.3.30.200"]
},
"frontend_directory": "/home/leonarski_f/nextgendcu/frontend_ui/build/",
"zmq_image_addr": ["tcp://0.0.0.0:5500"],
"zmq_preview_addr": "tcp://0.0.0.0:5400",
"detectors": [
{
"standard_geometry": {
@@ -49,20 +55,48 @@
},
{
"standard_geometry": {
"nmodules": 4,
"horizontal_stacking": 2,
"nmodules": 18,
"horizontal_stacking": 3,
"gap_x": 8,
"gap_y": 36,
"mirror_y": true
},
"description": "PSI JUNGFRAU 4M (2M ROI)",
"description": "PSI JUNGFRAU 9M",
"module_hostname": [
"10.10.10.10",
"10.10.10.11",
"10.10.10.12",
"10.10.10.13",
"10.10.10.14",
"10.10.10.15"
"10.10.10.15",
"10.10.10.16",
"10.10.10.17",
"10.10.10.18",
"10.10.10.19",
"10.10.10.20",
"10.10.10.21",
"10.10.10.22",
"10.10.10.23",
"10.10.10.24",
"10.10.10.25",
"10.10.10.26",
"10.10.10.27"
],
"gain_files": [
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",
"/home/leonarski_f/nextgendcu/tests/test_data/gainMaps_M049.bin",

View File

@@ -8,6 +8,7 @@ void generate_packet_jungfrau(STREAM_512 &data_out,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes,
ap_uint<32> frame,
ap_uint<10> mem_cell,
ap_uint<8> module,
ap_uint<7> eth_packet,
ap_uint<48> src_mac_addr,
@@ -60,8 +61,8 @@ void generate_packet_jungfrau(STREAM_512 &data_out,
ap_uint<208> remainder = header(719, 512);
for (int i = 0; i < 128; i++) {
ap_uint<512> tmp;
tmp(255, 0) = d_hbm_p0[offset_hbm_0 + module * 128 * 128 + eth_packet * 128 + i];
tmp(511, 256) = d_hbm_p1[offset_hbm_1 + module * 128 * 128 + eth_packet * 128 + i];
tmp(255, 0) = d_hbm_p0[offset_hbm_0 + mem_cell * 128 * 128 + eth_packet * 128 + i];
tmp(511, 256) = d_hbm_p1[offset_hbm_1 + mem_cell * 128 * 128 + eth_packet * 128 + i];
packet.data(207, 0) = remainder;
packet.data(511, 208) = tmp(303, 0);
@@ -80,6 +81,7 @@ void generate_packet_eiger(STREAM_512 &data_out,
ap_uint<256> *d_hbm_p1,
ap_uint<32> hbm_size_bytes,
ap_uint<32> frame,
ap_uint<10> mem_cell,
ap_uint<8> module,
ap_uint<8> eth_packet,
ap_uint<48> src_mac_addr,
@@ -133,8 +135,8 @@ void generate_packet_eiger(STREAM_512 &data_out,
ap_uint<208> remainder = header(719, 512);
for (int i = 0; i < 64; i++) {
ap_uint<512> tmp;
tmp(255, 0) = d_hbm_p0[offset_hbm_0 + module * 64 * 256 + eth_packet * 64 + i];
tmp(511, 256) = d_hbm_p1[offset_hbm_1 + module * 64 * 256 + eth_packet * 64 + i];
tmp(255, 0) = d_hbm_p0[offset_hbm_0 + mem_cell * 64 * 256 + eth_packet * 64 + i];
tmp(511, 256) = d_hbm_p1[offset_hbm_1 + mem_cell * 64 * 256 + eth_packet * 64 + i];
packet.data(207, 0) = remainder;
packet.data(511, 208) = tmp(303, 0);
@@ -155,7 +157,7 @@ int frame_generator(STREAM_512 &data_out,
ap_uint<48> src_mac_addr,
ap_uint<32> src_ipv4_addr,
volatile ap_uint<1> &in_cancel,
FrameGeneratorConfig &config) {
const FrameGeneratorConfig &config) {
#pragma HLS INTERFACE mode=s_axilite port=return
#pragma HLS INTERFACE mode=s_axilite port=config
#pragma HLS INTERFACE mode=ap_none register port=src_mac_addr
@@ -180,6 +182,9 @@ int frame_generator(STREAM_512 &data_out,
if (config.frames == 0)
return 0;
if (config.modules * (config.images_in_memory + 1) >= hbm_size_bytes * 2 / (RAW_MODULE_SIZE * sizeof(uint16_t)))
return 3;
union {
uint64_t u64;
double d;
@@ -191,7 +196,7 @@ int frame_generator(STREAM_512 &data_out,
d_hbm_p0,
d_hbm_p1,
hbm_size_bytes,
0, 0, 0,
0, 0, 0, 0,
src_mac_addr,
config.dest_mac_addr,
src_ipv4_addr,
@@ -201,6 +206,7 @@ int frame_generator(STREAM_512 &data_out,
config.exptime,
config.debug, 1);
ap_uint<7> frame_cell = 0;
for (uint32_t f = 0; f < config.frames; f++) {
ap_uint<1> local_cancel = in_cancel;
if (local_cancel == 1)
@@ -214,7 +220,8 @@ int frame_generator(STREAM_512 &data_out,
d_hbm_p0,
d_hbm_p1,
hbm_size_bytes,
f, m, p,
f, frame_cell * config.modules + m,
m, p,
src_mac_addr,
config.dest_mac_addr,
src_ipv4_addr,
@@ -234,7 +241,8 @@ int frame_generator(STREAM_512 &data_out,
d_hbm_p0,
d_hbm_p1,
hbm_size_bytes,
f, m, p,
f, frame_cell * config.modules + m,
m, p,
src_mac_addr,
config.dest_mac_addr,
src_ipv4_addr,
@@ -246,6 +254,11 @@ int frame_generator(STREAM_512 &data_out,
}
}
pulse_id_conv.d += 1.0;
if (frame_cell == config.images_in_memory)
frame_cell = 0;
else
frame_cell++;
}
return 0;
}

View File

@@ -35,7 +35,7 @@ namespace hls {
typedef ap_ufixed<16,2, AP_RND_CONV> gainG0_t;
typedef ap_ufixed<16,4, AP_RND_CONV> gainG1_t;
typedef ap_ufixed<16,6, AP_RND_CONV> gainG2_t;
typedef ap_ufixed<16,1, AP_RND_CONV> integration_factor_t;
typedef ap_ufixed<16,10, AP_RND_CONV> integration_factor_t;
typedef ap_ufixed<16,9, AP_RND_CONV> xray_d_t;
typedef ap_ufixed<32,12,AP_RND_CONV> one_over_energy_t;
@@ -392,7 +392,7 @@ int frame_generator(STREAM_512 &data_out,
ap_uint<48> src_mac_addr,
ap_uint<32> src_ipv4_addr,
volatile ap_uint<1> &in_cancel,
FrameGeneratorConfig &config);
const FrameGeneratorConfig &config);
int load_calibration(ap_uint<256> *d_hbm_p0,
ap_uint<256> *d_hbm_p1,

View File

@@ -32,7 +32,7 @@ void integration(STREAM_768 &data_in,
idle = 1;
ap_fixed<50,34, AP_RND_CONV> sum[64][FPGA_INTEGRATION_BIN_COUNT];
ap_fixed<50,44, AP_RND_CONV> sum[64][FPGA_INTEGRATION_BIN_COUNT];
// log2(32768*512*1024/64) = 32 + sign 1 bit
#pragma HLS BIND_STORAGE variable=sum type=ram_t2p impl=bram
#pragma HLS ARRAY_PARTITION variable=sum type=complete dim=1
@@ -104,7 +104,7 @@ void integration(STREAM_768 &data_in,
for (int i = 0; i < FPGA_INTEGRATION_BIN_COUNT; i++) {
#pragma HLS PIPELINE II=1
ap_axiu<64,1,1,1> res;
ap_fixed<64, 40, AP_RND_CONV> main_sum = 0;
ap_fixed<64, 50, AP_RND_CONV> main_sum = 0;
ap_uint<22> main_count = 0;
for (int j = 0; j < 64; j++) {
main_sum += sum[j][i];

View File

@@ -27,7 +27,7 @@ typedef __u64 uint64_t;
#define GAIN_G2_MULTIPLIER (-1)
#define JFJOCH_FPGA_MAGIC 0x52324158
#define JFJOCH_FPGA_RELEASE 0x0054
#define JFJOCH_FPGA_RELEASE 0x0055
#define JFJOCH_FPGA_VARIANT_100G 0
#define JFJOCH_FPGA_VARIANT_8x10G 1
@@ -175,14 +175,15 @@ struct DeviceStatus {
};
struct FrameGeneratorConfig {
uint32_t frames; // Number of frames
uint32_t modules; // Number of modules (1-32)
uint64_t dest_mac_addr; // Use the same as source address
uint32_t dest_ipv4_addr; // Use the same as source address
double pulse_id;
uint32_t frames; // Number of frames
uint32_t modules; // Number of modules (1-32)
uint32_t exptime;
uint32_t debug;
uint32_t detector_type; // EIGER = 1, JUNGFRAU = 3
uint32_t images_in_memory; // value minus one
};
struct RegisterConfig {

View File

@@ -70,13 +70,6 @@ proc create_hier_cell_mac_100g { parentCell nameHier } {
CONFIG.SYNCHRONIZATION_STAGES {5} \
] $axis_data_fifo_rx_1
# Create instance: axis_data_fifo_rx_2, and set properties
set axis_data_fifo_rx_2 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_rx_2 ]
set_property -dict [ list \
CONFIG.FIFO_DEPTH {256} \
CONFIG.FIFO_MEMORY_TYPE {block} \
] $axis_data_fifo_rx_2
# Create instance: axis_data_fifo_tx, and set properties
set axis_data_fifo_tx [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 axis_data_fifo_tx ]
set_property -dict [ list \
@@ -85,17 +78,11 @@ proc create_hier_cell_mac_100g { parentCell nameHier } {
CONFIG.IS_ACLK_ASYNC {1} \
] $axis_data_fifo_tx
# Create instance: axis_register_slice_rx_0, and set properties
set axis_register_slice_rx_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_register_slice:1.1 axis_register_slice_rx_0 ]
# Create instance: axis_register_slice_rx, and set properties
set axis_register_slice_rx [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_register_slice:1.1 axis_register_slice_rx ]
set_property -dict [ list \
CONFIG.REG_CONFIG {16} \
] $axis_register_slice_rx_0
# Create instance: axis_register_slice_rx_1, and set properties
set axis_register_slice_rx_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_register_slice:1.1 axis_register_slice_rx_1 ]
set_property -dict [ list \
CONFIG.REG_CONFIG {16} \
] $axis_register_slice_rx_1
] $axis_register_slice_rx
# Create instance: axis_register_slice_tx, and set properties
set axis_register_slice_tx [ create_bd_cell -type ip -vlnv xilinx.com:ip:axis_register_slice:1.1 axis_register_slice_tx ]
@@ -146,12 +133,10 @@ proc create_hier_cell_mac_100g { parentCell nameHier } {
# Create interface connections
connect_bd_intf_net -intf_net Conn1 [get_bd_intf_pins qsfp] [get_bd_intf_pins cmac_usplus_0/gt_serial_port]
connect_bd_intf_net -intf_net axis_data_fifo_rx_0_M_AXIS [get_bd_intf_pins axis_data_fifo_rx_1/M_AXIS] [get_bd_intf_pins axis_register_slice_rx_0/S_AXIS]
connect_bd_intf_net -intf_net axis_data_fifo_rx_0_M_AXIS [get_bd_intf_pins axis_data_fifo_rx_1/M_AXIS] [get_bd_intf_pins axis_register_slice_rx/S_AXIS]
connect_bd_intf_net -intf_net axis_data_fifo_rx_0_M_AXIS1 [get_bd_intf_pins axis_data_fifo_rx_0/M_AXIS] [get_bd_intf_pins axis_data_fifo_rx_1/S_AXIS]
connect_bd_intf_net -intf_net axis_data_fifo_rx_1_M_AXIS [get_bd_intf_pins axis_data_fifo_rx_2/M_AXIS] [get_bd_intf_pins axis_register_slice_rx_1/S_AXIS]
connect_bd_intf_net -intf_net axis_data_fifo_tx_M_AXIS [get_bd_intf_pins axis_data_fifo_tx/M_AXIS] [get_bd_intf_pins cmac_usplus_0/axis_tx]
connect_bd_intf_net -intf_net axis_register_slice_rx_0_M_AXIS [get_bd_intf_pins axis_data_fifo_rx_2/S_AXIS] [get_bd_intf_pins axis_register_slice_rx_0/M_AXIS]
connect_bd_intf_net -intf_net axis_register_slice_rx_1_M_AXIS [get_bd_intf_pins m_axis_eth_in] [get_bd_intf_pins axis_register_slice_rx_1/M_AXIS]
connect_bd_intf_net -intf_net axis_register_slice_rx_M_AXIS [get_bd_intf_pins m_axis_eth_in] [get_bd_intf_pins axis_register_slice_rx/M_AXIS]
connect_bd_intf_net -intf_net axis_register_slice_tx_M_AXIS [get_bd_intf_pins axis_data_fifo_tx/S_AXIS] [get_bd_intf_pins axis_register_slice_tx/M_AXIS]
connect_bd_intf_net -intf_net cmac_usplus_0_axis_rx [get_bd_intf_pins axis_data_fifo_rx_0/S_AXIS] [get_bd_intf_pins cmac_usplus_0/axis_rx]
connect_bd_intf_net -intf_net gt_ref_clk_0_1 [get_bd_intf_pins qsfp_ref] [get_bd_intf_pins cmac_usplus_0/gt_ref_clk]
@@ -160,12 +145,12 @@ proc create_hier_cell_mac_100g { parentCell nameHier } {
# Create port connections
connect_bd_net -net ap_rst_n_1 [get_bd_pins ap_rst_n] [get_bd_pins util_vector_logic_0/Op1]
connect_bd_net -net axi_clk_net [get_bd_pins axiclk] [get_bd_pins axis_data_fifo_rx_1/m_axis_aclk] [get_bd_pins axis_data_fifo_rx_2/s_axis_aclk] [get_bd_pins axis_data_fifo_tx/s_axis_aclk] [get_bd_pins axis_register_slice_rx_0/aclk] [get_bd_pins axis_register_slice_rx_1/aclk] [get_bd_pins axis_register_slice_tx/aclk]
connect_bd_net -net axi_clk_net [get_bd_pins axiclk] [get_bd_pins axis_data_fifo_rx_1/m_axis_aclk] [get_bd_pins axis_data_fifo_tx/s_axis_aclk] [get_bd_pins axis_register_slice_rx/aclk] [get_bd_pins axis_register_slice_tx/aclk]
connect_bd_net -net cmac_usplus_0_gt_txusrclk2 [get_bd_pins axis_data_fifo_rx_0/s_axis_aclk] [get_bd_pins axis_data_fifo_rx_1/s_axis_aclk] [get_bd_pins axis_data_fifo_tx/m_axis_aclk] [get_bd_pins cmac_usplus_0/gt_txusrclk2] [get_bd_pins cmac_usplus_0/rx_clk]
connect_bd_net -net cmac_usplus_0_stat_rx_status [get_bd_pins led_green] [get_bd_pins cmac_usplus_0/stat_rx_status]
connect_bd_net -net cmac_usplus_0_usr_rx_reset [get_bd_pins cmac_usplus_0/usr_rx_reset] [get_bd_pins util_vector_logic_1/Op1]
connect_bd_net -net init_clk_1 [get_bd_pins refclk100] [get_bd_pins cmac_usplus_0/init_clk] [get_bd_pins cmac_usplus_0/s_axi_aclk]
connect_bd_net -net resetn_1 [get_bd_pins resetn] [get_bd_pins axis_data_fifo_rx_2/s_axis_aresetn] [get_bd_pins axis_data_fifo_tx/s_axis_aresetn] [get_bd_pins axis_register_slice_rx_0/aresetn] [get_bd_pins axis_register_slice_rx_1/aresetn] [get_bd_pins axis_register_slice_tx/aresetn]
connect_bd_net -net resetn_1 [get_bd_pins resetn] [get_bd_pins axis_data_fifo_tx/s_axis_aresetn] [get_bd_pins axis_register_slice_rx/aresetn] [get_bd_pins axis_register_slice_tx/aresetn]
connect_bd_net -net util_vector_logic_0_Res [get_bd_pins cmac_usplus_0/s_axi_sreset] [get_bd_pins cmac_usplus_0/sys_reset] [get_bd_pins util_vector_logic_0/Res]
connect_bd_net -net util_vector_logic_1_Res [get_bd_pins axis_data_fifo_rx_0/s_axis_aresetn] [get_bd_pins axis_data_fifo_rx_1/s_axis_aresetn] [get_bd_pins util_vector_logic_1/Res]
connect_bd_net -net zero_0_dout [get_bd_pins led_yellow] [get_bd_pins cmac_usplus_0/core_drp_reset] [get_bd_pins cmac_usplus_0/core_rx_reset] [get_bd_pins cmac_usplus_0/core_tx_reset] [get_bd_pins cmac_usplus_0/drp_clk] [get_bd_pins zero_0/dout]

View File

@@ -73,7 +73,7 @@ class DetectorSelection extends Component<MyProps, MyState> {
}
render() {
return <Paper style={{textAlign: 'center'}} sx={{ height: 720, width: '100%' }}>
return <Paper style={{textAlign: 'center'}} sx={{ height: 800, width: '100%' }}>
<Grid container spacing={0}>

View File

@@ -17,7 +17,11 @@ type MyState = {
frame_time_error: boolean,
count_time_error: boolean,
storage_cell_delay_error: boolean,
connection_error: boolean
detector_trigger_delay_error: boolean,
internal_frame_generator_images_error: boolean,
connection_error: boolean,
storage_cell_delay_us_text: string,
detector_trigger_delay_us_text: string
}
class DetectorSettings extends Component<MyProps, MyState> {
@@ -33,13 +37,18 @@ class DetectorSettings extends Component<MyProps, MyState> {
pedestal_g0_frames: undefined,
pedestal_g1_frames: undefined,
pedestal_g2_frames: undefined,
storage_cell_delay_ns: 10000,
detector_trigger_delay_ns: undefined
storage_cell_delay_us: 10.0,
detector_trigger_delay_us: 0.0,
internal_frame_generator_images: 1
},
storage_cell_list_value: "1",
storage_cell_delay_us_text: "10.0",
detector_trigger_delay_us_text: "0.0",
detector_trigger_delay_error: false,
frame_time_error: false,
count_time_error: false,
storage_cell_delay_error: false,
internal_frame_generator_images_error: false,
connection_error: true
}
@@ -79,16 +88,52 @@ class DetectorSettings extends Component<MyProps, MyState> {
updateStorageCellDelay = (event: React.ChangeEvent<HTMLInputElement>) => {
let num_val = Number(event.target.value);
let err = !Number.isInteger(num_val);
let err = Number.isNaN(num_val);
if (!err) {
if (num_val < 2100) err = true;
if (num_val < 2.1) err = true;
}
this.setState(prevState => (
{
storage_cell_delay_us_text: event.target.value,
storage_cell_delay_error: err,
s : {...prevState.s,
storage_cell_delay_ns: num_val
storage_cell_delay_us: num_val
}
}
));
}
updateInternalGeneratorImages = (event: React.ChangeEvent<HTMLInputElement>) => {
let num_val = Number(event.target.value);
let err = !Number.isInteger(num_val);
if (!err) {
if ((num_val < 1) || (num_val >= 128)) err = true;
}
this.setState(prevState => (
{
internal_frame_generator_images_error: err,
s : {...prevState.s,
internal_frame_generator_images: num_val
}
}
));
}
updateDetectorTriggerDelay = (event: React.ChangeEvent<HTMLInputElement>) => {
let num_val = Number(event.target.value);
let err = Number.isNaN(num_val);
if (!err) {
if (num_val < 0) err = true;
}
this.setState(prevState => (
{
detector_trigger_delay_us_text: event.target.value,
detector_trigger_delay_error: err,
s : {...prevState.s,
detector_trigger_delay_us: num_val
}
}
));
@@ -112,6 +157,14 @@ class DetectorSettings extends Component<MyProps, MyState> {
));
}
internalFrameGeneratorToggle = (event: React.ChangeEvent<HTMLInputElement>) => {
this.setState(prevState => (
{
s : {...prevState.s,
internal_frame_generator: event.target.checked}
}
));
}
useGainHG0Toggle = (event: React.ChangeEvent<HTMLInputElement>) => {
this.setState(prevState => (
{
@@ -131,7 +184,7 @@ class DetectorSettings extends Component<MyProps, MyState> {
}
deactivate = () => {
DefaultService.postDeactivate()
DefaultService.postDeactivate()
.catch(error => console.log(error) );
}
@@ -140,7 +193,6 @@ class DetectorSettings extends Component<MyProps, MyState> {
s.pedestal_g0_frames = undefined;
s.pedestal_g1_frames = undefined;
s.pedestal_g2_frames = undefined;
s.detector_trigger_delay_ns = undefined;
DefaultService.putConfigDetector(s)
.catch(error => console.log(error) );
}
@@ -159,6 +211,12 @@ class DetectorSettings extends Component<MyProps, MyState> {
DefaultService.getConfigDetector()
.then(data => this.setState({
s: data,
detector_trigger_delay_us_text:
(data.detector_trigger_delay_us === undefined) ? "Unk" :
data.detector_trigger_delay_us.toFixed(3),
storage_cell_delay_us_text:
(data.storage_cell_delay_us === undefined) ? "Unk" :
data.storage_cell_delay_us.toFixed(3),
storage_cell_list_value: String(data.storage_cell_count),
connection_error: false
}))
@@ -172,7 +230,7 @@ class DetectorSettings extends Component<MyProps, MyState> {
}
render() {
return <Paper style={{textAlign: 'center'}} sx={{ height: 720, width: '100%' }}>
return <Paper style={{textAlign: 'center'}} sx={{ height: 800, width: '100%' }}>
<Grid container spacing={0}>
@@ -185,7 +243,7 @@ class DetectorSettings extends Component<MyProps, MyState> {
onChange={this.updateFrameTime}
value={this.state.s.frame_time_us}
disabled={this.state.connection_error}
InputProps = {{
InputProps={{
inputProps: {
style: {textAlign: 'right'}
},
@@ -197,7 +255,7 @@ class DetectorSettings extends Component<MyProps, MyState> {
onChange={this.updateCountTime}
value={this.state.s.count_time_us}
disabled={this.state.connection_error}
InputProps = {{
InputProps={{
inputProps: {
style: {textAlign: 'right'}
},
@@ -205,6 +263,18 @@ class DetectorSettings extends Component<MyProps, MyState> {
}}/>
<br/><br/>
<TextField id="detector_delay" label="Detector delay" variant="outlined"
error={this.state.detector_trigger_delay_error}
onChange={this.updateDetectorTriggerDelay}
value={this.state.detector_trigger_delay_us_text}
disabled={this.state.connection_error}
InputProps={{
inputProps: {
style: {textAlign: 'right'}
},
endAdornment: <InputAdornment position="end">&micro;s</InputAdornment>
}}/>
<br/><br/>
</Grid>
<Grid item xs={1}/>
<Grid item xs={1}/>
@@ -238,15 +308,14 @@ class DetectorSettings extends Component<MyProps, MyState> {
style={{ minWidth: "100px" }}
error={this.state.storage_cell_delay_error}
onChange={this.updateStorageCellDelay}
value={this.state.s.storage_cell_delay_ns}
value={this.state.storage_cell_delay_us_text}
disabled={this.state.connection_error || (this.state.storage_cell_list_value === "1")}
InputProps = {{
inputProps: {
style: {textAlign: 'right'}
},
endAdornment: <InputAdornment position="end">ns</InputAdornment>
endAdornment: <InputAdornment position="end">&micro;s</InputAdornment>
}}/>
<br/><br/>
</Grid>
<Grid item xs={1}/>
@@ -254,19 +323,43 @@ class DetectorSettings extends Component<MyProps, MyState> {
<Grid item xs={10}>
<Switch onChange={this.rawDataToggle} checked={this.state.s.collect_raw_data}
disabled={this.state.connection_error}/>
Collect raw data <br/><br/>
Raw (uncorrected)
<Switch onChange={this.fixedGainG1Toggle} checked={this.state.s.fixed_gain_g1}
disabled={this.state.connection_error}/>
Fixed gain G1 <br/><br/>
Fixed G1
<Switch onChange={this.useGainHG0Toggle} checked={this.state.s.use_gain_hg0}
disabled={this.state.connection_error}/>
Use gain HG0 <br/><br/>
HG0
</Grid>
<Grid item xs={1}/>
<Grid item xs={1}/>
<Grid item xs={10}>
<Switch onChange={this.internalFrameGeneratorToggle}
checked={this.state.s.internal_frame_generator}
disabled={this.state.connection_error}/>
Internal generator<br/><br/>
<TextField id="internal_generator-images" label="Internal generator images" variant="outlined"
style={{ minWidth: "50px" }}
error={this.state.internal_frame_generator_images_error}
onChange={this.updateInternalGeneratorImages}
value={this.state.s.internal_frame_generator_images}
disabled={this.state.connection_error || !this.state.s.internal_frame_generator}
InputProps = {{
inputProps: {
style: {textAlign: 'right'}
}
}}/>
<br/><br/>
</Grid>
<Grid item xs={1}/>
<Grid item xs={1}/>
<Grid item xs={10}>
<Button color="secondary" onClick={this.downloadButton} variant="contained" disableElevation>
Reload</Button>&nbsp;&nbsp;
Download</Button>&nbsp;&nbsp;
<Button color="secondary" onClick={this.uploadButton} variant="contained" disableElevation
disabled={this.state.count_time_error
|| this.state.frame_time_error
|| this.state.internal_frame_generator_images_error
|| this.state.storage_cell_delay_error}>Upload</Button>
<br/><br/>
<Button color="secondary" onClick={this.deactivate} variant="contained" disableElevation>
@@ -274,8 +367,6 @@ class DetectorSettings extends Component<MyProps, MyState> {
<br/><br/>
</Grid>
<Grid item xs={1}/>
</Grid>
</Paper>
}

View File

@@ -57,7 +57,7 @@ class DetectorStatus extends Component<MyProps, MyState> {
}
render() {
return <Paper style={{textAlign: 'center'}} sx={{ height: 720, width: '100%' }}>
return <Paper style={{textAlign: 'center'}} sx={{ height: 800, width: '100%' }}>
<Grid container spacing={0}>
<Grid item xs={1}/>
<Grid item xs={10}>

View File

@@ -89,6 +89,10 @@ export type dataset_settings = {
* Image appendix, added as user_data to image message
*/
image_appendix?: string;
/**
* For JUNGFRAU conversion it is possible to multiply energy by a given factor to get fractional/multiplied photon counts
*/
photon_energy_multiplier?: number;
/**
* Rectangle for ROI summation
*/

View File

@@ -17,6 +17,7 @@ export type detector_settings = {
* Use internal frame generator in FPGA instead of getting data from a real detector
*/
internal_frame_generator?: boolean;
internal_frame_generator_images?: number;
/**
* Turn off conversion of pixel read-out to photon count
*/
@@ -25,13 +26,13 @@ export type detector_settings = {
pedestal_g1_frames?: number;
pedestal_g2_frames?: number;
/**
* Delay between two storage cells
* Delay between two storage cells [us]
*/
storage_cell_delay_ns?: number;
storage_cell_delay_us?: number;
/**
* Delay between TTL trigger and acquisition start
* Delay between TTL trigger and acquisition start [us]
*/
detector_trigger_delay_ns?: number;
detector_trigger_delay_us?: number;
/**
* Fix gain to G1 (can be useful for storage cells)
*/

View File

@@ -274,6 +274,35 @@ export class DefaultService {
});
}
/**
* Load binary image for internal FPGA generator
* Load image for internal FPGA generator. This can only happen in Idle state of the detector.
* Requires binary blob with 16-bit integer numbers of size of detector in raw/converted coordinates
* (depending on detector settings).
*
* @param number Image number to upload
* @param requestBody
* @returns any Everything OK
* @throws ApiError
*/
public static putConfigInternalGeneratorImage(
number?: number,
requestBody?: Blob,
): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'PUT',
url: '/config/internal_generator_image',
query: {
'number': number,
},
body: requestBody,
mediaType: 'application/octet-stream',
errors: {
400: `Input parsing or validation error`,
},
});
}
/**
* Select detector
* Jungfraujoch allows to control multiple detectors and/or region-of-interests.

View File

@@ -0,0 +1,49 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include "AzimuthalIntegration.h"
#include "../common/JFJochException.h"
#include "../common/RawToConvertedGeometry.h"
#include "../common/DiffractionGeometry.h"
AzimuthalIntegration::AzimuthalIntegration(const DiffractionExperiment& experiment, const AzimuthalIntegrationMapping &mapping) :
pixel_to_bin(experiment.GetPixelsNum(), UINT16_MAX),
corrections(experiment.GetPixelsNum(), 1.0),
nbins(mapping.GetBinNumber()),
sum(mapping.GetBinNumber(), 0),
count(mapping.GetBinNumber(), 0)
{
auto mapping_raw = mapping.GetPixelToBinMappingRaw();
RawToConvertedGeometry(experiment, pixel_to_bin.data(), mapping_raw.data());
auto &bin_to_q = mapping.GetBinToQ();
solid_angle_corr.resize(mapping.GetBinNumber());
for (int i = 0; i < mapping.GetBinNumber(); i++)
solid_angle_corr[i] = 1.0 / CalcAzIntSolidAngleCorr(experiment, bin_to_q[i]);
}
void AzimuthalIntegration::Process(const int16_t *data, size_t npixel) {
if (npixel != pixel_to_bin.size())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Mismatch in size of pixel-to-bin mapping and image");
for (int i = 0; i < npixel; i++) {
auto bin = pixel_to_bin[i];
auto value = data[i];
if ((value > INT16_MIN + 4) && (value < INT16_MAX - 4) && (bin < nbins)) {
sum[bin] += value;
count[bin] += 1;
}
}
}
void AzimuthalIntegration::GetResult(std::vector<double> &result) const {
result.resize(nbins);
for (int i = 0; i < nbins; i++) {
if (count[i] > 0)
result[i] = static_cast<double>(sum[i]) / static_cast<double>(count[i]) * solid_angle_corr[i];
else
result[i] = 0;
}
}

View File

@@ -0,0 +1,27 @@
// Copyright (2019-2024) Paul Scherrer Institute
#ifndef JUNGFRAUJOCH_AZIMUTHALINTEGRATION_H
#define JUNGFRAUJOCH_AZIMUTHALINTEGRATION_H
#include <vector>
#include <cstdint>
#include <cmath>
#include "../common/DiffractionExperiment.h"
#include "AzimuthalIntegrationMapping.h"
class AzimuthalIntegration {
std::vector<uint16_t> pixel_to_bin;
std::vector<float> corrections;
std::vector<float> solid_angle_corr;
const uint16_t nbins;
std::vector<int64_t> sum;
std::vector<int64_t> count;
public:
AzimuthalIntegration(const DiffractionExperiment& experiment, const AzimuthalIntegrationMapping& mapping);
void Process(const int16_t *data, size_t npixel);
void GetResult(std::vector<double> &result) const;
};
#endif //JUNGFRAUJOCH_AZIMUTHALINTEGRATION_H

View File

@@ -3,7 +3,9 @@ ADD_LIBRARY(JFJochImageAnalysis STATIC
IndexerWrapper.cpp IndexerWrapper.h
AzimuthalIntegrationMapping.cpp AzimuthalIntegrationMapping.h
StrongPixelSet.cpp StrongPixelSet.h AzimuthalIntegrationProfile.cpp AzimuthalIntegrationProfile.h
SpotFindingSettings.h)
SpotFindingSettings.h
AzimuthalIntegration.cpp
AzimuthalIntegration.h)
TARGET_LINK_LIBRARIES(JFJochImageAnalysis JFJochCommon)

View File

@@ -154,3 +154,41 @@ std::string JFJochReceiverService::GetJPEG(const PreviewJPEGSettings &settings)
else
return "";
}
void JFJochReceiverService::LoadInternalGeneratorImage(const DiffractionExperiment &experiment,
const std::vector<uint16_t> &image,
uint64_t image_number) {
std::vector<uint16_t> raw_geom, eiger_geom;
const uint16_t *frame;
if (image.size() == RAW_MODULE_SIZE * experiment.GetModulesNum()) {
frame = image.data();
} else if (image.size() == experiment.GetPixelsNum()) {
raw_geom.resize(RAW_MODULE_SIZE * experiment.GetModulesNum());
ConvertedToRawGeometry(experiment, raw_geom.data(), image.data());
frame = raw_geom.data();
} else
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Size of input array with raw expected image is wrong");
for (int i = 0; i < experiment.GetDataStreamsNum(); i++) {
uint32_t module0 = experiment.GetFirstModuleOfDataStream(i);
switch (experiment.GetDetectorSetup().GetDetectorType()) {
case DetectorType::EIGER:
eiger_geom.resize(RAW_MODULE_SIZE);
for (int m = 0; m < experiment.GetModulesNum(i); m++) {
RawToEigerInput(eiger_geom.data(), frame + (module0 + m) * RAW_MODULE_SIZE);
aq_devices[i].SetInternalGeneratorFrame(eiger_geom.data(),
m + experiment.GetModulesNum(i) * image_number);
}
break;
case DetectorType::JUNGFRAU:
for (int m = 0; m < experiment.GetModulesNum(i); m++)
aq_devices[i].SetInternalGeneratorFrame(frame + (module0 + m) * RAW_MODULE_SIZE,
m + experiment.GetModulesNum(i) * image_number);
break;
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Detector not supported");
}
}
}

View File

@@ -33,6 +33,9 @@ public:
JFJochReceiverService& NUMAPolicy(const NUMAHWPolicy& policy);
JFJochReceiverService& NUMAPolicy(const std::string& policy);
void LoadInternalGeneratorImage(const DiffractionExperiment& experiment,
const std::vector<uint16_t> &raw_expected_image,
uint64_t image_number);
void Start(const DiffractionExperiment &experiment, const JFCalibration *calibration);
void Cancel(bool silent);
JFJochReceiverOutput Stop();

View File

@@ -7,38 +7,6 @@
#define STORAGE_CELL_FOR_TEST 11
JFJochReceiverOutput RunJFJochReceiverTest(AcquisitionDeviceGroup &aq_devices, ImagePusher &pusher,
const DiffractionExperiment &x,
Logger &logger, JFCalibration &calib,
uint16_t nthreads, bool abort,
ZMQStream2PreviewPublisher *in_preview_writer,
const std::string &numa_policy) {
ZMQContext context;
context.NumThreads(4);
JFJochReceiverService service(aq_devices, logger, pusher);
service.PreviewPublisher(in_preview_writer).NumThreads(nthreads).NUMAPolicy(numa_policy);
SpotFindingSettings settings = DiffractionExperiment::DefaultDataProcessingSettings();
settings.signal_to_noise_threshold = 2.5;
settings.photon_count_threshold = 5;
settings.min_pix_per_spot = 1;
settings.max_pix_per_spot = 200;
service.SetSpotFindingSettings(settings);
service.Start(x, &calib);
if (x.GetImageNum() > 0) {
// Initial communication
if (abort) {
std::this_thread::sleep_for(std::chrono::seconds(60));
service.Cancel(false);
}
}
return service.Stop();
}
static JFCalibration GeneratePedestalCalibration(const DiffractionExperiment &x) {
JFCalibration ret(x);
@@ -66,7 +34,7 @@ static JFCalibration GeneratePedestalCalibration(const DiffractionExperiment &x)
bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
AcquisitionDeviceGroup &aq_devices, const DiffractionExperiment &x,
uint16_t nthreads, bool abort,
uint16_t nthreads,
ZMQStream2PreviewPublisher *in_preview_writer,
const std::string &numa_policy) {
@@ -75,38 +43,16 @@ bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
for (int i = 0; i < raw_expected_image.size(); i++)
raw_expected_image[i] = i % 65536;
return JFJochReceiverTest(output, logger, aq_devices, x,
raw_expected_image, nthreads, abort,
in_preview_writer, numa_policy);
return JFJochReceiverTest(output, logger, aq_devices, x, raw_expected_image, nthreads, in_preview_writer, numa_policy);
}
bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
AcquisitionDeviceGroup &aq_devices, const DiffractionExperiment &x,
const std::vector<uint16_t> &raw_expected_image,
uint16_t nthreads, bool abort,
uint16_t nthreads,
ZMQStream2PreviewPublisher *in_preview_writer,
const std::string &numa_policy) {
if (raw_expected_image.size() != RAW_MODULE_SIZE * x.GetModulesNum())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Size of input array with raw expected image is wrong");
for (int i = 0; i < x.GetDataStreamsNum(); i++) {
uint32_t module0 = x.GetFirstModuleOfDataStream(i);
if (x.GetDetectorSetup().GetDetectorType() == DetectorType::JUNGFRAU) {
for (int m = 0; m < x.GetModulesNum(i); m++)
aq_devices[i].SetInternalGeneratorFrame(raw_expected_image.data() + (module0 + m) * RAW_MODULE_SIZE, m);
} else if (x.GetDetectorSetup().GetDetectorType() == DetectorType::EIGER) {
std::vector<uint16_t> tmp(RAW_MODULE_SIZE);
for (int m = 0; m < x.GetModulesNum(i); m++) {
RawToEigerInput(tmp.data(), raw_expected_image.data() + (module0 + m) * RAW_MODULE_SIZE);
aq_devices[i].SetInternalGeneratorFrame(tmp.data(), m);
}
} else
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Detector not supported");
}
JFCalibration calib = GeneratePedestalCalibration(x);
int64_t image_number = x.GetImageNum() - 1;
@@ -118,12 +64,23 @@ bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
TestImagePusher pusher(image_number);
output = RunJFJochReceiverTest(aq_devices, pusher, x, logger, calib, nthreads, abort,
in_preview_writer, numa_policy);
JFJochReceiverService service(aq_devices, logger, pusher);
service.PreviewPublisher(in_preview_writer).NumThreads(nthreads).NUMAPolicy(numa_policy);
service.LoadInternalGeneratorImage(x, raw_expected_image, 0);
SpotFindingSettings settings = DiffractionExperiment::DefaultDataProcessingSettings();
settings.signal_to_noise_threshold = 2.5;
settings.photon_count_threshold = 5;
settings.min_pix_per_spot = 1;
settings.max_pix_per_spot = 200;
service.SetSpotFindingSettings(settings);
service.Start(x, &calib);
output = service.Stop();
bool no_errors = true;
if ((x.GetImageNum() > 0) && (!abort)) {
if (x.GetImageNum() > 0) {
no_errors = pusher.CheckImage(x, raw_expected_image, calib, logger);
if (output.efficiency != 1.0) {

View File

@@ -5,22 +5,16 @@
#ifndef JUNGFRAUJOCH_JFJOCHRECEIVERTEST_H
#define JUNGFRAUJOCH_JFJOCHRECEIVERTEST_H
JFJochReceiverOutput RunJFJochReceiverTest(AcquisitionDeviceGroup &aq_devices, ImagePusher &pusher,
const DiffractionExperiment &x, Logger &logger, JFCalibration &calib,
uint16_t nthreads, bool abort = false,
ZMQStream2PreviewPublisher *in_preview_writer = nullptr,
const std::string &numa_policy = "");
bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
AcquisitionDeviceGroup &aq_devices, const DiffractionExperiment &x,
uint16_t nthreads, bool abort = false,
uint16_t nthreads,
ZMQStream2PreviewPublisher *in_preview_writer = nullptr,
const std::string &numa_policy = "");
bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
AcquisitionDeviceGroup &aq_devices, const DiffractionExperiment &x,
const std::vector<uint16_t> &data,
uint16_t nthreads, bool abort = false,
uint16_t nthreads,
ZMQStream2PreviewPublisher *in_preview_writer = nullptr,
const std::string &numa_policy = "");

View File

@@ -105,6 +105,8 @@ int main(int argc, char **argv) {
x.ImagesPerTrigger(nimages).Summation(nsummation).PedestalG0Frames(0).UseInternalPacketGenerator(true).PhotonEnergy_keV(12.4).NumTriggers(1);
x.MaskModuleEdges(false).MaskChipEdges(false).BeamX_pxl(x.GetXPixelsNum()/ 2.0).BeamY_pxl(x.GetYPixelsNum()/ 2.0).DetectorDistance_mm(100);
x.Compression(CompressionAlgorithm::BSHUF_LZ4).DataStreams(nstreams);
x.SetUnitCell(UnitCell{.a = 79, .b = 79, .c = 37, .alpha = 90.0, .beta = 90.0, .gamma = 90.0});
if (force_32bit)
x.FPGAOutputMode(FPGAPixelOutput::Int32);
if (!resonet_path.empty())
@@ -159,8 +161,7 @@ int main(int argc, char **argv) {
bool ret;
std::thread run_thread([&] {
try {
ret = JFJochReceiverTest(output, logger, aq_devices, x, input,
nthreads, false, nullptr, numa_policy_name);
ret = JFJochReceiverTest(output, logger, aq_devices, x, input, nthreads, nullptr, numa_policy_name);
} catch (std::exception &e) {
logger.Error(e.what());
ret = false;

View File

@@ -62,7 +62,7 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
.summation = 567,
.az_int_bin_to_q = {0.1, 0.2, 0.3, 0.5},
.total_flux = 123,
.attenuator_transmission = 57,
.attenuator_transmission = 0.345,
.roi_summation_area = ROIRectangle{12,15,17,29},
.user_data = "Some random string 12345"
};

View File

@@ -777,8 +777,6 @@ TEST_CASE("DiffractionExperiment_EIGER","[DiffractionExperiment]") {
REQUIRE(!x.IsConversionOnFPGA());
REQUIRE(!x.IsPixelSigned());
REQUIRE(x.GetPhotonEnergyMultiplier() == 1.0f);
REQUIRE_NOTHROW(x.PhotonEnergyMultiplayer(1.0f));
REQUIRE_THROWS(x.PhotonEnergyMultiplayer(2.0f));
}
TEST_CASE("DiffractionExperiment_PhotonEnergyMultiplayer","[DiffractionExperiment]") {

View File

@@ -5,76 +5,96 @@
TEST_CASE("FPGA_FrameGenerator_Cancel") {
STREAM_512 data_out;
std::vector<ap_uint<256>> d_hbm_p0(RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p1(RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p0(RAW_MODULE_SIZE/(256/8) * 22 * 32);
std::vector<ap_uint<256>> d_hbm_p1(RAW_MODULE_SIZE/(256/8) * 22 * 32);
ap_uint<1> cancel = 1;
FrameGeneratorConfig config{
.frames = 256,
.modules = 8,
.detector_type = SLS_DETECTOR_TYPE_JUNGFRAU
.detector_type = SLS_DETECTOR_TYPE_JUNGFRAU,
.images_in_memory = 0
};
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 0, 0, 0, cancel, config) == 0);
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 16*1024*1024, 0, 0, cancel, config) == 0);
REQUIRE(data_out.size() == 130);
}
TEST_CASE("FPGA_FrameGenerator_WrongDetectorType") {
STREAM_512 data_out;
std::vector<ap_uint<256>> d_hbm_p0(RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p1(RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p0(RAW_MODULE_SIZE/(256/8) * 22 * 32);
std::vector<ap_uint<256>> d_hbm_p1(RAW_MODULE_SIZE/(256/8) * 22 * 32);
ap_uint<1> cancel = 1;
FrameGeneratorConfig config{
.frames = 256,
.modules = 8,
.detector_type = 0
.detector_type = 0,
.images_in_memory = 0
};
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 0, 0, 0, cancel, config) != 0);
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 16*1024*1024, 0, 0, cancel, config) != 0);
REQUIRE(data_out.size() == 0);
}
TEST_CASE("FPGA_FrameGenerator_WrongModuleCount") {
STREAM_512 data_out;
std::vector<ap_uint<256>> d_hbm_p0(RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p1(RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p0(RAW_MODULE_SIZE/(256/8) * 22 * 32);
std::vector<ap_uint<256>> d_hbm_p1(RAW_MODULE_SIZE/(256/8) * 22 * 32);
ap_uint<1> cancel = 1;
FrameGeneratorConfig config{
.frames = 256,
.modules = MAX_MODULES_FPGA + 1,
.detector_type = SLS_DETECTOR_TYPE_JUNGFRAU
.detector_type = SLS_DETECTOR_TYPE_JUNGFRAU,
.images_in_memory = 0
};
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 0, 0, 0, cancel, config) != 0);
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 16*1024*1024, 0, 0, cancel, config) != 0);
REQUIRE(data_out.size() == 0);
config.modules = 0;
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 0, 0, 0, cancel, config) != 0);
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 16*1024*1024, 0, 0, cancel, config) != 0);
REQUIRE(data_out.size() == 0);
}
TEST_CASE("FPGA_FrameGenerator_TooManyCells") {
STREAM_512 data_out;
std::vector<ap_uint<256>> d_hbm_p0(RAW_MODULE_SIZE/(256/8) * 22 * 32);
std::vector<ap_uint<256>> d_hbm_p1(RAW_MODULE_SIZE/(256/8) * 22 * 32);
ap_uint<1> cancel = 1;
FrameGeneratorConfig config{
.frames = 256,
.modules = 4,
.detector_type = SLS_DETECTOR_TYPE_JUNGFRAU,
.images_in_memory = 8
};
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 16*1024*1024, 0, 0, cancel, config) == 3);
REQUIRE(data_out.size() == 0);
}
TEST_CASE("FPGA_FrameGenerator_Run_JF") {
STREAM_512 data_out;
std::vector<ap_uint<256>> d_hbm_p0(2*RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p1(2*RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p0(RAW_MODULE_SIZE/(256/8) * 22 * 32);
std::vector<ap_uint<256>> d_hbm_p1(RAW_MODULE_SIZE/(256/8) * 22 * 32);
ap_uint<1> cancel = 0;
FrameGeneratorConfig config{
.frames = 2,
.modules = 2,
.detector_type = SLS_DETECTOR_TYPE_JUNGFRAU
.detector_type = SLS_DETECTOR_TYPE_JUNGFRAU,
.images_in_memory = 0
};
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 0, 0, 0, cancel, config) == 0);
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 16*1024*1024, 0, 0, cancel, config) == 0);
REQUIRE(data_out.size() == (config.frames * config.modules * 128 + 1) * 130);
}
TEST_CASE("FPGA_FrameGenerator_Run_EIGER") {
STREAM_512 data_out;
std::vector<ap_uint<256>> d_hbm_p0(2*RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p1(2*RAW_MODULE_SIZE/(256/8));
std::vector<ap_uint<256>> d_hbm_p0(RAW_MODULE_SIZE/(256/8) * 22 * 32);
std::vector<ap_uint<256>> d_hbm_p1(RAW_MODULE_SIZE/(256/8) * 22 * 32);
ap_uint<1> cancel = 0;
FrameGeneratorConfig config{
.frames = 2,
.modules = 2,
.detector_type = SLS_DETECTOR_TYPE_EIGER
.detector_type = SLS_DETECTOR_TYPE_EIGER,
.images_in_memory = 0
};
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 0, 0, 0, cancel, config) == 0);
REQUIRE(frame_generator(data_out, d_hbm_p0.data(), d_hbm_p1.data(), 16*1024*1024, 0, 0, cancel, config) == 0);
REQUIRE(data_out.size() == (config.frames * config.modules * 256) * 66 + 130); // Trailing packet is JF type!
}

View File

@@ -2156,3 +2156,37 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_roi_calc", "[FPGA][Full]")
}
}
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_4_images", "[FPGA][Full]") {
const uint16_t nmodules = 4;
const uint16_t nimages = 4;
DiffractionExperiment x((DetectorGeometry(nmodules)));
x.Mode(DetectorMode::Raw);
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nimages).PedestalG0Frames(0).InternalPacketGeneratorImages(nimages);
HLSSimulatedDevice test(0, 64);
std::vector<uint16_t> ref_data(RAW_MODULE_SIZE*nimages*nmodules);
for (int i = 0; i < ref_data.size(); i++)
ref_data[i] = (7 * i + 5) % 65521;
for (int m = 0; m < nmodules*nimages; m++)
test.SetInternalGeneratorFrame(ref_data.data() + RAW_MODULE_SIZE * m, m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.OutputStream().size() == 1);
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
for (int m = 0; m < nmodules; m++) {
std::cout << image << " " << m << std::endl;
auto imageBuf = (uint16_t *) test.GetDeviceOutput(image, m)->pixels;
for (int i = 0; i < RAW_MODULE_SIZE; i++)
REQUIRE(imageBuf[i] == ref_data[i + (image * nmodules + m) * RAW_MODULE_SIZE]);
}
}
}

View File

@@ -6,6 +6,7 @@
#include "../acquisition_device/HLSSimulatedDevice.h"
#include "../jungfrau/JFPedestalCalc.h"
#include "../frame_serialize/TestImagePusher.h"
#include "../receiver/JFJochReceiverService.h"
using namespace std::literals::chrono_literals;
@@ -27,7 +28,7 @@ TEST_CASE("JFJochReceiverTest_Raw", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
@@ -55,7 +56,7 @@ TEST_CASE("JFJochReceiverTest_Conversion", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
@@ -82,7 +83,7 @@ TEST_CASE("JFJochReceiverTest_Conversion_FixedGainG1", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
@@ -111,7 +112,7 @@ TEST_CASE("JFJochReceiverTest_Conversion_FixedGainG1_onlyG1", "[JFJochReceiver]"
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, input, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, input, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
@@ -138,7 +139,7 @@ TEST_CASE("JFJochReceiverTest_Conversion_U16", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
@@ -164,7 +165,7 @@ TEST_CASE("JFJochReceiverTest_Conversion_I32", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
@@ -190,7 +191,7 @@ TEST_CASE("JFJochReceiverTest_Conversion_Summation2", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
@@ -219,7 +220,7 @@ TEST_CASE("JFJochReceiverTest_Conversion_StorageCell", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
@@ -268,7 +269,7 @@ TEST_CASE("JFJochReceiverTest_PedestalG1", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.status.images_sent == x.GetImageNum());
REQUIRE(output.efficiency == 1.0);
@@ -333,7 +334,7 @@ TEST_CASE("JFJochReceiverTest_PedestalG2_storage_cell", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.status.images_sent == x.GetImageNum());
REQUIRE(output.efficiency == 1.0);
@@ -385,7 +386,7 @@ TEST_CASE("JFJochReceiverTest_PedestalG0", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_PedestalG0");
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads,false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.status.images_sent == x.GetImageNum());
REQUIRE(output.efficiency == 1.0);
@@ -431,7 +432,7 @@ TEST_CASE("JFJochReceiverTest_PedestalG0_StorageCell", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_PedestalG0_StorageCell");
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.status.images_sent == x.GetImageNum());
REQUIRE(output.efficiency == 1.0);
@@ -470,7 +471,7 @@ TEST_CASE("JFJochReceiverTest_PedestalG1_NoFrames", "[JFJochReceiver]") {
Logger logger("JFJochReceiverTest_PedestalG1_NoFrames");
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.status.images_sent == 0);
REQUIRE(output.efficiency < 1.0);
@@ -512,7 +513,12 @@ TEST_CASE("JFJochReceiverTest_PacketLost_Raw", "[JFJochReceiver]") {
JFCalibration calib(x);
TestImagePusher pusher(x.GetImageNum() - 1);
auto receiver_out = RunJFJochReceiverTest(aq_devices, pusher, x, logger, calib, nthreads, false);
JFJochReceiverService service(aq_devices, logger, pusher);
service.NumThreads(nthreads);
service.Start(x, &calib);
auto receiver_out = service.Stop();
const auto image = pusher.GetImage();
@@ -556,12 +562,20 @@ TEST_CASE("JFJochReceiverTest_Cancel", "[JFJochReceiver]") {
test->CreateJFPackets(x, 3, 1, 1, frame_in.data());
aq_devices.Add(std::move(test));
}
Logger logger("JFJochReceiverTest_Cancelw");
Logger logger("JFJochReceiverTest_Cancel");
JFCalibration calib(x);
TestImagePusher pusher(x.GetImageNum() - 1);
auto receiver_out = RunJFJochReceiverTest(aq_devices, pusher, x, logger, calib, nthreads, true);
JFJochReceiverService service(aq_devices, logger, pusher);
service.NumThreads(nthreads);
service.Start(x, &calib);
std::this_thread::sleep_for(std::chrono::seconds(60));
service.Cancel(false);
auto receiver_out = service.Stop();
REQUIRE(receiver_out.status.cancelled);
}
@@ -583,7 +597,7 @@ TEST_CASE("JFJochReceiverTest_EIGER", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());
@@ -609,7 +623,7 @@ TEST_CASE("JFJochReceiverTest_EIGER_conversion", "[JFJochReceiver]") {
JFJochReceiverOutput output;
bool ret;
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads, false));
REQUIRE_NOTHROW(ret = JFJochReceiverTest(output, logger, aq_devices, x, nthreads));
REQUIRE(ret);
REQUIRE(output.efficiency == 1.0);
REQUIRE(output.status.images_sent == x.GetImageNum());

View File

@@ -12,12 +12,6 @@ TEST_CASE("JFJochStateMachine_States") {
state_machine.AddDetectorSetup(DetectorGeometry(4));
DatasetSettings setup;
setup.ntrigger = 1;
setup.detector_distance_mm = 100;
setup.file_prefix = "integration_test";
setup.images_per_trigger = 5;
setup.photon_energy_keV = 12.4;
setup.data_file_count = 5;
JFJochState state;
REQUIRE_NOTHROW(state = state_machine.GetState());
@@ -43,12 +37,6 @@ TEST_CASE("JFJochStateMachine_State_Pedestal") {
state_machine.AddDetectorSetup(DetectorGeometry(4));
DatasetSettings setup;
setup.ntrigger = 1;
setup.detector_distance_mm = 100;
setup.file_prefix = "integration_test";
setup.images_per_trigger = 5;
setup.photon_energy_keV = 12.4;
setup.data_file_count = 5;
state_machine.DebugOnly_SetState(JFJochState::Pedestal);
@@ -74,12 +62,6 @@ TEST_CASE("JFJochStateMachine_State_Measure") {
state_machine.AddDetectorSetup(DetectorGeometry(4));
DatasetSettings setup;
setup.ntrigger = 1;
setup.detector_distance_mm = 100;
setup.file_prefix = "integration_test";
setup.images_per_trigger = 5;
setup.photon_energy_keV = 12.4;
setup.data_file_count = 5;
state_machine.DebugOnly_SetState(JFJochState::Measuring);
@@ -105,12 +87,6 @@ TEST_CASE("JFJochStateMachine_State_Error") {
state_machine.AddDetectorSetup(DetectorGeometry(4));
DatasetSettings setup;
setup.ntrigger = 1;
setup.detector_distance_mm = 100;
setup.file_prefix = "integration_test";
setup.images_per_trigger = 5;
setup.photon_energy_keV = 12.4;
setup.data_file_count = 5;
state_machine.DebugOnly_SetState(JFJochState::Error);
@@ -246,58 +222,6 @@ TEST_CASE("JFJochStateMachine_AddDetectorSetup_Multiple") {
REQUIRE(state_machine.GetState() == JFJochState::Inactive);
}
TEST_CASE("JFJochStateMachine_LoadDatasetSettings", "[DiffractionExperiment]") {
DiffractionExperiment x;
x.ImagesPerTrigger(567).BeamY_pxl(324).Compression(CompressionAlgorithm::BSHUF_ZSTD);
DatasetSettings settings{};
settings.images_per_trigger = 234;
settings.ntrigger = 56;
settings.beam_x_pxl = 23.4;
settings.beam_y_pxl = 123.4;
settings.photon_energy_keV = WVL_1A_IN_KEV;
settings.detector_distance_mm = 57.6;
settings.data_file_count = 5;
settings.space_group_number = 45;
settings.sample_name = "lyso1";
settings.summation = 36;
settings.fpga_pixel_output = FPGAPixelOutput::Int16;
settings.compression = CompressionAlgorithm::BSHUF_LZ4;
settings.photon_energy_multiplier = 1.0;
REQUIRE_NOTHROW(LoadDatasetSettings(x,settings));
REQUIRE(x.GetImageNumPerTrigger() == 234);
REQUIRE(x.GetBeamX_pxl() == Approx(23.4));
REQUIRE(x.GetBeamY_pxl() == Approx(123.4));
REQUIRE(x.GetSpaceGroupNumber() == 45);
REQUIRE(x.GetCompressionAlgorithm() == CompressionAlgorithm::BSHUF_LZ4);
REQUIRE(x.GetSampleName() == "lyso1");
REQUIRE(x.GetDataFileCount() == 5);
REQUIRE(x.GetDetectorDistance_mm() == Approx(57.6));
REQUIRE(x.GetSummation() == 36);
REQUIRE(x.GetFPGAOutputMode() == FPGAPixelOutput::Int16);
}
TEST_CASE("JFJochStateMachine_LoadDatasetSettings_Invalid", "[DiffractionExperiment]") {
DiffractionExperiment x;
x.ImagesPerTrigger(567).BeamY_pxl(324).Compression(CompressionAlgorithm::BSHUF_ZSTD);
DatasetSettings settings{};
settings.images_per_trigger = -1;
settings.ntrigger = 56;
settings.beam_x_pxl = 23.4;
settings.beam_y_pxl = 123.4;
settings.photon_energy_keV = WVL_1A_IN_KEV;
settings.detector_distance_mm = 57.6;
settings.data_file_count = 5;
settings.space_group_number = 45;
settings.sample_name = "lyso1";
REQUIRE_THROWS(LoadDatasetSettings(x, settings));
REQUIRE(x.GetImageNumPerTrigger() == 567);
REQUIRE(x.GetBeamY_pxl() == Approx(324));
REQUIRE(x.GetSpaceGroupNumber() == 0);
}
TEST_CASE("JFJochStateMachine_SetDetectorSettings", "[DiffractionExperiment]") {
Logger logger("JFJochStateMachine_SetDetectorSettings");
JFJochServices services(logger);

View File

@@ -473,6 +473,40 @@ TEST_CASE("RawToConvertedGeometry_Gaps","[RawToConvertedGeometry]") {
free(input2);
}
TEST_CASE("RawToConvertedGeometry_Vertical","[RawToConvertedGeometry]") {
std::vector<DetectorModuleGeometry> module_geom;
REQUIRE_NOTHROW(module_geom.emplace_back(2999, 2999, DetectorModuleGeometry::Direction::Xneg,
DetectorModuleGeometry::Direction::Yneg));
REQUIRE_NOTHROW(module_geom.emplace_back(0, 0, DetectorModuleGeometry::Direction::Ypos,
DetectorModuleGeometry::Direction::Xpos));
REQUIRE_NOTHROW(module_geom.emplace_back(5000, 0, DetectorModuleGeometry::Direction::Ypos,
DetectorModuleGeometry::Direction::Xpos));
DetectorGeometry geometry(module_geom);
DiffractionExperiment x(geometry);
x.DataStreams(3);
x.Mode(DetectorMode::Conversion);
std::vector<uint32_t> input(x.GetModulesNum() * RAW_MODULE_SIZE);
std::vector<uint32_t> input2(x.GetModulesNum() * RAW_MODULE_SIZE);
std::vector<uint32_t> output(x.GetPixelsNum(), UINT32_MAX);
for (uint32_t i = 0; i < x.GetModulesNum() * RAW_MODULE_SIZE; i++)
input[i] = 3*i-1;
RawToConvertedGeometry<uint32_t, uint32_t>(x, output.data(), input.data());
ConvertedToRawGeometry<uint32_t>(x, input2.data(), output.data());
uint64_t diff = 0;
for (int i = 0; i < x.GetModulesNum(2) * RAW_MODULE_SIZE; i++) {
if (input[i] != input2[i]) diff++;
}
REQUIRE(diff == 0);
}
TEST_CASE("RawToConvertedCoordinate","[RawToConvertedGeometry]") {
DiffractionExperiment experiment(DetectorGeometry(4, 2, 8, 36, true));
auto [x,y] = RawToConvertedCoordinate(experiment, 1, 300 * RAW_MODULE_COLS + 800);

View File

@@ -243,7 +243,7 @@ TEST_CASE("JFJochCompressor_JFJochDecompressor_ZSTD","[ZSTD]") {
std::vector<int32_t> output;
REQUIRE_NOTHROW(JFJochDecompress(output, x.GetCompressionAlgorithm(), tmp, x.GetPixelsNum()));
REQUIRE(output.size() == x.GetPixelsNum() * x.GetPixelDepth());
REQUIRE(output.size() == x.GetPixelsNum());
REQUIRE(memcmp(image.data(), output.data(), x.GetPixelsNum() * sizeof(int32_t)) == 0);
}
@@ -265,7 +265,7 @@ TEST_CASE("JFJochCompressor_JFJochDecompressor_LZ4","[ZSTD]") {
std::vector<int32_t> output;
REQUIRE_NOTHROW(JFJochDecompress(output, x.GetCompressionAlgorithm(), tmp, x.GetPixelsNum()));
REQUIRE(output.size() == x.GetPixelsNum() * x.GetPixelDepth());
REQUIRE(output.size() == x.GetPixelsNum());
REQUIRE(memcmp(image.data(), output.data(), x.GetPixelsNum() * sizeof(int32_t)) == 0);
}
@@ -279,7 +279,7 @@ TEST_CASE("JFJochDecompressor_None","[ZSTD]") {
std::vector<int32_t> output;
REQUIRE_NOTHROW(JFJochDecompress(output, x.GetCompressionAlgorithm(), image, x.GetPixelsNum()));
REQUIRE(output.size() == x.GetPixelsNum() * x.GetPixelDepth());
REQUIRE(output.size() == x.GetPixelsNum());
REQUIRE(memcmp(image.data(), output.data(), x.GetPixelsNum() * sizeof(int32_t)) == 0);
}

118
tools/AzimIntDataset.cpp Normal file
View File

@@ -0,0 +1,118 @@
// Copyright (2019-2024) Paul Scherrer Institute
#include <iostream>
#include <cmath>
#include <vector>
#include <future>
#include "../writer/HDF5Objects.h"
#include "../image_analysis/AzimuthalIntegration.h"
#include "../compression/JFJochDecompress.h"
std::mutex m;
void CalcRadialIntegration(const DiffractionExperiment &x, const AzimuthalIntegrationMapping &mapping,
std::vector<double> *result, char *filename, int run, int stride) {
std::unique_lock<std::mutex> ul(m);
HDF5ReadOnlyFile x_data_file(filename);
HDF5DataSet x_dataset(x_data_file, "/entry/data/data");
HDF5DataSpace x_file_space(x_dataset);
std::cout << "# " << run << " " << filename << " images " << x_file_space.GetDimensions()[0] << " stride " << stride
<< std::endl;
AzimuthalIntegration rad_int(x, mapping);
std::vector<uint8_t> buffer;
std::vector<int16_t> uncompressed(x.GetPixelsNum());
for (hsize_t i = 0; i < x_file_space.GetDimensions()[0]; i += stride) {
std::vector<hsize_t> start = {i, 0, 0};
x_dataset.ReadDirectChunk(buffer, start);
ul.unlock();
JFJochDecompress(uncompressed, CompressionAlgorithm::BSHUF_LZ4, buffer, x.GetPixelsNum());
rad_int.Process(uncompressed.data(), x.GetPixelsNum());
ul.lock();
}
rad_int.GetResult(*result);
}
void GetGeometry(DiffractionExperiment &x, HDF5Object &master_file) {
x.BeamX_pxl(
HDF5DataSet(master_file, "/entry/instrument/detector/beam_center_x").ReadScalar<double>());
x.BeamY_pxl(
HDF5DataSet(master_file, "/entry/instrument/detector/beam_center_y").ReadScalar<double>());
x.DetectorDistance_mm(
HDF5DataSet(master_file, "/entry/instrument/detector/detector_distance").ReadScalar<double>() *1e3);
x.PhotonEnergy_keV(WVL_1A_IN_KEV /
HDF5DataSet(master_file, "/entry/instrument/beam/incident_wavelength").ReadScalar<double>());
}
int main(int argc, char **argv) {
RegisterHDF5Filter();
if (argc < 4) {
std::cout << "Usage ./ImageAverage <name of master dataset> <stride> {<name of data dataset>+}" << std::endl;
exit(EXIT_FAILURE);
}
int stride = atoi(argv[2]);
size_t nfiles = argc - 3;
if (stride <= 0) {
std::cout << "Stride cannot be less than 1" << std::endl;
exit(EXIT_FAILURE);
}
HDF5ReadOnlyFile master_file(argv[1]);
HDF5ReadOnlyFile data_file(argv[3]);
HDF5DataSet dataset(data_file, "/entry/data/data");
HDF5DataSpace file_space(dataset);
if (file_space.GetNumOfDimensions() != 3) {
std::cout << "/entry/data/data must be 3D" << std::endl;
exit(EXIT_FAILURE);
}
DiffractionExperiment x;
if ((file_space.GetDimensions()[1] == 2164) && (file_space.GetDimensions()[2] == 2068)) {
std::cout << "# JF4M with gaps detected (2068 x 2164)" << std::endl;
x = DiffractionExperiment(DetectorGeometry(8, 2, 8, 36));
} else if ((file_space.GetDimensions()[1] == 3264) && (file_space.GetDimensions()[2] == 3106)) {
std::cout << "# JF9M with gaps detected (3106x3264)" << std::endl;
x = DiffractionExperiment(DetectorGeometry(18, 3, 8, 36));
} else {
std::cout << "# Unknown geometry - exiting" << std::endl;
exit(EXIT_FAILURE);
}
GetGeometry(x, master_file);
std::cout << "# beam_center " << x.GetBeamX_pxl() << " " << x.GetBeamY_pxl() << std::endl;
std::cout << "# detector_distance " << x.GetDetectorDistance_mm() << std::endl;
std::cout << "# energy " << x.GetPhotonEnergyForConversion_keV() << std::endl;
AzimuthalIntegrationMapping rad_int_map(x);
auto result_x = rad_int_map.GetBinToQ();
std::vector<std::vector<double> > result(nfiles);
std::vector<std::future<void>> futures;
for (int i = 0; i < nfiles; i++)
futures.emplace_back(std::async(std::launch::async, &CalcRadialIntegration,
std::ref(x), std::ref(rad_int_map), &result[i], argv[i+3], i, stride));
for (int i = 0; i < nfiles; i++)
futures[i].get();
for (int i = 0; i < result_x.size(); i++) {
std::cout << result_x[i] << " ";
for (int f = 0; f < nfiles; f++)
std::cout << result[f][i] << " ";
std::cout << std::endl;
}
}

View File

@@ -20,4 +20,7 @@ TARGET_LINK_LIBRARIES(gain_file_statistics JFJochCommon)
ADD_EXECUTABLE(SpotFindingPerformanceTest SpotFindingPerformanceTest.cpp)
TARGET_LINK_LIBRARIES(SpotFindingPerformanceTest JFJochImageAnalysis JFJochCommon)
INSTALL(TARGETS jfjoch_udp_simulator CompressionBenchmark HDF5DatasetWriteTest jfjoch_writer_test RUNTIME)
ADD_EXECUTABLE(AzimIntDataset AzimIntDataset.cpp)
TARGET_LINK_LIBRARIES(AzimIntDataset JFJochImageAnalysis JFJochWriter JFJochCommon)
INSTALL(TARGETS jfjoch_udp_simulator CompressionBenchmark HDF5DatasetWriteTest jfjoch_writer_test AzimIntDataset RUNTIME)

View File

@@ -512,6 +512,21 @@ HDF5DataSet::~HDF5DataSet() {
if (id >= 0) H5Dclose(id);
}
void HDF5DataSet::ReadDirectChunk(std::vector<uint8_t> &val, const std::vector<hsize_t> &offset) {
if (offset.size() != ndim)
throw JFJochException(JFJochExceptionCategory::HDF5, "Inconsistent dimension settings");
hsize_t chunk_bytes;
if (H5Dget_chunk_storage_size(id, offset.data(), &chunk_bytes) < 0)
throw JFJochException(JFJochExceptionCategory::HDF5, "Error checking chunk size");
val.resize(chunk_bytes);
uint32_t filters;
if (H5Dread_chunk(id, H5P_DEFAULT, offset.data(), &filters, val.data()))
throw JFJochException(JFJochExceptionCategory::HDF5,
"Error reading dataset (with direct chunks) to HDF5 file");
}
void RegisterHDF5Filter() {
if (H5Zregister(bshuf_H5Filter) < 0)

View File

@@ -182,6 +182,7 @@ public:
}
HDF5DataSet& WriteDirectChunk(const void *val, hsize_t data_size, const std::vector<hsize_t>& offset);
void ReadDirectChunk(std::vector<uint8_t> &val, const std::vector<hsize_t>& offset);
HDF5DataSet& Flush();
void SetExtent(const std::vector<hsize_t>& dims);