imdclient 0.1.4__py3-none-any.whl → 0.2.0b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,7 @@
1
- imdclient/IMD.py,sha256=QkYU0OUxrrjKVxumeEju3Jcewkj46K7DBk_J3vO5m1E,3842
2
- imdclient/IMDClient.py,sha256=9AMKniQaCNDgWO2esF_SXEgdf3fp_4pcZ5fUNpzewcY,34349
1
+ imdclient/IMDClient.py,sha256=X4bTbEY9CjV7riRyWxZnsXsWvUPItb3ZC0VyoSRG6b0,34402
3
2
  imdclient/IMDProtocol.py,sha256=wePIuFlKGIULWXHJPCmzRVWBGlBiyDOJXgjxyQb7ssY,4063
4
- imdclient/__init__.py,sha256=Pa5h6Fjyvyxf3ECzO43pcmLm3Vk-vOuEb5Gi6TDWhds,339
5
- imdclient/backends.py,sha256=QmHjwYbmvFVHz-uFgpSOA0UmZTZqiMGqWMO7B8wr1zs,10368
6
- imdclient/results.py,sha256=2MyjFdQMW7BfiHhG5X6wQwMVrF_0mKYFnv907lgLMas,9920
7
- imdclient/streamanalysis.py,sha256=Qq0h_WPO-wb0_lP8jTRHe0HX7UDZNgJFA6C4PZdUmK8,38385
8
- imdclient/streambase.py,sha256=rwhdyC2V3_9pSz_6rNwjSc4MNToI9S318OH7AH0arHA,6176
9
- imdclient/utils.py,sha256=VWxk4vQ6hzxoYRu-8Ge8fJG-EitJwgJR93wOWCvzY-0,3308
3
+ imdclient/__init__.py,sha256=lSbwmZHgCd74dGAEKVb3RaBr4oTTuRLil8sbtKuOwE4,207
4
+ imdclient/utils.py,sha256=itf_Z24KnJxe-db6dHi7A2umCp_ZjjlpAMpETYYMxUs,4224
10
5
  imdclient/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
6
  imdclient/data/gromacs/md/gromacs_struct.gro,sha256=kt4vE10iF_1RbeyTogmYmIY9yKJacofrzNT-hPHGyL8,1459301
12
7
  imdclient/data/gromacs/md/gromacs_v3.top,sha256=AXFEDjvz5Qqq-VECffimdeEvhD6L-H0SFPILW-6Sums,348329
@@ -18,40 +13,41 @@ imdclient/data/lammps/md/lammps_v3_nst_8.in,sha256=gpdAp1dDhJbG06wZVDtBGUs6biJNz
18
13
  imdclient/data/namd/md/alanin.params,sha256=zWw-UfqYD3-xpdA_8R8T-0OYBbUM6py7jKAq_uyu8HE,17389
19
14
  imdclient/data/namd/md/alanin.pdb,sha256=eccDD-ledUXjbB2s1fxY40lmAKWWDpxkxANbsOkqjHc,5615
20
15
  imdclient/data/namd/md/alanin.psf,sha256=VhCZeGFhpUa8yN5iEL19zlVjqIJg2JIdPzhazpRForY,12953
21
- imdclient/data/namd/md/namd_v3_nst_1.namd,sha256=EZU7PGyytZdGixrBnmpAcwonN0n_JTk9U-Q82FoqO7k,983
16
+ imdclient/data/namd/md/namd3,sha256=NuLCXQFTWUFo6lQgTs5QQqsuX2HG0eHeLRmjAJnr8Bs,18234624
17
+ imdclient/data/namd/md/namd_v3_nst_1.namd,sha256=lx-cRWISTiqdKo9TMjifOGS7gQm6Mif3ykKm0T82jos,984
22
18
  imdclient/data/namd/md/namd_v3_nst_8.namd,sha256=WJmwj0E4nJVhYRr_ALBlTax6kyNkdRE1krPsmY-QFLM,984
23
19
  imdclient/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- imdclient/tests/base.py,sha256=gbu39CpII5mc9-rDSEZoQNv8JmNFwW1vviYkfOQmbD4,8043
20
+ imdclient/tests/base.py,sha256=AjxIls31BYf9E8bkSiyKBz9dDbTA06UHuD4hsb7M6yc,7009
25
21
  imdclient/tests/conftest.py,sha256=Xqz9ZjBXpnViSryR4CXjJdOyqZ1MOCAjuA0sRVwAVfk,31
26
- imdclient/tests/datafiles.py,sha256=0wAg1q5oB3Ve6XnSfnB6oGzbh7JvVpSGpj-ba0H2Z5w,1515
27
- imdclient/tests/server.py,sha256=x3IY5FDDS4z99_UyuuRe56CHd_XtfINJRolGbkNyOl8,6629
28
- imdclient/tests/test_gromacs.py,sha256=rXkabRB40xX7LRdF2_nrPgeNpfFF9J7m-5LeRNMA5TM,1454
29
- imdclient/tests/test_imdclient.py,sha256=FQwuNbJwOLgK33v5mFmbhaGaPSqXA8byTWFtYCpYyJo,7716
30
- imdclient/tests/test_imdreader.py,sha256=-DEFcwef87CZPXut45I2gpZPg_K3XXPFFreBqsW3ciE,25433
31
- imdclient/tests/test_lammps.py,sha256=hwZBVvhclN1mtPuYLyODUaWjlaZaAkhAFqX-mpQvWk4,2244
32
- imdclient/tests/test_manual.py,sha256=t5NeT1oPit9EMGxH4yG7hxnKQ24UEzZtR-vC1WOQAkc,8118
33
- imdclient/tests/test_namd.py,sha256=dFOJUQl9ByekuuYgUOIirf6qFj5_qaKfgQq4Qimtotw,3671
34
- imdclient/tests/test_stream_analysis.py,sha256=qqsm_Bv8qCXyNwgdSKZM8bLyiEO5nlpqJ-XtEn-YKew,1723
22
+ imdclient/tests/datafiles.py,sha256=G3Zsyuv3R6H0cpBoOuJQl0G_EAuuOLXzt9WvohHm33I,1497
23
+ imdclient/tests/minimalreader.py,sha256=84gvbule_6oRALO1bQAnrfECWcEkOz5NHHI0g18IXKk,2589
24
+ imdclient/tests/server.py,sha256=qmEJS53QNuz0SJAtKwPqTo7A59FZGt1IFHPBd4O_uC8,6619
25
+ imdclient/tests/test_gromacs.py,sha256=SMs3HkU2dScRsMae770TVbFJQzO_m6eoe6cvXxG5Rj0,1775
26
+ imdclient/tests/test_imdclient.py,sha256=JdEEG7qB-e1ro1BshPT6HJiW_aqyzCWRAF23N3lc1fs,7637
27
+ imdclient/tests/test_lammps.py,sha256=de5G8EHSh8AmTeEniPVnETYbBd1229K7UMtZ4oSp8wU,2341
28
+ imdclient/tests/test_manual.py,sha256=is4pnIUV_VuoywbQKjm8PICvEBGfMYcp8GqlsKX8JsU,8088
29
+ imdclient/tests/test_namd.py,sha256=GsViDL6xcNF4xruWbjNW-dU5F_ANIEZwGeMkiU88rcc,4417
30
+ imdclient/tests/test_utils.py,sha256=4T6pnOQshl8hkMkS_oT-o9v66Sx5ZiQi6OqWSGNQ7YY,880
35
31
  imdclient/tests/utils.py,sha256=_x1gVQ3AmhaMurpcEPLKBG5BTGu4ZMy5EGUpr0P6D6g,854
36
- imdclient/tests/docker_testing/docker.md,sha256=SxHEpSA1mXAvzYzsxL0EesGqPCVC8qdRMbvxGz5R0Yo,840
32
+ imdclient/tests/docker_testing/docker.md,sha256=wW42KFaGiO82RngNJg0yWPDwIQmgNcmhaUOdstvDgxE,840
37
33
  imdclient/tests/hpc_testing/gromacs/README.md,sha256=2SHVtIu5EyS8bwCMeWTZFgQoh1mmOwcBFjijzYDkj6k,2847
38
34
  imdclient/tests/hpc_testing/gromacs/gmx_gpu_test.mdp,sha256=BZl554WoHVi0bQq-Eb8UeYrdfum2TBHhtWFj4DxReCY,3050
39
35
  imdclient/tests/hpc_testing/gromacs/gmx_gpu_test.top,sha256=AXFEDjvz5Qqq-VECffimdeEvhD6L-H0SFPILW-6Sums,348329
40
36
  imdclient/tests/hpc_testing/gromacs/struct.gro,sha256=uT_Je8Jc37-o8gfkhFRH0PWcg3LOGkQj4ErSCkLMk00,1459301
41
37
  imdclient/tests/hpc_testing/gromacs/validate_gmx.sh,sha256=dszRgiWu-_9b4DxQP4u5x4Hi1liedjMG2YXQNURZQsQ,1938
42
- imdclient/tests/hpc_testing/lammps/README.md,sha256=Ek5z8H3gSxCoHg-gymMfmqKqi1URFvgRH4dYZuaC8Ro,1594
38
+ imdclient/tests/hpc_testing/lammps/README.md,sha256=Zatm6Wby2_tysDMrGPSLsfI7d79y1RfNDEBpk5mUXRo,1634
43
39
  imdclient/tests/hpc_testing/lammps/lammps_v3_nst_1.in,sha256=AcvkgNNDtTkB7RlFZwpUEKKp6W_7o_UFgrX_LwC3HXI,2586
44
40
  imdclient/tests/hpc_testing/lammps/topology_after_min.data,sha256=6CXJTFiVnnK6rKGK541sFYZ_6xjlkjebeWu0KPQl8Gc,172948
45
41
  imdclient/tests/hpc_testing/lammps/validate_lmp.sh,sha256=gqNFUvxLojBM1yrUHloL4FJm8pl4CNjTvgSYwh11pTc,1402
46
- imdclient/tests/hpc_testing/namd/README.md,sha256=fNnhQPcVS-wkG4aCtj7ru2CpoIMmxJFA9-9bGa9NQ2o,2103
42
+ imdclient/tests/hpc_testing/namd/README.md,sha256=9bL5jtgWifbhxqze3Y59aA6BJEdD7TkbacWm-Kh-6-I,3633
47
43
  imdclient/tests/hpc_testing/namd/alanin.params,sha256=zWw-UfqYD3-xpdA_8R8T-0OYBbUM6py7jKAq_uyu8HE,17389
48
44
  imdclient/tests/hpc_testing/namd/alanin.pdb,sha256=eccDD-ledUXjbB2s1fxY40lmAKWWDpxkxANbsOkqjHc,5615
49
45
  imdclient/tests/hpc_testing/namd/alanin.psf,sha256=VhCZeGFhpUa8yN5iEL19zlVjqIJg2JIdPzhazpRForY,12953
50
46
  imdclient/tests/hpc_testing/namd/namd_v3_nst_1.namd,sha256=EZU7PGyytZdGixrBnmpAcwonN0n_JTk9U-Q82FoqO7k,983
51
47
  imdclient/tests/hpc_testing/namd/validate_namd.sh,sha256=oMZNkY2p13q_4TJwepS5WjlT4xwxCoaZbDiWfLIWIvs,1543
52
- imdclient-0.1.4.dist-info/AUTHORS.md,sha256=R4JTI7mrgL1WYgfyuAv4quw0e0oLQGVjWcMQa-UXJlE,652
53
- imdclient-0.1.4.dist-info/LICENSE,sha256=28aS5DC2LCwcOVe3VN0g2L-Dooqof34T9TMGJ6jqMig,593
54
- imdclient-0.1.4.dist-info/METADATA,sha256=Uu9wpmeThDtEKtLPeqElgkG9R_DZSyxsIxzQUOjchds,6531
55
- imdclient-0.1.4.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
56
- imdclient-0.1.4.dist-info/top_level.txt,sha256=40W62GWiXUT2CbDm-No7GTeJG160wyIMpk1hBNrdkkE,10
57
- imdclient-0.1.4.dist-info/RECORD,,
48
+ imdclient-0.2.0b0.dist-info/licenses/AUTHORS.md,sha256=7GNvwDxWmGCYAB2BtazCCsBlHYWXMnpnWEiRL-XU53g,704
49
+ imdclient-0.2.0b0.dist-info/licenses/LICENSE,sha256=cTaJq_fhRiCQLCob0QRha2-437_8352CM36u14GQbZE,1060
50
+ imdclient-0.2.0b0.dist-info/METADATA,sha256=xEXouQ_n3pJ51CZUObT_n77nH6h3WzPeHfCNuL_Oeic,6095
51
+ imdclient-0.2.0b0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
52
+ imdclient-0.2.0b0.dist-info/top_level.txt,sha256=40W62GWiXUT2CbDm-No7GTeJG160wyIMpk1hBNrdkkE,10
53
+ imdclient-0.2.0b0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -4,7 +4,7 @@ IMDClient was created by Lawson in 2024.
4
4
 
5
5
 
6
6
  <!-- All contributing authors are listed in this file below.
7
- The repository history at https://github.com/becksteinlab/imdreader
7
+ The repository history at https://github.com/becksteinlab/imdclient
8
8
  and the CHANGELOG show individual code contributions. -->
9
9
 
10
10
  ## Chronological list of authors
@@ -19,5 +19,8 @@ The rules for this file:
19
19
  * Don't ever delete anything
20
20
  -->
21
21
 
22
+ **2025**
23
+ - Amruthesh Thirumalaiswamy <@amruthesht>
24
+
22
25
  **2024**
23
26
  - Lawson <@ljwoods2>
@@ -2,4 +2,6 @@ Copyright 2024 Lawson Woods
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
5
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
imdclient/IMD.py DELETED
@@ -1,132 +0,0 @@
1
- """
2
- MDAnalysis IMDReader
3
- ^^^^^^^^^^^^^^^^^^^^
4
-
5
- .. autoclass:: IMDReader
6
- :members:
7
- :inherited-members:
8
-
9
- """
10
-
11
- from MDAnalysis.coordinates import core
12
- from MDAnalysis.lib.util import store_init_arguments
13
-
14
- # NOTE: changeme
15
- from .IMDClient import IMDClient
16
- from .utils import *
17
- import logging
18
-
19
- from .streambase import StreamReaderBase
20
-
21
- logger = logging.getLogger("imdclient.IMDClient")
22
-
23
-
24
- class IMDReader(StreamReaderBase):
25
- """
26
- Reader for IMD protocol packets.
27
-
28
- Parameters
29
- ----------
30
- filename : a string of the form "host:port" where host is the hostname
31
- or IP address of the listening GROMACS server and port
32
- is the port number.
33
- n_atoms : int (optional)
34
- number of atoms in the system. defaults to number of atoms
35
- in the topology. don't set this unless you know what you're doing.
36
- kwargs : dict (optional)
37
- keyword arguments passed to the constructed :class:`IMDClient`
38
- """
39
-
40
- format = "IMD"
41
- one_pass = True
42
-
43
- @store_init_arguments
44
- def __init__(
45
- self,
46
- filename,
47
- convert_units=True,
48
- n_atoms=None,
49
- **kwargs,
50
- ):
51
- super(IMDReader, self).__init__(filename, **kwargs)
52
-
53
- self._imdclient = None
54
- logger.debug("IMDReader initializing")
55
-
56
- if n_atoms is None:
57
- raise ValueError("IMDReader: n_atoms must be specified")
58
- self.n_atoms = n_atoms
59
-
60
- host, port = parse_host_port(filename)
61
-
62
- # This starts the simulation
63
- self._imdclient = IMDClient(host, port, n_atoms, **kwargs)
64
-
65
- imdsinfo = self._imdclient.get_imdsessioninfo()
66
- # NOTE: after testing phase, fail out on IMDv2
67
-
68
- self.ts = self._Timestep(
69
- self.n_atoms,
70
- positions=imdsinfo.positions,
71
- velocities=imdsinfo.velocities,
72
- forces=imdsinfo.forces,
73
- **self._ts_kwargs,
74
- )
75
-
76
- self._frame = -1
77
-
78
- try:
79
- self._read_next_timestep()
80
- except StopIteration:
81
- raise RuntimeError("IMDReader: No data found in stream")
82
-
83
- def _read_frame(self, frame):
84
-
85
- try:
86
- imdf = self._imdclient.get_imdframe()
87
- except EOFError as e:
88
- raise e
89
-
90
- self._frame = frame
91
- self._load_imdframe_into_ts(imdf)
92
-
93
- logger.debug(f"IMDReader: Loaded frame {self._frame}")
94
- return self.ts
95
-
96
- def _load_imdframe_into_ts(self, imdf):
97
- self.ts.frame = self._frame
98
- if imdf.time is not None:
99
- self.ts.time = imdf.time
100
- # NOTE: timestep.pyx "dt" method is suspicious bc it uses "new" keyword for a float
101
- self.ts.data["dt"] = imdf.dt
102
- self.ts.data["step"] = imdf.step
103
- if imdf.energies is not None:
104
- self.ts.data.update(
105
- {k: v for k, v in imdf.energies.items() if k != "step"}
106
- )
107
- if imdf.box is not None:
108
- self.ts.dimensions = core.triclinic_box(*imdf.box)
109
- if imdf.positions is not None:
110
- # must call copy because reference is expected to reset
111
- # see 'test_frame_collect_all_same' in MDAnalysisTests.coordinates.base
112
- self.ts.positions = imdf.positions
113
- if imdf.velocities is not None:
114
- self.ts.velocities = imdf.velocities
115
- if imdf.forces is not None:
116
- self.ts.forces = imdf.forces
117
-
118
- @staticmethod
119
- def _format_hint(thing):
120
- try:
121
- parse_host_port(thing)
122
- except:
123
- return False
124
- return True
125
-
126
- def close(self):
127
- """Gracefully shut down the reader. Stops the producer thread."""
128
- logger.debug("IMDReader close() called")
129
- if self._imdclient is not None:
130
- self._imdclient.stop()
131
- # NOTE: removeme after testing
132
- logger.debug("IMDReader shut down gracefully.")
imdclient/backends.py DELETED
@@ -1,352 +0,0 @@
1
- # Copy of backends from MDA 2.8.0
2
- """Analysis backends --- :mod:`MDAnalysis.analysis.backends`
3
- ============================================================
4
-
5
- .. versionadded:: 2.8.0
6
-
7
-
8
- The :mod:`backends` module provides :class:`BackendBase` base class to
9
- implement custom execution backends for
10
- :meth:`MDAnalysis.analysis.base.AnalysisBase.run` and its
11
- subclasses.
12
-
13
- .. SeeAlso:: :ref:`parallel-analysis`
14
-
15
- .. _backends:
16
-
17
- Backends
18
- --------
19
-
20
- Three built-in backend classes are provided:
21
-
22
- * *serial*: :class:`BackendSerial`, that is equivalent to using no
23
- parallelization and is the default
24
-
25
- * *multiprocessing*: :class:`BackendMultiprocessing` that supports
26
- parallelization via standard Python :mod:`multiprocessing` module
27
- and uses default :mod:`pickle` serialization
28
-
29
- * *dask*: :class:`BackendDask`, that uses the same process-based
30
- parallelization as :class:`BackendMultiprocessing`, but different
31
- serialization algorithm via `dask <https://dask.org/>`_ (see `dask
32
- serialization algorithms
33
- <https://distributed.dask.org/en/latest/serialization.html>`_ for details)
34
-
35
- Classes
36
- -------
37
-
38
- """
39
- import warnings
40
- from typing import Callable
41
- import importlib.util
42
-
43
-
44
- def is_installed(modulename: str):
45
- """Checks if module is installed
46
-
47
- Parameters
48
- ----------
49
- modulename : str
50
- name of the module to be tested
51
-
52
-
53
- .. versionadded:: 2.8.0
54
- """
55
- return importlib.util.find_spec(modulename) is not None
56
-
57
-
58
- class BackendBase:
59
- """Base class for backend implementation.
60
-
61
- Initializes an instance and performs checks for its validity, such as
62
- ``n_workers`` and possibly other ones.
63
-
64
- Parameters
65
- ----------
66
- n_workers : int
67
- number of workers (usually, processes) over which the work is split
68
-
69
- Examples
70
- --------
71
- .. code-block:: python
72
-
73
- from MDAnalysis.analysis.backends import BackendBase
74
-
75
- class ThreadsBackend(BackendBase):
76
- def apply(self, func, computations):
77
- from multiprocessing.dummy import Pool
78
-
79
- with Pool(processes=self.n_workers) as pool:
80
- results = pool.map(func, computations)
81
- return results
82
-
83
- import MDAnalysis as mda
84
- from MDAnalysis.tests.datafiles import PSF, DCD
85
- from MDAnalysis.analysis.rms import RMSD
86
-
87
- u = mda.Universe(PSF, DCD)
88
- ref = mda.Universe(PSF, DCD)
89
-
90
- R = RMSD(u, ref)
91
-
92
- n_workers = 2
93
- backend = ThreadsBackend(n_workers=n_workers)
94
- R.run(backend=backend, unsupported_backend=True)
95
-
96
- .. warning::
97
- Using `ThreadsBackend` above will lead to erroneous results, since it
98
- is an educational example. Do not use it for real analysis.
99
-
100
-
101
- .. versionadded:: 2.8.0
102
-
103
- """
104
-
105
- def __init__(self, n_workers: int):
106
- self.n_workers = n_workers
107
- self._validate()
108
-
109
- def _get_checks(self):
110
- """Get dictionary with ``condition: error_message`` pairs that ensure the
111
- validity of the backend instance
112
-
113
- Returns
114
- -------
115
- dict
116
- dictionary with ``condition: error_message`` pairs that will get
117
- checked during ``_validate()`` run
118
- """
119
- return {
120
- isinstance(self.n_workers, int)
121
- and self.n_workers
122
- > 0: f"n_workers should be positive integer, got {self.n_workers=}",
123
- }
124
-
125
- def _get_warnings(self):
126
- """Get dictionary with ``condition: warning_message`` pairs that ensure
127
- the good usage of the backend instance
128
-
129
- Returns
130
- -------
131
- dict
132
- dictionary with ``condition: warning_message`` pairs that will get
133
- checked during ``_validate()`` run
134
- """
135
- return dict()
136
-
137
- def _validate(self):
138
- """Check correctness (e.g. ``dask`` is installed if using ``backend='dask'``)
139
- and good usage (e.g. ``n_workers=1`` if backend is serial) of the backend
140
-
141
- Raises
142
- ------
143
- ValueError
144
- if one of the conditions in :meth:`_get_checks` is ``True``
145
- """
146
- for check, msg in self._get_checks().items():
147
- if not check:
148
- raise ValueError(msg)
149
- for check, msg in self._get_warnings().items():
150
- if not check:
151
- warnings.warn(msg)
152
-
153
- def apply(self, func: Callable, computations: list) -> list:
154
- """map function `func` to all tasks in the `computations` list
155
-
156
- Main method that will get called when using an instance of
157
- ``BackendBase``. It is equivalent to running ``[func(item) for item in
158
- computations]`` while using the parallel backend capabilities.
159
-
160
- Parameters
161
- ----------
162
- func : Callable
163
- function to be called on each of the tasks in computations list
164
- computations : list
165
- computation tasks to apply function to
166
-
167
- Returns
168
- -------
169
- list
170
- list of results of the function
171
-
172
- """
173
- raise NotImplementedError
174
-
175
-
176
- class BackendSerial(BackendBase):
177
- """A built-in backend that does serial execution of the function, without any
178
- parallelization.
179
-
180
- Parameters
181
- ----------
182
- n_workers : int
183
- Is ignored in this class, and if ``n_workers`` > 1, a warning will be
184
- given.
185
-
186
-
187
- .. versionadded:: 2.8.0
188
- """
189
-
190
- def _get_warnings(self):
191
- """Get dictionary with ``condition: warning_message`` pairs that ensure
192
- the good usage of the backend instance. Here, it checks if the number
193
- of workers is not 1, otherwise gives warning.
194
-
195
- Returns
196
- -------
197
- dict
198
- dictionary with ``condition: warning_message`` pairs that will get
199
- checked during ``_validate()`` run
200
- """
201
- return {
202
- self.n_workers
203
- == 1: "n_workers is ignored when executing with backend='serial'"
204
- }
205
-
206
- def apply(self, func: Callable, computations: list) -> list:
207
- """
208
- Serially applies `func` to each task object in ``computations``.
209
-
210
- Parameters
211
- ----------
212
- func : Callable
213
- function to be called on each of the tasks in computations list
214
- computations : list
215
- computation tasks to apply function to
216
-
217
- Returns
218
- -------
219
- list
220
- list of results of the function
221
- """
222
- return [func(task) for task in computations]
223
-
224
-
225
- class BackendMultiprocessing(BackendBase):
226
- """A built-in backend that executes a given function using the
227
- :meth:`multiprocessing.Pool.map <multiprocessing.pool.Pool.map>` method.
228
-
229
- Parameters
230
- ----------
231
- n_workers : int
232
- number of processes in :class:`multiprocessing.Pool
233
- <multiprocessing.pool.Pool>` to distribute the workload
234
- between. Must be a positive integer.
235
-
236
- Examples
237
- --------
238
-
239
- .. code-block:: python
240
-
241
- from MDAnalysis.analysis.backends import BackendMultiprocessing
242
- import multiprocessing as mp
243
-
244
- backend_obj = BackendMultiprocessing(n_workers=mp.cpu_count())
245
-
246
-
247
- .. versionadded:: 2.8.0
248
-
249
- """
250
-
251
- def apply(self, func: Callable, computations: list) -> list:
252
- """Applies `func` to each object in ``computations`` using `multiprocessing`'s `Pool.map`.
253
-
254
- Parameters
255
- ----------
256
- func : Callable
257
- function to be called on each of the tasks in computations list
258
- computations : list
259
- computation tasks to apply function to
260
-
261
- Returns
262
- -------
263
- list
264
- list of results of the function
265
- """
266
- from multiprocessing import Pool
267
-
268
- with Pool(processes=self.n_workers) as pool:
269
- results = pool.map(func, computations)
270
- return results
271
-
272
-
273
- class BackendDask(BackendBase):
274
- """A built-in backend that executes a given function with *dask*.
275
-
276
- Execution is performed with the :func:`dask.compute` function of
277
- :class:`dask.delayed.Delayed` object (created with
278
- :func:`dask.delayed.delayed`) with ``scheduler='processes'`` and
279
- ``chunksize=1`` (this ensures uniform distribution of tasks among
280
- processes). Requires the `dask package <https://docs.dask.org/en/stable/>`_
281
- to be `installed <https://docs.dask.org/en/stable/install.html>`_.
282
-
283
- Parameters
284
- ----------
285
- n_workers : int
286
- number of processes in to distribute the workload
287
- between. Must be a positive integer. Workers are actually
288
- :class:`multiprocessing.pool.Pool` processes, but they use a different and
289
- more flexible `serialization protocol
290
- <https://docs.dask.org/en/stable/phases-of-computation.html#graph-serialization>`_.
291
-
292
- Examples
293
- --------
294
-
295
- .. code-block:: python
296
-
297
- from MDAnalysis.analysis.backends import BackendDask
298
- import multiprocessing as mp
299
-
300
- backend_obj = BackendDask(n_workers=mp.cpu_count())
301
-
302
-
303
- .. versionadded:: 2.8.0
304
-
305
- """
306
-
307
- def apply(self, func: Callable, computations: list) -> list:
308
- """Applies `func` to each object in ``computations``.
309
-
310
- Parameters
311
- ----------
312
- func : Callable
313
- function to be called on each of the tasks in computations list
314
- computations : list
315
- computation tasks to apply function to
316
-
317
- Returns
318
- -------
319
- list
320
- list of results of the function
321
- """
322
- from dask.delayed import delayed
323
- import dask
324
-
325
- computations = [delayed(func)(task) for task in computations]
326
- results = dask.compute(
327
- computations,
328
- scheduler="processes",
329
- chunksize=1,
330
- num_workers=self.n_workers,
331
- )[0]
332
- return results
333
-
334
- def _get_checks(self):
335
- """Get dictionary with ``condition: error_message`` pairs that ensure the
336
- validity of the backend instance. Here checks if ``dask`` module is
337
- installed in the environment.
338
-
339
- Returns
340
- -------
341
- dict
342
- dictionary with ``condition: error_message`` pairs that will get
343
- checked during ``_validate()`` run
344
- """
345
- base_checks = super()._get_checks()
346
- checks = {
347
- is_installed("dask"): (
348
- "module 'dask' is missing. Please install 'dask': "
349
- "https://docs.dask.org/en/stable/install.html"
350
- )
351
- }
352
- return base_checks | checks