Skip to content

Commit b704e97

Browse files
authored
Merge branch 'develop' into update-micromamba
2 parents 396f451 + 4de96a4 commit b704e97

File tree

4 files changed

+66
-68
lines changed

4 files changed

+66
-68
lines changed
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import pytest
2+
3+
from mdpow.workflows import registry
4+
5+
def test_registry():
6+
assert list(registry.registry.keys()) == ['DihedralAnalysis']

mdpow/workflows/base.py

+3-8
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
import re
2525
import pandas as pd
2626

27-
from mdpow.workflows import registry
28-
2927
import logging
3028

3129
logger = logging.getLogger('mdpow.workflows.base')
@@ -147,6 +145,8 @@ def automated_project_analysis(project_paths, ensemble_analysis, **kwargs):
147145
automated_project_analysis(project_paths, ensemble_analysis='DihedralAnalysis', **kwargs)
148146
149147
"""
148+
# import inside function to avoid circular imports
149+
from .registry import registry
150150

151151
for row in project_paths.itertuples():
152152
molname = row.molecule
@@ -156,24 +156,19 @@ def automated_project_analysis(project_paths, ensemble_analysis, **kwargs):
156156
logger.info(f'starting {molname}')
157157

158158
try:
159-
registry.registry[ensemble_analysis](dirname=dirname, resname=resname, molname=molname, **kwargs)
160-
159+
registry[ensemble_analysis](dirname=dirname, resname=resname, molname=molname, **kwargs)
161160
logger.info(f'{molname} completed')
162-
163161
except KeyError as err:
164162
msg = (f"Invalid ensemble_analysis {err}. An EnsembleAnalysis type that corresponds "
165163
"to an existing automated workflow module must be input as a kwarg. "
166164
"ex: ensemble_analysis='DihedralAnalysis'")
167165
logger.error(f'{err} is an invalid selection')
168-
169166
raise KeyError(msg)
170-
171167
except TypeError as err:
172168
msg = (f"Invalid ensemble_analysis {ensemble_analysis}. An EnsembleAnalysis type that "
173169
"corresponds to an existing automated workflow module must be input as a kwarg. "
174170
"ex: ensemble_analysis='DihedralAnalysis'")
175171
logger.error(f'workflow module for {ensemble_analysis} does not exist yet')
176-
177172
raise TypeError(msg)
178173

179174
logger.info('all analyses completed')

mdpow/workflows/dihedrals.py

+53-54
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
88
:mod:`~mdpow.workflows.dihedrals` module provides functions for automated
99
workflows that encompass :class:`~mdpow.analysis.dihedral.DihedralAnalysis`.
10-
See each function for requirements and examples.
10+
See each function for requirements and examples.
1111
1212
Most functions can be used as standalone, individually, or in combination
1313
depending on the desired results. Details of the completely automated workflow
@@ -42,12 +42,11 @@
4242
import seaborn as sns
4343
import matplotlib.pyplot as plt
4444

45-
import mdpow
46-
from mdpow.analysis.dihedral import DihedralAnalysis
47-
4845
import MDAnalysis as mda
4946
from MDAnalysis.topology.guessers import guess_atom_element
5047

48+
from ..analysis import ensemble, dihedral
49+
5150
import logging
5251

5352
logger = logging.getLogger('mdpow.workflows.dihedrals')
@@ -92,11 +91,11 @@
9291
def build_universe(dirname):
9392
"""Builds :class:`~MDAnalysis.core.universe.Universe` from
9493
``water/Coulomb/0000`` topology and trajectory for the specified project.
95-
94+
9695
Used by :func:`~mdpow.workflows.dihedrals.rdkit_conversion`
9796
and :func:`~mdpow.workflows.dihedrals.dihedral_indices` to obtain atom indices
9897
for each dihedral atom group.
99-
98+
10099
:keywords:
101100
102101
*dirname*
@@ -108,12 +107,12 @@ def build_universe(dirname):
108107
searches for .gro, .gro.bz2, .gro.gz, and .tpr files for topology,
109108
and .xtc files for trajectory. It will default to using the tpr file
110109
available.
111-
110+
112111
:returns:
113112
114113
*u*
115114
:class:`~MDAnalysis.core.universe.Universe` object
116-
115+
117116
"""
118117

119118
path = pathlib.Path(dirname)
@@ -127,30 +126,30 @@ def rdkit_conversion(u, resname):
127126
"""Converts the solute, `resname`, of the
128127
:class:`~MDAnalysis.core.universe.Universe` to :class:`rdkit.Chem.rdchem.Mol` object
129128
for use with a SMARTS selection string to identify dihedral atom groups.
130-
129+
131130
Accepts :class:`~MDAnalysis.core.universe.Universe` object made with
132131
:func:`~mdpow.workflows.dihedrals.build_universe` and a `resname` as input.
133132
Uses `resname` to select the solute for conversion by
134133
:class:`~MDAnalysis.converters.RDKit.RDKitConverter` to :class:`rdkit.Chem.rdchem.Mol`,
135134
and will add element attributes for Hydrogen if not listed in the topology.
136-
135+
137136
:keywords:
138-
137+
139138
*u*
140139
:class:`~MDAnalysis.core.universe.Universe` object
141-
140+
142141
*resname*
143-
`resname` for the molecule as defined in
142+
`resname` for the molecule as defined in
144143
the topology and trajectory
145-
144+
146145
:returns:
147-
146+
148147
*tuple(mol, solute)*
149148
function call returns tuple, see below
150-
149+
151150
*mol*
152151
:class:`rdkit.Chem.rdchem.Mol` object converted from `solute`
153-
152+
154153
*solute*
155154
molecule specified by :func:`~MDAnalysis.core.groups.select_atoms`
156155
for :class:`~MDAnalysis.core.universe.Universe` object
@@ -171,8 +170,8 @@ def rdkit_conversion(u, resname):
171170
def dihedral_indices(dirname, resname, SMARTS=SMARTS_DEFAULT):
172171
'''Uses a SMARTS selection string to identify indices for
173172
relevant dihedral atom groups.
174-
175-
Requires an MDPOW project directory and `resname`
173+
174+
Requires an MDPOW project directory and `resname`
176175
as input. With :func:`~mdpow.workflows.dihedrals.build_universe` and
177176
:func:`~mdpow.workflows.dihedrals.rdkit_conversion`, uses the topology
178177
and trajectory from ``water/Coulomb/0000`` and creates a
@@ -190,16 +189,16 @@ def dihedral_indices(dirname, resname, SMARTS=SMARTS_DEFAULT):
190189
searches for .gro, .gro.bz2, .gro.gz, and .tpr files for topology,
191190
and .xtc files for trajectory. It will default to using the tpr file
192191
available.
193-
192+
194193
*resname*
195-
`resname` for the molecule as defined in
194+
`resname` for the molecule as defined in
196195
the topology and trajectory
197196
198197
*SMARTS*
199198
The default SMARTS string is described in detail under :data:`SMARTS_DEFAULT`.
200-
199+
201200
:returns:
202-
201+
203202
*atom_group_indices*
204203
tuple of tuples of indices for each dihedral atom group
205204
@@ -209,15 +208,15 @@ def dihedral_indices(dirname, resname, SMARTS=SMARTS_DEFAULT):
209208
mol = rdkit_conversion(u=u, resname=resname)[0]
210209
pattern = Chem.MolFromSmarts(SMARTS)
211210
atom_group_indices = mol.GetSubstructMatches(pattern)
212-
211+
213212
return atom_group_indices
214213

215214
def dihedral_groups(dirname, resname, SMARTS=SMARTS_DEFAULT):
216215
'''Uses the indices of the relevant dihedral atom groups determined
217216
by :func:`~mdpow.workflows.dihedral.dihedral_indices`
218217
and returns the names for each atom in each group.
219-
220-
Requires an MDPOW project directory and `resname`
218+
219+
Requires an MDPOW project directory and `resname`
221220
as input. Expands upon usage of
222221
:func:`~mdpow.workflows.dihedral.dihedral_indices`
223222
to return an array of the names of each atom within
@@ -239,14 +238,14 @@ def dihedral_groups(dirname, resname, SMARTS=SMARTS_DEFAULT):
239238
available.
240239
241240
*resname*
242-
`resname` for the molecule as defined in
241+
`resname` for the molecule as defined in
243242
the topology and trajectory
244243
245244
*SMARTS*
246245
The default SMARTS string is described in detail under :data:`SMARTS_DEFAULT`.
247-
246+
248247
:returns:
249-
248+
250249
*dihedral_groups*
251250
list of :func:`numpy.array` for atom names in each dihedral atom group
252251
@@ -263,12 +262,12 @@ def dihedral_groups(dirname, resname, SMARTS=SMARTS_DEFAULT):
263262
def dihedral_groups_ensemble(dirname, atom_group_indices,
264263
solvents=SOLVENTS_DEFAULT,
265264
interactions=INTERACTIONS_DEFAULT,
266-
start=None, stop=None, step=None):
265+
start=None, stop=None, step=None):
267266
'''Creates one :class:`~mdpow.analysis.ensemble.Ensemble` for the MDPOW
268267
project and runs :class:`~mdpow.analysis.dihedral.DihedralAnalysis`
269268
for each dihedral atom group identified by the SMARTS
270269
selection string.
271-
270+
272271
.. seealso::
273272
274273
:func:`~mdpow.workflows.dihedrals.automated_dihedral_analysis`,
@@ -304,30 +303,30 @@ def dihedral_groups_ensemble(dirname, atom_group_indices,
304303
.. seealso:: :class:`~mdpow.analysis.ensemble.EnsembleAnalysis`
305304
306305
:returns:
307-
306+
308307
*df*
309308
:class:`pandas.DataFrame` of :class:`~mdpow.analysis.dihedral.DihedralAnalysis`
310309
results, including all dihedral atom groups for molecule of current project
311310
312311
'''
313312

314-
dih_ens = mdpow.analysis.ensemble.Ensemble(dirname=dirname,
315-
solvents=solvents,
316-
interactions=interactions)
313+
dih_ens = ensemble.Ensemble(dirname=dirname,
314+
solvents=solvents,
315+
interactions=interactions)
317316
indices = atom_group_indices
318317
all_dihedrals = [dih_ens.select_atoms(f'index {i[0]}',
319318
f'index {i[1]}',
320319
f'index {i[2]}',
321320
f'index {i[3]}' ) for i in indices]
322321

323-
da = DihedralAnalysis(all_dihedrals)
322+
da = dihedral.DihedralAnalysis(all_dihedrals)
324323
da.run(start=start, stop=stop, step=step)
325324
df = da.results
326325

327326
return df
328327

329328
def save_df(df, df_save_dir, resname=None, molname=None):
330-
'''Takes a :class:`pandas.DataFrame` of results from
329+
'''Takes a :class:`pandas.DataFrame` of results from
331330
:class:`~mdpow.analysis.dihedral.DihedralAnalysis`
332331
as input before padding the angles to optionaly save the raw
333332
data.
@@ -349,13 +348,13 @@ def save_df(df, df_save_dir, resname=None, molname=None):
349348
optional, path to the location to save results :class:`pandas.DataFrame`
350349
351350
*resname*
352-
`resname` for the molecule as defined in
351+
`resname` for the molecule as defined in
353352
the topology and trajectory
354353
355354
*molname*
356355
molecule name to be used for labelling
357356
plots, if different from `resname`
358-
357+
359358
'''
360359

361360
df = df.sort_values(by=["selection",
@@ -379,13 +378,13 @@ def save_df(df, df_save_dir, resname=None, molname=None):
379378
def periodic_angle(df, padding=45):
380379
'''Pads the angles from the results :class:`~pandas.DataFrame`
381380
to maintain periodicity in the violin plots.
382-
381+
383382
Takes a :class:`pandas.DataFrame` of results from
384383
:class:`~mdpow.analysis.dihedral.DihedralAnalysis`
385384
as input and pads the angles to maintain periodicity
386385
for properly plotting dihedral angle frequencies as KDE violins
387386
with :func:`~mdpow.workflows.dihedrals.dihedral_violins`.
388-
Creates two new :class:`pandas.DataFrame` based on the
387+
Creates two new :class:`pandas.DataFrame` based on the
389388
cutoff value specified, adds to the angle values, concatenates
390389
all three :class:`pandas.DataFrame`, maintaining original data and
391390
adding padding, and returns new augmented :class:`pandas.DataFrame`.
@@ -399,15 +398,15 @@ def periodic_angle(df, padding=45):
399398
*padding*
400399
value in degrees
401400
default: 45
402-
401+
403402
:returns:
404-
403+
405404
*df_aug*
406405
augmented results :class:`pandas.DataFrame` containing
407406
padded dihedral angles as specified by `padding`
408407
409408
.. rubric:: Example
410-
409+
411410
Typical Workflow::
412411
413412
da = DihedralAnalysis(all_dihedrals)
@@ -443,7 +442,7 @@ def dihedral_violins(df, width=0.9, solvents=SOLVENTS_DEFAULT):
443442
444443
*solvents*
445444
The default solvents are documented under :data:`SOLVENTS_DEFAULT`.
446-
445+
447446
:returns:
448447
449448
*violin plot*
@@ -468,7 +467,7 @@ def dihedral_violins(df, width=0.9, solvents=SOLVENTS_DEFAULT):
468467
solv2 = 'octanol'
469468
if solvs.size > 1:
470469
solv2 = solvs[1]
471-
470+
472471
g = sns.catplot(data=df, x="lambda", y="dihedral", hue="solvent", col="interaction",
473472
kind="violin", split=True, width=width, inner=None, cut=0,
474473
linewidth=0.5,
@@ -496,7 +495,7 @@ def dihedral_violins(df, width=0.9, solvents=SOLVENTS_DEFAULT):
496495
def plot_violins(df, resname, figdir=None, molname=None, width=0.9, solvents=SOLVENTS_DEFAULT):
497496
'''Coordinates plotting and optionally saving figures for all dihedral
498497
atom groups.
499-
498+
500499
Makes a subdirectory within the specified
501500
`figdir` using `resname` or `molname` provided and saves violin plot
502501
figur for each dihedral atom group separately.
@@ -505,15 +504,15 @@ def plot_violins(df, resname, figdir=None, molname=None, width=0.9, solvents=SOL
505504
506505
:func:`~mdpow.workflows.dihedrals.automated_dihedral_analysis`,
507506
:func:`~mdpow.workflows.dihedrals.dihedral_violins`
508-
507+
509508
:keywords:
510-
509+
511510
*df*
512511
augmented results :class:`pandas.DataFrame` from
513512
:func:`~mdpow.workflows.dihedrals.periodic_angle`
514513
515514
*resname*
516-
`resname` for the molecule as defined in
515+
`resname` for the molecule as defined in
517516
the topology and trajectory
518517
519518
*figdir*
@@ -575,7 +574,7 @@ def automated_dihedral_analysis(dirname=None, df_save_dir=None, figdir=None,
575574
'''Runs :class:`~mdpow.analysis.dihedral.DihedralAnalysis` for a single MDPOW
576575
project and creates violin plots of dihedral angle frequencies for each
577576
relevant dihedral atom group.
578-
577+
579578
For one MDPOW project, automatically determines all relevant dihedral atom groups
580579
in the molecule, runs :class:`~mdpow.analysis.dihedral.DihedralAnalysis` for each group,
581580
pads the dihedral angles from analysis results for all groups to maintain periodicity,
@@ -605,13 +604,13 @@ def automated_dihedral_analysis(dirname=None, df_save_dir=None, figdir=None,
605604
optional, path to the location to save figures
606605
607606
*resname*
608-
`resname` for the molecule as defined in
607+
`resname` for the molecule as defined in
609608
the topology and trajectory
610609
611610
*molname*
612611
molecule name to be used for labelling
613612
plots, if different from `resname`
614-
613+
615614
*SMARTS*
616615
The default SMARTS string is described in detail under :data:`SMARTS_DEFAULT`.
617616
@@ -652,7 +651,7 @@ def automated_dihedral_analysis(dirname=None, df_save_dir=None, figdir=None,
652651
relevant dihedral atom group in the molecule from the current MDPOW project
653652
654653
.. rubric:: Example
655-
654+
656655
Typical Workflow::
657656
658657
import automated_dihedral_analysis as ada

0 commit comments

Comments
 (0)