Merge branch 'rc187-live-fix-backend' into rc186-merge2
This commit is contained in:
commit
f487aa3ab2
16 files changed
+75
-16
No files matched your search
@@ -730,7 +730,8 @@ DatasetSettings Convert(const org::openapitools::server::model::Dataset_settings
|
||||
ret.SpotFindingEnable(input.isSpotFinding());
|
||||
ret.MaxSpotCount(input.getMaxSpotCount());
|
||||
|
||||
ret.DetectIceRings(input.isDetectIceRings());
|
||||
if (input.detectIceRingsIsSet())
|
||||
ret.DetectIceRings(input.isDetectIceRings());
|
||||
|
||||
if (input.xrayFluorescenceSpectrumIsSet()) {
|
||||
auto fl = input.getXrayFluorescenceSpectrum();
|
||||
|
||||
@@ -325,7 +325,7 @@ public:
|
||||
bool maxSpotCountIsSet() const;
|
||||
void unsetMax_spot_count();
|
||||
/// <summary>
|
||||
/// Flag spots as ice rings and reduce their effect on indexing
|
||||
/// Flag spots as ice rings and reduce their effect on indexing. Left out, the broker's own spot finding treats no spot as an ice ring, rugnux live decides as a bare `rugnux` would (on for a rotation sweep, off for stills), and the master file carries no `detect_ice_rings`.
|
||||
/// </summary>
|
||||
bool isDetectIceRings() const;
|
||||
void setDetectIceRings(bool const value);
|
||||
|
||||
@@ -162,12 +162,12 @@ public:
|
||||
bool isaIsSet() const;
|
||||
void unsetIsa();
|
||||
/// <summary>
|
||||
/// Answer of the early lattice probe on the first 60 degrees; empty until it answers
|
||||
/// Answer of the early lattice probe on the first 60 degrees; empty until it answers, and the run's own lattice once the run has indexed
|
||||
/// </summary>
|
||||
std::string getProbe() const;
|
||||
void setProbe(std::string const& value);
|
||||
/// <summary>
|
||||
/// When the probe answered, since the first image
|
||||
/// When the probe answered (or the run indexed), since the first image
|
||||
/// </summary>
|
||||
double getProbeS() const;
|
||||
void setProbeS(double const value);
|
||||
|
||||
@@ -671,7 +671,10 @@ components:
|
||||
description: Maximum number of spots that are saved/used for indexing; spots with highest intensity are selected
|
||||
detect_ice_rings:
|
||||
type: boolean
|
||||
description: Flag spots as ice rings and reduce their effect on indexing
|
||||
description: |
|
||||
Flag spots as ice rings and reduce their effect on indexing. Left out, the broker's own
|
||||
spot finding treats no spot as an ice ring, rugnux live decides as a bare `rugnux` would (on
|
||||
for a rotation sweep, off for stills), and the master file carries no `detect_ice_rings`.
|
||||
async_start:
|
||||
type: boolean
|
||||
default: false
|
||||
@@ -3345,11 +3348,11 @@ components:
|
||||
description: ISa of the error model; absent until the run is over, or where it was not determined
|
||||
probe:
|
||||
type: string
|
||||
description: Answer of the early lattice probe on the first 60 degrees; empty until it answers
|
||||
description: Answer of the early lattice probe on the first 60 degrees; empty until it answers, and the run's own lattice once the run has indexed
|
||||
probe_s:
|
||||
type: number
|
||||
format: double
|
||||
description: When the probe answered, since the first image
|
||||
description: When the probe answered (or the run indexed), since the first image
|
||||
start_to_first_image_s:
|
||||
type: number
|
||||
format: double
|
||||
|
||||
@@ -30,8 +30,6 @@ DatasetSettings::DatasetSettings() {
|
||||
poni_rot_3_rad = 0.0f;
|
||||
|
||||
max_spot_count = std::min(MAX_SPOT_COUNT, 250);
|
||||
|
||||
detect_ice_rings = false;
|
||||
}
|
||||
|
||||
DatasetSettings &DatasetSettings::ImagesPerTrigger(int64_t input) {
|
||||
@@ -542,6 +540,10 @@ DatasetSettings & DatasetSettings::DetectIceRings(bool input) {
|
||||
}
|
||||
|
||||
bool DatasetSettings::IsDetectIceRings() const {
|
||||
return detect_ice_rings.value_or(false);
|
||||
}
|
||||
|
||||
std::optional<bool> DatasetSettings::GetDetectIceRings() const {
|
||||
return detect_ice_rings;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,9 @@ class DatasetSettings {
|
||||
bool spot_finding_enable;
|
||||
int64_t max_spot_count;
|
||||
|
||||
bool detect_ice_rings; // Enable special handling of ice rings
|
||||
// Special handling of ice rings; unset where the user did not ask either way, so that the analysis takes its own
|
||||
// default (rugnux: on for a rotation sweep, off for stills) and the master file carries no detect_ice_rings
|
||||
std::optional<bool> detect_ice_rings;
|
||||
XrayFluorescenceSpectrum fluorescence_spectrum;
|
||||
|
||||
std::optional<SmargonPosition> smargon_position;
|
||||
@@ -186,7 +188,8 @@ public:
|
||||
bool IsSpotFindingEnabled() const;
|
||||
int64_t GetMaxSpotCount() const;
|
||||
|
||||
bool IsDetectIceRings() const;
|
||||
bool IsDetectIceRings() const; // false where unset
|
||||
std::optional<bool> GetDetectIceRings() const;
|
||||
const XrayFluorescenceSpectrum &GetFluorescenceSpectrum() const;
|
||||
std::optional<SmargonPosition> GetSmargonPosition() const;
|
||||
};
|
||||
@@ -773,7 +773,7 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
|
||||
message.poni_rot2 = dataset.GetPoniRot2_rad();
|
||||
message.poni_rot3 = dataset.GetPoniRot3_rad();
|
||||
|
||||
message.detect_ice_rings = dataset.IsDetectIceRings();
|
||||
message.detect_ice_rings = dataset.GetDetectIceRings();
|
||||
|
||||
message.channels = {"default"};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "spdlog/fmt/bin_to_hex.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "Logger.h"
|
||||
#include "GitInfo.h"
|
||||
@@ -64,6 +65,15 @@ Logger::Logger(const std::string &service_name, const std::string &file_name) {
|
||||
spdlog_logger = std::make_shared<spdlog::logger>(service_name, std::begin(sinks), std::end(sinks));
|
||||
if (const auto it = service_levels.find(service_name); it != service_levels.end())
|
||||
spdlog_logger->set_level(it->second);
|
||||
{
|
||||
// The version line goes out once per service: a run makes many loggers of one service (every FFT indexer
|
||||
// is one). Function-local, as a static Logger (jfjoch_writer's) is made before this file's own statics.
|
||||
static std::mutex version_mutex;
|
||||
static std::set<std::string> version_logged;
|
||||
std::unique_lock ul(version_mutex);
|
||||
if (!version_logged.insert(service_name).second)
|
||||
return;
|
||||
}
|
||||
if (jfjoch_git_sha1().empty())
|
||||
spdlog_logger->info("Version {} {}", jfjoch_version(), variant);
|
||||
else
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ There are minor differences at the moment:
|
||||
| - xfel_pulse_id | uint64 | Pulse IDs are recorded for images | |
|
||||
| - ring_current_mA | float | Ring current at the start of the measurement | |
|
||||
| - sample_temperature_K | float | Sample temperature \[K\] | |
|
||||
| - detect_ice_rings | bool | Ice ring detection feature is enabled | |
|
||||
| - detect_ice_rings | bool | Ice ring detection feature is enabled; absent where the dataset settings left it unset (rugnux then decides) | |
|
||||
| - indexing_algorithm | string | Indexing algorithm used on-the-fly; allowed values: ffbidx, fft, fftw, none | |
|
||||
| - geom_refinement_algorithm | string | Post-indexing detector geometry refinement algorithm; allowed values: none, beam_center | |
|
||||
| - poni_rot1 | float | Tilt of the detector rot1 according to PyFAI PONI convention \[rad\] | |
|
||||
|
||||
@@ -74,7 +74,12 @@ namespace {
|
||||
}
|
||||
void OnProgress(uint64_t done, uint64_t total) override { status.Progress(done, total); }
|
||||
void OnStep(const std::string &title) override { status.Step(title); }
|
||||
void OnNote(const std::string &text) override { status.Note(text); }
|
||||
void OnNote(const std::string &text) override {
|
||||
status.Note(text);
|
||||
// The run has its lattice (RugnuxFirstPassAccept): the probe's answer on the first degrees is overtaken
|
||||
if (text.starts_with("lattice "))
|
||||
status.Lattice("lattice on the sweep: " + text.substr(8));
|
||||
}
|
||||
};
|
||||
|
||||
std::string StateName(RugnuxLiveState state) {
|
||||
|
||||
@@ -66,6 +66,7 @@ void JFJochReceiverRugnuxStills::OnImage(uint32_t id, DataMessage &message, std:
|
||||
logger.Error("Dropping image {} - the collection has {} images", message.number, experiment.GetImageNum());
|
||||
return;
|
||||
}
|
||||
live_status.ImageReceived(received);
|
||||
CountImage(message);
|
||||
const size_t size = message.image.GetCompressedSize();
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ void RugnuxLiveStatus::Start(int64_t images_expected, std::optional<double> expe
|
||||
snapshot.expected_collection_s = expected_collection_s;
|
||||
start = start_received;
|
||||
last_image.reset();
|
||||
lattice = false;
|
||||
}
|
||||
|
||||
void RugnuxLiveStatus::ImageReceived(std::chrono::steady_clock::time_point received) {
|
||||
@@ -226,10 +227,19 @@ void RugnuxLiveStatus::Cut(const std::string &reason) {
|
||||
|
||||
void RugnuxLiveStatus::Probe(const std::string &text) {
|
||||
std::unique_lock ul(status_mutex);
|
||||
if (lattice)
|
||||
return;
|
||||
snapshot.probe = text;
|
||||
snapshot.probe_s = Now();
|
||||
}
|
||||
|
||||
void RugnuxLiveStatus::Lattice(const std::string &text) {
|
||||
std::unique_lock ul(status_mutex);
|
||||
snapshot.probe = text;
|
||||
snapshot.probe_s = Now();
|
||||
lattice = true;
|
||||
}
|
||||
|
||||
void RugnuxLiveStatus::Warning(const std::string &text) {
|
||||
std::unique_lock ul(status_mutex);
|
||||
snapshot.warnings.push_back(text);
|
||||
@@ -246,6 +256,7 @@ void RugnuxLiveStatus::Clear() {
|
||||
std::unique_lock ul(status_mutex);
|
||||
snapshot = RugnuxLiveSnapshot{};
|
||||
last_image.reset();
|
||||
lattice = false;
|
||||
}
|
||||
|
||||
RugnuxLiveSnapshot RugnuxLiveStatus::Get() const {
|
||||
|
||||
@@ -181,6 +181,7 @@ class RugnuxLiveStatus {
|
||||
// Kept since the START message, shifted to the first image by Get().
|
||||
std::chrono::steady_clock::time_point start;
|
||||
std::optional<std::chrono::steady_clock::time_point> last_image;
|
||||
bool lattice = false; // the run has its lattice: the probe's answer is overtaken
|
||||
double Since(std::chrono::steady_clock::time_point t) const;
|
||||
double Now() const;
|
||||
void CloseStep();
|
||||
@@ -204,7 +205,9 @@ public:
|
||||
// The collection is over: last_image_s is set, and the last image's time is returned (none if no image came).
|
||||
std::optional<std::chrono::steady_clock::time_point> LastImage();
|
||||
void Cut(const std::string &reason);
|
||||
// The probe's answer, unless the run has its lattice already; Lattice: the run's, in the probe's place
|
||||
void Probe(const std::string &text);
|
||||
void Lattice(const std::string &text);
|
||||
void Warning(const std::string &text);
|
||||
void Structure(std::shared_ptr<const RugnuxStructure> structure,
|
||||
std::shared_ptr<const RugnuxStructure> refined_structure = nullptr);
|
||||
|
||||
@@ -67,7 +67,6 @@ void StillsGPUAnalysis::Publish() {
|
||||
}
|
||||
|
||||
void StillsGPUAnalysis::Hold(const std::shared_ptr<HeldImage> &image) {
|
||||
status.ImageReceived(std::chrono::steady_clock::now());
|
||||
queue.PutBlocking(image);
|
||||
{
|
||||
std::unique_lock ul(prepass_mutex);
|
||||
|
||||
@@ -54,6 +54,25 @@ TEST_CASE("RugnuxLiveStatus_BeforeFirstImage", "[RugnuxLive]") {
|
||||
CHECK(!status.LastImage());
|
||||
}
|
||||
|
||||
TEST_CASE("RugnuxLiveStatus_RunLatticeOvertakesProbe", "[RugnuxLive]") {
|
||||
RugnuxLiveStatus status;
|
||||
status.Start(10, 1.0, std::chrono::steady_clock::now());
|
||||
|
||||
// The probe answers first, the run indexes later: the banner is the run's
|
||||
status.Probe("no lattice on the first 60 deg");
|
||||
CHECK(status.Get().probe == "no lattice on the first 60 deg");
|
||||
status.Lattice("lattice on the sweep: monoclinic P: 35.00 29.00 63.00 90.0 105.0 90.0");
|
||||
CHECK(status.Get().probe.starts_with("lattice on the sweep"));
|
||||
// The run indexed before the probe answered: the probe's answer is not shown
|
||||
status.Probe("no lattice on the first 60 deg");
|
||||
CHECK(status.Get().probe.starts_with("lattice on the sweep"));
|
||||
|
||||
// The next collection starts afresh
|
||||
status.Start(10, 1.0, std::chrono::steady_clock::now());
|
||||
status.Probe("no lattice on the first 60 deg");
|
||||
CHECK(status.Get().probe == "no lattice on the first 60 deg");
|
||||
}
|
||||
|
||||
TEST_CASE("RugnuxLiveStatus_Clear", "[RugnuxLive]") {
|
||||
RugnuxLiveStatus status;
|
||||
status.Start(10, 1.0, std::chrono::steady_clock::now() - 2s);
|
||||
|
||||
@@ -114,8 +114,10 @@ TEST_CASE("StillsGPUAnalysis_FailingFrameDoesNotStopAnalysis", "[StillsGPUAnalys
|
||||
};
|
||||
StillsGPUAnalysis gpu(x, mask, Start(x), nullptr, 1, 100, logger, sink, status);
|
||||
// The frames carry no image, so their analysis fails too - they are passed on all the same.
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int i = 0; i < 3; i++) {
|
||||
status.ImageReceived(std::chrono::steady_clock::now()); // as the receiver does before it holds a frame
|
||||
gpu.Hold(Frame(buffer, i));
|
||||
}
|
||||
REQUIRE_NOTHROW(gpu.Finish());
|
||||
CHECK(sunk == 3);
|
||||
// The outcome waits for everything to be written, and comes after the latency.
|
||||
|
||||
Reference in new issue
Block a user