Skip to content

Commit

Permalink
Fix the output trajectory dialog for converters
Browse files Browse the repository at this point in the history
  • Loading branch information
MBartkowiakSTFC committed Jan 29, 2024
1 parent c86794c commit db2499d
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class OutputTrajectoryConfigurator(IConfigurator):
conversion, you must inherit from the MDANSE.Framework.Formats.IFormat.IFormat interface.
"""

_default = ("OUTPUT_TRAJECTORY", "MDTFormat")
_default = ("OUTPUT_TRAJECTORY", 64, "none")

def __init__(self, name, format=None, **kwargs):
"""
Expand All @@ -52,7 +52,7 @@ def __init__(self, name, format=None, **kwargs):

IConfigurator.__init__(self, name, **kwargs)

self._format = OutputTrajectoryConfigurator._default[-1]
self._format = "MDTFormat"
self._dtype = np.float64
self._compression = "none"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def initialize(self):

# The output trajectory is opened for writing.
self._output_trajectory = TrajectoryWriter(
self.configuration["output_file"]["files"][0],
self.configuration["output_file"]["file"],
chemical_system,
self.numberOfSteps,
positions_dtype=self.configuration["output_file"]["dtype"],
Expand Down
2 changes: 1 addition & 1 deletion MDANSE/Src/MDANSE/Framework/Jobs/CroppedTrajectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def initialize(self):

# The output trajectory is opened for writing.
self._output_trajectory = TrajectoryWriter(
self.configuration["output_file"]["files"][0],
self.configuration["output_file"]["file"],
self.configuration["trajectory"]["instance"].chemical_system,
self.numberOfSteps,
self._selectedAtoms,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def initialize(self):
self._reference_atoms = AtomGroup(self._reference_atoms)

self._output_trajectory = TrajectoryWriter(
self.configuration["output_file"]["files"][0],
self.configuration["output_file"]["file"],
self.configuration["trajectory"]["instance"].chemical_system,
self.numberOfSteps,
self._selected_atoms.atom_list,
Expand Down
4 changes: 2 additions & 2 deletions MDANSE/Src/MDANSE/Framework/Jobs/MoleculeFinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class MoleculeFinder(IJob):
"FramesConfigurator",
{"dependencies": {"trajectory": "trajectory"}, "default": (0, -1, 1)},
)
settings["output_files"] = (
settings["output_file"] = (
"OutputTrajectoryConfigurator",
{"format": "MDTFormat"},
)
Expand All @@ -77,7 +77,7 @@ def initialize(self):

# The output trajectory is opened for writing.
self._output_trajectory = TrajectoryWriter(
self.configuration["output_files"]["files"][0],
self.configuration["output_file"]["file"],
chemical_system,
self.numberOfSteps,
positions_dtype=self.configuration["output_file"]["dtype"],
Expand Down
6 changes: 3 additions & 3 deletions MDANSE/Src/MDANSE/Framework/Jobs/RigidBodyTrajectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class RigidBodyTrajectory(IJob):
)
settings["reference"] = ("IntegerConfigurator", {"mini": 0})
settings["remove_translation"] = ("BooleanConfigurator", {"default": False})
settings["output_files"] = ("OutputTrajectoryConfigurator", {"format": "MDTFormat"})
settings["output_file"] = ("OutputTrajectoryConfigurator", {"format": "MDTFormat"})

def initialize(self):
""" """
Expand Down Expand Up @@ -135,7 +135,7 @@ def initialize(self):

# Create trajectory
self._output_trajectory = TrajectoryWriter(
self.configuration["output_files"]["files"][0],
self.configuration["output_file"]["file"],
trajectory.chemical_system,
self.configuration["frames"]["number"],
selectedAtoms,
Expand Down Expand Up @@ -226,7 +226,7 @@ def finalize(self):
time, units={"time": "ps", "unit_cell": "nm", "coordinates": "nm"}
)

outputFile = h5py.File(self.configuration["output_files"]["files"][0], "r+")
outputFile = h5py.File(self.configuration["output_file"]["file"], "r+")

n_groups = self.configuration["atom_selection"]["selection_length"]
n_frames = self.configuration["frames"]["number"]
Expand Down
6 changes: 3 additions & 3 deletions MDANSE/Src/MDANSE/MolecularDynamics/Connectivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@

from MDANSE.Chemistry import ATOMS_DATABASE
from MDANSE.Chemistry.ChemicalEntity import ChemicalSystem
from MDANSE.Framework.InputData.HDFTrajectoryInputData import HDFTrajectoryInputData
from MDANSE.MolecularDynamics.Trajectory import Trajectory


class Connectivity:
"""This class calculates the distances between atoms in a trajectory,
and identifies potential molecules based on distances alone.
"""

def __init__(self, *args, trajectory: HDFTrajectoryInputData = None, **kwargs):
def __init__(self, *args, trajectory: Trajectory = None, **kwargs):
self._chemical_system = trajectory.chemical_system
self._frames = trajectory.trajectory
self._frames = trajectory
self._unit_cell = self._chemical_system.configuration
self._periodic = self._chemical_system.configuration.is_periodic
self.check_composition(self._chemical_system)
Expand Down
17 changes: 9 additions & 8 deletions MDANSE/Tests/UnitTests/molecules/test_connectivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import numpy as np
from MDANSE.MolecularDynamics.Connectivity import Connectivity
from MDANSE.Framework.InputData.HDFTrajectoryInputData import HDFTrajectoryInputData
from MDANSE.MolecularDynamics.Trajectory import Trajectory
from MDANSE.Chemistry.Structrures import MoleculeTester


Expand All @@ -12,30 +13,30 @@


@pytest.fixture(scope="module")
def trajectory() -> HDFTrajectoryInputData:
def trajectory() -> Trajectory:
trajectory = HDFTrajectoryInputData(short_traj)
yield trajectory
yield trajectory.trajectory


def test_create_connectivity(trajectory: HDFTrajectoryInputData):
def test_create_connectivity(trajectory: Trajectory):
conn = Connectivity(trajectory=trajectory)
print(conn._unique_elements)
assert len(conn._unique_elements) == 2


def test_find_bonds(trajectory: HDFTrajectoryInputData):
def test_find_bonds(trajectory: Trajectory):
conn = Connectivity(trajectory=trajectory)
conn.find_bonds()
assert len(conn._unique_bonds) == 40


def test_find_molecules(trajectory: HDFTrajectoryInputData):
def test_find_molecules(trajectory: Trajectory):
conn = Connectivity(trajectory=trajectory)
conn.find_molecules()
assert len(conn._molecules) == 20


def test_rebuild_molecules(trajectory: HDFTrajectoryInputData):
def test_rebuild_molecules(trajectory: Trajectory):
print(trajectory.chemical_system.atom_list)
conn = Connectivity(trajectory=trajectory)
conn.find_molecules()
Expand All @@ -47,7 +48,7 @@ def test_rebuild_molecules(trajectory: HDFTrajectoryInputData):
assert atoms_before == atoms_after


def test_unwrap_molecules(trajectory: HDFTrajectoryInputData):
def test_unwrap_molecules(trajectory: Trajectory):
conn = Connectivity(trajectory=trajectory)
conn.find_molecules()
chemical_system = trajectory.chemical_system
Expand All @@ -61,7 +62,7 @@ def test_unwrap_molecules(trajectory: HDFTrajectoryInputData):
assert not np.allclose(original_coords, contiguous_config.coordinates)


def test_identify_molecules(trajectory: HDFTrajectoryInputData):
def test_identify_molecules(trajectory: Trajectory):
conn = Connectivity(trajectory=trajectory)
conn.find_molecules()
chemical_system = trajectory.chemical_system
Expand Down
9 changes: 3 additions & 6 deletions MDANSE_GUI/Src/MDANSE_GUI/PyQtGUI/InputWidgets/FloatWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@ def newFloat(self, num: float):
self._value = num
self.updateValue()

@Slot()
def updateValue(self):
self._configurator.configure(self._value)

def get_value(self):
return self._configurator["value"]
def get_widget_value(self):
"""Collect the results from the input widgets and return the value."""
return float(self._field.text())
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ def newInt(self, num: int):
self._value = num
self.updateValue()

@Slot()
def updateValue(self):
self._configurator.configure(self._value)

def get_value(self):
return self._configurator["value"]
def get_widget_value(self):
"""Collect the results from the input widgets and return the value."""
return int(self._field.text())
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
import os
import os.path

from qtpy.QtWidgets import QComboBox, QLabel, QLineEdit, QPushButton, QFileDialog
from qtpy.QtWidgets import QComboBox, QLineEdit, QPushButton, QFileDialog
from qtpy.QtCore import Qt, Slot
from qtpy.QtGui import QStandardItemModel, QStandardItem

from MDANSE.MolecularDynamics.Trajectory import TrajectoryWriter
from MDANSE_GUI.PyQtGUI.InputWidgets.WidgetBase import WidgetBase
Expand All @@ -47,10 +46,10 @@ def __init__(self, *args, **kwargs):
self.field = QLineEdit(default_value[0], self._base)
self.dtype_box = QComboBox(self._base)
self.dtype_box.addItems(["float16", "float32", "float64", "float128"])
self.dtype_box.set_default("float64")
self.dtype_box.setCurrentText("float64")
self.compression_box = QComboBox(self._base)
self.compression_box.addItems(["none"] + TrajectoryWriter.allowed_compression)
self.compression_box.set_default("lza")
self.compression_box.setCurrentText("lzf")
# self.type_box.setCurrentText(default_value[1])
browse_button = QPushButton("Browse", self._base)
browse_button.clicked.connect(self.file_dialog)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ def default_labels(self):
if self._tooltip == "":
self._tooltip = "A text string variable. Do you know what to type in?"

@Slot()
def updateValue(self):
self._configurator.configure(self._field.text())

def get_value(self):
return self._configurator["value"]
def get_widget_value(self):
"""Collect the results from the input widgets and return the value."""
return self._field.text()
63 changes: 61 additions & 2 deletions MDANSE_GUI/Src/MDANSE_GUI/PyQtGUI/Widgets/GeneralWidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,6 @@ def returnValue(self):
if self.file_dialog is not None:
ic(f"File Field Return Value: {self.current_value}")
self.final_value.emit(self.current_value)
if self.file_direction == "out":
return (self.current_value, "MDTFormat")
return self.current_value

@Slot()
Expand Down Expand Up @@ -229,6 +227,12 @@ def register_value(self, field: GeneralInput):
self.fields.append(field)
field.value_changed.connect(self.valueChanged)

def returnValue(self):
result = []
for field in self.fields:
result.append(field.returnValue())
return result


def translate_file_associations(input_str: str):
"""Takes the string describing valid file formats, as specified for
Expand Down Expand Up @@ -297,6 +301,8 @@ def createInputField(*args, **kwargs):
result = InputFactory.createFile(*args, direction="in", **kwargs)
elif kind == "SingleOutputFileConfigurator":
result = InputFactory.createFile(*args, direction="out", **kwargs)
elif kind == "OutputTrajectoryConfigurator":
result = InputFactory.createTrajectory(*args, direction="out", **kwargs)
else:
result = InputFactory.createBlank(*args, **kwargs)

Expand Down Expand Up @@ -369,6 +375,59 @@ def createFile(*args, direction="in", **kwargs):
layout.addWidget(button)
return [base, data_handler]

def createTrajectory(*args, direction="out", **kwargs):
"""Creates an input field with an additional button which
creates a FileDialog, to allow the user to browse the file system.
Keyword Arguments:
direction -- if 'in', create a FileDialog for an exisitng file,
if 'out', a FileDialog for creating a new file.
"""
kind = kwargs.get("kind", "String")
default_value = kwargs.get("default", "")
tooltip_text = kwargs.get(
"tooltip", "Specify the name of the output trajectory."
)
file_association = kwargs.get("wildcard", "")
qt_file_association = translate_file_associations(file_association)
base, layout = InputFactory.createBase(*args, **kwargs)
field = QLineEdit(base)
main_handler = InputGroup(base)
data_handler1 = GeneralInput(
data_type=str,
file_association=qt_file_association,
file_direction=direction,
**kwargs,
)
data_handler2 = GeneralInput(
data_type=int,
)
data_handler3 = GeneralInput(
data_type=str,
)
main_handler.register_value(data_handler1)
main_handler.register_value(data_handler2)
main_handler.register_value(data_handler3)
data_handler1.string_value.connect(field.setText)
field.textChanged.connect(data_handler1.updateValue)
field.setText(str(default_value))
field.setToolTip(tooltip_text)
layout.addWidget(field)
cbox1 = QComboBox(base)
cbox1.addItems(["16", "32", "64", "128"])
cbox1.setCurrentText("64")
layout.addWidget(cbox1)
cbox2 = QComboBox(base)
cbox2.addItems(["no compression", "gzip"])
cbox2.setCurrentText("gzip")
layout.addWidget(cbox2)
cbox1.currentTextChanged.connect(data_handler2.updateValue)
cbox2.currentTextChanged.connect(data_handler3.updateValue)
button = QPushButton("Browse", base)
button.clicked.connect(data_handler1.valueFromDialog)
layout.addWidget(button)
return [base, main_handler]

def createBool(*args, **kwargs):
"""Creates an input field for a logical variable,
which is currently implemented as a check box.
Expand Down

0 comments on commit db2499d

Please sign in to comment.