Release 1.0.0_rc.9
This commit is contained in:
@@ -52,6 +52,7 @@ inline org::openapitools::server::model::Measurement_statistics Convert(const Me
|
||||
if (!input.file_prefix.empty())
|
||||
ret.setFilePrefix(input.file_prefix);
|
||||
|
||||
ret.setExperimentGroup(input.experiment_group);
|
||||
ret.setImagesExpected(input.images_expected);
|
||||
ret.setImagesCollected(input.images_collected);
|
||||
ret.setImagesSent(input.images_sent);
|
||||
@@ -75,7 +76,7 @@ inline org::openapitools::server::model::Measurement_statistics Convert(const Me
|
||||
if (input.bkg_estimate)
|
||||
ret.setBkgEstimate(input.bkg_estimate.value());
|
||||
ret.setUnitCell(input.unit_cell);
|
||||
|
||||
ret.setRunNumber(input.run_number);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -192,10 +193,10 @@ inline org::openapitools::server::model::Detector_status Convert(const DetectorS
|
||||
output.setHighVoltageV(input.high_voltage_V);
|
||||
switch (input.power_state) {
|
||||
case DetectorPowerState::ON:
|
||||
output.setPowerchip("On");
|
||||
output.setPowerchip("PowerOn");
|
||||
break;
|
||||
case DetectorPowerState::OFF:
|
||||
output.setPowerchip("Off");
|
||||
output.setPowerchip("PowerOff");
|
||||
break;
|
||||
case DetectorPowerState::PARTIAL:
|
||||
output.setPowerchip("Partial");
|
||||
@@ -336,6 +337,10 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s
|
||||
ret.ImagesPerTrigger(input.getImagesPerTrigger());
|
||||
ret.NumTriggers(input.getNtrigger());
|
||||
|
||||
if (input.runNumberIsSet())
|
||||
ret.RunNumber(input.getRunNumber());
|
||||
ret.ExperimentGroup(input.getExperimentGroup());
|
||||
|
||||
if (!input.fpgaOutputIsSet())
|
||||
ret.FPGAOutputMode(FPGAPixelOutput::Auto);
|
||||
else {
|
||||
@@ -358,9 +363,8 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s
|
||||
ret.BeamX_pxl(input.getBeamXPxl());
|
||||
ret.BeamY_pxl(input.getBeamYPxl());
|
||||
ret.DetectorDistance_mm(input.getDetectorDistanceMm());
|
||||
ret.PhotonEnergy_keV(input.getPhotonEnergyKeV());
|
||||
|
||||
ret.PhotonEnergyMultiplayer(input.getPhotonEnergyMultiplier());
|
||||
ret.PhotonEnergy_keV(input.getIncidentEnergyKeV());
|
||||
ret.PhotonEnergyMultiplayer(input.getEnergyMultiplier());
|
||||
|
||||
ret.FilePrefix(input.getFilePrefix());
|
||||
|
||||
@@ -395,12 +399,15 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s
|
||||
if (input.transmissionIsSet())
|
||||
ret.AttenuatorTransmission(input.getTransmission());
|
||||
|
||||
if (input.omegaIsSet()) {
|
||||
ret.OmegaStep(input.getOmega().getStep());
|
||||
ret.OmegaStart(input.getOmega().getStart());
|
||||
if (input.getOmega().getVector().size() == 3) {
|
||||
auto v = input.getOmega().getVector();
|
||||
ret.OmegaAxis(Coord(v[0], v[1], v[2]));
|
||||
if (input.goniometerIsSet()) {
|
||||
ret.Goniometer(GoniometerAxis{
|
||||
.name = input.getGoniometer().getName(),
|
||||
.increment = input.getGoniometer().getStep(),
|
||||
.start = input.getGoniometer().getStart()
|
||||
});
|
||||
if (input.getGoniometer().getVector().size() == 3) {
|
||||
auto v = input.getGoniometer().getVector();
|
||||
ret.RotationAxis(Coord(v[0], v[1], v[2]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -304,19 +304,21 @@ void ParseFacilityConfiguration(const nlohmann::json &input, const std::string&
|
||||
auto j = input[tag];
|
||||
experiment.SourceName(GET_STR(j, "source_name"));
|
||||
experiment.SourceNameShort(GET_STR(j, "source_name_short"));
|
||||
experiment.SourceType(GET_STR(j, "source_type", ""));
|
||||
|
||||
experiment.InstrumentName(GET_STR(j, "instrument_name"));
|
||||
experiment.InstrumentNameShort(GET_STR(j, "instrument_name_short"));
|
||||
|
||||
experiment.PulsedSource(GET_BOOL(j, "pulsed_source", false));
|
||||
|
||||
if (j.contains("omega_axis")) {
|
||||
if (j["omega_axis"].is_array() && (j["omega_axis"].size() == 3))
|
||||
experiment.DefaultOmegaAxis(Coord(j["omega_axis"][0].get<float>(),
|
||||
j["omega_axis"][1].get<float>(),
|
||||
j["omega_axis"][2].get<float>()));
|
||||
if (j.contains("rotation_axis")) {
|
||||
if (j["rotation_axis"].is_array() && (j["rotation_axis"].size() == 3))
|
||||
experiment.DefaultRotationAxis(Coord(j["rotation_axis"][0].get<float>(),
|
||||
j["rotation_axis"][1].get<float>(),
|
||||
j["rotation_axis"][2].get<float>()));
|
||||
else
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"omega_axis must be float array of 3");
|
||||
"rotation_axis must be float array of 3");
|
||||
}
|
||||
|
||||
if (j.contains("pedestal_g0_frames"))
|
||||
|
||||
@@ -324,7 +324,7 @@ void JFJochStateMachine::Start(const DatasetSettings& settings) {
|
||||
else
|
||||
experiment.StorageCellStart(0);
|
||||
|
||||
experiment.IncrementSeriesID();
|
||||
experiment.IncrementRunNumber();
|
||||
|
||||
try {
|
||||
state = JFJochState::Busy;
|
||||
@@ -401,6 +401,9 @@ void JFJochStateMachine::SetFullMeasurementOutput(const JFJochServicesOutput &ou
|
||||
MeasurementStatistics tmp{}; // reset last measurement statistics
|
||||
|
||||
tmp.file_prefix = experiment.GetFilePrefix();
|
||||
tmp.run_number = experiment.GetRunNumber();
|
||||
tmp.experiment_group = experiment.GetExperimentGroup();
|
||||
|
||||
tmp.detector_width = experiment.GetXPixelsNum();
|
||||
tmp.detector_height = experiment.GetYPixelsNum();
|
||||
tmp.detector_pixel_depth = experiment.GetPixelDepth();
|
||||
@@ -427,6 +430,9 @@ void JFJochStateMachine::ClearAndSetMeasurementStatistics() {
|
||||
MeasurementStatistics tmp{};
|
||||
|
||||
tmp.file_prefix = experiment.GetFilePrefix();
|
||||
tmp.run_number = experiment.GetRunNumber();
|
||||
tmp.experiment_group = experiment.GetExperimentGroup();
|
||||
|
||||
tmp.detector_height = experiment.GetXPixelsNum();
|
||||
tmp.detector_width = experiment.GetYPixelsNum();
|
||||
tmp.detector_pixel_depth = experiment.GetPixelDepth();
|
||||
@@ -448,6 +454,9 @@ std::optional<MeasurementStatistics> JFJochStateMachine::GetMeasurementStatistic
|
||||
MeasurementStatistics tmp;
|
||||
|
||||
tmp.file_prefix = experiment.GetFilePrefix();
|
||||
tmp.run_number = experiment.GetRunNumber();
|
||||
tmp.experiment_group = experiment.GetExperimentGroup();
|
||||
|
||||
tmp.detector_width = experiment.GetXPixelsNum();
|
||||
tmp.detector_height = experiment.GetYPixelsNum();
|
||||
tmp.detector_pixel_depth = experiment.GetPixelDepth();
|
||||
|
||||
@@ -37,6 +37,9 @@ struct DetectorList {
|
||||
|
||||
struct MeasurementStatistics {
|
||||
std::string file_prefix;
|
||||
std::string experiment_group;
|
||||
int64_t run_number;
|
||||
|
||||
int64_t images_expected;
|
||||
int64_t images_collected;
|
||||
int64_t images_sent;
|
||||
|
||||
@@ -30,7 +30,7 @@ Dataset_settings::Dataset_settings()
|
||||
m_Beam_x_pxl = 0.0f;
|
||||
m_Beam_y_pxl = 0.0f;
|
||||
m_Detector_distance_mm = 0.0f;
|
||||
m_Photon_energy_keV = 0.0f;
|
||||
m_Incident_energy_keV = 0.0f;
|
||||
m_File_prefix = "";
|
||||
m_File_prefixIsSet = false;
|
||||
m_Images_per_file = 1000L;
|
||||
@@ -46,15 +46,19 @@ Dataset_settings::Dataset_settings()
|
||||
m_Total_fluxIsSet = false;
|
||||
m_Transmission = 0.0f;
|
||||
m_TransmissionIsSet = false;
|
||||
m_OmegaIsSet = false;
|
||||
m_GoniometerIsSet = false;
|
||||
m_Header_appendix = "";
|
||||
m_Header_appendixIsSet = false;
|
||||
m_Image_appendix = "";
|
||||
m_Image_appendixIsSet = false;
|
||||
m_Photon_energy_multiplier = 1.0f;
|
||||
m_Photon_energy_multiplierIsSet = false;
|
||||
m_Energy_multiplier = 1.0f;
|
||||
m_Energy_multiplierIsSet = false;
|
||||
m_Data_reduction_factor_serialmx = 1.0f;
|
||||
m_Data_reduction_factor_serialmxIsSet = false;
|
||||
m_Run_number = 0L;
|
||||
m_Run_numberIsSet = false;
|
||||
m_Experiment_group = "";
|
||||
m_Experiment_groupIsSet = false;
|
||||
m_Unit_cellIsSet = false;
|
||||
|
||||
}
|
||||
@@ -141,9 +145,9 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP
|
||||
}
|
||||
|
||||
|
||||
/* Photon_energy_keV */ {
|
||||
const float& value = m_Photon_energy_keV;
|
||||
const std::string currentValuePath = _pathPrefix + ".photonEnergyKeV";
|
||||
/* Incident_energy_keV */ {
|
||||
const float& value = m_Incident_energy_keV;
|
||||
const std::string currentValuePath = _pathPrefix + ".incidentEnergyKeV";
|
||||
|
||||
|
||||
if (value < static_cast<float>(0))
|
||||
@@ -206,10 +210,10 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP
|
||||
|
||||
}
|
||||
|
||||
if (photonEnergyMultiplierIsSet())
|
||||
if (energyMultiplierIsSet())
|
||||
{
|
||||
const float& value = m_Photon_energy_multiplier;
|
||||
const std::string currentValuePath = _pathPrefix + ".photonEnergyMultiplier";
|
||||
const float& value = m_Energy_multiplier;
|
||||
const std::string currentValuePath = _pathPrefix + ".energyMultiplier";
|
||||
|
||||
|
||||
if (value < static_cast<float>(0.015625))
|
||||
@@ -243,7 +247,21 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (runNumberIsSet())
|
||||
{
|
||||
const int64_t& value = m_Run_number;
|
||||
const std::string currentValuePath = _pathPrefix + ".runNumber";
|
||||
|
||||
|
||||
if (value < 0ll)
|
||||
{
|
||||
success = false;
|
||||
msg << currentValuePath << ": must be greater than or equal to 0;";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -270,7 +288,7 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
|
||||
(getDetectorDistanceMm() == rhs.getDetectorDistanceMm())
|
||||
&&
|
||||
|
||||
(getPhotonEnergyKeV() == rhs.getPhotonEnergyKeV())
|
||||
(getIncidentEnergyKeV() == rhs.getIncidentEnergyKeV())
|
||||
&&
|
||||
|
||||
|
||||
@@ -298,7 +316,7 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
|
||||
((!transmissionIsSet() && !rhs.transmissionIsSet()) || (transmissionIsSet() && rhs.transmissionIsSet() && getTransmission() == rhs.getTransmission())) &&
|
||||
|
||||
|
||||
((!omegaIsSet() && !rhs.omegaIsSet()) || (omegaIsSet() && rhs.omegaIsSet() && getOmega() == rhs.getOmega())) &&
|
||||
((!goniometerIsSet() && !rhs.goniometerIsSet()) || (goniometerIsSet() && rhs.goniometerIsSet() && getGoniometer() == rhs.getGoniometer())) &&
|
||||
|
||||
|
||||
((!headerAppendixIsSet() && !rhs.headerAppendixIsSet()) || (headerAppendixIsSet() && rhs.headerAppendixIsSet() && getHeaderAppendix() == rhs.getHeaderAppendix())) &&
|
||||
@@ -307,12 +325,18 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
|
||||
((!imageAppendixIsSet() && !rhs.imageAppendixIsSet()) || (imageAppendixIsSet() && rhs.imageAppendixIsSet() && getImageAppendix() == rhs.getImageAppendix())) &&
|
||||
|
||||
|
||||
((!photonEnergyMultiplierIsSet() && !rhs.photonEnergyMultiplierIsSet()) || (photonEnergyMultiplierIsSet() && rhs.photonEnergyMultiplierIsSet() && getPhotonEnergyMultiplier() == rhs.getPhotonEnergyMultiplier())) &&
|
||||
((!energyMultiplierIsSet() && !rhs.energyMultiplierIsSet()) || (energyMultiplierIsSet() && rhs.energyMultiplierIsSet() && getEnergyMultiplier() == rhs.getEnergyMultiplier())) &&
|
||||
|
||||
|
||||
((!dataReductionFactorSerialmxIsSet() && !rhs.dataReductionFactorSerialmxIsSet()) || (dataReductionFactorSerialmxIsSet() && rhs.dataReductionFactorSerialmxIsSet() && getDataReductionFactorSerialmx() == rhs.getDataReductionFactorSerialmx())) &&
|
||||
|
||||
|
||||
((!runNumberIsSet() && !rhs.runNumberIsSet()) || (runNumberIsSet() && rhs.runNumberIsSet() && getRunNumber() == rhs.getRunNumber())) &&
|
||||
|
||||
|
||||
((!experimentGroupIsSet() && !rhs.experimentGroupIsSet()) || (experimentGroupIsSet() && rhs.experimentGroupIsSet() && getExperimentGroup() == rhs.getExperimentGroup())) &&
|
||||
|
||||
|
||||
((!unitCellIsSet() && !rhs.unitCellIsSet()) || (unitCellIsSet() && rhs.unitCellIsSet() && getUnitCell() == rhs.getUnitCell()))
|
||||
|
||||
;
|
||||
@@ -335,7 +359,7 @@ void to_json(nlohmann::json& j, const Dataset_settings& o)
|
||||
j["beam_x_pxl"] = o.m_Beam_x_pxl;
|
||||
j["beam_y_pxl"] = o.m_Beam_y_pxl;
|
||||
j["detector_distance_mm"] = o.m_Detector_distance_mm;
|
||||
j["photon_energy_keV"] = o.m_Photon_energy_keV;
|
||||
j["incident_energy_keV"] = o.m_Incident_energy_keV;
|
||||
if(o.filePrefixIsSet())
|
||||
j["file_prefix"] = o.m_File_prefix;
|
||||
if(o.imagesPerFileIsSet())
|
||||
@@ -351,16 +375,20 @@ void to_json(nlohmann::json& j, const Dataset_settings& o)
|
||||
j["total_flux"] = o.m_Total_flux;
|
||||
if(o.transmissionIsSet())
|
||||
j["transmission"] = o.m_Transmission;
|
||||
if(o.omegaIsSet())
|
||||
j["omega"] = o.m_Omega;
|
||||
if(o.goniometerIsSet())
|
||||
j["goniometer"] = o.m_Goniometer;
|
||||
if(o.headerAppendixIsSet())
|
||||
j["header_appendix"] = o.m_Header_appendix;
|
||||
if(o.imageAppendixIsSet())
|
||||
j["image_appendix"] = o.m_Image_appendix;
|
||||
if(o.photonEnergyMultiplierIsSet())
|
||||
j["photon_energy_multiplier"] = o.m_Photon_energy_multiplier;
|
||||
if(o.energyMultiplierIsSet())
|
||||
j["energy_multiplier"] = o.m_Energy_multiplier;
|
||||
if(o.dataReductionFactorSerialmxIsSet())
|
||||
j["data_reduction_factor_serialmx"] = o.m_Data_reduction_factor_serialmx;
|
||||
if(o.runNumberIsSet())
|
||||
j["run_number"] = o.m_Run_number;
|
||||
if(o.experimentGroupIsSet())
|
||||
j["experiment_group"] = o.m_Experiment_group;
|
||||
if(o.unitCellIsSet())
|
||||
j["unit_cell"] = o.m_Unit_cell;
|
||||
|
||||
@@ -386,7 +414,7 @@ void from_json(const nlohmann::json& j, Dataset_settings& o)
|
||||
j.at("beam_x_pxl").get_to(o.m_Beam_x_pxl);
|
||||
j.at("beam_y_pxl").get_to(o.m_Beam_y_pxl);
|
||||
j.at("detector_distance_mm").get_to(o.m_Detector_distance_mm);
|
||||
j.at("photon_energy_keV").get_to(o.m_Photon_energy_keV);
|
||||
j.at("incident_energy_keV").get_to(o.m_Incident_energy_keV);
|
||||
if(j.find("file_prefix") != j.end())
|
||||
{
|
||||
j.at("file_prefix").get_to(o.m_File_prefix);
|
||||
@@ -423,10 +451,10 @@ void from_json(const nlohmann::json& j, Dataset_settings& o)
|
||||
j.at("transmission").get_to(o.m_Transmission);
|
||||
o.m_TransmissionIsSet = true;
|
||||
}
|
||||
if(j.find("omega") != j.end())
|
||||
if(j.find("goniometer") != j.end())
|
||||
{
|
||||
j.at("omega").get_to(o.m_Omega);
|
||||
o.m_OmegaIsSet = true;
|
||||
j.at("goniometer").get_to(o.m_Goniometer);
|
||||
o.m_GoniometerIsSet = true;
|
||||
}
|
||||
if(j.find("header_appendix") != j.end())
|
||||
{
|
||||
@@ -438,16 +466,26 @@ void from_json(const nlohmann::json& j, Dataset_settings& o)
|
||||
j.at("image_appendix").get_to(o.m_Image_appendix);
|
||||
o.m_Image_appendixIsSet = true;
|
||||
}
|
||||
if(j.find("photon_energy_multiplier") != j.end())
|
||||
if(j.find("energy_multiplier") != j.end())
|
||||
{
|
||||
j.at("photon_energy_multiplier").get_to(o.m_Photon_energy_multiplier);
|
||||
o.m_Photon_energy_multiplierIsSet = true;
|
||||
j.at("energy_multiplier").get_to(o.m_Energy_multiplier);
|
||||
o.m_Energy_multiplierIsSet = true;
|
||||
}
|
||||
if(j.find("data_reduction_factor_serialmx") != j.end())
|
||||
{
|
||||
j.at("data_reduction_factor_serialmx").get_to(o.m_Data_reduction_factor_serialmx);
|
||||
o.m_Data_reduction_factor_serialmxIsSet = true;
|
||||
}
|
||||
if(j.find("run_number") != j.end())
|
||||
{
|
||||
j.at("run_number").get_to(o.m_Run_number);
|
||||
o.m_Run_numberIsSet = true;
|
||||
}
|
||||
if(j.find("experiment_group") != j.end())
|
||||
{
|
||||
j.at("experiment_group").get_to(o.m_Experiment_group);
|
||||
o.m_Experiment_groupIsSet = true;
|
||||
}
|
||||
if(j.find("unit_cell") != j.end())
|
||||
{
|
||||
j.at("unit_cell").get_to(o.m_Unit_cell);
|
||||
@@ -531,13 +569,13 @@ void Dataset_settings::setDetectorDistanceMm(float const value)
|
||||
{
|
||||
m_Detector_distance_mm = value;
|
||||
}
|
||||
float Dataset_settings::getPhotonEnergyKeV() const
|
||||
float Dataset_settings::getIncidentEnergyKeV() const
|
||||
{
|
||||
return m_Photon_energy_keV;
|
||||
return m_Incident_energy_keV;
|
||||
}
|
||||
void Dataset_settings::setPhotonEnergyKeV(float const value)
|
||||
void Dataset_settings::setIncidentEnergyKeV(float const value)
|
||||
{
|
||||
m_Photon_energy_keV = value;
|
||||
m_Incident_energy_keV = value;
|
||||
}
|
||||
std::string Dataset_settings::getFilePrefix() const
|
||||
{
|
||||
@@ -666,22 +704,22 @@ void Dataset_settings::unsetTransmission()
|
||||
{
|
||||
m_TransmissionIsSet = false;
|
||||
}
|
||||
org::openapitools::server::model::Rotation_axis Dataset_settings::getOmega() const
|
||||
org::openapitools::server::model::Rotation_axis Dataset_settings::getGoniometer() const
|
||||
{
|
||||
return m_Omega;
|
||||
return m_Goniometer;
|
||||
}
|
||||
void Dataset_settings::setOmega(org::openapitools::server::model::Rotation_axis const& value)
|
||||
void Dataset_settings::setGoniometer(org::openapitools::server::model::Rotation_axis const& value)
|
||||
{
|
||||
m_Omega = value;
|
||||
m_OmegaIsSet = true;
|
||||
m_Goniometer = value;
|
||||
m_GoniometerIsSet = true;
|
||||
}
|
||||
bool Dataset_settings::omegaIsSet() const
|
||||
bool Dataset_settings::goniometerIsSet() const
|
||||
{
|
||||
return m_OmegaIsSet;
|
||||
return m_GoniometerIsSet;
|
||||
}
|
||||
void Dataset_settings::unsetOmega()
|
||||
void Dataset_settings::unsetGoniometer()
|
||||
{
|
||||
m_OmegaIsSet = false;
|
||||
m_GoniometerIsSet = false;
|
||||
}
|
||||
std::string Dataset_settings::getHeaderAppendix() const
|
||||
{
|
||||
@@ -717,22 +755,22 @@ void Dataset_settings::unsetImage_appendix()
|
||||
{
|
||||
m_Image_appendixIsSet = false;
|
||||
}
|
||||
float Dataset_settings::getPhotonEnergyMultiplier() const
|
||||
float Dataset_settings::getEnergyMultiplier() const
|
||||
{
|
||||
return m_Photon_energy_multiplier;
|
||||
return m_Energy_multiplier;
|
||||
}
|
||||
void Dataset_settings::setPhotonEnergyMultiplier(float const value)
|
||||
void Dataset_settings::setEnergyMultiplier(float const value)
|
||||
{
|
||||
m_Photon_energy_multiplier = value;
|
||||
m_Photon_energy_multiplierIsSet = true;
|
||||
m_Energy_multiplier = value;
|
||||
m_Energy_multiplierIsSet = true;
|
||||
}
|
||||
bool Dataset_settings::photonEnergyMultiplierIsSet() const
|
||||
bool Dataset_settings::energyMultiplierIsSet() const
|
||||
{
|
||||
return m_Photon_energy_multiplierIsSet;
|
||||
return m_Energy_multiplierIsSet;
|
||||
}
|
||||
void Dataset_settings::unsetPhoton_energy_multiplier()
|
||||
void Dataset_settings::unsetEnergy_multiplier()
|
||||
{
|
||||
m_Photon_energy_multiplierIsSet = false;
|
||||
m_Energy_multiplierIsSet = false;
|
||||
}
|
||||
float Dataset_settings::getDataReductionFactorSerialmx() const
|
||||
{
|
||||
@@ -751,6 +789,40 @@ void Dataset_settings::unsetData_reduction_factor_serialmx()
|
||||
{
|
||||
m_Data_reduction_factor_serialmxIsSet = false;
|
||||
}
|
||||
int64_t Dataset_settings::getRunNumber() const
|
||||
{
|
||||
return m_Run_number;
|
||||
}
|
||||
void Dataset_settings::setRunNumber(int64_t const value)
|
||||
{
|
||||
m_Run_number = value;
|
||||
m_Run_numberIsSet = true;
|
||||
}
|
||||
bool Dataset_settings::runNumberIsSet() const
|
||||
{
|
||||
return m_Run_numberIsSet;
|
||||
}
|
||||
void Dataset_settings::unsetRun_number()
|
||||
{
|
||||
m_Run_numberIsSet = false;
|
||||
}
|
||||
std::string Dataset_settings::getExperimentGroup() const
|
||||
{
|
||||
return m_Experiment_group;
|
||||
}
|
||||
void Dataset_settings::setExperimentGroup(std::string const& value)
|
||||
{
|
||||
m_Experiment_group = value;
|
||||
m_Experiment_groupIsSet = true;
|
||||
}
|
||||
bool Dataset_settings::experimentGroupIsSet() const
|
||||
{
|
||||
return m_Experiment_groupIsSet;
|
||||
}
|
||||
void Dataset_settings::unsetExperiment_group()
|
||||
{
|
||||
m_Experiment_groupIsSet = false;
|
||||
}
|
||||
org::openapitools::server::model::Dataset_settings_unit_cell Dataset_settings::getUnitCell() const
|
||||
{
|
||||
return m_Unit_cell;
|
||||
|
||||
@@ -97,10 +97,10 @@ public:
|
||||
float getDetectorDistanceMm() const;
|
||||
void setDetectorDistanceMm(float const value);
|
||||
/// <summary>
|
||||
/// Used to calculate /entry/beam/incident_wavelength in NXmx Incident photon energy in keV
|
||||
/// Used to calculate /entry/beam/incident_wavelength in NXmx Incident particle (photon, electron) energy in keV
|
||||
/// </summary>
|
||||
float getPhotonEnergyKeV() const;
|
||||
void setPhotonEnergyKeV(float const value);
|
||||
float getIncidentEnergyKeV() const;
|
||||
void setIncidentEnergyKeV(float const value);
|
||||
/// <summary>
|
||||
/// Prefix for filenames. If left empty, no file will be saved.
|
||||
/// </summary>
|
||||
@@ -158,10 +158,10 @@ public:
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
org::openapitools::server::model::Rotation_axis getOmega() const;
|
||||
void setOmega(org::openapitools::server::model::Rotation_axis const& value);
|
||||
bool omegaIsSet() const;
|
||||
void unsetOmega();
|
||||
org::openapitools::server::model::Rotation_axis getGoniometer() const;
|
||||
void setGoniometer(org::openapitools::server::model::Rotation_axis const& value);
|
||||
bool goniometerIsSet() const;
|
||||
void unsetGoniometer();
|
||||
/// <summary>
|
||||
/// Header appendix, added as user_data to start message
|
||||
/// </summary>
|
||||
@@ -177,12 +177,12 @@ public:
|
||||
bool imageAppendixIsSet() const;
|
||||
void unsetImage_appendix();
|
||||
/// <summary>
|
||||
/// For JUNGFRAU conversion it is possible to multiply energy by a given factor to get fractional/multiplied photon counts
|
||||
/// For JUNGFRAU conversion it is possible to multiply incident energy by a given factor to get fractional/multiplied particle counts
|
||||
/// </summary>
|
||||
float getPhotonEnergyMultiplier() const;
|
||||
void setPhotonEnergyMultiplier(float const value);
|
||||
bool photonEnergyMultiplierIsSet() const;
|
||||
void unsetPhoton_energy_multiplier();
|
||||
float getEnergyMultiplier() const;
|
||||
void setEnergyMultiplier(float const value);
|
||||
bool energyMultiplierIsSet() const;
|
||||
void unsetEnergy_multiplier();
|
||||
/// <summary>
|
||||
/// Rate at which non-indexed images are accepted to be forwarded to writer. Value of 1.0 (default) means that all images are written. Values below zero mean that non-indexed images will be accepted with a given probability.
|
||||
/// </summary>
|
||||
@@ -191,6 +191,20 @@ public:
|
||||
bool dataReductionFactorSerialmxIsSet() const;
|
||||
void unsetData_reduction_factor_serialmx();
|
||||
/// <summary>
|
||||
/// Number of run within an experimental session. Transferred over CBOR stream as \"series ID\", though not saved in HDF5 file. It is highly recommended to keep this number unique for each data collection during experimental series. If not provided, the number will be automatically incremented.
|
||||
/// </summary>
|
||||
int64_t getRunNumber() const;
|
||||
void setRunNumber(int64_t const value);
|
||||
bool runNumberIsSet() const;
|
||||
void unsetRun_number();
|
||||
/// <summary>
|
||||
/// Name of group owning the data (e.g. p-group or proposal number). Transferred over CBOR stream, though not saved in HDF5 file.
|
||||
/// </summary>
|
||||
std::string getExperimentGroup() const;
|
||||
void setExperimentGroup(std::string const& value);
|
||||
bool experimentGroupIsSet() const;
|
||||
void unsetExperiment_group();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
org::openapitools::server::model::Dataset_settings_unit_cell getUnitCell() const;
|
||||
@@ -213,7 +227,7 @@ protected:
|
||||
|
||||
float m_Detector_distance_mm;
|
||||
|
||||
float m_Photon_energy_keV;
|
||||
float m_Incident_energy_keV;
|
||||
|
||||
std::string m_File_prefix;
|
||||
bool m_File_prefixIsSet;
|
||||
@@ -231,16 +245,20 @@ protected:
|
||||
bool m_Total_fluxIsSet;
|
||||
float m_Transmission;
|
||||
bool m_TransmissionIsSet;
|
||||
org::openapitools::server::model::Rotation_axis m_Omega;
|
||||
bool m_OmegaIsSet;
|
||||
org::openapitools::server::model::Rotation_axis m_Goniometer;
|
||||
bool m_GoniometerIsSet;
|
||||
std::string m_Header_appendix;
|
||||
bool m_Header_appendixIsSet;
|
||||
std::string m_Image_appendix;
|
||||
bool m_Image_appendixIsSet;
|
||||
float m_Photon_energy_multiplier;
|
||||
bool m_Photon_energy_multiplierIsSet;
|
||||
float m_Energy_multiplier;
|
||||
bool m_Energy_multiplierIsSet;
|
||||
float m_Data_reduction_factor_serialmx;
|
||||
bool m_Data_reduction_factor_serialmxIsSet;
|
||||
int64_t m_Run_number;
|
||||
bool m_Run_numberIsSet;
|
||||
std::string m_Experiment_group;
|
||||
bool m_Experiment_groupIsSet;
|
||||
org::openapitools::server::model::Dataset_settings_unit_cell m_Unit_cell;
|
||||
bool m_Unit_cellIsSet;
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@ Measurement_statistics::Measurement_statistics()
|
||||
{
|
||||
m_File_prefix = "";
|
||||
m_File_prefixIsSet = false;
|
||||
m_Run_number = 0L;
|
||||
m_Run_numberIsSet = false;
|
||||
m_Experiment_group = "";
|
||||
m_Experiment_groupIsSet = false;
|
||||
m_Images_expected = 0L;
|
||||
m_Images_expectedIsSet = false;
|
||||
m_Images_collected = 0L;
|
||||
@@ -75,7 +79,7 @@ bool Measurement_statistics::validate(std::stringstream& msg, const std::string&
|
||||
bool success = true;
|
||||
const std::string _pathPrefix = pathPrefix.empty() ? "Measurement_statistics" : pathPrefix;
|
||||
|
||||
|
||||
|
||||
if (collectionEfficiencyIsSet())
|
||||
{
|
||||
const float& value = m_Collection_efficiency;
|
||||
@@ -121,6 +125,12 @@ bool Measurement_statistics::operator==(const Measurement_statistics& rhs) const
|
||||
((!filePrefixIsSet() && !rhs.filePrefixIsSet()) || (filePrefixIsSet() && rhs.filePrefixIsSet() && getFilePrefix() == rhs.getFilePrefix())) &&
|
||||
|
||||
|
||||
((!runNumberIsSet() && !rhs.runNumberIsSet()) || (runNumberIsSet() && rhs.runNumberIsSet() && getRunNumber() == rhs.getRunNumber())) &&
|
||||
|
||||
|
||||
((!experimentGroupIsSet() && !rhs.experimentGroupIsSet()) || (experimentGroupIsSet() && rhs.experimentGroupIsSet() && getExperimentGroup() == rhs.getExperimentGroup())) &&
|
||||
|
||||
|
||||
((!imagesExpectedIsSet() && !rhs.imagesExpectedIsSet()) || (imagesExpectedIsSet() && rhs.imagesExpectedIsSet() && getImagesExpected() == rhs.getImagesExpected())) &&
|
||||
|
||||
|
||||
@@ -178,6 +188,10 @@ void to_json(nlohmann::json& j, const Measurement_statistics& o)
|
||||
j = nlohmann::json();
|
||||
if(o.filePrefixIsSet())
|
||||
j["file_prefix"] = o.m_File_prefix;
|
||||
if(o.runNumberIsSet())
|
||||
j["run_number"] = o.m_Run_number;
|
||||
if(o.experimentGroupIsSet())
|
||||
j["experiment_group"] = o.m_Experiment_group;
|
||||
if(o.imagesExpectedIsSet())
|
||||
j["images_expected"] = o.m_Images_expected;
|
||||
if(o.imagesCollectedIsSet())
|
||||
@@ -218,6 +232,16 @@ void from_json(const nlohmann::json& j, Measurement_statistics& o)
|
||||
j.at("file_prefix").get_to(o.m_File_prefix);
|
||||
o.m_File_prefixIsSet = true;
|
||||
}
|
||||
if(j.find("run_number") != j.end())
|
||||
{
|
||||
j.at("run_number").get_to(o.m_Run_number);
|
||||
o.m_Run_numberIsSet = true;
|
||||
}
|
||||
if(j.find("experiment_group") != j.end())
|
||||
{
|
||||
j.at("experiment_group").get_to(o.m_Experiment_group);
|
||||
o.m_Experiment_groupIsSet = true;
|
||||
}
|
||||
if(j.find("images_expected") != j.end())
|
||||
{
|
||||
j.at("images_expected").get_to(o.m_Images_expected);
|
||||
@@ -313,6 +337,40 @@ void Measurement_statistics::unsetFile_prefix()
|
||||
{
|
||||
m_File_prefixIsSet = false;
|
||||
}
|
||||
int64_t Measurement_statistics::getRunNumber() const
|
||||
{
|
||||
return m_Run_number;
|
||||
}
|
||||
void Measurement_statistics::setRunNumber(int64_t const value)
|
||||
{
|
||||
m_Run_number = value;
|
||||
m_Run_numberIsSet = true;
|
||||
}
|
||||
bool Measurement_statistics::runNumberIsSet() const
|
||||
{
|
||||
return m_Run_numberIsSet;
|
||||
}
|
||||
void Measurement_statistics::unsetRun_number()
|
||||
{
|
||||
m_Run_numberIsSet = false;
|
||||
}
|
||||
std::string Measurement_statistics::getExperimentGroup() const
|
||||
{
|
||||
return m_Experiment_group;
|
||||
}
|
||||
void Measurement_statistics::setExperimentGroup(std::string const& value)
|
||||
{
|
||||
m_Experiment_group = value;
|
||||
m_Experiment_groupIsSet = true;
|
||||
}
|
||||
bool Measurement_statistics::experimentGroupIsSet() const
|
||||
{
|
||||
return m_Experiment_groupIsSet;
|
||||
}
|
||||
void Measurement_statistics::unsetExperiment_group()
|
||||
{
|
||||
m_Experiment_groupIsSet = false;
|
||||
}
|
||||
int64_t Measurement_statistics::getImagesExpected() const
|
||||
{
|
||||
return m_Images_expected;
|
||||
|
||||
@@ -66,6 +66,20 @@ public:
|
||||
bool filePrefixIsSet() const;
|
||||
void unsetFile_prefix();
|
||||
/// <summary>
|
||||
/// Number of data collection run. This can be either automatically incremented or provided externally for each data collection.
|
||||
/// </summary>
|
||||
int64_t getRunNumber() const;
|
||||
void setRunNumber(int64_t const value);
|
||||
bool runNumberIsSet() const;
|
||||
void unsetRun_number();
|
||||
/// <summary>
|
||||
/// Name of group owning the data (e.g. p-group or proposal number).
|
||||
/// </summary>
|
||||
std::string getExperimentGroup() const;
|
||||
void setExperimentGroup(std::string const& value);
|
||||
bool experimentGroupIsSet() const;
|
||||
void unsetExperiment_group();
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
int64_t getImagesExpected() const;
|
||||
@@ -176,6 +190,10 @@ public:
|
||||
protected:
|
||||
std::string m_File_prefix;
|
||||
bool m_File_prefixIsSet;
|
||||
int64_t m_Run_number;
|
||||
bool m_Run_numberIsSet;
|
||||
std::string m_Experiment_group;
|
||||
bool m_Experiment_groupIsSet;
|
||||
int64_t m_Images_expected;
|
||||
bool m_Images_expectedIsSet;
|
||||
int64_t m_Images_collected;
|
||||
|
||||
@@ -21,6 +21,8 @@ namespace org::openapitools::server::model
|
||||
|
||||
Rotation_axis::Rotation_axis()
|
||||
{
|
||||
m_Name = "omega";
|
||||
m_NameIsSet = false;
|
||||
m_Step = 0.0f;
|
||||
m_Start = 0.0f;
|
||||
m_StartIsSet = false;
|
||||
@@ -47,6 +49,20 @@ bool Rotation_axis::validate(std::stringstream& msg, const std::string& pathPref
|
||||
bool success = true;
|
||||
const std::string _pathPrefix = pathPrefix.empty() ? "Rotation_axis" : pathPrefix;
|
||||
|
||||
|
||||
if (nameIsSet())
|
||||
{
|
||||
const std::string& value = m_Name;
|
||||
const std::string currentValuePath = _pathPrefix + ".name";
|
||||
|
||||
|
||||
if (value.length() < 1)
|
||||
{
|
||||
success = false;
|
||||
msg << currentValuePath << ": must be at least 1 characters long;";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (vectorIsSet())
|
||||
{
|
||||
@@ -87,6 +103,9 @@ bool Rotation_axis::operator==(const Rotation_axis& rhs) const
|
||||
return
|
||||
|
||||
|
||||
|
||||
((!nameIsSet() && !rhs.nameIsSet()) || (nameIsSet() && rhs.nameIsSet() && getName() == rhs.getName())) &&
|
||||
|
||||
(getStep() == rhs.getStep())
|
||||
&&
|
||||
|
||||
@@ -107,6 +126,8 @@ bool Rotation_axis::operator!=(const Rotation_axis& rhs) const
|
||||
void to_json(nlohmann::json& j, const Rotation_axis& o)
|
||||
{
|
||||
j = nlohmann::json();
|
||||
if(o.nameIsSet())
|
||||
j["name"] = o.m_Name;
|
||||
j["step"] = o.m_Step;
|
||||
if(o.startIsSet())
|
||||
j["start"] = o.m_Start;
|
||||
@@ -117,6 +138,11 @@ void to_json(nlohmann::json& j, const Rotation_axis& o)
|
||||
|
||||
void from_json(const nlohmann::json& j, Rotation_axis& o)
|
||||
{
|
||||
if(j.find("name") != j.end())
|
||||
{
|
||||
j.at("name").get_to(o.m_Name);
|
||||
o.m_NameIsSet = true;
|
||||
}
|
||||
j.at("step").get_to(o.m_Step);
|
||||
if(j.find("start") != j.end())
|
||||
{
|
||||
@@ -131,6 +157,23 @@ void from_json(const nlohmann::json& j, Rotation_axis& o)
|
||||
|
||||
}
|
||||
|
||||
std::string Rotation_axis::getName() const
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
void Rotation_axis::setName(std::string const& value)
|
||||
{
|
||||
m_Name = value;
|
||||
m_NameIsSet = true;
|
||||
}
|
||||
bool Rotation_axis::nameIsSet() const
|
||||
{
|
||||
return m_NameIsSet;
|
||||
}
|
||||
void Rotation_axis::unsetName()
|
||||
{
|
||||
m_NameIsSet = false;
|
||||
}
|
||||
float Rotation_axis::getStep() const
|
||||
{
|
||||
return m_Step;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define Rotation_axis_H_
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@@ -58,6 +59,13 @@ public:
|
||||
/////////////////////////////////////////////
|
||||
/// Rotation_axis members
|
||||
|
||||
/// <summary>
|
||||
/// Name of rotation axis (e.g., omega, phi)
|
||||
/// </summary>
|
||||
std::string getName() const;
|
||||
void setName(std::string const& value);
|
||||
bool nameIsSet() const;
|
||||
void unsetName();
|
||||
/// <summary>
|
||||
/// Angle step in degrees
|
||||
/// </summary>
|
||||
@@ -81,6 +89,8 @@ public:
|
||||
friend void to_json(nlohmann::json& j, const Rotation_axis& o);
|
||||
friend void from_json(const nlohmann::json& j, Rotation_axis& o);
|
||||
protected:
|
||||
std::string m_Name;
|
||||
bool m_NameIsSet;
|
||||
float m_Step;
|
||||
|
||||
float m_Start;
|
||||
|
||||
@@ -25,7 +25,7 @@ Spot_finding_settings::Spot_finding_settings()
|
||||
m_Indexing = true;
|
||||
m_Filter_powder_rings = false;
|
||||
m_Filter_powder_ringsIsSet = false;
|
||||
m_Min_spot_count_powder_ring = 20L;
|
||||
m_Min_spot_count_powder_ring = 0L;
|
||||
m_Min_spot_count_powder_ringIsSet = false;
|
||||
m_Signal_to_noise_threshold = 0.0f;
|
||||
m_Photon_count_threshold = 0L;
|
||||
|
||||
@@ -11,6 +11,11 @@ components:
|
||||
required:
|
||||
- step
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
default: omega
|
||||
minLength: 1
|
||||
description: Name of rotation axis (e.g., omega, phi)
|
||||
step:
|
||||
type: number
|
||||
format: float
|
||||
@@ -37,7 +42,7 @@ components:
|
||||
- beam_x_pxl
|
||||
- beam_y_pxl
|
||||
- detector_distance_mm
|
||||
- photon_energy_keV
|
||||
- incident_energy_keV
|
||||
- sample_name
|
||||
properties:
|
||||
images_per_trigger:
|
||||
@@ -86,13 +91,13 @@ components:
|
||||
description:
|
||||
/entry/detector/distance in NXmx
|
||||
Detector distance [mm]
|
||||
photon_energy_keV:
|
||||
incident_energy_keV:
|
||||
type: number
|
||||
format: float
|
||||
minimum: 0
|
||||
description: |
|
||||
Used to calculate /entry/beam/incident_wavelength in NXmx
|
||||
Incident photon energy in keV
|
||||
Incident particle (photon, electron) energy in keV
|
||||
file_prefix:
|
||||
type: string
|
||||
default: ""
|
||||
@@ -148,7 +153,7 @@ components:
|
||||
description: |
|
||||
/entry/instrument/attenuator/attenuator_transmission
|
||||
Transmission of attenuator (filter) [no units]
|
||||
omega:
|
||||
goniometer:
|
||||
$ref: "#/components/schemas/rotation_axis"
|
||||
header_appendix:
|
||||
type: string
|
||||
@@ -156,13 +161,13 @@ components:
|
||||
image_appendix:
|
||||
type: string
|
||||
description: Image appendix, added as user_data to image message
|
||||
photon_energy_multiplier:
|
||||
energy_multiplier:
|
||||
type: number
|
||||
format: float
|
||||
default: 1.0
|
||||
minimum: 0.015625
|
||||
maximum: 4.0
|
||||
description: For JUNGFRAU conversion it is possible to multiply energy by a given factor to get fractional/multiplied photon counts
|
||||
description: For JUNGFRAU conversion it is possible to multiply incident energy by a given factor to get fractional/multiplied particle counts
|
||||
data_reduction_factor_serialmx:
|
||||
type: number
|
||||
format: float
|
||||
@@ -173,6 +178,20 @@ components:
|
||||
Rate at which non-indexed images are accepted to be forwarded to writer.
|
||||
Value of 1.0 (default) means that all images are written.
|
||||
Values below zero mean that non-indexed images will be accepted with a given probability.
|
||||
run_number:
|
||||
type: integer
|
||||
format: int64
|
||||
minimum: 0
|
||||
description: |
|
||||
Number of run within an experimental session.
|
||||
Transferred over CBOR stream as "series ID", though not saved in HDF5 file.
|
||||
It is highly recommended to keep this number unique for each data collection during experimental series.
|
||||
If not provided, the number will be automatically incremented.
|
||||
experiment_group:
|
||||
type: string
|
||||
description: |
|
||||
Name of group owning the data (e.g. p-group or proposal number).
|
||||
Transferred over CBOR stream, though not saved in HDF5 file.
|
||||
unit_cell:
|
||||
type: object
|
||||
description: Units of angstrom and degree
|
||||
@@ -235,7 +254,7 @@ components:
|
||||
powerchip:
|
||||
type: string
|
||||
description: Power on of ASICs
|
||||
enum: ["On", "Off", "Partial"]
|
||||
enum: ["PowerOn", "PowerOff", "Partial"]
|
||||
server_version:
|
||||
type: string
|
||||
description: Detector server (on read-out boards) version
|
||||
@@ -459,6 +478,15 @@ components:
|
||||
properties:
|
||||
file_prefix:
|
||||
type: string
|
||||
run_number:
|
||||
type: integer
|
||||
format: int64
|
||||
description: |
|
||||
Number of data collection run. This can be either automatically incremented or provided externally for each data collection.
|
||||
experiment_group:
|
||||
type: string
|
||||
description: |
|
||||
Name of group owning the data (e.g. p-group or proposal number).
|
||||
images_expected:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
@@ -115,9 +115,9 @@ int main (int argc, char **argv) {
|
||||
|
||||
logger.Info("Source {} Instrument {} Default rotation axis {:.2f},{:.2f},{:.2f}",
|
||||
experiment.GetSourceName(), experiment.GetInstrumentName(),
|
||||
experiment.GetDefaultOmegaAxis().x,
|
||||
experiment.GetDefaultOmegaAxis().y,
|
||||
experiment.GetDefaultOmegaAxis().z);
|
||||
experiment.GetDefaultRotationAxis().x,
|
||||
experiment.GetDefaultRotationAxis().y,
|
||||
experiment.GetDefaultRotationAxis().z);
|
||||
|
||||
Pistache::Address addr(Pistache::Ipv4::any(), Pistache::Port(http_port));
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -24,7 +24,6 @@ DatasetSettings::DatasetSettings() {
|
||||
space_group_number = 0; // not set
|
||||
compression = CompressionAlgorithm::BSHUF_LZ4;
|
||||
photon_energy_multiplier = 1.0f;
|
||||
omega_start = 0.0f;
|
||||
images_per_file = 1000;
|
||||
data_reduction_factor_serialmx = 1.0;
|
||||
}
|
||||
@@ -151,31 +150,25 @@ DatasetSettings &DatasetSettings::TotalFlux(const std::optional<float> &input) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
DatasetSettings &DatasetSettings::OmegaStep(const std::optional<float> &input) {
|
||||
DatasetSettings &DatasetSettings::Goniometer(const std::optional<GoniometerAxis> &input) {
|
||||
if (input) {
|
||||
check_finite("Omega step", input.value());
|
||||
check_finite("Rotation angle increment", input->increment);
|
||||
if (input->increment == 0.0f)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Angle increment cannot be zero");
|
||||
check_finite("Rotation angle start", input->start);
|
||||
goniometer = input;
|
||||
}
|
||||
|
||||
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) {
|
||||
DatasetSettings &DatasetSettings::RotationAxis(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();
|
||||
rotation_axis = c->Normalize();
|
||||
} else
|
||||
omega_rotation_axis = c;
|
||||
rotation_axis = c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -228,16 +221,12 @@ std::optional<float> DatasetSettings::GetTotalFlux() const {
|
||||
return total_flux;
|
||||
}
|
||||
|
||||
std::optional<float> DatasetSettings::GetOmegaStep() const {
|
||||
return omega_step;
|
||||
std::optional<GoniometerAxis> DatasetSettings::GetGoniometer() const {
|
||||
return goniometer;
|
||||
}
|
||||
|
||||
float DatasetSettings::GetOmegaStart() const {
|
||||
return omega_start;
|
||||
}
|
||||
|
||||
std::optional<Coord> DatasetSettings::GetOmegaAxis() const {
|
||||
return omega_rotation_axis;
|
||||
std::optional<Coord> DatasetSettings::GetRotationAxis() const {
|
||||
return rotation_axis;
|
||||
}
|
||||
|
||||
std::string DatasetSettings::GetHeaderAppendix() const {
|
||||
@@ -332,3 +321,25 @@ DatasetSettings &DatasetSettings::DataReductionFactorSerialMX(float input) {
|
||||
float DatasetSettings::GetDataReductionFactorSerialMX() const {
|
||||
return data_reduction_factor_serialmx;
|
||||
}
|
||||
|
||||
DatasetSettings &DatasetSettings::RunNumber(const std::optional<uint64_t> &input) {
|
||||
if (input) {
|
||||
check_min("Run number", input, 0);
|
||||
check_max("Run number", input, INT64_MAX);
|
||||
}
|
||||
run_number = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DatasetSettings &DatasetSettings::ExperimentGroup(const std::string &input) {
|
||||
group = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::optional<uint64_t> DatasetSettings::GetRunNumber() const {
|
||||
return run_number;
|
||||
}
|
||||
|
||||
std::string DatasetSettings::GetExperimentGroup() const {
|
||||
return group;
|
||||
}
|
||||
|
||||
@@ -40,14 +40,16 @@ class DatasetSettings {
|
||||
|
||||
std::optional<float> total_flux;
|
||||
std::optional<float> attenuator_transmission;
|
||||
std::optional<float> omega_step;
|
||||
float omega_start;
|
||||
std::optional<GoniometerAxis> goniometer;
|
||||
std::string image_appendix;
|
||||
std::string header_appendix;
|
||||
|
||||
std::optional<Coord> omega_rotation_axis;
|
||||
std::optional<Coord> rotation_axis;
|
||||
|
||||
float data_reduction_factor_serialmx;
|
||||
|
||||
std::optional<uint64_t> run_number;
|
||||
std::string group;
|
||||
public:
|
||||
|
||||
DatasetSettings();
|
||||
@@ -65,9 +67,8 @@ public:
|
||||
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& Goniometer(const std::optional<GoniometerAxis>& input);
|
||||
DatasetSettings& RotationAxis(const std::optional<Coord> &c);
|
||||
DatasetSettings& HeaderAppendix(const std::string& input);
|
||||
DatasetSettings& ImageAppendix(const std::string& input);
|
||||
DatasetSettings& PhotonEnergyMultiplayer(float input);
|
||||
@@ -75,12 +76,13 @@ public:
|
||||
DatasetSettings& FPGAOutputMode(FPGAPixelOutput input);
|
||||
DatasetSettings& ImagesPerFile(int64_t input);
|
||||
DatasetSettings& DataReductionFactorSerialMX(float input);
|
||||
DatasetSettings& RunNumber(const std::optional<uint64_t> &run_number);
|
||||
DatasetSettings& ExperimentGroup(const std::string &group);
|
||||
|
||||
std::optional<float> GetAttenuatorTransmission() const;
|
||||
std::optional<float> GetTotalFlux() const;
|
||||
std::optional<float> GetOmegaStep() const;
|
||||
float GetOmegaStart() const;
|
||||
std::optional<Coord> GetOmegaAxis() const;
|
||||
std::optional<GoniometerAxis> GetGoniometer() const;
|
||||
std::optional<Coord> GetRotationAxis() const;
|
||||
std::string GetHeaderAppendix() const;
|
||||
std::string GetImageAppendix() const;
|
||||
float GetPhotonEnergyMultiplier() const;
|
||||
@@ -104,6 +106,9 @@ public:
|
||||
int64_t GetImageNumPerTrigger() const;
|
||||
int64_t GetImagesPerFile() const;
|
||||
float GetDataReductionFactorSerialMX() const;
|
||||
|
||||
std::optional<uint64_t> GetRunNumber() const;
|
||||
std::string GetExperimentGroup() const;
|
||||
};
|
||||
|
||||
#endif //JUNGFRAUJOCH_DATASETSETTINGS_H
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
#define CONVERTED_MODULE_SIZE (CONVERTED_MODULE_LINES * CONVERTED_MODULE_COLS)
|
||||
#define JUNGFRAU_PACKET_SIZE_BYTES (8192)
|
||||
|
||||
#define MIN_COUNT_TIME_IN_US 5
|
||||
#define MIN_FRAME_TIME_HALF_SPEED_IN_US 1000
|
||||
#define MIN_FRAME_TIME_FULL_SPEED_IN_US 470
|
||||
#define MAX_FRAME_TIME 2000
|
||||
|
||||
#define MAX_COUNT_TIME_IN_US 1980
|
||||
#define MIN_COUNT_TIME_IN_US 3
|
||||
|
||||
#define MIN_STORAGE_CELL_DELAY_IN_NS 2100
|
||||
#define READOUT_TIME_IN_US 20
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "RawToConvertedGeometry.h"
|
||||
#include "../fpga/pcie_driver/jfjoch_fpga.h"
|
||||
#include "../include/spdlog/fmt/fmt.h"
|
||||
#include "GitInfo.h"
|
||||
|
||||
using namespace std::literals::chrono_literals;
|
||||
|
||||
@@ -100,10 +101,13 @@ DiffractionExperiment &DiffractionExperiment::NumTriggers(int64_t input) {
|
||||
DiffractionExperiment &DiffractionExperiment::FrameTime(std::chrono::microseconds in_frame_time,
|
||||
std::chrono::microseconds in_count_time) {
|
||||
check_min("Frame time (us)", in_frame_time.count(), MIN_FRAME_TIME_FULL_SPEED_IN_US);
|
||||
check_max("Frame time (us)", in_frame_time.count(), MAX_FRAME_TIME);
|
||||
check_max("Count time (us)", in_count_time.count(), in_frame_time.count() - READOUT_TIME_IN_US);
|
||||
if (in_count_time.count() != 0) {
|
||||
check_min("Count time (us)", in_count_time.count(), MIN_COUNT_TIME_IN_US);
|
||||
check_max("Count time (us)", in_count_time.count(), MAX_COUNT_TIME_IN_US);
|
||||
} else {
|
||||
check_max("Count time (us)", in_frame_time.count() - READOUT_TIME_IN_US,
|
||||
MAX_COUNT_TIME_IN_US);
|
||||
}
|
||||
|
||||
frame_time = in_frame_time;
|
||||
@@ -729,6 +733,7 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
|
||||
|
||||
message.source_name = GetSourceName();
|
||||
message.source_name_short = GetSourceNameShort();
|
||||
message.source_type = GetSourceType();
|
||||
|
||||
message.instrument_name = GetInstrumentName();
|
||||
message.instrument_name_short = GetInstrumentNameShort();
|
||||
@@ -738,14 +743,16 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
|
||||
message.countrate_correction_enabled = false;
|
||||
message.flatfield_enabled = false;
|
||||
|
||||
if (GetOmegaStep())
|
||||
message.omega = GoniometerAxis{.increment = GetOmegaStep().value(), .start = GetOmegaStart(),
|
||||
.axis = {GetOmegaAxis().x, GetOmegaAxis().y, GetOmegaAxis().z}};
|
||||
else
|
||||
message.omega = GoniometerAxis{.increment = 0.0f};
|
||||
auto goniometer = dataset.GetGoniometer();
|
||||
if (goniometer) {
|
||||
message.goniometer = goniometer;
|
||||
message.rotation_axis[0] = GetRotationAxis().x;
|
||||
message.rotation_axis[1] = GetRotationAxis().y;
|
||||
message.rotation_axis[2] = GetRotationAxis().z;
|
||||
}
|
||||
|
||||
message.series_id = GetSeriesID();
|
||||
message.series_unique_id = GetSeriesIDString();
|
||||
message.series_id = GetRunNumber();
|
||||
message.series_unique_id = GetRunName();
|
||||
|
||||
message.gain_file_names = detector.GetGainFileNames();
|
||||
|
||||
@@ -753,6 +760,8 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
|
||||
message.roi_names.emplace_back(x);
|
||||
|
||||
message.data_reduction_factor_serialmx = GetDataReductionFactorSerialMX();
|
||||
message.experiment_group = dataset.GetExperimentGroup();
|
||||
message.jfjoch_release = jfjoch_version();
|
||||
}
|
||||
|
||||
float DiffractionExperiment::GetPixelSize_mm() const {
|
||||
@@ -769,6 +778,11 @@ DiffractionExperiment &DiffractionExperiment::SourceNameShort(std::string input)
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::SourceType(std::string input) {
|
||||
source_type = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::InstrumentName(std::string input) {
|
||||
instrument_name = input;
|
||||
return *this;
|
||||
@@ -787,6 +801,10 @@ std::string DiffractionExperiment::GetSourceNameShort() const {
|
||||
return source_name_short;
|
||||
}
|
||||
|
||||
std::string DiffractionExperiment::GetSourceType() const {
|
||||
return source_type;
|
||||
}
|
||||
|
||||
std::string DiffractionExperiment::GetInstrumentName() const {
|
||||
return instrument_name;
|
||||
}
|
||||
@@ -949,22 +967,13 @@ std::optional<float> DiffractionExperiment::GetTotalFlux() const {
|
||||
return dataset.GetTotalFlux();
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::OmegaStep(const std::optional<float> &input) {
|
||||
dataset.OmegaStep(input);
|
||||
DiffractionExperiment &DiffractionExperiment::Goniometer(const std::optional<GoniometerAxis> &input) {
|
||||
dataset.Goniometer(input);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::OmegaStart(float input) {
|
||||
dataset.OmegaStart(input);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::optional<float> DiffractionExperiment::GetOmegaStep() const {
|
||||
return dataset.GetOmegaStep();
|
||||
}
|
||||
|
||||
float DiffractionExperiment::GetOmegaStart() const {
|
||||
return dataset.GetOmegaStart();
|
||||
std::optional<GoniometerAxis> DiffractionExperiment::GetGoniometer() const {
|
||||
return dataset.GetGoniometer();
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::UsingGainHG0(bool input) {
|
||||
@@ -1003,45 +1012,42 @@ std::string DiffractionExperiment::GetImageAppendix() const {
|
||||
return dataset.GetImageAppendix();
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::OmegaAxis(const Coord &c) {
|
||||
dataset.OmegaAxis(c);
|
||||
DiffractionExperiment &DiffractionExperiment::RotationAxis(const std::optional<Coord> &c) {
|
||||
dataset.RotationAxis(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::OmegaAxis() {
|
||||
dataset.OmegaAxis({});
|
||||
return *this;
|
||||
}
|
||||
|
||||
Coord DiffractionExperiment::GetOmegaAxis() const {
|
||||
auto tmp = dataset.GetOmegaAxis();
|
||||
Coord DiffractionExperiment::GetRotationAxis() const {
|
||||
auto tmp = dataset.GetRotationAxis();
|
||||
if (tmp)
|
||||
return tmp.value();
|
||||
else
|
||||
return default_omega_axis;
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::DefaultOmegaAxis(const Coord &c) {
|
||||
DiffractionExperiment &DiffractionExperiment::DefaultRotationAxis(const Coord &c) {
|
||||
if (c.Length() == 0.0)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Cannot use empty vector for omega axis");
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Cannot use empty vector for goniometer axis");
|
||||
|
||||
default_omega_axis = c.Normalize();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Coord DiffractionExperiment::GetDefaultOmegaAxis() const {
|
||||
Coord DiffractionExperiment::GetDefaultRotationAxis() const {
|
||||
return default_omega_axis;
|
||||
}
|
||||
|
||||
uint64_t DiffractionExperiment::GetSeriesID() const {
|
||||
uint64_t DiffractionExperiment::GetRunNumber() const {
|
||||
if (dataset.GetRunNumber())
|
||||
return dataset.GetRunNumber().value();
|
||||
return series_id;
|
||||
}
|
||||
|
||||
std::string DiffractionExperiment::GetSeriesIDString() const {
|
||||
std::string DiffractionExperiment::GetRunName() const {
|
||||
return std::to_string(series_id) + ": " + dataset.GetFilePrefix();
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::IncrementSeriesID() {
|
||||
DiffractionExperiment &DiffractionExperiment::IncrementRunNumber() {
|
||||
series_id++;
|
||||
return *this;
|
||||
}
|
||||
@@ -1068,6 +1074,7 @@ bool DiffractionExperiment::IsConversionOnFPGA() const {
|
||||
}
|
||||
|
||||
DiffractionExperiment &DiffractionExperiment::DetectorDelay(std::chrono::nanoseconds input) {
|
||||
check_min("Detector delay (us)", input.count(), 0);
|
||||
detector_delay = input;
|
||||
return *this;
|
||||
}
|
||||
@@ -1184,3 +1191,7 @@ DiffractionExperiment &DiffractionExperiment::DataReductionFactorSerialMX(float
|
||||
dataset.DataReductionFactorSerialMX(input);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string DiffractionExperiment::GetExperimentGroup() const {
|
||||
return dataset.GetExperimentGroup();
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ class DiffractionExperiment {
|
||||
|
||||
std::string source_name;
|
||||
std::string source_name_short;
|
||||
std::string source_type;
|
||||
std::string instrument_name;
|
||||
std::string instrument_name_short;
|
||||
bool pulsed_source;
|
||||
@@ -132,14 +133,15 @@ public:
|
||||
DiffractionExperiment& StorageCellStart(int64_t input = 15);
|
||||
|
||||
DiffractionExperiment& SourceName(std::string input);
|
||||
DiffractionExperiment& SourceType(std::string input);
|
||||
DiffractionExperiment& SourceNameShort(std::string input);
|
||||
DiffractionExperiment& InstrumentName(std::string input);
|
||||
DiffractionExperiment& InstrumentNameShort(std::string input);
|
||||
DiffractionExperiment& DefaultOmegaAxis(const Coord &c);
|
||||
DiffractionExperiment& DefaultRotationAxis(const Coord &c);
|
||||
|
||||
DiffractionExperiment& UsingGainHG0(bool input);
|
||||
DiffractionExperiment& FixedGainG1(bool input);
|
||||
DiffractionExperiment& IncrementSeriesID();
|
||||
DiffractionExperiment& IncrementRunNumber();
|
||||
DiffractionExperiment& ConversionOnFPGA(bool input);
|
||||
DiffractionExperiment& PulsedSource(bool input);
|
||||
|
||||
@@ -156,10 +158,8 @@ public:
|
||||
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& Goniometer(const std::optional<GoniometerAxis> &input);
|
||||
DiffractionExperiment& RotationAxis(const std::optional<Coord> &c);
|
||||
DiffractionExperiment& HeaderAppendix(const std::string& input);
|
||||
DiffractionExperiment& ImageAppendix(const std::string& input);
|
||||
DiffractionExperiment& PhotonEnergyMultiplayer(float input);
|
||||
@@ -252,6 +252,7 @@ public:
|
||||
|
||||
float GetPixelSize_mm() const;
|
||||
std::string GetSourceName() const;
|
||||
std::string GetSourceType() const;
|
||||
std::string GetSourceNameShort() const;
|
||||
std::string GetInstrumentName() const;
|
||||
std::string GetInstrumentNameShort() const;
|
||||
@@ -268,13 +269,13 @@ public:
|
||||
|
||||
int64_t GetUDPInterfaceCount() const;
|
||||
std::vector<DetectorModuleConfig> GetDetectorModuleConfig(const std::vector<AcquisitionDeviceNetConfig>& net_config) const;
|
||||
Coord GetDefaultOmegaAxis() const;
|
||||
Coord GetDefaultRotationAxis() const;
|
||||
|
||||
bool IsFixedGainG1() const;
|
||||
bool IsUsingGainHG0() const;
|
||||
|
||||
uint64_t GetSeriesID() const;
|
||||
std::string GetSeriesIDString() const;
|
||||
uint64_t GetRunNumber() const;
|
||||
std::string GetRunName() const;
|
||||
bool IsConversionOnFPGA() const;
|
||||
|
||||
const DetectorSetup& GetDetectorSetup() const;
|
||||
@@ -287,9 +288,9 @@ public:
|
||||
|
||||
std::optional<float> GetAttenuatorTransmission() const;
|
||||
std::optional<float> GetTotalFlux() const;
|
||||
std::optional<float> GetOmegaStep() const;
|
||||
float GetOmegaStart() const;
|
||||
Coord GetOmegaAxis() const;
|
||||
std::optional<GoniometerAxis> GetGoniometer() const;
|
||||
|
||||
Coord GetRotationAxis() const;
|
||||
std::string GetHeaderAppendix() const;
|
||||
std::string GetImageAppendix() const;
|
||||
float GetPhotonEnergyMultiplier() const;
|
||||
@@ -320,6 +321,7 @@ public:
|
||||
int64_t GetImagesPerFile() const;
|
||||
|
||||
float GetDataReductionFactorSerialMX() const;
|
||||
std::string GetExperimentGroup() const;
|
||||
};
|
||||
|
||||
#endif //DIFFRACTIONEXPERIMENT_H
|
||||
|
||||
@@ -528,30 +528,38 @@ namespace {
|
||||
cborErr(cbor_value_leave_container(&value, &array_value));
|
||||
}
|
||||
|
||||
void ProcessGoniometerOmega(StartMessage &message, CborValue &value) {
|
||||
GoniometerAxis ProcessGoniometerOmega(std::string &name, CborValue &value) {
|
||||
GoniometerAxis ret;
|
||||
ret.name = name;
|
||||
|
||||
CborValue map_value;
|
||||
|
||||
cborErr(cbor_value_enter_container(&value, &map_value));
|
||||
while (!cbor_value_at_end(&map_value)) {
|
||||
auto key = GetCBORString(map_value);
|
||||
if (key == "increment")
|
||||
message.omega.increment = GetCBORFloat(map_value);
|
||||
ret.increment = GetCBORFloat(map_value);
|
||||
else if (key == "start")
|
||||
message.omega.start = GetCBORFloat(map_value);
|
||||
ret.start = GetCBORFloat(map_value);
|
||||
else
|
||||
cbor_value_advance(&value);
|
||||
}
|
||||
cborErr(cbor_value_leave_container(&value, &map_value));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ProcessGoniometerMap(StartMessage &message, CborValue &value) {
|
||||
CborValue map_value;
|
||||
|
||||
if (GetCBORMapLen(value) > 1)
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError, "Max one rotation angle allowed");
|
||||
|
||||
cborErr(cbor_value_enter_container(&value, &map_value));
|
||||
while (!cbor_value_at_end(&map_value)) {
|
||||
GoniometerAxis axis;
|
||||
auto key = GetCBORString(map_value);
|
||||
if (key == "omega")
|
||||
ProcessGoniometerOmega(message, map_value);
|
||||
message.goniometer = ProcessGoniometerOmega(key, map_value);
|
||||
}
|
||||
cborErr(cbor_value_leave_container(&value, &map_value));
|
||||
}
|
||||
@@ -615,6 +623,8 @@ namespace {
|
||||
message.sample_name = j["sample_name"];
|
||||
if (j.contains("source_name"))
|
||||
message.source_name = j["source_name"];
|
||||
if (j.contains("source_type"))
|
||||
message.source_type = j["source_type"];
|
||||
if (j.contains("source_name_short"))
|
||||
message.source_name_short = j["source_name_short"];
|
||||
if (j.contains("instrument_name"))
|
||||
@@ -625,10 +635,10 @@ namespace {
|
||||
message.total_flux = j["total_flux"];
|
||||
if (j.contains("attenuator_transmission"))
|
||||
message.attenuator_transmission = j["attenuator_transmission"];
|
||||
if (j.contains("omega_rotation_axis") && j["omega_rotation_axis"].is_array() &&
|
||||
(j["omega_rotation_axis"].size() == 3)) {
|
||||
if (j.contains("rotation_axis") && j["rotation_axis"].is_array() &&
|
||||
(j["rotation_axis"].size() == 3)) {
|
||||
for (int i = 0; i < 3; i++)
|
||||
message.omega.axis[i] = j["omega_rotation_axis"][i];
|
||||
message.rotation_axis[i] = j["rotation_axis"][i];
|
||||
}
|
||||
if (j.contains("space_group_number"))
|
||||
message.space_group_number = j["space_group_number"];
|
||||
@@ -640,6 +650,11 @@ namespace {
|
||||
message.write_master_file = j["write_master_file"];
|
||||
if (j.contains("data_reduction_factor_serialmx"))
|
||||
message.data_reduction_factor_serialmx = j["data_reduction_factor_serialmx"];
|
||||
if (j.contains("experiment_group"))
|
||||
message.experiment_group = j["experiment_group"];
|
||||
if (j.contains("jfjoch_release"))
|
||||
message.jfjoch_release = j["jfjoch_release"];
|
||||
|
||||
} catch (const std::exception &e) {
|
||||
throw JFJochException(JFJochExceptionCategory::CBORError,
|
||||
"Cannot parse user_data as valid JSON " + std::string(e.what()));
|
||||
|
||||
@@ -215,10 +215,10 @@ inline void CBOR_ENC_AXIS(CborEncoder &encoder, const char* key, const float det
|
||||
cborErr(cbor_encoder_close_container(&encoder, &arrayEncoder));
|
||||
}
|
||||
|
||||
inline void CBOR_ENC_GONIOMETER(CborEncoder &encoder, const char* key, const GoniometerAxis &g) {
|
||||
inline void CBOR_ENC_GONIOMETER(CborEncoder &encoder, const GoniometerAxis &g) {
|
||||
CborEncoder mapEncoder;
|
||||
|
||||
cborErr(cbor_encode_text_stringz(&encoder, key));
|
||||
cborErr(cbor_encode_text_stringz(&encoder, g.name.c_str()));
|
||||
cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 2));
|
||||
CBOR_ENC(mapEncoder, "increment", g.increment);
|
||||
CBOR_ENC(mapEncoder, "start", g.start);
|
||||
@@ -228,11 +228,12 @@ inline void CBOR_ENC_GONIOMETER(CborEncoder &encoder, const char* key, const Gon
|
||||
inline void CBOR_ENC_GONIOMETER_MAP(CborEncoder &encoder, const char* key, const StartMessage &msg) {
|
||||
CborEncoder mapEncoder;
|
||||
|
||||
cborErr(cbor_encode_text_stringz(&encoder, key));
|
||||
cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 1));
|
||||
CBOR_ENC_GONIOMETER(mapEncoder, "omega", msg.omega);
|
||||
|
||||
cborErr(cbor_encoder_close_container(&encoder, &mapEncoder));
|
||||
if (msg.goniometer) {
|
||||
cborErr(cbor_encode_text_stringz(&encoder, key));
|
||||
cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 1));
|
||||
CBOR_ENC_GONIOMETER(mapEncoder, msg.goniometer.value());
|
||||
cborErr(cbor_encoder_close_container(&encoder, &mapEncoder));
|
||||
}
|
||||
}
|
||||
|
||||
inline void CBOR_ENC(CborEncoder &encoder, const char* key, const std::vector<std::string> &v) {
|
||||
@@ -302,6 +303,8 @@ inline void CBOR_ENC_START_USER_DATA(CborEncoder& encoder, const char* key,
|
||||
j["images_per_file"] = message.images_per_file;
|
||||
j["source_name"] = message.source_name;
|
||||
j["source_name_short"] = message.source_name_short;
|
||||
if (!message.source_type.empty())
|
||||
j["source_type"] = message.source_type;
|
||||
j["instrument_name"] = message.instrument_name;
|
||||
j["instrument_name_short"] = message.instrument_name_short;
|
||||
j["sample_name"] = message.sample_name;
|
||||
@@ -310,7 +313,7 @@ inline void CBOR_ENC_START_USER_DATA(CborEncoder& encoder, const char* key,
|
||||
j["attenuator_transmission"] = message.attenuator_transmission.value();
|
||||
if (message.total_flux)
|
||||
j["total_flux"] = message.total_flux.value();
|
||||
j["omega_rotation_axis"] = {message.omega.axis[0], message.omega.axis[1], message.omega.axis[2]};
|
||||
j["rotation_axis"] = {message.rotation_axis[0], message.rotation_axis[1], message.rotation_axis[2]};
|
||||
j["space_group_number"] = message.space_group_number;
|
||||
j["roi_names"] = message.roi_names;
|
||||
j["gain_file_names"] = message.gain_file_names;
|
||||
@@ -318,7 +321,9 @@ inline void CBOR_ENC_START_USER_DATA(CborEncoder& encoder, const char* key,
|
||||
j["write_master_file"] = message.write_master_file.value();
|
||||
if (message.data_reduction_factor_serialmx)
|
||||
j["data_reduction_factor_serialmx"] = message.data_reduction_factor_serialmx.value();
|
||||
|
||||
if (message.experiment_group)
|
||||
j["experiment_group"] = message.experiment_group.value();
|
||||
j["jfjoch_release"] = message.jfjoch_release;
|
||||
auto str = j.dump();
|
||||
|
||||
CBOR_ENC(encoder, key, str);
|
||||
|
||||
@@ -85,9 +85,9 @@ struct DataMessage {
|
||||
};
|
||||
|
||||
struct GoniometerAxis {
|
||||
std::string name;
|
||||
float increment;
|
||||
float start;
|
||||
float axis[3];
|
||||
};
|
||||
|
||||
struct StartMessage {
|
||||
@@ -144,9 +144,11 @@ struct StartMessage {
|
||||
|
||||
std::vector<std::string> roi_names;
|
||||
|
||||
GoniometerAxis omega;
|
||||
std::optional<GoniometerAxis> goniometer;
|
||||
float rotation_axis[3];
|
||||
float detector_translation[3];
|
||||
|
||||
std::string source_type;
|
||||
std::string source_name;
|
||||
std::string source_name_short;
|
||||
std::string instrument_name;
|
||||
@@ -171,6 +173,9 @@ struct StartMessage {
|
||||
std::string user_data;
|
||||
|
||||
std::optional<float> data_reduction_factor_serialmx;
|
||||
std::optional<std::string> experiment_group;
|
||||
|
||||
std::string jfjoch_release;
|
||||
};
|
||||
|
||||
struct EndMessage {
|
||||
|
||||
@@ -13,96 +13,98 @@ There are minor differences at the moment:
|
||||
|
||||
## Start message
|
||||
|
||||
| Field name | Type | Description | Present in DECTRIS format |
|
||||
|---------------------------|---------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|
|
||||
| type | String | value "start" | X |
|
||||
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | |
|
||||
| detector_distance | float | Detector distance \[m\] | |
|
||||
| detector_translation | float | Detector translation vector \[m\] | X |
|
||||
| beam_center_x | float | Beam center in X direction \[pixels\] | X |
|
||||
| beam_center_y | float | Beam center in Y direction \[pixels\] | X |
|
||||
| number_of_images | uint64 | Number of images in the series | X |
|
||||
| image_size_x | uint64 | Image width \[pixels\] | X |
|
||||
| image_size_y | uint64 | Image height \[pixels\] | X |
|
||||
| incident_energy | float | X-ray energy \[eV\] | X |
|
||||
| incident_wavelength | float | X-ray wavelength \[Angstrom\] | X |
|
||||
| frame_time | float | Frame time, if multiple frames per trigger \[s\] | X |
|
||||
| count_time | float | Exposure time \[s\] | X |
|
||||
| saturation_value | int64 | Maximum valid sample value | X |
|
||||
| error_value | int64 | Value used in images to describe pixels that are in error state or missing | |
|
||||
| pixel_size_x | float | Pixel width \[m\] | X |
|
||||
| pixel_size_y | float | Pixel height \[m\] | X |
|
||||
| sensor_thickness | float | Sensor thickness \[m\] | X |
|
||||
| sensor_material | string | Sensor material | X |
|
||||
| arm_data | data | Approximate date of arming | X |
|
||||
| pixel_mask_enabled | bool | Pixel mask applied on images | X |
|
||||
| detector_description | string | Name of the detector | X |
|
||||
| series_unique_id | string | Unique text ID of the series | X |
|
||||
| series_id | uint64 | Unique numeric ID of the series | X |
|
||||
| goniometer | Map | See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) - only "omega" axis is supported | X |
|
||||
| pixel_mask | Map(string -> Image) | Pixel mask - multiple in case of storage cells | X |
|
||||
| channels | Array(string) | List of image channels | X |
|
||||
| max_spot_count | uint64 | Maximum number of spots identified in spot finding | |
|
||||
| storage_cell_number | uint64 | Number of storage cells used by JUNGFRAU | |
|
||||
| image_dtype | string | Pixel bit type (e.g. uint16) | X |
|
||||
| unit_cell | Array(6 * float) (optional) | Unit cell of the system: a, b, c \[angstrom\] and alpha, beta, gamma \[degree\] | |
|
||||
| az_int_bin_number | uint64 | Number of azimuthal integration bins | |
|
||||
| az_int_bin_to_q | Array(float) | Q value for each azimuthal integration bin \[angstrom^-1\] | |
|
||||
| summation | uint64 | Factor of frame summation | |
|
||||
| user_data | string | JSON string that can contain the following fields (among others): | X |
|
||||
| - source_name | string | Facility name | |
|
||||
| - source_name_short | string | Facility name (short) | |
|
||||
| - instrument_name | string | Instrument name | |
|
||||
| - instrument_name_short | string | Instrument name (short | |
|
||||
| - attenuator_transmission | float (optional) | Attenuator transmission \[\] | |
|
||||
| - total_flux | float (optional) | Total flux \[ph/s\] | |
|
||||
| - data_file_count | uint64 | Number of used data files | |
|
||||
| - file_prefix | string | File prefix | |
|
||||
| - sample_name | string | Name of the sample | |
|
||||
| - omega_rotation_axis | Array(float) | Omega rotation axis (array of size 3) | |
|
||||
| - space_group_number | uint64 | Space group number | |
|
||||
| - write_master_file | bool | With multiple sockets, it selects which socket will provide master file | |
|
||||
| Field name | Type | Description | Present in DECTRIS format |
|
||||
|---------------------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|
|
||||
| type | String | value "start" | X |
|
||||
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | |
|
||||
| detector_distance | float | Detector distance \[m\] | |
|
||||
| detector_translation | float | Detector translation vector \[m\] | X |
|
||||
| beam_center_x | float | Beam center in X direction \[pixels\] | X |
|
||||
| beam_center_y | float | Beam center in Y direction \[pixels\] | X |
|
||||
| number_of_images | uint64 | Number of images in the series | X |
|
||||
| image_size_x | uint64 | Image width \[pixels\] | X |
|
||||
| image_size_y | uint64 | Image height \[pixels\] | X |
|
||||
| incident_energy | float | X-ray energy \[eV\] | X |
|
||||
| incident_wavelength | float | X-ray wavelength \[Angstrom\] | X |
|
||||
| frame_time | float | Frame time, if multiple frames per trigger \[s\] | X |
|
||||
| count_time | float | Exposure time \[s\] | X |
|
||||
| saturation_value | int64 | Maximum valid sample value | X |
|
||||
| error_value | int64 | Value used in images to describe pixels that are in error state or missing | |
|
||||
| pixel_size_x | float | Pixel width \[m\] | X |
|
||||
| pixel_size_y | float | Pixel height \[m\] | X |
|
||||
| sensor_thickness | float | Sensor thickness \[m\] | X |
|
||||
| sensor_material | string | Sensor material | X |
|
||||
| arm_data | data | Approximate date of arming | X |
|
||||
| pixel_mask_enabled | bool | Pixel mask applied on images | X |
|
||||
| detector_description | string | Name of the detector | X |
|
||||
| series_unique_id | string | Unique text ID of the series | X |
|
||||
| series_id | uint64 | Unique numeric ID of the series | X |
|
||||
| goniometer | Map | See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) - only one axis is supported | X |
|
||||
| pixel_mask | Map(string -> Image) | Pixel mask - multiple in case of storage cells | X |
|
||||
| channels | Array(string) | List of image channels | X |
|
||||
| max_spot_count | uint64 | Maximum number of spots identified in spot finding | |
|
||||
| storage_cell_number | uint64 | Number of storage cells used by JUNGFRAU | |
|
||||
| image_dtype | string | Pixel bit type (e.g. uint16) | X |
|
||||
| unit_cell | Array(6 * float) (optional) | Unit cell of the system: a, b, c \[angstrom\] and alpha, beta, gamma \[degree\] | |
|
||||
| az_int_bin_number | uint64 | Number of azimuthal integration bins | |
|
||||
| az_int_bin_to_q | Array(float) | Q value for each azimuthal integration bin \[angstrom^-1\] | |
|
||||
| summation | uint64 | Factor of frame summation | |
|
||||
| user_data | string | JSON string that can contain the following fields (among others): | X |
|
||||
| - source_name | string | Facility name | |
|
||||
| - source_name_short | string | Facility name (short) | |
|
||||
| - source_type | string (optional) | Type of X-ray source (use NXsource/type values, for example "Synchrotron X-ray Source" or "Free-Electron Laser") | |
|
||||
| - instrument_name | string | Instrument name | |
|
||||
| - instrument_name_short | string | Instrument name (short) | |
|
||||
| - attenuator_transmission | float (optional) | Attenuator transmission \[\] | |
|
||||
| - total_flux | float (optional) | Total flux \[ph/s\] | |
|
||||
| - data_file_count | uint64 | Number of used data files | |
|
||||
| - file_prefix | string | File prefix | |
|
||||
| - sample_name | string | Name of the sample | |
|
||||
| - rotation_axis | Array(float) | Rotation axis vector (array of size 3) | |
|
||||
| - space_group_number | uint64 | Space group number | |
|
||||
| - write_master_file | bool | With multiple sockets, it selects which socket will provide master file | |
|
||||
| - experiment_group | string | ID of instrument user, e.g., p-group (SLS/SwissFEL) or proposal number | |
|
||||
|
||||
See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) for definition of Image as MultiDimArray with optional compression.
|
||||
|
||||
## Image message
|
||||
|
||||
| Field name | Type | Description | Present in DECTRIS format | Optional |
|
||||
|----------------------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|:--------:|
|
||||
| type | String | value "image" | X | |
|
||||
| Field name | Type | Description | Present in DECTRIS format | Optional |
|
||||
|----------------------------|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|:--------:|
|
||||
| type | String | value "image" | X | |
|
||||
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | | |
|
||||
| series_unique_id | string | Unique text ID of the series | X | |
|
||||
| series_id | uint64 | Unique numeric ID of the series | X | |
|
||||
| image_id | uint64 | Number of image within the series | X | |
|
||||
| real_time | Rational | Exposure time | X | |
|
||||
| start_time | Rational | Exposure start time (highly approximate) | X | |
|
||||
| end_time | Rational | Exposure end time (highly approximate) | X | |
|
||||
| spots | Array(object) | Spots: | | |
|
||||
| - x | float | position in x (pixels) | | |
|
||||
| - y | float | position in y (pixels) | | |
|
||||
| - I | float | intensity (photons) | | |
|
||||
| - indexed | bool | indexed solution | | |
|
||||
| az_int_profile | Array(float) | Azimuthal integration results, use az_int_bin_to_q from start message for legend | | |
|
||||
| indexing_result | bool | Indexing successful | | |
|
||||
| indexing_lattice | Array(float * 9) (optional) | Indexing result real lattice; present only if indexed | | |
|
||||
| xfel_pulse_id | uint64 | Bunch ID (for SwissFEL) | | X |
|
||||
| xfel_event_code | uint64 | Event code (for SwissFEL) | | X |
|
||||
| jf_info | uint64 | Detector info field | | |
|
||||
| receiver_aq_dev_delay | uint64 | Receiver internal delay | | |
|
||||
| receiver_free_send_buf | uint64 | Receiver internal number of available send buffers | | |
|
||||
| storage_cell | uint64 | Storage cell number | | |
|
||||
| saturated_pixel_count | uint64 | Saturated pixel count | | |
|
||||
| error_pixel_count | uint64 | Error pixel count | | |
|
||||
| strong_pixel_count | uint64 | Strong pixel count (first stage of spot finding) | | |
|
||||
| data_collection_efficiency | float | Image collection efficiency \[\] | | |
|
||||
| bkg_estimate | float | Mean value for pixels in resolution range from 3.0 to 5.0 A [\photons\] | | |
|
||||
| adu_histogram | Array(uint64) | ADU histogram | | |
|
||||
| corr_beam_x_pxl | float | Difference between provided and calculated beam center X (pixels) - requires indexing | | X |
|
||||
| corr_beam_y_pxl | float | Difference between provided and calculated beam center Y (pixels) - requires indexing | | X |
|
||||
| corr_det_dist_mm | float | Difference between provided and calculated detector distance (mm) - requires indexing | | X |
|
||||
| user_data | string | Optional user defined text information | | |
|
||||
| roi_sum | int64 | Sum of ROI rectangle \[photons\] | | X |
|
||||
| image | Map(string -> Image) | Image | | |
|
||||
| series_unique_id | string | Unique text ID of the series | X | |
|
||||
| series_id | uint64 | Unique numeric ID of the series | X | |
|
||||
| image_id | uint64 | Number of image within the series | X | |
|
||||
| real_time | Rational | Exposure time | X | |
|
||||
| start_time | Rational | Exposure start time (highly approximate) | X | |
|
||||
| end_time | Rational | Exposure end time (highly approximate) | X | |
|
||||
| spots | Array(object) | Spots: | | |
|
||||
| - x | float | position in x (pixels) | | |
|
||||
| - y | float | position in y (pixels) | | |
|
||||
| - I | float | intensity (photons) | | |
|
||||
| - indexed | bool | indexed solution | | |
|
||||
| az_int_profile | Array(float) | Azimuthal integration results, use az_int_bin_to_q from start message for legend | | |
|
||||
| indexing_result | bool | Indexing successful | | |
|
||||
| indexing_lattice | Array(float * 9) (optional) | Indexing result real lattice; present only if indexed | | |
|
||||
| xfel_pulse_id | uint64 | Bunch ID (for pulsed source, e.g., SwissFEL) | | X |
|
||||
| xfel_event_code | uint64 | Event code (for pulsed source, e.g., SwissFEL) | | X |
|
||||
| jf_info | uint64 | Detector info field | | |
|
||||
| receiver_aq_dev_delay | uint64 | Receiver internal delay | | |
|
||||
| receiver_free_send_buf | uint64 | Receiver internal number of available send buffers | | |
|
||||
| storage_cell | uint64 | Storage cell number | | |
|
||||
| saturated_pixel_count | uint64 | Saturated pixel count | | |
|
||||
| error_pixel_count | uint64 | Error pixel count | | |
|
||||
| strong_pixel_count | uint64 | Strong pixel count (first stage of spot finding) | | |
|
||||
| data_collection_efficiency | float | Image collection efficiency \[\] | | |
|
||||
| bkg_estimate | float | Mean value for pixels in resolution range from 3.0 to 5.0 A [\photons\] | | |
|
||||
| adu_histogram | Array(uint64) | ADU histogram | | |
|
||||
| corr_beam_x_pxl | float | Difference between provided and calculated beam center X (pixels) - requires indexing | | X |
|
||||
| corr_beam_y_pxl | float | Difference between provided and calculated beam center Y (pixels) - requires indexing | | X |
|
||||
| corr_det_dist_mm | float | Difference between provided and calculated detector distance (mm) - requires indexing | | X |
|
||||
| user_data | string | Optional user defined text information | | |
|
||||
| roi_sum | int64 | Sum of ROI rectangle \[photons\] | | X |
|
||||
| image | Map(string -> Image) | Image | | |
|
||||
|
||||
## End message
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import Calibration from "./components/Calibration";
|
||||
import StatusBar from "./components/StatusBar";
|
||||
import DataProcessingPlots from "./components/DataProcessingPlots";
|
||||
import DetectorSelection from "./components/DetectorSelection";
|
||||
import BkgEstimatePlot from "./components/BkgEstimatePlot";
|
||||
import MeasurementStatistics from "./components/MeasurementStatistics";
|
||||
import DetectorStatus from "./components/DetectorStatus";
|
||||
import Paper from "@mui/material/Paper";
|
||||
@@ -91,13 +90,13 @@ class App extends Component<MyProps, MyState> {
|
||||
spacing={3}
|
||||
sx={{width: "95%"}}>
|
||||
<Grid item xs={8}>
|
||||
<BkgEstimatePlot/>
|
||||
<DataProcessingPlots default_tab={"12"} height={550}/>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<MeasurementStatistics/>
|
||||
</Grid>
|
||||
<Grid item xs={8}>
|
||||
<DataProcessingPlots/>
|
||||
<DataProcessingPlots default_tab={"1"} height={700}/>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<DataProcessingSettings/>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import Paper from "@mui/material/Paper";
|
||||
import DataProcessingPlot, {PlotType} from "./DataProcessingPlot";
|
||||
import React, {Component} from "react";
|
||||
import {Box} from "@mui/material";
|
||||
|
||||
type MyProps = {};
|
||||
|
||||
|
||||
class BkgEstimatePlot extends Component<MyProps> {
|
||||
|
||||
render() {
|
||||
return <Paper style={{textAlign: 'center'}} sx={{height: 500, width: "100%"}}>
|
||||
<Box sx={{width: "100%", height: 50}}>
|
||||
<br/>
|
||||
<center><strong>Background estimate</strong></center>
|
||||
</Box>
|
||||
<Box sx={{width: "95%", height: 350}}>
|
||||
<DataProcessingPlot type={PlotType.BKG_ESTIMATE} xlabel={"Image Number"}
|
||||
ylabel={"Photon count"} binning={0}/><br/>
|
||||
</Box>
|
||||
</Paper>
|
||||
}
|
||||
}
|
||||
|
||||
export default BkgEstimatePlot;
|
||||
@@ -9,7 +9,9 @@ import FormControl from "@mui/material/FormControl";
|
||||
import Select, {SelectChangeEvent} from "@mui/material/Select";
|
||||
|
||||
type MyProps = {
|
||||
};
|
||||
default_tab: string,
|
||||
height: number
|
||||
}
|
||||
|
||||
type MyState = {
|
||||
type: PlotType,
|
||||
@@ -28,7 +30,7 @@ class DataProcessingPlots extends Component<MyProps, MyState> {
|
||||
xlabel: "Image number",
|
||||
ylabel: "Indexing rate",
|
||||
binning: "0",
|
||||
tab: "1",
|
||||
tab: this.props.default_tab,
|
||||
connection_error: true
|
||||
}
|
||||
|
||||
@@ -69,6 +71,9 @@ class DataProcessingPlots extends Component<MyProps, MyState> {
|
||||
case "11":
|
||||
this.setState({type: PlotType.ROI_SUM, xlabel: "Image number", ylabel: "Photon count"});
|
||||
break;
|
||||
case "12":
|
||||
this.setState({type: PlotType.BKG_ESTIMATE, xlabel: "Image number", ylabel: "Photon count"});
|
||||
break;
|
||||
case "13":
|
||||
this.setState({type: PlotType.RECEIVER_FREE_SEND_BUFS, xlabel: "Image number", ylabel: "Number of buffers"});
|
||||
break;
|
||||
@@ -80,7 +85,7 @@ class DataProcessingPlots extends Component<MyProps, MyState> {
|
||||
};
|
||||
|
||||
render() {
|
||||
return <Paper style={{textAlign: 'center'}} sx={{ height: 700, width: "100%" }}>
|
||||
return <Paper style={{textAlign: 'center'}} sx={{ height: this.props.height, width: "100%" }}>
|
||||
<Toolbar>
|
||||
|
||||
<Grid container sx={{ minWidth: 500 }} >
|
||||
@@ -95,6 +100,7 @@ class DataProcessingPlots extends Component<MyProps, MyState> {
|
||||
<MenuItem value={1}>Indexing rate</MenuItem>
|
||||
<MenuItem value={2}>Spot count</MenuItem>
|
||||
<MenuItem value={3}>Azimuthal integration profile</MenuItem>
|
||||
<MenuItem value={12}>Background estimate</MenuItem>
|
||||
<MenuItem value={11}>ROI area sum</MenuItem>
|
||||
<MenuItem value={6}>ROI area max count</MenuItem>
|
||||
<MenuItem value={4}>Indexing rate (per time point)</MenuItem>
|
||||
@@ -129,7 +135,7 @@ class DataProcessingPlots extends Component<MyProps, MyState> {
|
||||
</FormControl>
|
||||
</Grid>
|
||||
</Toolbar>
|
||||
<Box sx={{width:"95%", height: 550}} >
|
||||
<Box sx={{width:"95%", height: this.props.height - 150}} >
|
||||
<DataProcessingPlot type={this.state.type} xlabel={this.state.xlabel} ylabel={this.state.ylabel}
|
||||
binning={Number(this.state.binning)}/>
|
||||
</Box>
|
||||
|
||||
@@ -65,12 +65,12 @@ class DetectorSettings extends Component<MyProps, MyState> {
|
||||
}
|
||||
|
||||
if (!frame_err) {
|
||||
if ((Number(frame_time) < 470) || (Number(frame_time) > 2000))
|
||||
if (Number(frame_time) < 470)
|
||||
frame_err = true;
|
||||
}
|
||||
|
||||
if (!count_err) {
|
||||
if (Number(count_time) < 5)
|
||||
if ((Number(count_time) < 3) || (Number(count_time) > 1980))
|
||||
count_err = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import React, {Component} from 'react';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import {Grid, Table, TableBody, TableCell, TableContainer, TableRow,} from "@mui/material";
|
||||
import {DefaultService, detector_status} from "../openapi";
|
||||
import powerchip = detector_status.powerchip;
|
||||
import state = detector_status.state;
|
||||
import powerchip = detector_status.powerchip;
|
||||
|
||||
type MyProps = {}
|
||||
|
||||
@@ -13,16 +13,28 @@ type MyState = {
|
||||
connection_error: boolean
|
||||
}
|
||||
|
||||
function powerchipToString(s : detector_status) : string {
|
||||
if (s.powerchip === undefined)
|
||||
return "";
|
||||
switch (s.powerchip) {
|
||||
case powerchip.POWER_ON:
|
||||
return "On";
|
||||
case powerchip.POWER_OFF:
|
||||
return "Off";
|
||||
case powerchip.PARTIAL:
|
||||
return "Partially on";
|
||||
}
|
||||
}
|
||||
class DetectorStatus extends Component<MyProps, MyState> {
|
||||
interval : NodeJS.Timer | undefined;
|
||||
state : MyState = {
|
||||
s: {
|
||||
state: state.IDLE,
|
||||
powerchip: powerchip.OFF,
|
||||
powerchip: powerchip.POWER_OFF,
|
||||
server_version: "Detector off",
|
||||
number_of_triggers_left: 0,
|
||||
fpga_temp_degC: [0,0,0,0,0,1],
|
||||
high_voltage_V: [1,0,0,0,-1]
|
||||
fpga_temp_degC: [-1],
|
||||
high_voltage_V: [-1]
|
||||
},
|
||||
connection_error: true
|
||||
}
|
||||
@@ -37,11 +49,11 @@ class DetectorStatus extends Component<MyProps, MyState> {
|
||||
this.setState({
|
||||
s: {
|
||||
state: state.IDLE,
|
||||
powerchip: powerchip.OFF,
|
||||
powerchip: powerchip.POWER_OFF,
|
||||
server_version: "Detector off",
|
||||
number_of_triggers_left: 0,
|
||||
fpga_temp_degC: [30,29,35,40,32],
|
||||
high_voltage_V: [120,120,110,115]
|
||||
fpga_temp_degC: [-1],
|
||||
high_voltage_V: [-1]
|
||||
},
|
||||
connection_error: true
|
||||
});
|
||||
@@ -72,7 +84,7 @@ class DetectorStatus extends Component<MyProps, MyState> {
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell component="th" scope="row"> Detector ASIC power: </TableCell>
|
||||
<TableCell align="right">{this.state.s.powerchip.toString()}</TableCell>
|
||||
<TableCell align="right">{powerchipToString(this.state.s)}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell component="th" scope="row"> Triggers remaining: </TableCell>
|
||||
|
||||
@@ -15,7 +15,9 @@ class MeasurementStatistics extends Component<MyProps, MyState> {
|
||||
interval : NodeJS.Timer | undefined;
|
||||
state : MyState = {
|
||||
s: {
|
||||
run_number: undefined,
|
||||
file_prefix: undefined,
|
||||
experiment_group: undefined,
|
||||
images_expected: 0,
|
||||
images_collected: 0,
|
||||
images_sent: 0,
|
||||
@@ -48,7 +50,7 @@ class MeasurementStatistics extends Component<MyProps, MyState> {
|
||||
}
|
||||
|
||||
render() {
|
||||
return <Paper style={{textAlign: 'center'}} sx={{ height: 500, width: '100%' }}>
|
||||
return <Paper style={{textAlign: 'center'}} sx={{ height: 550, width: '100%' }}>
|
||||
<Grid container spacing={0}>
|
||||
<Grid item xs={1}/>
|
||||
<Grid item xs={10}>
|
||||
@@ -57,10 +59,19 @@ class MeasurementStatistics extends Component<MyProps, MyState> {
|
||||
<TableContainer component={Paper} style={{marginLeft: "auto", marginRight: "auto"}}>
|
||||
<Table size="small" aria-label="simple table">
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell component="th" scope="row"> File prefix: </TableCell>
|
||||
<TableCell align="right">{(this.state.s.file_prefix !== undefined) ? this.state.s.file_prefix : "(images not written)"}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell component="th" scope="row"> File prefix: </TableCell>
|
||||
<TableCell align="right">{(this.state.s.file_prefix !== undefined) ? this.state.s.file_prefix : "(images not written)"}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell component="th" scope="row"> Run number: </TableCell>
|
||||
<TableCell align="right">{(this.state.s.run_number !== undefined) ? this.state.s.run_number : "(not set)"}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell component="th" scope="row"> Experiment group: </TableCell>
|
||||
<TableCell align="right">{this.state.s.experiment_group}</TableCell>
|
||||
</TableRow>
|
||||
|
||||
<TableRow>
|
||||
<TableCell component="th" scope="row"> Images expected: </TableCell>
|
||||
<TableCell align="right">{this.state.s.images_expected}</TableCell>
|
||||
|
||||
@@ -44,10 +44,10 @@ export type dataset_settings = {
|
||||
detector_distance_mm: number;
|
||||
/**
|
||||
* Used to calculate /entry/beam/incident_wavelength in NXmx
|
||||
* Incident photon energy in keV
|
||||
* Incident particle (photon, electron) energy in keV
|
||||
*
|
||||
*/
|
||||
photon_energy_keV: number;
|
||||
incident_energy_keV: number;
|
||||
/**
|
||||
* Prefix for filenames. If left empty, no file will be saved.
|
||||
*/
|
||||
@@ -80,7 +80,7 @@ export type dataset_settings = {
|
||||
*
|
||||
*/
|
||||
transmission?: number;
|
||||
omega?: rotation_axis;
|
||||
goniometer?: rotation_axis;
|
||||
/**
|
||||
* Header appendix, added as user_data to start message
|
||||
*/
|
||||
@@ -90,9 +90,9 @@ export type dataset_settings = {
|
||||
*/
|
||||
image_appendix?: string;
|
||||
/**
|
||||
* For JUNGFRAU conversion it is possible to multiply energy by a given factor to get fractional/multiplied photon counts
|
||||
* For JUNGFRAU conversion it is possible to multiply incident energy by a given factor to get fractional/multiplied particle counts
|
||||
*/
|
||||
photon_energy_multiplier?: number;
|
||||
energy_multiplier?: number;
|
||||
/**
|
||||
* Rate at which non-indexed images are accepted to be forwarded to writer.
|
||||
* Value of 1.0 (default) means that all images are written.
|
||||
@@ -100,6 +100,20 @@ export type dataset_settings = {
|
||||
*
|
||||
*/
|
||||
data_reduction_factor_serialmx?: number;
|
||||
/**
|
||||
* Number of run within an experimental session.
|
||||
* Transferred over CBOR stream as "series ID", though not saved in HDF5 file.
|
||||
* It is highly recommended to keep this number unique for each data collection during experimental series.
|
||||
* If not provided, the number will be automatically incremented.
|
||||
*
|
||||
*/
|
||||
run_number?: number;
|
||||
/**
|
||||
* Name of group owning the data (e.g. p-group or proposal number).
|
||||
* Transferred over CBOR stream, though not saved in HDF5 file.
|
||||
*
|
||||
*/
|
||||
experiment_group?: string;
|
||||
/**
|
||||
* Units of angstrom and degree
|
||||
*/
|
||||
|
||||
@@ -46,8 +46,8 @@ export namespace detector_status {
|
||||
* Power on of ASICs
|
||||
*/
|
||||
export enum powerchip {
|
||||
ON = 'On',
|
||||
OFF = 'Off',
|
||||
POWER_ON = 'PowerOn',
|
||||
POWER_OFF = 'PowerOff',
|
||||
PARTIAL = 'Partial',
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,16 @@
|
||||
|
||||
export type measurement_statistics = {
|
||||
file_prefix?: string;
|
||||
/**
|
||||
* Number of data collection run. This can be either automatically incremented or provided externally for each data collection.
|
||||
*
|
||||
*/
|
||||
run_number?: number;
|
||||
/**
|
||||
* Name of group owning the data (e.g. p-group or proposal number).
|
||||
*
|
||||
*/
|
||||
experiment_group?: string;
|
||||
images_expected?: number;
|
||||
/**
|
||||
* Images collected by the receiver. This number will be lower than images expected if there were issues with data collection performance.
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
* Definition of a crystal rotation axis
|
||||
*/
|
||||
export type rotation_axis = {
|
||||
/**
|
||||
* Name of rotation axis (e.g., omega, phi)
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Angle step in degrees
|
||||
*/
|
||||
|
||||
@@ -297,8 +297,8 @@ void JFJochReceiver::FrameTransformationThread(uint32_t threadid) {
|
||||
message.number = image_number;
|
||||
message.original_number = image_number;
|
||||
message.user_data = experiment.GetImageAppendix();
|
||||
message.series_id = experiment.GetSeriesID();
|
||||
message.series_unique_id = experiment.GetSeriesIDString();
|
||||
message.series_id = experiment.GetRunNumber();
|
||||
message.series_unique_id = experiment.GetRunName();
|
||||
|
||||
ImageMetadata metadata(experiment);
|
||||
|
||||
@@ -452,8 +452,8 @@ void JFJochReceiver::FinalizeMeasurement() {
|
||||
message.max_receiver_delay = max_delay;
|
||||
message.efficiency = GetEfficiency();
|
||||
message.end_date = time_UTC(std::chrono::system_clock::now());
|
||||
message.series_id = experiment.GetSeriesID();
|
||||
message.series_unique_id = experiment.GetSeriesIDString();
|
||||
message.series_id = experiment.GetRunNumber();
|
||||
message.series_unique_id = experiment.GetRunName();
|
||||
|
||||
message.az_int_result["dataset"] = plots.GetAzIntProfile();
|
||||
for (int i = 0; i < experiment.GetTimePointNumber(); i++)
|
||||
|
||||
@@ -48,12 +48,14 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
|
||||
.series_id = 4567,
|
||||
.gain_file_names = {"abc" , "def", "/dsadasdsa/dadsadas/dsadsa/M056.bin"},
|
||||
.roi_names = {"roi0", "roi1"},
|
||||
.omega = {
|
||||
.goniometer = GoniometerAxis{
|
||||
.name = "omega",
|
||||
.increment = 0.1f,
|
||||
.start = 10.0f,
|
||||
.axis = {0,-1.0, 0.0}
|
||||
.start = 10.0f
|
||||
},
|
||||
.rotation_axis = {0,-1.0, 0.0},
|
||||
.detector_translation = {0.5f, 0.0f, 0.5f},
|
||||
.source_type = "Synchrotron X-ray Source",
|
||||
.source_name = "Swiss Light Source",
|
||||
.source_name_short = "SLS",
|
||||
.instrument_name = "X06SA",
|
||||
@@ -65,7 +67,9 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
|
||||
.attenuator_transmission = 0.345,
|
||||
.write_master_file = true,
|
||||
.user_data = "Some random string 12345",
|
||||
.data_reduction_factor_serialmx = 0.75
|
||||
.data_reduction_factor_serialmx = 0.75,
|
||||
.experiment_group = "p10001",
|
||||
.jfjoch_release = "1.4.98"
|
||||
};
|
||||
|
||||
REQUIRE_NOTHROW(serializer.SerializeSequenceStart(message));
|
||||
@@ -108,6 +112,7 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
|
||||
CHECK(output_message.detector_serial_number == message.detector_serial_number);
|
||||
CHECK(output_message.series_unique_id == message.series_unique_id);
|
||||
CHECK(output_message.series_id == message.series_id);
|
||||
CHECK(output_message.source_type == message.source_type);
|
||||
CHECK(output_message.source_name == message.source_name);
|
||||
CHECK(output_message.source_name_short == message.source_name_short);
|
||||
CHECK(output_message.instrument_name == message.instrument_name);
|
||||
@@ -127,10 +132,11 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
|
||||
CHECK(output_message.unit_cell->beta == message.unit_cell->beta);
|
||||
CHECK(output_message.unit_cell->gamma == message.unit_cell->gamma);
|
||||
|
||||
CHECK(output_message.omega.increment == message.omega.increment);
|
||||
CHECK(output_message.omega.start == message.omega.start);
|
||||
CHECK(output_message.goniometer->name == message.goniometer->name);
|
||||
CHECK(output_message.goniometer->increment == message.goniometer->increment);
|
||||
CHECK(output_message.goniometer->start == message.goniometer->start);
|
||||
for (int i = 0; i < 3; i++)
|
||||
CHECK(output_message.omega.axis[i] == message.omega.axis[i]);
|
||||
CHECK(output_message.rotation_axis[i] == message.rotation_axis[i]);
|
||||
|
||||
REQUIRE (output_message.total_flux);
|
||||
CHECK(output_message.total_flux.value() == message.total_flux.value());
|
||||
@@ -143,6 +149,8 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
|
||||
CHECK(output_message.flatfield_enabled == message.flatfield_enabled);
|
||||
CHECK(output_message.write_master_file == message.write_master_file);
|
||||
CHECK(output_message.data_reduction_factor_serialmx == message.data_reduction_factor_serialmx);
|
||||
CHECK(output_message.experiment_group == message.experiment_group);
|
||||
CHECK(output_message.jfjoch_release == message.jfjoch_release);
|
||||
}
|
||||
|
||||
TEST_CASE("CBORSerialize_Start_PixelMask", "[CBOR]") {
|
||||
|
||||
@@ -472,6 +472,18 @@ TEST_CASE("DiffractionExperiment_SaveCalibration", "[DiffractionExperiment]") {
|
||||
REQUIRE(!x.GetSaveCalibration());
|
||||
}
|
||||
|
||||
TEST_CASE("DiffractionExperiment_FrameCountTime","[DiffractionExperiment]") {
|
||||
DiffractionExperiment x;
|
||||
REQUIRE_NOTHROW(x.FrameTime(1000us, 3us));
|
||||
REQUIRE_NOTHROW(x.FrameTime(1000us));
|
||||
REQUIRE(x.GetFrameCountTime() == 1000us - std::chrono::microseconds(READOUT_TIME_IN_US));
|
||||
|
||||
REQUIRE_NOTHROW(x.FrameTime(2000us));
|
||||
REQUIRE_THROWS(x.FrameTime(2500us));
|
||||
REQUIRE_THROWS(x.FrameTime(10000us, 2100us));
|
||||
REQUIRE_NOTHROW(x.FrameTime(10000us, 10us));
|
||||
}
|
||||
|
||||
//TODO: Update
|
||||
/*
|
||||
TEST_CASE("DiffractionExperiment_FrameCountTime","[DiffractionExperiment]") {
|
||||
@@ -774,40 +786,44 @@ TEST_CASE("DiffractionExperiment_Appendix","") {
|
||||
TEST_CASE("DiffractionExperiment_OmegaRotationAxis","[DiffractionExperiment]") {
|
||||
DiffractionExperiment x;
|
||||
|
||||
x.DefaultOmegaAxis({0,-1,0});
|
||||
REQUIRE(x.GetDefaultOmegaAxis().x == 0);
|
||||
REQUIRE(x.GetDefaultOmegaAxis().y == -1);
|
||||
x.DefaultRotationAxis({0, -1, 0});
|
||||
REQUIRE(x.GetDefaultRotationAxis().x == 0);
|
||||
REQUIRE(x.GetDefaultRotationAxis().y == -1);
|
||||
|
||||
x.OmegaAxis();
|
||||
REQUIRE(x.GetOmegaAxis().x == 0);
|
||||
REQUIRE(x.GetOmegaAxis().y == -1);
|
||||
x.RotationAxis({});
|
||||
REQUIRE(x.GetRotationAxis().x == 0);
|
||||
REQUIRE(x.GetRotationAxis().y == -1);
|
||||
|
||||
x.OmegaAxis({-1, 0, 0});
|
||||
REQUIRE(x.GetOmegaAxis().x == -1);
|
||||
REQUIRE(x.GetOmegaAxis().y == 0);
|
||||
x.RotationAxis(Coord{-1, 0, 0});
|
||||
REQUIRE(x.GetRotationAxis().x == -1);
|
||||
REQUIRE(x.GetRotationAxis().y == 0);
|
||||
|
||||
REQUIRE_THROWS(x.DefaultOmegaAxis({0,0,0}));
|
||||
REQUIRE_THROWS(x.OmegaAxis({0,0,0}));
|
||||
REQUIRE_THROWS(x.DefaultRotationAxis({0, 0, 0}));
|
||||
REQUIRE_THROWS(x.RotationAxis(Coord{0,0,0}));
|
||||
}
|
||||
|
||||
TEST_CASE("DiffractionExperiment_OmegaStep","[DiffractionExperiment]") {
|
||||
DiffractionExperiment x;
|
||||
StartMessage msg;
|
||||
|
||||
x.OmegaStep(std::optional<float>());
|
||||
x.FillMessage(msg);
|
||||
REQUIRE(!x.GetOmegaStep());
|
||||
REQUIRE(msg.omega.increment == 0.0f);
|
||||
REQUIRE(!x.GetGoniometer());
|
||||
REQUIRE(!msg.goniometer);
|
||||
|
||||
x.OmegaStep(0.0);
|
||||
REQUIRE(!x.GetOmegaStep());
|
||||
x.FillMessage(msg);
|
||||
REQUIRE(msg.omega.increment == 0.0f);
|
||||
DatasetSettings d;
|
||||
d.Goniometer(GoniometerAxis{
|
||||
.name = "omega",
|
||||
.increment = 75.0f,
|
||||
.start = 20.0f
|
||||
});
|
||||
x.ImportDatasetSettings(d);
|
||||
|
||||
x.OmegaStep(1.0);
|
||||
x.FillMessage(msg);
|
||||
REQUIRE(x.GetOmegaStep());
|
||||
REQUIRE(msg.omega.increment == 1.0f);
|
||||
REQUIRE(x.GetGoniometer().has_value());
|
||||
REQUIRE(msg.goniometer);
|
||||
REQUIRE(msg.goniometer->name == "omega");
|
||||
REQUIRE(msg.goniometer->increment == 75.0f);
|
||||
REQUIRE(msg.goniometer->start == 20.0f);
|
||||
}
|
||||
|
||||
TEST_CASE("DiffractionExperiment_ConversionOnFPGA","[DiffractionExperiment]") {
|
||||
@@ -862,7 +878,23 @@ TEST_CASE("DiffractionExperiment_PhotonEnergyMultiplayer","[DiffractionExperimen
|
||||
REQUIRE(x.GetPhotonEnergyForConversion_keV() == 16.0f);
|
||||
}
|
||||
|
||||
TEST_CASE("DiffractioExperiment_GetDefaultPlotBinning", "[DiffractionExperiment]") {
|
||||
TEST_CASE("DiffractionExperiment_SeriesID","[DiffractionExperiment]") {
|
||||
DiffractionExperiment x;
|
||||
REQUIRE(x.GetRunNumber() == 0);
|
||||
x.IncrementRunNumber();
|
||||
REQUIRE(x.GetRunNumber() == 1);
|
||||
|
||||
DatasetSettings d;
|
||||
d.RunNumber(25);
|
||||
x.ImportDatasetSettings(d);
|
||||
REQUIRE(x.GetRunNumber() == 25);
|
||||
|
||||
d.RunNumber({});
|
||||
x.ImportDatasetSettings(d);
|
||||
REQUIRE(x.GetRunNumber() == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("DiffractionExperiment_GetDefaultPlotBinning", "[DiffractionExperiment]") {
|
||||
DiffractionExperiment x;
|
||||
x.FrameTime(std::chrono::milliseconds(1));
|
||||
|
||||
@@ -879,7 +911,7 @@ TEST_CASE("DiffractioExperiment_GetDefaultPlotBinning", "[DiffractionExperiment]
|
||||
CHECK(x.GetDefaultPlotBinning() == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("DiffractioExperiment_ImportDataset_TooManyFrames", "[DiffractionExperiment]") {
|
||||
TEST_CASE("DiffractionExperiment_ImportDataset_TooManyFrames", "[DiffractionExperiment]") {
|
||||
DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36, true));
|
||||
x.ImagesPerTrigger(345).NumTriggers(17);
|
||||
DatasetSettings dataset;
|
||||
@@ -888,7 +920,7 @@ TEST_CASE("DiffractioExperiment_ImportDataset_TooManyFrames", "[DiffractionExper
|
||||
REQUIRE(x.GetImageNum() == 345 * 17);
|
||||
}
|
||||
|
||||
TEST_CASE("DiffractioExperiment_ExportROIMask", "[DiffractionExperiment]") {
|
||||
TEST_CASE("DiffractionExperiment_ExportROIMask", "[DiffractionExperiment]") {
|
||||
DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36, true));
|
||||
x.Mode(DetectorMode::Conversion);
|
||||
|
||||
|
||||
@@ -223,13 +223,16 @@ TEST_CASE("HDF5Writer_Socket", "[HDF5][Full]") {
|
||||
{
|
||||
RegisterHDF5Filter();
|
||||
DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36));
|
||||
std::vector<SpotToSave> spots;
|
||||
x.FrameTime(std::chrono::microseconds(1000), std::chrono::microseconds(100));
|
||||
|
||||
x.FilePrefix("test05").ImagesPerTrigger(5).ImagesPerFile(2).Compression(CompressionAlgorithm::NO_COMPRESSION)
|
||||
DatasetSettings d;
|
||||
d.FilePrefix("run0345_lysozyme_acq").ImagesPerTrigger(5).ImagesPerFile(2).Compression(CompressionAlgorithm::NO_COMPRESSION)
|
||||
.HeaderAppendix("{\"z\":567}").DetectorDistance_mm(155).BeamX_pxl(1606.62).BeamY_pxl(1669.59)
|
||||
.FrameTime(std::chrono::microseconds(1000), std::chrono::microseconds(100))
|
||||
.PhotonEnergy_keV(12.07).SetUnitCell(UnitCell{.a = 97, .b = 97, .c = 38, .alpha= 90, .beta = 90, .gamma = 90})
|
||||
.SpaceGroupNumber(96);
|
||||
.SpaceGroupNumber(96).RunNumber(345).ExperimentGroup("p12345").SampleName("lysozyme");
|
||||
|
||||
x.ImportDatasetSettings(d);
|
||||
std::vector<SpotToSave> spots;
|
||||
|
||||
StartMessage start_message;
|
||||
x.FillMessage(start_message);
|
||||
@@ -265,24 +268,29 @@ TEST_CASE("HDF5Writer_Socket", "[HDF5][Full]") {
|
||||
REQUIRE(s.Receive(msg, true));
|
||||
|
||||
j = nlohmann::json::parse(std::string((char *) msg.data(), msg.size()));
|
||||
REQUIRE(j["filename"] == "test05_data_000001.h5");
|
||||
REQUIRE(j["filename"] == "run0345_lysozyme_acq_data_000001.h5");
|
||||
REQUIRE(j["file_number"] == 1);
|
||||
REQUIRE(j["nimages"] == 2);
|
||||
REQUIRE(j["photon_energy_eV"] == Catch::Approx(x.GetPhotonEnergy_keV() * 1000.0));
|
||||
REQUIRE(j["space_group_number"] == 96);
|
||||
REQUIRE(j["experiment_group"] == "p12345");
|
||||
REQUIRE(j["run_number"] == 345);
|
||||
REQUIRE(j.contains("user_data"));
|
||||
REQUIRE(j["user_data"]["z"] == 567);
|
||||
std::cout << j.dump(4) << std::endl;
|
||||
|
||||
REQUIRE(s.Receive(msg, true));
|
||||
j = nlohmann::json::parse(std::string((char *) msg.data(), msg.size()));
|
||||
REQUIRE(j["filename"] == "test05_data_000002.h5");
|
||||
REQUIRE(j["filename"] == "run0345_lysozyme_acq_data_000002.h5");
|
||||
REQUIRE(j["file_number"] == 2);
|
||||
REQUIRE(j["nimages"] == 2);
|
||||
REQUIRE(j.contains("user_data"));
|
||||
REQUIRE(j["user_data"]["z"] == 567);
|
||||
|
||||
REQUIRE(s.Receive(msg, true));
|
||||
j = nlohmann::json::parse(std::string((char *) msg.data(), msg.size()));
|
||||
REQUIRE(j["filename"] == "test05_data_000003.h5");
|
||||
REQUIRE(j["filename"] == "run0345_lysozyme_acq_data_000003.h5");
|
||||
REQUIRE(j["file_number"] == 3);
|
||||
REQUIRE(j["nimages"] == 1);
|
||||
REQUIRE(j.contains("user_data"));
|
||||
REQUIRE(j["user_data"]["z"] == 567);
|
||||
|
||||
@@ -23,9 +23,6 @@ ADD_LIBRARY(JFJochWriter STATIC
|
||||
|
||||
TARGET_LINK_LIBRARIES(JFJochWriter JFJochZMQ JFJochLogger JFJochHDF5Wrappers CBORStream2FrameSerialize)
|
||||
|
||||
ADD_EXECUTABLE(HDF5Sum HDF5Sum.cpp)
|
||||
TARGET_LINK_LIBRARIES(HDF5Sum JFJochWriter)
|
||||
|
||||
AUX_SOURCE_DIRECTORY(gen/model MODEL_SOURCES)
|
||||
ADD_LIBRARY(WriterAPI STATIC ${MODEL_SOURCES} gen/api/DefaultApi.cpp gen/api/DefaultApi.h JFJochWriterHttp.h JFJochWriterHttp.cpp)
|
||||
|
||||
|
||||
@@ -11,24 +11,24 @@
|
||||
#include "HDF5DataFilePluginXFEL.h"
|
||||
#include "HDF5DataFilePluginJUNGFRAU.h"
|
||||
#include "../include/spdlog/fmt/fmt.h"
|
||||
#include "HDF5NXmx.h"
|
||||
|
||||
HDF5DataFile::HDF5DataFile(const StartMessage &msg, uint64_t in_file_number) {
|
||||
file_number = in_file_number;
|
||||
|
||||
HDF5DataFile::HDF5DataFile(const std::string &in_filename,
|
||||
const std::vector<float>& in_rad_int_bin_to_q,
|
||||
int32_t in_image_low,
|
||||
size_t in_max_spots) {
|
||||
xpixel = 0;
|
||||
ypixel = 0;
|
||||
max_image_number = 0;
|
||||
nimages = 0;
|
||||
filename = in_filename;
|
||||
image_low = in_image_low;
|
||||
filename = HDF5Metadata::DataFileName(msg.file_prefix, file_number);
|
||||
image_low = file_number * msg.images_per_file;
|
||||
|
||||
tmp_filename = fmt::format("{}.tmp{:8x}", filename, std::chrono::system_clock::now().time_since_epoch().count());
|
||||
|
||||
plugins.emplace_back(std::make_unique<HDF5DataFilePluginJUNGFRAU>());
|
||||
plugins.emplace_back(std::make_unique<HDF5DataFilePluginAzInt>(in_rad_int_bin_to_q));
|
||||
plugins.emplace_back(std::make_unique<HDF5DataFilePluginAzInt>(msg.az_int_bin_to_q));
|
||||
plugins.emplace_back(std::make_unique<HDF5DataFilePluginXFEL>());
|
||||
plugins.emplace_back(std::make_unique<HDF5DataFilePluginMX>(in_max_spots));
|
||||
plugins.emplace_back(std::make_unique<HDF5DataFilePluginMX>(msg.max_spot_count));
|
||||
}
|
||||
|
||||
std::optional<HDF5DataFileStatistics> HDF5DataFile::Close() {
|
||||
@@ -62,6 +62,7 @@ std::optional<HDF5DataFileStatistics> HDF5DataFile::Close() {
|
||||
ret.max_image_number = max_image_number;
|
||||
ret.total_images = nimages;
|
||||
ret.filename = filename;
|
||||
ret.file_number = file_number + 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
struct HDF5DataFileStatistics {
|
||||
std::string filename;
|
||||
uint64_t file_number; // counting from 1!
|
||||
size_t max_image_number;
|
||||
uint64_t total_images;
|
||||
};
|
||||
@@ -43,10 +44,10 @@ class HDF5DataFile {
|
||||
|
||||
bool closed = false;
|
||||
|
||||
int64_t file_number;
|
||||
void CreateFile(const DataMessage& msg);
|
||||
public:
|
||||
HDF5DataFile(const std::string& name, const std::vector<float>& rad_int_bin_to_q,
|
||||
int32_t image_low, size_t max_spots = 0);
|
||||
HDF5DataFile(const StartMessage &msg, uint64_t file_number);
|
||||
~HDF5DataFile();
|
||||
std::optional<HDF5DataFileStatistics> Close();
|
||||
void Write(const DataMessage& msg, uint64_t image_number);
|
||||
|
||||
@@ -103,6 +103,8 @@ void NXmx::Detector(const StartMessage &start) {
|
||||
HDF5Group det_specific(group, "detectorSpecific");
|
||||
det_specific.NXClass("NXcollection");
|
||||
|
||||
if (!start.jfjoch_release.empty())
|
||||
SaveScalar(det_specific, "jfjoch_release", start.jfjoch_release);
|
||||
SaveScalar(det_specific, "ntrigger", 1);
|
||||
|
||||
SaveScalar(det_specific, "x_pixels_in_detector", static_cast<uint32_t>(start.image_size_x));
|
||||
@@ -171,6 +173,9 @@ void NXmx::Facility(const StartMessage &start) {
|
||||
SaveScalar(*hdf5_file, "/entry/source/name", start.source_name)
|
||||
->Attr("short_name", start.source_name_short);
|
||||
|
||||
if (!start.source_type.empty())
|
||||
SaveScalar(*hdf5_file, "/entry/source/type", start.source_type);
|
||||
|
||||
HDF5Group(*hdf5_file, "/entry/instrument").NXClass("NXinstrument");
|
||||
SaveScalar(*hdf5_file, "/entry/instrument/name", start.instrument_name)
|
||||
->Attr("short_name", start.instrument_name_short);
|
||||
@@ -223,17 +228,17 @@ void NXmx::Sample(const StartMessage &start, const EndMessage &end) {
|
||||
group.SaveVector("unit_cell", v);
|
||||
}
|
||||
|
||||
if ((end.max_image_number > 0) && (start.omega.increment != 0.0f)) {
|
||||
group.SaveScalar("depends_on", "/entry/sample/transformations/omega");
|
||||
if ((end.max_image_number > 0) && start.goniometer) {
|
||||
group.SaveScalar("depends_on", "/entry/sample/transformations/" + start.goniometer->name);
|
||||
HDF5Group transformations(group, "transformations");
|
||||
transformations.NXClass("NXtransformations");
|
||||
|
||||
std::vector<double> angle_container(end.max_image_number);
|
||||
for (int32_t i = 0; i < end.max_image_number; i++)
|
||||
angle_container[i] = start.omega.start + i * start.omega.increment;
|
||||
std::vector<double> axis = {start.omega.axis[0], start.omega.axis[1], start.omega.axis[2]};
|
||||
angle_container[i] = start.goniometer->start + i * start.goniometer->increment;
|
||||
std::vector<double> axis = {start.rotation_axis[0], start.rotation_axis[1], start.rotation_axis[2]};
|
||||
|
||||
SaveVector(transformations, "omega", angle_container)->
|
||||
SaveVector(transformations, start.goniometer->name, angle_container)->
|
||||
Transformation("deg", ".", "", "", "rotation", axis, {0,0,0}, "");
|
||||
} else
|
||||
group.SaveScalar("depends_on", ".");
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../compression/JFJochCompressor.h"
|
||||
#include "HDF5Objects.h"
|
||||
#include "HDF5DataFile.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
RegisterHDF5Filter();
|
||||
|
||||
if (argc != 4) {
|
||||
std::cerr << "Usage: ./HDF5Sum <HDF5 input file> <HDF5 output file> <summation factor>" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
char *pEnd = nullptr;
|
||||
size_t summation_factor = std::strtol(argv[3], &pEnd, 10);
|
||||
|
||||
if (summation_factor <= 1) {
|
||||
std::cerr << "Summation factor must be at least 2" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
try {
|
||||
HDF5ReadOnlyFile data_in(argv[1]);
|
||||
HDF5DataSet dataset_in(data_in, "/entry/data/data");
|
||||
HDF5DataSpace file_space_in(dataset_in);
|
||||
|
||||
if (file_space_in.GetNumOfDimensions() != 3) {
|
||||
std::cerr << "Doesn't look like JF data file" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
hsize_t nimages_in = file_space_in.GetDimensions()[0];
|
||||
hsize_t height = file_space_in.GetDimensions()[1];
|
||||
hsize_t width = file_space_in.GetDimensions()[2];
|
||||
|
||||
if (nimages_in < summation_factor) {
|
||||
std::cerr << "Summation factor doesn't make sense (must be less or equal than images in the input file)" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
hsize_t nimages_out = nimages_in / summation_factor;
|
||||
|
||||
std::cout << "Summing dataset of " << nimages_in << " to " << nimages_out << " images" << std::endl;
|
||||
|
||||
HDF5DataFile dataFile(std::string(argv[2]), std::vector<float>(), nimages_out, 1);
|
||||
|
||||
std::vector<hsize_t> dim = {summation_factor, height, width};
|
||||
|
||||
constexpr const int32_t underload_sum = INT32_MIN;
|
||||
constexpr const int32_t overload_sum = INT32_MAX;
|
||||
|
||||
JFJochBitShuffleCompressor compressor(CompressionAlgorithm::BSHUF_LZ4);
|
||||
std::vector<uint8_t> output(bshuf_compress_lz4_bound(height*width, 4, 4096) + 12);
|
||||
|
||||
for (int i = 0; i < nimages_out; i++) {
|
||||
std::vector<hsize_t> start = {summation_factor * i,0,0};
|
||||
std::vector<int16_t> image_in(summation_factor * height*width);
|
||||
dataset_in.ReadVector(image_in, start, dim);
|
||||
|
||||
std::vector<int32_t> image_out(height*width, 0);
|
||||
for (int j = 0; j < summation_factor; j++) {
|
||||
for (int pxl = 0; pxl < width * height; pxl++) {
|
||||
int16_t tmp = image_in[j * width * height + pxl];
|
||||
if ((tmp < INT16_MIN + 4) || (image_out[pxl] == underload_sum))
|
||||
image_out[pxl] = underload_sum;
|
||||
else if ((tmp > INT16_MAX - 4) || (image_out[pxl] == overload_sum))
|
||||
image_out[pxl] = overload_sum;
|
||||
else image_out[pxl] += tmp;
|
||||
}
|
||||
}
|
||||
|
||||
auto image_size = compressor.Compress(output.data(), image_out);
|
||||
DataMessage message;
|
||||
message.image.data = output.data();
|
||||
message.image.size = image_size;
|
||||
message.image.pixel_depth_bytes = 4;
|
||||
message.image.pixel_is_signed = true;
|
||||
message.image.xpixel = width;
|
||||
message.image.ypixel = height;
|
||||
message.image.algorithm = CompressionAlgorithm::BSHUF_LZ4;
|
||||
message.number = i;
|
||||
|
||||
dataFile.Write(message, i);
|
||||
}
|
||||
} catch (const JFJochException &e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (2019-2023) Paul Scherrer Institute
|
||||
|
||||
#include "HDF5Writer.h"
|
||||
#include "HDF5NXmx.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
HDF5Writer::HDF5Writer(const StartMessage &request)
|
||||
@@ -17,7 +16,7 @@ void HDF5Writer::Write(const DataMessage& message) {
|
||||
if (message.number < 0)
|
||||
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "No support for negative images");
|
||||
|
||||
size_t file_number = 0;
|
||||
uint64_t file_number = 0;
|
||||
size_t image_number = message.number;
|
||||
if (start_message.images_per_file > 0) {
|
||||
file_number = message.number / start_message.images_per_file;
|
||||
@@ -27,10 +26,8 @@ void HDF5Writer::Write(const DataMessage& message) {
|
||||
files.resize(file_number + 1);
|
||||
|
||||
if (!files[file_number])
|
||||
files[file_number] = std::make_unique<HDF5DataFile>(HDF5Metadata::DataFileName(start_message.file_prefix, file_number),
|
||||
start_message.az_int_bin_to_q,
|
||||
file_number * start_message.images_per_file,
|
||||
start_message.max_spot_count);
|
||||
files[file_number] = std::make_unique<HDF5DataFile>(start_message, file_number);
|
||||
|
||||
// Ignore zero size images
|
||||
if (message.image.size > 0)
|
||||
files[file_number]->Write(message, image_number);
|
||||
@@ -57,6 +54,8 @@ void HDF5Writer::AddStats(const std::optional<HDF5DataFileStatistics>& s) {
|
||||
nlohmann::json j;
|
||||
j["filename"] = s->filename;
|
||||
j["nimages"] = s->total_images;
|
||||
j["file_number"] = s->file_number;
|
||||
|
||||
j["detector_distance_m"] = start_message.detector_distance;
|
||||
j["beam_x_pxl"] = start_message.beam_center_x;
|
||||
j["beam_y_pxl"] = start_message.beam_center_y;
|
||||
@@ -65,6 +64,12 @@ void HDF5Writer::AddStats(const std::optional<HDF5DataFileStatistics>& s) {
|
||||
j["detector_height_pxl"] = start_message.image_size_y;
|
||||
j["photon_energy_eV"] = start_message.incident_energy;
|
||||
j["saturation"] = start_message.saturation_value;
|
||||
j["sample_name"] = start_message.sample_name;
|
||||
j["run_number"] = start_message.series_id;
|
||||
|
||||
if (start_message.experiment_group)
|
||||
j["experiment_group"] = start_message.experiment_group.value();
|
||||
|
||||
if (start_message.unit_cell) {
|
||||
j["unit_cell"]["a"] = start_message.unit_cell->a;
|
||||
j["unit_cell"]["b"] = start_message.unit_cell->b;
|
||||
|
||||
Reference in New Issue
Block a user