Skip to content

Commit

Permalink
Adapt the Converter GUI to the nee code structure
Browse files Browse the repository at this point in the history
  • Loading branch information
MBartkowiakSTFC committed Jan 8, 2024
1 parent 9d1d5ff commit daa480e
Show file tree
Hide file tree
Showing 16 changed files with 130 additions and 38 deletions.
2 changes: 2 additions & 0 deletions MDANSE/Src/Framework/Converters/ASE.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ class ASEInteractiveConverter(InteractiveConverter):
Converts any trajectory to a HDF trajectory using the ASE io module.
"""

category = ("InteractiveConverter",)

label = "ASE"

input_files = collections.OrderedDict()
Expand Down
2 changes: 2 additions & 0 deletions MDANSE/Src/Framework/Converters/Converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@


class InteractiveConverter(IJob):
category = ("InteractiveConverter",)

_converter_registry = {}
_next_number = 1

Expand Down
5 changes: 4 additions & 1 deletion MDANSE/Src/Framework/Converters/DL_POLY.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,10 @@ class DL_POLY(Converter):
"label": "Input HISTORY file",
},
)
settings["atom_aliases"] = ("python_object", {"default": {}})
settings["atom_aliases"] = (
"PythonObjectConfigurator",
{"default": {}, "label": "Atom aliases (Python dictionary)"},
)
settings["fold"] = (
"BooleanConfigurator",
{"default": False, "label": "Fold coordinates into box"},
Expand Down
2 changes: 1 addition & 1 deletion MDANSE/Src/Framework/Converters/XPLOR.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from MDANSE.Framework.Converters.DCD import DCD


class XPLORConverter(DCD):
class XPLOR(DCD):
"""
Converts an Xplor trajectory to a HDF trajectory.
"""
Expand Down
5 changes: 5 additions & 0 deletions MDANSE/Src/Framework/Jobs/DistanceHistogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class DistanceHistogram(IJob):

type = None

category = (
"Analysis",
"Structure",
)

settings = collections.OrderedDict()
settings["trajectory"] = ("HDFTrajectoryConfigurator", {})
settings["frames"] = (
Expand Down
4 changes: 2 additions & 2 deletions MDANSE_GUI/Src/PyQtGUI/BackEnd.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ def checkConverters(self):
self._reverse_converters = {}
for key, conv in Converter.indirect_subclass_dictionary().items():
ic(f"key:{key}, val:{conv}")
self._converters.append(conv)
self._reverse_converters[str(conv)] = Converter.create(str(key))
self._converters.append(key)
self._reverse_converters[str(key)] = Converter.create(str(key))
self.lock.unlock()

def getConverters(self):
Expand Down
2 changes: 1 addition & 1 deletion MDANSE_GUI/Src/PyQtGUI/InputWidgets/AtomSelectionWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class SelectionDialog(QDialog):
class AtomSelectionWidget(WidgetBase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
default_value = "atom_symbol *"
default_value = "all"
self._value = default_value
self.field = QLineEdit(default_value, self._base)
browse_button = QPushButton("Atom selection creator", self._base)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def add_line(self):
line_base = QWidget(self._base)
line_layout = QHBoxLayout(line_base)
line_base.setLayout(line_layout)
default_value = "atom_symbol *"
default_value = "all"
starter = QLabel("Transmute ", line_base)
leftfield = QLineEdit(default_value, self._base)
spacer = QLabel(" to ", line_base)
Expand Down
79 changes: 79 additions & 0 deletions MDANSE_GUI/Src/PyQtGUI/InputWidgets/RangeWidget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# **************************************************************************
#
# MDANSE: Molecular Dynamics Analysis for Neutron Scattering Experiments
#
# @file Src/PyQtGUI/InputWidgets/FramesWidget.py
# @brief Implements module/class/test FramesWidget
#
# @homepage https://www.isis.stfc.ac.uk/Pages/MDANSEproject.aspx
# @license GNU General Public License v3 or higher (see LICENSE)
# @copyright Institut Laue Langevin 2013-now
# @copyright ISIS Neutron and Muon Source, STFC, UKRI 2021-now
# @authors Scientific Computing Group at ILL (see AUTHORS)
#
# **************************************************************************

from qtpy.QtWidgets import QLineEdit, QSpinBox, QLabel
from qtpy.QtCore import Slot, Signal
from qtpy.QtGui import QDoubleValidator, QIntValidator

from MDANSE_GUI.PyQtGUI.InputWidgets.WidgetBase import WidgetBase


class RangeWidget(WidgetBase):
def __init__(self, *args, **kwargs):
super().__init__(*args, layout_type="QGridLayout", **kwargs)
source_object = kwargs.get("source_object", None)
num_type = kwargs.get("valueType", int)
if num_type is int:
step_val = 1
else:
step_val = 0.1
labels = [
QLabel("From", self._base),
QLabel("to", self._base),
QLabel("in steps of", self._base),
]
fields = [
QLineEdit(str(num_type(0)), self._base),
QLineEdit(str(num_type(5)), self._base),
QLineEdit(str(num_type(step_val)), self._base),
]
if num_type is int:
validators = [QIntValidator(parent_field) for parent_field in fields]
else:
validators = [QDoubleValidator(parent_field) for parent_field in fields]
for field_num in range(3):
self._layout.addWidget(labels[field_num], 0, 2 * field_num)
self._layout.addWidget(fields[field_num], 0, 2 * field_num + 1)
fields[field_num].setValidator(validators[field_num])
fields[field_num].textChanged.connect(self.updateValue)
self._fields = fields
self._validators = validators
self._num_type = num_type
self.default_labels()
self.update_labels()

def default_labels(self):
"""Each Widget should have a default tooltip and label,
which will be set in this method, unless specific
values are provided in the settings of the job that
is being configured."""
if self._label_text == "":
self._label_text = "RangeWidget"
if self._tooltip == "":
self._tooltip = "Values to be used, given as (First, Last, StepSize)"

def value_from_configurator(self):
if self._configurator.check_dependencies():
minval, maxval = self._configurator._mini, self._configurator._maxi
print(f"Configurator min/max: {minval}, {maxval}")
if maxval is None:
return
for val in self._validators:
val.setBottom(-abs(maxval))
val.setTop(abs(maxval))

def get_widget_value(self):
val = [self._num_type(field.text()) for field in self._fields]
return val
1 change: 1 addition & 0 deletions MDANSE_GUI/Src/PyQtGUI/InputWidgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"FloatWidget",
"StringWidget",
"FramesWidget",
"RangeWidget",
"HDFTrajectoryWidget",
"DummyWidget",
"InterpolationOrderWidget",
Expand Down
8 changes: 3 additions & 5 deletions MDANSE_GUI/Src/PyQtGUI/MolecularViewer/AtomProperties.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,14 @@ def initialise_from_database(
index_list = []
for nat, atom in enumerate(atoms):
row = []
rgb = [int(x) for x in element_database["atoms"][atom]["color"].split(";")]
rgb = [int(x) for x in element_database[atom]["color"].split(";")]
index_list.append(self.add_colour(rgb))
row.append(QStandardItem(str(nat + 1))) # atom number
row.append(
QStandardItem(str(element_database["atoms"][atom]["symbol"]))
QStandardItem(str(element_database[atom]["symbol"]))
) # chemical element name
row.append(
QStandardItem(
str(round(element_database["atoms"][atom]["atomic_radius"], 2))
)
QStandardItem(str(round(element_database[atom]["atomic_radius"], 2)))
)
row.append(
QStandardItem(
Expand Down
8 changes: 4 additions & 4 deletions MDANSE_GUI/Src/PyQtGUI/MolecularViewer/MolecularViewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

from MDANSE.Framework.InputData.HDFTrajectoryInputData import HDFTrajectoryInputData
from MDANSE.Chemistry import ATOMS_DATABASE as CHEMICAL_ELEMENTS

from MDANSE_GUI.PyQtGUI.MolecularViewer.database import CHEMICAL_ELEMENTS
# from MDANSE_GUI.PyQtGUI.MolecularViewer.database import CHEMICAL_ELEMENTS
from MDANSE_GUI.PyQtGUI.MolecularViewer.readers import hdf5wrapper
from MDANSE_GUI.PyQtGUI.MolecularViewer.Dummy import PyConnectivity
from MDANSE_GUI.PyQtGUI.MolecularViewer.Contents import TrajectoryAtomData
Expand Down Expand Up @@ -544,8 +545,7 @@ def set_coordinates(self, frame: int):
self._polydata.SetPoints(atoms)

covalent_radii = [
CHEMICAL_ELEMENTS["atoms"][at]["covalent_radius"]
for at in self._reader.atom_types
CHEMICAL_ELEMENTS[at]["covalent_radius"] for at in self._reader.atom_types
]
self.set_connectivity_builder(coords, covalent_radii)
chemical_bonds = self._fixed_bonds
Expand Down Expand Up @@ -599,7 +599,7 @@ def set_reader(self, reader, frame=0):
# this returs a list of indices, mapping colours to atoms

self._atom_scales = np.array(
[CHEMICAL_ELEMENTS["atoms"][at]["vdw_radius"] for at in self._atoms]
[CHEMICAL_ELEMENTS[at]["vdw_radius"] for at in self._atoms]
).astype(np.float32)

scalars = ndarray_to_vtkarray(
Expand Down
1 change: 1 addition & 0 deletions MDANSE_GUI/Src/PyQtGUI/SubclassViewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ def parentsFromCategories(self, category_tuple):
self._categories[cat_string] = current_node
else:
current_node = self._categories[cat_string]
parent = current_node
return current_node


Expand Down
1 change: 1 addition & 0 deletions MDANSE_GUI/Src/PyQtGUI/Widgets/ActionDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"StringConfigurator": StringWidget,
"IntegerConfigurator": IntegerWidget,
"FramesConfigurator": FramesWidget,
"RangeConfigurator": RangeWidget,
"HDFTrajectoryConfigurator": HDFTrajectoryWidget,
"InterpolationOrderConfigurator": InterpolationOrderWidget,
"OutputFilesConfigurator": OutputFilesWidget,
Expand Down
2 changes: 1 addition & 1 deletion MDANSE_GUI/Src/PyQtGUI/Widgets/ConvertDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def __init__(self, *args, converter: IJob = "Dummy", **kwargs):
]
)
else:
converter_instance = converter()
converter_instance = converter
converter_instance.build_configuration()
settings = converter_instance.settings
self.converter_instance = converter_instance
Expand Down
44 changes: 22 additions & 22 deletions MDANSE_GUI/Src/PyQtGUI/Widgets/GeneralWidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,25 +277,25 @@ def createInputField(*args, **kwargs):
Returns:
[QWidget, GeneralInput] pair
"""
kind = kwargs.get("kind", "str")
kind = kwargs.get("kind", "String")

if kind == "str":
if kind == "StringConfigurator":
result = InputFactory.createSingle(*args, **kwargs)
elif kind == "int" or kind == "integer":
elif kind == "PythonObjectConfigurator":
result = InputFactory.createSingle(*args, **kwargs)
elif kind == "range" or kind == "intrange":
result = InputFactory.createMultiple(*args, **kwargs)
elif kind == "arange" or kind == "floatrange":
elif kind == "IntegerConfigurator":
result = InputFactory.createSingle(*args, **kwargs)
elif kind == "RangeConfigurator":
result = InputFactory.createMultiple(*args, **kwargs)
elif kind == "float":
elif kind == "FloatConfigurator":
result = InputFactory.createSingle(*args, **kwargs)
elif kind == "single_choice":
elif kind == "SingleChoiceConfigurator":
result = InputFactory.createCombo(*args, **kwargs)
elif kind == "bool" or kind == "boolean":
elif kind == "BooleanConfigurator":
result = InputFactory.createBool(*args, **kwargs)
elif kind == "input_file":
elif kind == "InputFileConfigurator":
result = InputFactory.createFile(*args, direction="in", **kwargs)
elif kind == "single_output_file":
elif kind == "SingleOutputFileConfigurator":
result = InputFactory.createFile(*args, direction="out", **kwargs)
else:
result = InputFactory.createBlank(*args, **kwargs)
Expand Down Expand Up @@ -326,7 +326,7 @@ def createBlank(*args, **kwargs):
the users that the requested input field could not
be constructed.
"""
kind = kwargs.get("kind", "str")
kind = kwargs.get("kind", "String")
base, layout = InputFactory.createBase(
label=f"<b>MISSING TYPE</b>:{kind}",
tooltip="This is not handled by the MDANSE GUI correctly! Please report the problem to the authors.",
Expand All @@ -341,7 +341,7 @@ def createFile(*args, direction="in", **kwargs):
direction -- if 'in', create a FileDialog for an exisitng file,
if 'out', a FileDialog for creating a new file.
"""
kind = kwargs.get("kind", "str")
kind = kwargs.get("kind", "String")
default_value = kwargs.get("default", "")
tooltip_text = kwargs.get("tooltip", "Specify a path to an existing file.")
file_association = kwargs.get("wildcard", "")
Expand Down Expand Up @@ -373,7 +373,7 @@ def createBool(*args, **kwargs):
"""Creates an input field for a logical variable,
which is currently implemented as a check box.
"""
kind = kwargs.get("kind", "bool")
kind = kwargs.get("kind", "Boolean")
default_value = kwargs.get("default", False)
tooltip_text = kwargs.get("tooltip", None)
ic(kind)
Expand Down Expand Up @@ -406,13 +406,13 @@ def createSingle(*args, **kwargs):
ic(kwargs)
base, layout = InputFactory.createBase(*args, **kwargs)
field = QLineEdit(base)
if kind == "int" or kind == "integer":
if "Integer" in kind:
data_handler = GeneralInput(data_type=int, **kwargs)
validator = QIntValidator(field)
elif kind == "float":
elif "Float" in kind:
data_handler = GeneralInput(data_type=float, **kwargs)
validator = QDoubleValidator(field)
elif kind == "str":
else:
data_handler = GeneralInput(data_type=str, **kwargs)
validator = None
if validator is not None:
Expand All @@ -432,7 +432,7 @@ def createMultiple(*args, **kwargs):
For numerical values, it adds a QValidator instance
to filter out invalid inputs.
"""
kind = kwargs.get("kind", "str")
kind = kwargs.get("kind", "String")
default_value = kwargs.get("default", None)
tooltip_text = kwargs.get("tooltip", None)
minval = kwargs.get("mini", None)
Expand All @@ -447,13 +447,13 @@ def createMultiple(*args, **kwargs):
main_handler = InputGroup(base)
for nfield in range(number_of_fields):
field = QLineEdit(base)
if kind == "int" or kind == "integer":
if "Integer" in kind:
data_handler = GeneralInput(data_type=int, **kwargs)
validator = QIntValidator(field)
elif kind == "float":
elif "Float" in kind:
data_handler = GeneralInput(data_type=float, **kwargs)
validator = QDoubleValidator(field)
elif kind == "str":
else:
data_handler = GeneralInput(data_type=str, **kwargs)
validator = None
if validator is not None:
Expand All @@ -470,7 +470,7 @@ def createMultiple(*args, **kwargs):
def createCombo(*args, **kwargs):
"""For the variable where one option has to be picked from
a list of possible values, we create a ComboBox"""
kind = kwargs.get("kind", "str")
kind = kwargs.get("kind", "String")
default_value = kwargs.get("default", False)
tooltip_text = kwargs.get("tooltip", None)
option_list = kwargs.get("choices", [])
Expand Down

0 comments on commit daa480e

Please sign in to comment.