Skip to content

Commit

Permalink
Adds plotting widget
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenNneji committed Nov 6, 2024
1 parent 80c671d commit 9739c60
Show file tree
Hide file tree
Showing 14 changed files with 372 additions and 40 deletions.
79 changes: 79 additions & 0 deletions rascal2/core/commands.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
"""File for Qt commands."""

import copy
from enum import IntEnum, unique
from typing import Callable

import RATapi
from PyQt6 import QtGui
from RATapi import ClassList

Expand Down Expand Up @@ -96,3 +98,80 @@ def update_attribute(self):

def id(self):
return CommandID.EditProject


class SaveResults(QtGui.QUndoCommand):
"""Command for saving the Results object.
Parameters
----------
problem : RATapi.rat_core.ProblemDefinition
The problem
results : Union[RATapi.outputs.Results, RATapi.outputs.BayesResults]
The calculation results.
log : str
log text from the given calculation.
"""

def __init__(self, problem, results, log: str, presenter):
super().__init__()
self.presenter = presenter
self.results = results
self.log = log
self.problem = self.get_parameter_values(problem)
self.old_problem = self.get_parameter_values(RATapi.inputs.make_problem(self.presenter.model.project))
self.old_results = copy.deepcopy(self.presenter.model.results)
self.old_log = self.presenter.model.result_log
self.setText("Save calculation results")

def get_parameter_values(self, problem_definition: RATapi.rat_core.ProblemDefinition):
"""Get parameter values from problem definition."""
parameter_field = {
"parameters": "params",
"bulk_in": "bulkIn",
"bulk_out": "bulkOut",
"scalefactors": "scalefactors",
"domain_ratios": "domainRatio",
"background_parameters": "backgroundParams",
"resolution_parameters": "resolutionParams",
}

values = {}
for class_list in RATapi.project.parameter_class_lists:
entry = values.setdefault(class_list, [])
entry.extend(getattr(problem_definition, parameter_field[class_list]))
return values

def set_parameter_values(self, values):
"""Update the project given a set of results."""

for key, value in values.items():
for index in range(len(value)):
getattr(self.presenter.model.project, key)[index].value = value[index]
return values

def undo(self):
self.swap_results(self.old_problem, self.old_results, self.old_log)

def redo(self):
self.swap_results(self.problem, self.results, self.log)

def swap_results(self, problem, results, log):
"""Swap problem, result and log in model with given one
Parameters
----------
problem : RATapi.rat_core.ProblemDefinition
The problem definition
results : Union[RATapi.outputs.Results, RATapi.outputs.BayesResults]
The calculation results.
log : str
log text from the given calculation.
"""
self.set_parameter_values(problem)
self.presenter.model.update_results(copy.deepcopy(results))
self.presenter.model.result_log = log
chi_text = "" if results is None else f"{results.calculationResults.sumChi:.6g}"
self.presenter.view.controls_widget.chi_squared.setText(chi_text)
self.presenter.view.terminal_widget.clear()
self.presenter.view.terminal_widget.write(log)
1 change: 1 addition & 0 deletions rascal2/core/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def run(queue, rat_inputs: tuple, procedure: str, display: bool):
if display:
RAT.events.register(RAT.events.EventTypes.Message, queue.put)
RAT.events.register(RAT.events.EventTypes.Progress, queue.put)
RAT.events.register(RAT.events.EventTypes.Plot, queue.put)
queue.put(LogData(INFO, "Starting RAT"))

try:
Expand Down
Binary file added rascal2/static/images/hide-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 17 additions & 18 deletions rascal2/ui/model.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from pathlib import Path
from typing import Union

import RATapi as RAT
import RATapi.outputs
from PyQt6 import QtCore


Expand All @@ -9,12 +11,14 @@ class MainWindowModel(QtCore.QObject):

project_updated = QtCore.pyqtSignal()
controls_updated = QtCore.pyqtSignal()
results_updated = QtCore.pyqtSignal()

def __init__(self):
super().__init__()

self.project = None
self.results = None
self.result_log = ""
self.controls = None

self.save_path = ""
Expand All @@ -33,21 +37,16 @@ def create_project(self, name: str, save_path: str):
self.controls = RAT.Controls()
self.save_path = save_path

def handle_results(self, problem_definition: RAT.rat_core.ProblemDefinition):
"""Update the project given a set of results."""
parameter_field = {
"parameters": "params",
"bulk_in": "bulkIn",
"bulk_out": "bulkOut",
"scalefactors": "scalefactors",
"domain_ratios": "domainRatio",
"background_parameters": "backgroundParams",
"resolution_parameters": "resolutionParams",
}

for class_list in RAT.project.parameter_class_lists:
for index, value in enumerate(getattr(problem_definition, parameter_field[class_list])):
getattr(self.project, class_list)[index].value = value
def update_results(self, results: Union[RATapi.outputs.Results, RATapi.outputs.BayesResults]):
"""Update the project given a set of results.
Parameters
----------
results : Union[RATapi.outputs.Results, RATapi.outputs.BayesResults]
The calculation results.
"""
self.results = results
self.results_updated.emit()

def update_project(self, new_values: dict) -> None:
"""Replaces the project with a new project.
Expand Down Expand Up @@ -111,12 +110,12 @@ def load_r1_project(self, load_path: str):
self.controls = RAT.Controls()
self.save_path = str(Path(load_path).parent)

def update_controls(self, new_values):
"""
def update_controls(self, new_values: dict):
"""Updates the control attributes.
Parameters
----------
new_values: Dict
new_values: dict
The attribute name-value pair to updated on the controls.
"""
vars(self.controls).update(new_values)
Expand Down
13 changes: 11 additions & 2 deletions rascal2/ui/presenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def run(self):
self.view.terminal_widget.progress_bar.setVisible(False)
if self.view.settings.clear_terminal:
self.view.terminal_widget.clear()

self.model.project, _ = RAT.examples.non_polarised.DSPC_standard_layers.DSPC_standard_layers()
rat_inputs = RAT.inputs.make_input(self.model.project, self.model.controls)
display_on = self.model.controls.display != RAT.utils.enums.Display.Off

Expand All @@ -150,7 +150,14 @@ def run(self):

def handle_results(self):
"""Handle a RAT run being finished."""
self.model.handle_results(self.runner.updated_problem)
self.view.undo_stack.push(
commands.SaveResults(
self.runner.updated_problem,
self.runner.results,
self.view.terminal_widget.text_area.toPlainText(),
self,
)
)
self.view.handle_results(self.runner.results)

def handle_interrupt(self):
Expand All @@ -171,6 +178,8 @@ def handle_event(self):
self.view.controls_widget.chi_squared.setText(chi_squared)
elif isinstance(event, RAT.events.ProgressEventData):
self.view.terminal_widget.update_progress(event)
elif isinstance(event, RAT.events.PlotEventData):
self.view.plotting_widget.plot_event(event)
elif isinstance(event, LogData):
self.view.logging.log(event.level, event.msg)

Expand Down
11 changes: 4 additions & 7 deletions rascal2/ui/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from rascal2.core.settings import MDIGeometries, Settings
from rascal2.dialogs.project_dialog import PROJECT_FILES, LoadDialog, LoadR1Dialog, NewProjectDialog, StartupDialog
from rascal2.dialogs.settings_dialog import SettingsDialog
from rascal2.widgets import ControlsWidget, TerminalWidget
from rascal2.widgets import ControlsWidget, PlotWidget, TerminalWidget
from rascal2.widgets.project import ProjectWidget
from rascal2.widgets.startup import StartUpWidget

Expand All @@ -32,11 +32,9 @@ def __init__(self):

self.presenter = MainWindowPresenter(self)
self.mdi = QtWidgets.QMdiArea()
# TODO replace the widgets below
# plotting: NO ISSUE YET
# https://github.com/RascalSoftware/RasCAL-2/issues/5
self.plotting_widget = QtWidgets.QWidget()
self.terminal_widget = TerminalWidget(self)

self.plotting_widget = PlotWidget(self)
self.terminal_widget = TerminalWidget()
self.controls_widget = ControlsWidget(self)
self.project_widget = ProjectWidget(self)

Expand Down Expand Up @@ -255,7 +253,6 @@ def setup_mdi(self):
"Fitting Controls": self.controls_widget,
}
self.setup_mdi_widgets()
self.terminal_widget.text_area.setVisible(True)

for title, widget in reversed(widgets.items()):
widget.setWindowTitle(title)
Expand Down
3 changes: 2 additions & 1 deletion rascal2/widgets/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from rascal2.widgets.controls import ControlsWidget
from rascal2.widgets.inputs import AdaptiveDoubleSpinBox, get_validated_input
from rascal2.widgets.plotter import PlotWidget
from rascal2.widgets.terminal import TerminalWidget

__all__ = ["ControlsWidget", "AdaptiveDoubleSpinBox", "get_validated_input", "TerminalWidget"]
__all__ = ["ControlsWidget", "AdaptiveDoubleSpinBox", "get_validated_input", "PlotWidget", "TerminalWidget"]
2 changes: 1 addition & 1 deletion rascal2/widgets/controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ControlsWidget(QtWidgets.QWidget):
"""Widget for editing the Controls window."""

def __init__(self, parent):
super().__init__(parent)
super().__init__()
self.presenter = parent.presenter
self.presenter.model.controls_updated.connect(self.update_ui)

Expand Down
Loading

0 comments on commit 9739c60

Please sign in to comment.