Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Artificial trajectory generator #288

Merged
merged 12 commits into from
Jan 30, 2024
25 changes: 24 additions & 1 deletion MDANSE/Src/MDANSE/Framework/Configurable.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Configurable(object):

settings = collections.OrderedDict()

def __init__(self, settings=None):
def __init__(self, settings=None, trajectory_input="mdasne"):
"""
Constructor
"""
Expand All @@ -56,6 +56,29 @@ def __init__(self, settings=None):
if settings is not None:
self.set_settings(settings)

if trajectory_input == "mdmc":
self.mdmc_trajectory_input()
elif trajectory_input == "mock":
self.mock_trajectory_input()

def mdmc_trajectory_input(self):
"""Remove the hdf_trajectory (file-based) from settings,
and introduce an MDMC trajectory instead.
"""
for key, value in self.settings.items():
if key == "trajectory":
if value[0] == "HDFTrajectoryConfigurator":
self.settings[key] = ("MDMCTrajectoryConfigurator", {})

def mock_trajectory_input(self):
"""Remove the hdf_trajectory (file-based) from settings,
and introduce a mock trajectory instead.
"""
for key, value in self.settings.items():
if key == "trajectory":
if value[0] == "HDFTrajectoryConfigurator":
self.settings[key] = ("MockTrajectoryConfigurator", {})

def build_configuration(self):
self._configuration.clear()

Expand Down
8 changes: 5 additions & 3 deletions MDANSE/Src/MDANSE/Framework/Configurators/IConfigurator.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,11 @@ def __init__(self, name, **kwargs):

self._label = kwargs.get(
"label",
self.__class__._label
if hasattr(self.__class__, "_label")
else " ".join(name.split("_")).strip(),
(
self.__class__._label
if hasattr(self.__class__, "_label")
else " ".join(name.split("_")).strip()
),
)

self._widget = kwargs.get("widget", self.__class__)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# **************************************************************************
#
# MDANSE: Molecular Dynamics Analysis for Neutron Scattering Experiments
#
# @file Src/Framework/Configurators/MDMCTrajectoryConfigurator.py
# @brief A way to take in a trajectory from MDMC in a wrapper
#
# @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)
#
# **************************************************************************

import os

from MDANSE.Framework.Configurators.IConfigurator import IConfigurator


class MDMCTrajectoryConfigurator(IConfigurator):
"""
This is a replacement for a trajectory stored in and HDF5 file.
It is intended to be a drop-in replacement for HDFTrajectoryConfigurator,
even though it is NOT file-based.
"""

_default = None

def __init__(self, name, wildcard="All files|*", **kwargs):
"""
Initializes the configurator object.

:param name: the name of the configurator as it will appear in the configuration.
:type name: str
:param wildcard: the wildcard used to filter the file. This will be used in MDANSE GUI when
browsing for the input file.
:type wildcard: str
"""

# The base class constructor.
IConfigurator.__init__(self, name, **kwargs)

self._wildcard = wildcard

def configure(self, value):
"""
Configure a HDF trajectory file.

:param value: an instance of the MdanseTrajectory class
:type value: MdanseTrajectory from MDMC
"""

self["value"] = value
self["filename"] = "MDMC.temp"

self["instance"] = value

self["basename"] = "MDMC"

self["length"] = len(self["instance"])

self["md_time_step"] = 1.0

self["has_velocities"] = self["instance"].has_velocity

def get_information(self):
"""
Returns some basic informations about the contents of the HDF trajectory file.

:return: the informations about the contents of the HDF trajectory file.
:rtype: str
"""

info = ["MDMC trajectory used as input"]
info.append("Number of steps: %d\n" % self["length"])
info.append(
"Size of the chemical system: %d\n"
% self["instance"].chemical_system.number_of_atoms
)
if self["has_velocities"]:
info.append("The trajectory contains atomic velocities\n")
else:
info.append("The trajectory does not contain atomic velocities\n")

return "".join(info)
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# **************************************************************************
#
# MDANSE: Molecular Dynamics Analysis for Neutron Scattering Experiments
#
# @file Src/Framework/Configurators/MDMCTrajectoryConfigurator.py
# @brief A way to take in a trajectory from MDMC in a wrapper
#
# @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)
#
# **************************************************************************

import os

from MDANSE.Framework.Configurators.IConfigurator import IConfigurator
from MDANSE.MolecularDynamics.MockTrajectory import MockTrajectory


class MockTrajectoryConfigurator(IConfigurator):
"""
This is a replacement for a trajectory stored in and HDF5 file.
It is intended to be a drop-in replacement for HDFTrajectoryConfigurator,
even though it is NOT based on an HDF5 file.
It can use a JSON file with MockTrajectory parameters to create
a trajectory entirely in the RAM.
"""

_default = None

def __init__(self, name, wildcard="JSON file|*.json", **kwargs):
"""
Initializes the configurator object.

:param name: the name of the configurator as it will appear in the configuration.
:type name: str
:param wildcard: the wildcard used to filter the file. This will be used in MDANSE GUI when
browsing for the input file.
:type wildcard: str
"""

# The base class constructor.
IConfigurator.__init__(self, name, **kwargs)

self._wildcard = wildcard

def configure(self, value: str):
"""
Configure a mock trajectory file.

:param value: a JSON file with a MockTrajectory definition
:type value: str
"""

self["value"] = value
self["filename"] = "Mock"

self["instance"] = MockTrajectory.from_json(value)

self["basename"] = "Mock"

self["length"] = len(self["instance"])

self["md_time_step"] = self["instance"]._time_step

self["has_velocities"] = self["instance"].has_velocities

def get_information(self):
"""
Returns some basic informations about the contents of the HDF trajectory file.

:return: the informations about the contents of the HDF trajectory file.
:rtype: str
"""

info = ["Mock trajectory used as input"]
info.append("Number of steps: %d\n" % self["length"])
info.append(
"Size of the chemical system: %d\n"
% self["instance"].chemical_system.number_of_atoms
)
if self["has_velocities"]:
info.append("The trajectory contains atomic velocities\n")
else:
info.append("The trajectory does not contain atomic velocities\n")

return "".join(info)
80 changes: 80 additions & 0 deletions MDANSE/Src/MDANSE/Framework/InputData/MockTrajectoryInputData.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# **************************************************************************
#
# MDANSE: Molecular Dynamics Analysis for Neutron Scattering Experiments
#
# @file Src/Framework/InputData/HDFTrajectoryInputData.py
# @brief Implements module/class/test HDFTrajectoryInputData
#
# @homepage https://mdanse.org
# @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 MDANSE.Framework.InputData.IInputData import InputDataError
from MDANSE.Framework.InputData.InputFileData import InputFileData
from MDANSE.MolecularDynamics.MockTrajectory import MockTrajectory


class MockTrajectoryInputData(InputFileData):
"""Imitates the HDFTrajectoryInputData,
but builds a MockTrajectory out of a JSON file instead.
"""

extension = "json"

def load(self):
try:
traj = MockTrajectory.from_json(self._name)
except IOError as e:
raise InputDataError(str(e))
except ValueError as e:
raise InputDataError(str(e))

self._data = traj

def close(self):
self._data.close()

def info(self):
val = []

val.append("Path:")
val.append("%s\n" % self._name)
val.append("Number of steps:")
val.append("%s\n" % len(self._data))
mol_types = {}
val.append("\nMolecular types found:")
for ce in self._data.chemical_system.chemical_entities:
if ce.__class__.__name__ in mol_types:
mol_types[ce.__class__.__name__] += 1
else:
mol_types[ce.__class__.__name__] = 1

for k, v in mol_types.items():
val.append("\t- {:d} {}".format(v, k))

val = "\n".join(val)

return val

@property
def trajectory(self):
return self._data

@property
def chemical_system(self):
return self._data.chemical_system

@property
def hdf(self):
"""There is no HDF5 file for a mock trajectory

Returns
-------
str
name of a nonexistent file
"""
return self._data.file
4 changes: 2 additions & 2 deletions MDANSE/Src/MDANSE/Framework/Jobs/IJob.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ def define_unique_name():

return name

def __init__(self):
def __init__(self, trajectory_input="mdanse"):
"""
The base class constructor.
"""

Configurable.__init__(self)
Configurable.__init__(self, trajectory_input=trajectory_input)

self._outputData = OutputData()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ def _generate(self):
)

hklMax = (
np.ceil([qMax / np.sqrt(np.sum(v**2)) for v in self._inverseUnitCell.T])
+ 1
np.ceil([qMax / np.sqrt(np.sum(v**2)) for v in self._inverseUnitCell.T]) + 1
)

vects = np.mgrid[
Expand Down
2 changes: 0 additions & 2 deletions MDANSE/Src/MDANSE/IO/FortranFormat.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
# which can be accessed as text or as a list of items.
#
class FortranLine:

"""Fortran-style record in formatted files

FortranLine objects represent the content of one record of a
Expand Down Expand Up @@ -244,7 +243,6 @@ def _output(self):
# little error checking.
#
class FortranFormat:

"""
Parsed Fortran-style format string

Expand Down
Loading
Loading