Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/scm/plams/interfaces/adfsuite/amsanalysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,14 @@ def get_D(self, i: int = 1) -> Tuple[Optional[float], Optional[str]]:
return None, None
section = sections[i - 1]
plot = self.get_xy(section.split("(")[0], i)
if not plot.properties or "DiffusionCoefficient" not in plot.properties.keys():
if not plot.properties or "Final" not in plot.properties.keys():
return None, None
if "Legend" not in plot.properties.keys() or not isinstance(plot.properties["Legend"], str):
return None, None
if "Diffusion" not in plot.properties["Legend"]:
return None, None

D = cast(float, plot.properties["DiffusionCoefficient"])
D = cast(float, plot.properties["Final"])
D_units = plot.y_units
return D, D_units

Expand Down
93 changes: 64 additions & 29 deletions src/scm/plams/recipes/md/trajectoryanalysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
__all__ = ["AMSRDFJob", "AMSMSDJob", "AMSMSDResults", "AMSVACFJob", "AMSVACFResults"]


class MDAnalysisSettingsError(Exception):
"""
Error in supplied settings object
"""


class AMSConvenientAnalysisJob(AMSAnalysisJob):
_task = "None"

Expand All @@ -32,6 +38,7 @@ def __init__(self, previous_job=None, atom_indices=None, **kwargs): # needs to

self.previous_job = previous_job
self.atom_indices = atom_indices
self._settings_updated = False

def _get_max_dt_frames(self, max_correlation_time_fs):
if max_correlation_time_fs is None:
Expand All @@ -57,11 +64,17 @@ def get_input(self):
Generate the input file
"""
self._settings_to_list(self.settings.input, self._task)
if self.atom_indices and self._parent_write_atoms:
section = getattr(self.settings.input, self._task)
for entry in section:
if not (self._has_settings_entry(entry, "Atoms") and self._has_settings_entry(entry.Atoms, "Atom")):
self._add_nonunique_settings_entries(entry.Atoms.Atom, self.atom_indices)

if not self._settings_updated:
if self.atom_indices and self._parent_write_atoms:
section = getattr(self.settings.input, self._task)
for entry in section:
if not (self._has_settings_entry(entry, "Atoms") and self._has_settings_entry(entry.Atoms, "Atom")):
self._add_nonunique_settings_entries(entry.Atoms, "Atom", self.atom_indices)
else:
msg = "Atom indices cannot be supplied as argument if already present in settings"
raise MDAnalysisSettingsError(msg)
self._settings_updated = True
return super().get_input()

@staticmethod
Expand Down Expand Up @@ -100,7 +113,7 @@ def _has_settings_entry(settings, entry):
return getattr(settings, entry).value_changed

@staticmethod
def _add_nonunique_settings_entries(settings, entries):
def _add_nonunique_settings_entries(settings, key, entries):
"""
For non-default entries, multiple entries can be supplied

Expand All @@ -109,9 +122,10 @@ def _add_nonunique_settings_entries(settings, entries):
"""
if not isinstance(settings, Settings):
for i, entry in enumerate(entries):
settings[i] = entry
subsettings = getattr(settings, key)
subsettings[i] = entry
else:
settings = entries
settings[key] = entries

def _parent_prerun(self):
"""
Expand Down Expand Up @@ -459,7 +473,7 @@ def get_input(self):
"""
Generate the input file
"""
self.settings_to_list()
self._settings_to_list(self.settings.input, self._task)

for settings in self.settings.input.AutoCorrelation:
settings.Property = "Velocities"
Expand All @@ -470,7 +484,7 @@ def prerun(self): # noqa F811
Creates final settings
"""
self._parent_prerun() # trajectory and atom_indices handled
self.settings_to_list()
self._settings_to_list(self.settings.input, self._task)

for settings in self.settings.input.AutoCorrelation:
if not self._has_settings_entry(settings, "MaxFrame"):
Expand Down Expand Up @@ -655,15 +669,45 @@ def get_input(self):
"""
self._settings_to_list(self.settings.input, self._task)

for settings in self.settings.input.RadialDistribution:
if not self._has_settings_entry(settings, "AtomsFrom"):
if self.atom_indices:
settings.AtomsFrom.Atom = self.atom_indices
if not self._has_settings_entry(settings, "AtomsTo"):
if self.atom_indices_to:
settings.Atom = self.atom_indices_to
if not self._has_settings_entry(settings, "Range"):
settings.Range = f"{self.rmin} {self.rmax} {self.rstep}"
if not self._settings_updated:
prevjobs = self.previous_job
if not isinstance(prevjobs, list):
prevjobs = [prevjobs]
main_mol = prevjobs[0].results.get_main_molecule()

for settings in self.settings.input.RadialDistribution:
# If no atom iindices were provided, and there is nothing in the settings at all, add them
atom_indices = self.atom_indices
atom_indices_to = self.atom_indices_to
if not atom_indices:
if not self._has_settings_entry(settings, "AtomsFrom"):
atom_indices = list(range(1, len(main_mol) + 1))
if not atom_indices_to:
if not self._has_settings_entry(settings, "AtomsTo"):
atom_indices_to = list(range(1, len(main_mol) + 1))

# Add the atom indices only if there were no atom indices in the settings (if elements are present, add indices)
if atom_indices:
atoms_from_present = self._has_settings_entry(settings, "AtomsFrom")
atom_present = atoms_from_present and self._has_settings_entry(settings.AtomsFrom, "Atom")
if not atom_present:
self._add_nonunique_settings_entries(settings.AtomsFrom, "Atom", atom_indices)
else:
msg = "Atom indices cannot be supplied as argument if already present in settings"
raise MDAnalysisSettingsError(msg)
if atom_indices_to:
atoms_to_present = self._has_settings_entry(settings, "AtomsTo")
atom_present = atoms_to_present and self._has_settings_entry(settings.AtomsTo, "Atom")
if not atom_present:
self._add_nonunique_settings_entries(settings.AtomsTo, "Atom", atom_indices_to)
else:
msg = "Atom indices cannot be supplied as argument if already present in settings"
raise MDAnalysisSettingsError(msg)
if not self._has_settings_entry(settings, "Range"):
if isinstance(settings, Settings):
settings.Range = f"{self.rmin} {self.rmax} {self.rstep}"
else:
settings.Range = [self.rmin, self.rmax, self.rstep]
return super().get_input()

def prerun(self): # noqa F811
Expand All @@ -673,16 +717,7 @@ def prerun(self): # noqa F811
self._parent_prerun()
self._settings_to_list(self.settings.input, self._task)

prevjobs = self.previous_jobs
if not isinstance(prevjobs, list):
prevjobs = [prevjobs]
main_mol = prevjobs[0].results.get_main_molecule()

if not self.atom_indices:
self.atom_indices = list(range(1, len(main_mol) + 1))
if not self.atom_indices_to:
self.atom_indices_to = list(range(1, len(main_mol) + 1))
# Settings will be adjusted when get_input is called (again).
# Atom_indices will be adjusted when get_input is called (again).

def postrun(self):
"""
Expand Down
2 changes: 1 addition & 1 deletion unit_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def config():
_finish()


@pytest.fixture
@pytest.fixture(scope="session")
def xyz_folder():
"""
Returns the path to the XYZ folder
Expand Down
Loading
Loading