Updates March 2023
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
331
common/DatasetSettings.cpp
Normal 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
111
common/DatasetSettings.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Submodule compression/bitshuffle_hperf updated: be844a76f4...7be5b2005f
@@ -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": [
|
||||
|
||||
@@ -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": [
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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}>
|
||||
|
||||
|
||||
@@ -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">µ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">µ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>
|
||||
Download</Button>
|
||||
<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>
|
||||
}
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
|
||||
49
image_analysis/AzimuthalIntegration.cpp
Normal file
49
image_analysis/AzimuthalIntegration.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
27
image_analysis/AzimuthalIntegration.h
Normal file
27
image_analysis/AzimuthalIntegration.h
Normal 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
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 = "");
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
|
||||
@@ -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]") {
|
||||
|
||||
@@ -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!
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
118
tools/AzimIntDataset.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user