From 45fd8462f3153a7d7c008a2d45cb1394eaf373fb Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Mon, 4 Nov 2024 18:36:01 +0100 Subject: [PATCH] + catch peaks based on current raw statistics + allow to load savepoints via load button --- source/EngineInterface/RawStatisticsData.h | 10 +- source/Gui/AlienImGui.cpp | 30 ++++++ source/Gui/AlienImGui.h | 9 ++ source/Gui/AutosaveWindow.cpp | 64 ++++++++---- source/Gui/AutosaveWindow.h | 13 +-- source/Gui/BrowserWindow.cpp | 11 +-- source/Gui/FileTransferController.cpp | 98 ++++++++++--------- source/Gui/FileTransferController.h | 6 +- source/Gui/MainLoopController.cpp | 4 +- source/Gui/StyleRepository.h | 4 + source/PersisterImpl/PersisterWorker.cpp | 11 ++- source/PersisterInterface/ParameterParser.h | 4 +- .../SaveDeserializedSimulationResultData.h | 1 + source/PersisterInterface/SavepointTable.h | 2 + .../SavepointTableService.cpp | 2 + .../SharedDeserializedSimulation.h | 14 ++- 16 files changed, 188 insertions(+), 95 deletions(-) diff --git a/source/EngineInterface/RawStatisticsData.h b/source/EngineInterface/RawStatisticsData.h index 8ad71a424..721ebd952 100644 --- a/source/EngineInterface/RawStatisticsData.h +++ b/source/EngineInterface/RawStatisticsData.h @@ -3,7 +3,6 @@ #include "EngineInterface/EngineConstants.h" #include "EngineInterface/Colors.h" - struct TimestepStatistics { ColorVector numCells = {0, 0, 0, 0, 0, 0, 0}; @@ -55,3 +54,12 @@ struct RawStatisticsData TimelineStatistics timeline; HistogramData histogram; }; + +inline double sumColorVector(ColorVector const& v) +{ + auto result = 0.0; + for (int i = 0; i < MAX_COLORS; ++i) { + result += v[i]; + } + return result; +}; diff --git a/source/Gui/AlienImGui.cpp b/source/Gui/AlienImGui.cpp index fd8b47fe7..3963e40a3 100644 --- a/source/Gui/AlienImGui.cpp +++ b/source/Gui/AlienImGui.cpp @@ -448,6 +448,10 @@ bool AlienImGui::Combo(ComboParameters& parameters, int& value, bool* enabled) items[i] = parameters._values[i].c_str(); } + if (parameters._disabled) { + ImGui::BeginDisabled(); + } + if (enabled) { ImGui::Checkbox(("##checkbox" + parameters._name).c_str(), enabled); ImGui::BeginDisabled(!(*enabled)); @@ -479,6 +483,10 @@ bool AlienImGui::Combo(ComboParameters& parameters, int& value, bool* enabled) ImGui::EndDisabled(); } + if (parameters._disabled) { + ImGui::EndDisabled(); + } + if (parameters._tooltip) { AlienImGui::HelpMarker(*parameters._tooltip); } @@ -491,6 +499,10 @@ bool AlienImGui::Switcher(SwitcherParameters& parameters, int& value, bool* enab { ImGui::PushID(parameters._name.c_str()); + if (parameters._disabled) { + ImGui::BeginDisabled(); + } + //enable button if (enabled) { ImGui::Checkbox("##checkbox", enabled); @@ -542,6 +554,9 @@ bool AlienImGui::Switcher(SwitcherParameters& parameters, int& value, bool* enab if (enabled) { ImGui::EndDisabled(); } + if (parameters._disabled) { + ImGui::EndDisabled(); + } if (parameters._tooltip) { AlienImGui::HelpMarker(*parameters._tooltip); @@ -1174,6 +1189,21 @@ bool AlienImGui::Button(ButtonParameters const& parameters) return result; } +bool AlienImGui::ActionButton(ActionButtonParameters const& parameters) +{ + ImGui::PushStyleColor(ImGuiCol_Text, Const::ActionButtonTextColor.Value); + ImGui::PushStyleColor(ImGuiCol_Button, Const::ActionButtonBackgroundColor.Value); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, Const::ActionButtonHoveredColor.Value); + auto result = ImGui::Button(parameters._buttonText.c_str()); + ImGui::PopStyleColor(3); + + if (parameters._tooltip) { + AlienImGui::HelpMarker(*parameters._tooltip); + } + + return result; +} + void AlienImGui::Spinner(SpinnerParameters const& parameters) { static std::optional spinnerRefTimepoint; diff --git a/source/Gui/AlienImGui.h b/source/Gui/AlienImGui.h index ae88678fd..16a1eab64 100644 --- a/source/Gui/AlienImGui.h +++ b/source/Gui/AlienImGui.h @@ -179,6 +179,7 @@ class AlienImGui { MEMBER_DECLARATION(ComboParameters, std::string, name, ""); MEMBER_DECLARATION(ComboParameters, float, textWidth, 100); + MEMBER_DECLARATION(ComboParameters, bool, disabled, false); MEMBER_DECLARATION(ComboParameters, std::optional, defaultValue, std::nullopt); MEMBER_DECLARATION(ComboParameters, std::vector, values, std::vector()); MEMBER_DECLARATION(ComboParameters, std::optional, tooltip, std::nullopt); @@ -190,6 +191,7 @@ class AlienImGui MEMBER_DECLARATION(SwitcherParameters, std::string, name, ""); MEMBER_DECLARATION(SwitcherParameters, float, width, 0); MEMBER_DECLARATION(SwitcherParameters, float, textWidth, 100); + MEMBER_DECLARATION(SwitcherParameters, bool, disabled, false); MEMBER_DECLARATION(SwitcherParameters, std::optional, defaultValue, std::nullopt); MEMBER_DECLARATION(SwitcherParameters, std::vector, values, std::vector()); MEMBER_DECLARATION(SwitcherParameters, std::optional, tooltip, std::nullopt); @@ -311,6 +313,13 @@ class AlienImGui }; static bool Button(ButtonParameters const& parameters); + struct ActionButtonParameters + { + MEMBER_DECLARATION(ActionButtonParameters, std::string, buttonText, ""); + MEMBER_DECLARATION(ActionButtonParameters, std::optional, tooltip, std::nullopt); + }; + static bool ActionButton(ActionButtonParameters const& parameters); + struct SpinnerParameters { MEMBER_DECLARATION(SpinnerParameters, RealVector2D, pos, RealVector2D()); diff --git a/source/Gui/AutosaveWindow.cpp b/source/Gui/AutosaveWindow.cpp index fed9064d0..b4f766f72 100644 --- a/source/Gui/AutosaveWindow.cpp +++ b/source/Gui/AutosaveWindow.cpp @@ -9,13 +9,14 @@ #include "Base/StringHelper.h" #include "PersisterInterface/SavepointTableService.h" #include "PersisterInterface/SerializerService.h" +#include "PersisterInterface/TaskProcessor.h" #include "AlienImGui.h" +#include "FileTransferController.h" #include "GenericMessageDialog.h" #include "OverlayController.h" #include "StyleRepository.h" #include "Viewport.h" -#include "PersisterInterface/TaskProcessor.h" namespace { @@ -46,8 +47,8 @@ void AutosaveWindow::initIntern(SimulationFacade simulationFacade, PersisterFaca _origDirectory = GlobalSettings::get().getValue("windows.autosave.directory", (std::filesystem::current_path() / Const::BasePath).string()); _directory = _origDirectory; - _origCatchPeak = GlobalSettings::get().getValue("windows.autosave.catch peak", _origCatchPeak); - _catchPeak = _origCatchPeak; + _origCatchPeaks = GlobalSettings::get().getValue("windows.autosave.catch peaks", _origCatchPeaks); + _catchPeaks = _origCatchPeaks; _lastAutosaveTimepoint = std::chrono::steady_clock::now(); _lastPeakTimepoint = std::chrono::steady_clock::now(); @@ -66,7 +67,7 @@ void AutosaveWindow::shutdownIntern() GlobalSettings::get().setValue("windows.autosave.mode", _saveMode); GlobalSettings::get().setValue("windows.autosave.number of files", _numberOfFiles); GlobalSettings::get().setValue("windows.autosave.directory", _directory); - GlobalSettings::get().setValue("windows.autosave.catch peak", _origCatchPeak); + GlobalSettings::get().setValue("windows.autosave.catch peaks", _catchPeaks); } void AutosaveWindow::processIntern() @@ -122,7 +123,7 @@ void AutosaveWindow::processToolbar() ImGui::EndDisabled(); ImGui::SameLine(); - ImGui::BeginDisabled(_savepointTable->isEmpty()); + ImGui::BeginDisabled(!_savepointTable.has_value() || _savepointTable->isEmpty()); if (AlienImGui::ToolbarButton(ICON_FA_BROOM)) { GenericMessageDialog::get().yesNo("Delete", "Do you really want to delete the all savepoints?", [&]() { scheduleCleanup(); }); } @@ -146,14 +147,13 @@ void AutosaveWindow::processTable() | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX; if (ImGui::BeginTable("Save files", 4, flags, ImVec2(0, 0), 0.0f)) { - ImGui::TableSetupColumn("No", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(30.0f)); + ImGui::TableSetupColumn("Simulation", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); ImGui::TableSetupColumn("Timestamp", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(140.0f)); - ImGui::TableSetupColumn("Project name", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, scale(200.0f)); ImGui::TableSetupColumn("Time step", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(100.0f)); + ImGui::TableSetupColumn("Peak value", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, scale(200.0f)); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); - auto sequenceNumberAtFrom = _savepointTable->getSequenceNumber(); ImGuiListClipper clipper; clipper.Begin(_savepointTable->getSize()); while (clipper.Step()) { @@ -164,8 +164,18 @@ void AutosaveWindow::processTable() ImGui::PushID(row); ImGui::TableNextRow(0, scale(ImGui::GetTextLineHeightWithSpacing())); + // project name ImGui::TableNextColumn(); - AlienImGui::Text(std::to_string(sequenceNumberAtFrom - row)); + if (entry->state == SavepointState_Persisted) { + auto triggerLoadSavepoint = AlienImGui::ActionButton(AlienImGui::ActionButtonParameters().buttonText(ICON_FA_DOWNLOAD)); + AlienImGui::Tooltip("Load savepoint", false); + if (triggerLoadSavepoint) { + onLoadSavepoint(entry); + } + + ImGui::SameLine(); + AlienImGui::Text(entry->name); + } ImGui::SameLine(); auto selected = _selectedEntry == entry; @@ -177,6 +187,7 @@ void AutosaveWindow::processTable() _selectedEntry = selected ? entry : nullptr; } + // timestamp ImGui::TableNextColumn(); if (entry->state == SavepointState_InQueue) { AlienImGui::Text("In queue"); @@ -191,14 +202,21 @@ void AutosaveWindow::processTable() AlienImGui::Text("Error"); } + // timestep ImGui::TableNextColumn(); if (entry->state == SavepointState_Persisted) { - AlienImGui::Text(entry->name); + AlienImGui::Text(StringHelper::format(entry->timestep)); } + // peak ImGui::TableNextColumn(); - if (entry->state == SavepointState_Persisted) { - AlienImGui::Text(StringHelper::format(entry->timestep)); + AlienImGui::Text(entry->peak); + + if (!entry->peakType.empty()) { + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, Const::BrowserResourcePropertiesTextColor.Value); + AlienImGui::Text(" (" + entry->peakType + ")"); + ImGui::PopStyleColor(); } ImGui::PopID(); @@ -229,16 +247,17 @@ void AutosaveWindow::processSettings() _lastAutosaveTimepoint = std::chrono::steady_clock::now(); } } - if (AlienImGui::Switcher( - AlienImGui::SwitcherParameters() - .name("Catch peak") + if (AlienImGui::Combo( + AlienImGui::ComboParameters() + .name("Catch peaks") .textWidth(RightColumnWidth) - .defaultValue(_origCatchPeak) + .defaultValue(_origCatchPeaks) + .disabled(!_autosaveEnabled) .values({ "None", "Genome complexity variance", }), - _catchPeak)) { + _catchPeaks)) { _peakDeserializedSimulation->setDeserializedSimulation(DeserializedSimulation()); } @@ -316,6 +335,11 @@ void AutosaveWindow::onDeleteSavepoint(SavepointEntry const& entry) _selectedEntry.reset(); } +void AutosaveWindow::onLoadSavepoint(SavepointEntry const& entry) +{ + FileTransferController::get().onOpenSimulation(entry->filename); +} + void AutosaveWindow::processCleanup() { if (_scheduleCleanup) { @@ -335,11 +359,11 @@ void AutosaveWindow::processAutomaticSavepoints() auto minSinceLastAutosave = std::chrono::duration_cast(std::chrono::steady_clock::now() - _lastAutosaveTimepoint).count(); if (minSinceLastAutosave >= _autosaveInterval) { - onCreateSavepoint(_catchPeak != CatchPeak_None); + onCreateSavepoint(_catchPeaks != CatchPeaks_None); _lastAutosaveTimepoint = std::chrono::steady_clock::now(); } - if (_catchPeak != CatchPeak_None) { + if (_catchPeaks != CatchPeaks_None) { auto minSinceLastCatchPeak = std::chrono::duration_cast(std::chrono::steady_clock::now() - _lastPeakTimepoint).count(); if (minSinceLastCatchPeak >= 30) { _peakProcessor->executeTask( @@ -418,6 +442,8 @@ void AutosaveWindow::updateSavepoint(int row) newEntry->timestamp = StringHelper::format(data.timestamp); newEntry->name = data.projectName; newEntry->filename = data.filename; + newEntry->peak = StringHelper::format(toFloat(sumColorVector(data.rawStatisticsData.timeline.timestep.genomeComplexityVariance)), 2); + newEntry->peakType = "genome complexity variance"; _peakDeserializedSimulation->setDeserializedSimulation(DeserializedSimulation()); } } diff --git a/source/Gui/AutosaveWindow.h b/source/Gui/AutosaveWindow.h index a11009831..64a4f7af0 100644 --- a/source/Gui/AutosaveWindow.h +++ b/source/Gui/AutosaveWindow.h @@ -28,6 +28,7 @@ class AutosaveWindow : public AlienWindow void onCreateSavepoint(bool usePeakSimulation); void onDeleteSavepoint(SavepointEntry const& entry); + void onLoadSavepoint(SavepointEntry const& entry); void scheduleDeleteNonPersistentSavepoint(std::vector const& entries); void processDeleteNonPersistentSavepoint(); @@ -74,14 +75,14 @@ class AutosaveWindow : public AlienWindow std::chrono::steady_clock::time_point _lastAutosaveTimepoint; - using CatchPeak = int; - enum CatchPeak_ + using CatchPeaks = int; + enum CatchPeaks_ { - CatchPeak_None, - CatchPeak_Variance + CatchPeaks_None, + CatchPeaks_Variance }; - CatchPeak _origCatchPeak = CatchPeak_None; - CatchPeak _catchPeak = _origCatchPeak; + CatchPeaks _origCatchPeaks = CatchPeaks_None; + CatchPeaks _catchPeaks = _origCatchPeaks; std::chrono::steady_clock::time_point _lastPeakTimepoint; TaskProcessor _peakProcessor; SharedDeserializedSimulation _peakDeserializedSimulation; diff --git a/source/Gui/BrowserWindow.cpp b/source/Gui/BrowserWindow.cpp index e308c1a2c..0d7ca803b 100644 --- a/source/Gui/BrowserWindow.cpp +++ b/source/Gui/BrowserWindow.cpp @@ -817,9 +817,8 @@ void BrowserWindow::processReactionList(NetworkResourceTreeTO const& treeTO) { if (treeTO->isLeaf()) { auto& leaf = treeTO->getLeaf(); - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserDownloadButtonTextColor); - auto isAddReaction = processActionButton(ICON_FA_PLUS); - ImGui::PopStyleColor(); + + auto isAddReaction = AlienImGui::ActionButton(AlienImGui::ActionButtonParameters().buttonText(ICON_FA_PLUS)); AlienImGui::Tooltip("Add a reaction", false); if (isAddReaction) { _activateEmojiPopup = true; @@ -1115,11 +1114,9 @@ void BrowserWindow::processEmojiButton(int emojiType) void BrowserWindow::processDownloadButton(BrowserLeaf const& leaf) { - ImGui::PushStyleColor(ImGuiCol_Text, (ImU32)Const::BrowserDownloadButtonTextColor); - auto downloadButtonResult = processActionButton(ICON_FA_DOWNLOAD); + auto isDownload = AlienImGui::ActionButton(AlienImGui::ActionButtonParameters().buttonText(ICON_FA_DOWNLOAD)); AlienImGui::Tooltip("Download", false); - ImGui::PopStyleColor(); - if (downloadButtonResult) { + if (isDownload) { onDownloadResource(leaf); } } diff --git a/source/Gui/FileTransferController.cpp b/source/Gui/FileTransferController.cpp index 21780af0e..6a74c59e3 100644 --- a/source/Gui/FileTransferController.cpp +++ b/source/Gui/FileTransferController.cpp @@ -23,63 +23,67 @@ void FileTransferController::init(PersisterFacade persisterFacade, SimulationFac _saveSimulationProcessor = _TaskProcessor::createTaskProcessor(_persisterFacade); } -void FileTransferController::onOpenSimulation() +void FileTransferController::onOpenSimulationDialog() { GenericFileDialog::get().showOpenFileDialog( - "Open simulation", "Simulation file (*.sim){.sim},.*", _referencePath, [&](std::filesystem::path const& path) { - auto firstFilename = ifd::FileDialog::Instance().GetResult(); - auto firstFilenameCopy = firstFilename; - _referencePath = firstFilenameCopy.remove_filename().string(); + "Open simulation", "Simulation file (*.sim){.sim},.*", _referencePath, [&](std::filesystem::path const& filename) { + auto filenameCopy = filename; + _referencePath = filenameCopy.remove_filename().string(); + onOpenSimulation(filename); + + }); +} - printOverlayMessage("Loading ..."); +void FileTransferController::onOpenSimulation(std::filesystem::path const& filename) +{ + printOverlayMessage("Loading ..."); - _openSimulationProcessor->executeTask( - [&](auto const& senderId) { - auto senderInfo = SenderInfo{.senderId = senderId, .wishResultData = true, .wishErrorInfo = true}; - auto readData = ReadSimulationRequestData{firstFilename.string()}; - return _persisterFacade->scheduleReadSimulation(senderInfo, readData); - }, - [&](auto const& requestId) { - auto const& data = _persisterFacade->fetchReadSimulationData(requestId); - _persisterFacade->shutdown(); + _openSimulationProcessor->executeTask( + [&](auto const& senderId) { + auto senderInfo = SenderInfo{.senderId = senderId, .wishResultData = true, .wishErrorInfo = true}; + auto readData = ReadSimulationRequestData{filename.string()}; + return _persisterFacade->scheduleReadSimulation(senderInfo, readData); + }, + [&](auto const& requestId) { + auto const& data = _persisterFacade->fetchReadSimulationData(requestId); + _persisterFacade->shutdown(); - _simulationFacade->closeSimulation(); + _simulationFacade->closeSimulation(); - std::optional errorMessage; - try { - _simulationFacade->newSimulation( - data.deserializedSimulation.auxiliaryData.timestep, - data.deserializedSimulation.auxiliaryData.generalSettings, - data.deserializedSimulation.auxiliaryData.simulationParameters); - _simulationFacade->setClusteredSimulationData(data.deserializedSimulation.mainData); - _simulationFacade->setStatisticsHistory(data.deserializedSimulation.statistics); - _simulationFacade->setRealTime(data.deserializedSimulation.auxiliaryData.realTime); - } catch (CudaMemoryAllocationException const& exception) { - errorMessage = exception.what(); - } catch (...) { - errorMessage = "Failed to load simulation."; - } + std::optional errorMessage; + try { + _simulationFacade->newSimulation( + data.deserializedSimulation.auxiliaryData.timestep, + data.deserializedSimulation.auxiliaryData.generalSettings, + data.deserializedSimulation.auxiliaryData.simulationParameters); + _simulationFacade->setClusteredSimulationData(data.deserializedSimulation.mainData); + _simulationFacade->setStatisticsHistory(data.deserializedSimulation.statistics); + _simulationFacade->setRealTime(data.deserializedSimulation.auxiliaryData.realTime); + } catch (CudaMemoryAllocationException const& exception) { + errorMessage = exception.what(); + } catch (...) { + errorMessage = "Failed to load simulation."; + } - if (errorMessage) { - showMessage("Error", *errorMessage); - _simulationFacade->closeSimulation(); - _simulationFacade->newSimulation( - data.deserializedSimulation.auxiliaryData.timestep, - data.deserializedSimulation.auxiliaryData.generalSettings, - data.deserializedSimulation.auxiliaryData.simulationParameters); - } - _persisterFacade->restart(); + if (errorMessage) { + showMessage("Error", *errorMessage); + _simulationFacade->closeSimulation(); + _simulationFacade->newSimulation( + data.deserializedSimulation.auxiliaryData.timestep, + data.deserializedSimulation.auxiliaryData.generalSettings, + data.deserializedSimulation.auxiliaryData.simulationParameters); + } + _persisterFacade->restart(); - Viewport::get().setCenterInWorldPos(data.deserializedSimulation.auxiliaryData.center); - Viewport::get().setZoomFactor(data.deserializedSimulation.auxiliaryData.zoom); - TemporalControlWindow::get().onSnapshot(); - printOverlayMessage(data.filename.string()); - }, - [](auto const& criticalErrors) { GenericMessageDialog::get().information("Error", criticalErrors); }); - }); + Viewport::get().setCenterInWorldPos(data.deserializedSimulation.auxiliaryData.center); + Viewport::get().setZoomFactor(data.deserializedSimulation.auxiliaryData.zoom); + TemporalControlWindow::get().onSnapshot(); + printOverlayMessage(data.filename.string()); + }, + [](auto const& criticalErrors) { GenericMessageDialog::get().information("Error", criticalErrors); }); } -void FileTransferController::onSaveSimulation() +void FileTransferController::onSaveSimulationDialog() { GenericFileDialog::get().showSaveFileDialog( "Save simulation", "Simulation file (*.sim){.sim},.*", _referencePath, [&](std::filesystem::path const& path) { diff --git a/source/Gui/FileTransferController.h b/source/Gui/FileTransferController.h index e115d62e9..3b6d8e636 100644 --- a/source/Gui/FileTransferController.h +++ b/source/Gui/FileTransferController.h @@ -12,8 +12,10 @@ class FileTransferController : public MainLoopEntityisSimulationRunning(); AlienImGui::MenuItem(AlienImGui::MenuItemParameters().name("Run").key(ImGuiKey_Space).disabled(running).closeMenuWhenItemClicked(false), [&] { diff --git a/source/Gui/StyleRepository.h b/source/Gui/StyleRepository.h index 671d870f0..10c4c87fc 100644 --- a/source/Gui/StyleRepository.h +++ b/source/Gui/StyleRepository.h @@ -67,6 +67,10 @@ namespace Const ImColor const ToolbarButtonBackgroundColor = ImColor::HSV(0, 0, 0.06f, 0); ImColor const ToolbarButtonHoveredColor = ImColor::HSV(0, 0, 1, 0.35f); + ImColor const ActionButtonTextColor = ImColor::HSV(0.55f, 0.6f, 1.0f, 1.0f); + ImColor const ActionButtonBackgroundColor = ImColor::HSV(0, 0, 0.06f, 0); + ImColor const ActionButtonHoveredColor = ImColor::HSV(0, 0, 1, 0.35f); + ImColor const ButtonColor = ImColor::HSV(0.54f, 0.33f, 1.0f, 1.0f); ImColor const ToggleColor = ImColor::HSV(0.58f, 0.83f, 1.0f, 1.0f); ImColor const DetailButtonColor = ImColor::HSV(0, 0, 1.0f); diff --git a/source/PersisterImpl/PersisterWorker.cpp b/source/PersisterImpl/PersisterWorker.cpp index 1dfb4144b..36ffbd283 100644 --- a/source/PersisterImpl/PersisterWorker.cpp +++ b/source/PersisterImpl/PersisterWorker.cpp @@ -625,12 +625,13 @@ _PersisterWorker::PersisterRequestResultOrError _PersisterWorker::processRequest auto const& requestData = request->getData(); - auto peakStatistics = requestData.peakDeserializedSimulation->getLastStatisticsData(); + auto peakStatistics = requestData.peakDeserializedSimulation->getRawStatisticsData(); DeserializedSimulation deserializedSimulation; deserializedSimulation.statistics = _simulationFacade->getStatisticsHistory().getCopiedData(); - if (!deserializedSimulation.statistics.empty() && deserializedSimulation.statistics.back().varianceGenomeComplexity.summedValues - >= peakStatistics.varianceGenomeComplexity.summedValues) { + auto currentRawStatistics = _simulationFacade->getRawStatistics(); + if (sumColorVector(currentRawStatistics.timeline.timestep.genomeComplexityVariance) + >= sumColorVector(peakStatistics.timeline.timestep.genomeComplexityVariance)) { deserializedSimulation.auxiliaryData.realTime = _simulationFacade->getRealTime(); deserializedSimulation.auxiliaryData.zoom = requestData.zoom; @@ -640,6 +641,7 @@ _PersisterWorker::PersisterRequestResultOrError _PersisterWorker::processRequest deserializedSimulation.auxiliaryData.timestep = static_cast(_simulationFacade->getCurrentTimestep()); deserializedSimulation.mainData = _simulationFacade->getClusteredSimulationData(); requestData.peakDeserializedSimulation->setDeserializedSimulation(std::move(deserializedSimulation)); + requestData.peakDeserializedSimulation->setLastStatisticsData(currentRawStatistics); } return std::make_shared<_GetPeakSimulationRequestResult>(request->getRequestId(), GetPeakSimulationResultData()); } catch (...) { @@ -673,7 +675,8 @@ _PersisterWorker::PersisterRequestResultOrError _PersisterWorker::processRequest .filename = filename, .projectName = deserializedData.auxiliaryData.simulationParameters.projectName, .timestep = deserializedData.auxiliaryData.timestep, - .timestamp = requestData.sharedDeserializedSimulation->getTimestamp()}); + .timestamp = requestData.sharedDeserializedSimulation->getTimestamp(), + .rawStatisticsData = requestData.sharedDeserializedSimulation->getRawStatisticsData()}); } catch (...) { return std::make_shared<_PersisterRequestError>( request->getRequestId(), diff --git a/source/PersisterInterface/ParameterParser.h b/source/PersisterInterface/ParameterParser.h index 65b1d58b7..73c77f2a1 100644 --- a/source/PersisterInterface/ParameterParser.h +++ b/source/PersisterInterface/ParameterParser.h @@ -44,9 +44,9 @@ namespace detail std::string valueAsString; std::string defaultValueAsString(defaultValue); result = JsonParser::encodeDecode(tree, valueAsString, defaultValueAsString, node, task); - auto copyLength = std::min(127, toInt(valueAsString.size())); + auto copyLength = std::min(63, toInt(valueAsString.size())); valueAsString.copy(value, copyLength); - value[copyLength + 1] = '\0'; + value[copyLength] = '\0'; } return result; } diff --git a/source/PersisterInterface/SaveDeserializedSimulationResultData.h b/source/PersisterInterface/SaveDeserializedSimulationResultData.h index 8d568ed8d..b3e7c076c 100644 --- a/source/PersisterInterface/SaveDeserializedSimulationResultData.h +++ b/source/PersisterInterface/SaveDeserializedSimulationResultData.h @@ -9,4 +9,5 @@ struct SaveDeserializedSimulationResultData std::string projectName; uint64_t timestep = 0; std::chrono::system_clock::time_point timestamp; + RawStatisticsData rawStatisticsData; }; diff --git a/source/PersisterInterface/SavepointTable.h b/source/PersisterInterface/SavepointTable.h index b2115a710..b9a82b9d8 100644 --- a/source/PersisterInterface/SavepointTable.h +++ b/source/PersisterInterface/SavepointTable.h @@ -23,6 +23,8 @@ struct _SavepointEntry std::string timestamp; std::string name; uint64_t timestep = 0; + std::string peak; + std::string peakType; std::string requestId; // transient }; diff --git a/source/PersisterInterface/SavepointTableService.cpp b/source/PersisterInterface/SavepointTableService.cpp index 64ae98c9c..ea5625894 100644 --- a/source/PersisterInterface/SavepointTableService.cpp +++ b/source/PersisterInterface/SavepointTableService.cpp @@ -158,6 +158,8 @@ void SavepointTableService::encodeDecode(boost::property_tree::ptree& tree, Save JsonParser::encodeDecode(tree, entry->timestamp, std::string(), "timestamp", task); JsonParser::encodeDecode(tree, entry->name, std::string(), "name", task); JsonParser::encodeDecode(tree, entry->timestep, uint64_t(0), "timestep", task); + JsonParser::encodeDecode(tree, entry->peak, std::string(), "peak", task); + JsonParser::encodeDecode(tree, entry->peakType, std::string(), "peak type", task); } void SavepointTableService::encodeDecode(boost::property_tree::ptree& tree, std::filesystem::path& path, std::string const& node, ParserTask task) const diff --git a/source/PersisterInterface/SharedDeserializedSimulation.h b/source/PersisterInterface/SharedDeserializedSimulation.h index ab09319a7..ec4b847e9 100644 --- a/source/PersisterInterface/SharedDeserializedSimulation.h +++ b/source/PersisterInterface/SharedDeserializedSimulation.h @@ -8,13 +8,16 @@ class _SharedDeserializedSimulation { public: - DataPointCollection getLastStatisticsData() const + void setLastStatisticsData(RawStatisticsData const& value) { std::lock_guard lock(_mutex); - if (_deserializedSimulation.statistics.empty()) { - return DataPointCollection(); - } - return _deserializedSimulation.statistics.back(); + _rawStatisticsData = value; + } + + RawStatisticsData getRawStatisticsData() const + { + std::lock_guard lock(_mutex); + return _rawStatisticsData; } void setDeserializedSimulation(DeserializedSimulation&& value) @@ -45,6 +48,7 @@ class _SharedDeserializedSimulation private: mutable std::mutex _mutex; DeserializedSimulation _deserializedSimulation; + RawStatisticsData _rawStatisticsData; std::chrono::system_clock::time_point _timestamp; }; using SharedDeserializedSimulation = std::shared_ptr<_SharedDeserializedSimulation>; \ No newline at end of file