imdclient 0.1.0__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.
- imdclient/IMDClient.py +896 -0
- imdclient/IMDProtocol.py +164 -0
- imdclient/IMDREADER.py +129 -0
- imdclient/__init__.py +14 -0
- imdclient/backends.py +352 -0
- imdclient/data/__init__.py +0 -0
- imdclient/data/gromacs/md/gromacs_struct.gro +21151 -0
- imdclient/data/gromacs/md/gromacs_v3.top +11764 -0
- imdclient/data/gromacs/md/gromacs_v3_nst1.mdp +58 -0
- imdclient/data/gromacs/md/gromacs_v3_nst1.tpr +0 -0
- imdclient/data/gromacs/md/gromacs_v3_nst1.trr +0 -0
- imdclient/data/lammps/md/lammps_topol.data +8022 -0
- imdclient/data/lammps/md/lammps_trj.h5md +0 -0
- imdclient/data/lammps/md/lammps_v3.in +71 -0
- imdclient/data/namd/md/alanin.dcd +0 -0
- imdclient/data/namd/md/alanin.params +402 -0
- imdclient/data/namd/md/alanin.pdb +77 -0
- imdclient/data/namd/md/alanin.psf +206 -0
- imdclient/data/namd/md/namd_v3.namd +47 -0
- imdclient/results.py +332 -0
- imdclient/streamanalysis.py +1056 -0
- imdclient/streambase.py +199 -0
- imdclient/tests/__init__.py +0 -0
- imdclient/tests/base.py +122 -0
- imdclient/tests/conftest.py +38 -0
- imdclient/tests/datafiles.py +34 -0
- imdclient/tests/server.py +212 -0
- imdclient/tests/test_gromacs.py +33 -0
- imdclient/tests/test_imdclient.py +150 -0
- imdclient/tests/test_imdreader.py +644 -0
- imdclient/tests/test_lammps.py +38 -0
- imdclient/tests/test_manual.py +70 -0
- imdclient/tests/test_namd.py +38 -0
- imdclient/tests/test_stream_analysis.py +61 -0
- imdclient/tests/utils.py +41 -0
- imdclient/utils.py +118 -0
- imdclient-0.1.0.dist-info/AUTHORS.md +23 -0
- imdclient-0.1.0.dist-info/LICENSE +21 -0
- imdclient-0.1.0.dist-info/METADATA +143 -0
- imdclient-0.1.0.dist-info/RECORD +42 -0
- imdclient-0.1.0.dist-info/WHEEL +5 -0
- imdclient-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,206 @@
|
|
1
|
+
PSF
|
2
|
+
|
3
|
+
11 !NTITLE
|
4
|
+
REMARKS FILENAME="/usr/people/nonella/xplor/benchmark1/ALANIN.PSF"
|
5
|
+
REMARKS PARAM11.PRO ( from PARAM6A )
|
6
|
+
REMARKS ===========
|
7
|
+
REMARKS PROTEIN PARAMETERS:
|
8
|
+
REMARKS PEPTIDE GEOMETRY FROM RAMACHANDRAN ET AL BBA 359:298 (1974)
|
9
|
+
REMARKS TORSIONS FROM HAGLER ET AL JACS 98:4600 (1976)
|
10
|
+
REMARKS LENNARD-JONES NONBONDED PARAMETERS WITH SPECIAL TREATMENT OF 1:4
|
11
|
+
REMARKS CARBON-CARBON INTERACTIONS: JORGENSON ET. AL.
|
12
|
+
REMARKS JACS 103:3976-3985 WITH 1-4 RC=1.80/0.1
|
13
|
+
REMARKS
|
14
|
+
REMARKS DATE:16-Feb-89 11:21:29 created by user: nonella
|
15
|
+
|
16
|
+
66 !NATOM
|
17
|
+
1 MAIN 1 ACE CA CH3E 0.000000E+00 15.0350 0
|
18
|
+
2 MAIN 1 ACE C C 0.450000 12.0110 0
|
19
|
+
3 MAIN 1 ACE O O -0.450000 15.9994 0
|
20
|
+
4 MAIN 2 ALA N NH1 -0.350000 14.0067 0
|
21
|
+
5 MAIN 2 ALA H H 0.250000 1.00800 0
|
22
|
+
6 MAIN 2 ALA CA CH1E 0.100000 13.0190 0
|
23
|
+
7 MAIN 2 ALA CB CH3E 0.000000E+00 15.0350 0
|
24
|
+
8 MAIN 2 ALA C C 0.450000 12.0110 0
|
25
|
+
9 MAIN 2 ALA O O -0.450000 15.9994 0
|
26
|
+
10 MAIN 3 ALA N NH1 -0.350000 14.0067 0
|
27
|
+
11 MAIN 3 ALA H H 0.250000 1.00800 0
|
28
|
+
12 MAIN 3 ALA CA CH1E 0.100000 13.0190 0
|
29
|
+
13 MAIN 3 ALA CB CH3E 0.000000E+00 15.0350 0
|
30
|
+
14 MAIN 3 ALA C C 0.450000 12.0110 0
|
31
|
+
15 MAIN 3 ALA O O -0.450000 15.9994 0
|
32
|
+
16 MAIN 4 ALA N NH1 -0.350000 14.0067 0
|
33
|
+
17 MAIN 4 ALA H H 0.250000 1.00800 0
|
34
|
+
18 MAIN 4 ALA CA CH1E 0.100000 13.0190 0
|
35
|
+
19 MAIN 4 ALA CB CH3E 0.000000E+00 15.0350 0
|
36
|
+
20 MAIN 4 ALA C C 0.450000 12.0110 0
|
37
|
+
21 MAIN 4 ALA O O -0.450000 15.9994 0
|
38
|
+
22 MAIN 5 ALA N NH1 -0.350000 14.0067 0
|
39
|
+
23 MAIN 5 ALA H H 0.250000 1.00800 0
|
40
|
+
24 MAIN 5 ALA CA CH1E 0.100000 13.0190 0
|
41
|
+
25 MAIN 5 ALA CB CH3E 0.000000E+00 15.0350 0
|
42
|
+
26 MAIN 5 ALA C C 0.450000 12.0110 0
|
43
|
+
27 MAIN 5 ALA O O -0.450000 15.9994 0
|
44
|
+
28 MAIN 6 ALA N NH1 -0.350000 14.0067 0
|
45
|
+
29 MAIN 6 ALA H H 0.250000 1.00800 0
|
46
|
+
30 MAIN 6 ALA CA CH1E 0.100000 13.0190 0
|
47
|
+
31 MAIN 6 ALA CB CH3E 0.000000E+00 15.0350 0
|
48
|
+
32 MAIN 6 ALA C C 0.450000 12.0110 0
|
49
|
+
33 MAIN 6 ALA O O -0.450000 15.9994 0
|
50
|
+
34 MAIN 7 ALA N NH1 -0.350000 14.0067 0
|
51
|
+
35 MAIN 7 ALA H H 0.250000 1.00800 0
|
52
|
+
36 MAIN 7 ALA CA CH1E 0.100000 13.0190 0
|
53
|
+
37 MAIN 7 ALA CB CH3E 0.000000E+00 15.0350 0
|
54
|
+
38 MAIN 7 ALA C C 0.450000 12.0110 0
|
55
|
+
39 MAIN 7 ALA O O -0.450000 15.9994 0
|
56
|
+
40 MAIN 8 ALA N NH1 -0.350000 14.0067 0
|
57
|
+
41 MAIN 8 ALA H H 0.250000 1.00800 0
|
58
|
+
42 MAIN 8 ALA CA CH1E 0.100000 13.0190 0
|
59
|
+
43 MAIN 8 ALA CB CH3E 0.000000E+00 15.0350 0
|
60
|
+
44 MAIN 8 ALA C C 0.450000 12.0110 0
|
61
|
+
45 MAIN 8 ALA O O -0.450000 15.9994 0
|
62
|
+
46 MAIN 9 ALA N NH1 -0.350000 14.0067 0
|
63
|
+
47 MAIN 9 ALA H H 0.250000 1.00800 0
|
64
|
+
48 MAIN 9 ALA CA CH1E 0.100000 13.0190 0
|
65
|
+
49 MAIN 9 ALA CB CH3E 0.000000E+00 15.0350 0
|
66
|
+
50 MAIN 9 ALA C C 0.450000 12.0110 0
|
67
|
+
51 MAIN 9 ALA O O -0.450000 15.9994 0
|
68
|
+
52 MAIN 10 ALA N NH1 -0.350000 14.0067 0
|
69
|
+
53 MAIN 10 ALA H H 0.250000 1.00800 0
|
70
|
+
54 MAIN 10 ALA CA CH1E 0.100000 13.0190 0
|
71
|
+
55 MAIN 10 ALA CB CH3E 0.000000E+00 15.0350 0
|
72
|
+
56 MAIN 10 ALA C C 0.450000 12.0110 0
|
73
|
+
57 MAIN 10 ALA O O -0.450000 15.9994 0
|
74
|
+
58 MAIN 11 ALA N NH1 -0.350000 14.0067 0
|
75
|
+
59 MAIN 11 ALA H H 0.250000 1.00800 0
|
76
|
+
60 MAIN 11 ALA CA CH1E 0.100000 13.0190 0
|
77
|
+
61 MAIN 11 ALA CB CH3E 0.000000E+00 15.0350 0
|
78
|
+
62 MAIN 11 ALA C C 0.450000 12.0110 0
|
79
|
+
63 MAIN 11 ALA O O -0.450000 15.9994 0
|
80
|
+
64 MAIN 12 CBX N NH1 -0.350000 14.0067 0
|
81
|
+
65 MAIN 12 CBX H H 0.250000 1.00800 0
|
82
|
+
66 MAIN 12 CBX CA CH3E 0.100000 15.0350 0
|
83
|
+
|
84
|
+
65 !NBOND: bonds
|
85
|
+
1 2 2 3 4 6 6 8
|
86
|
+
8 9 4 5 6 7 2 4
|
87
|
+
10 12 12 14 14 15 10 11
|
88
|
+
12 13 8 10 16 18 18 20
|
89
|
+
20 21 16 17 18 19 14 16
|
90
|
+
22 24 24 26 26 27 22 23
|
91
|
+
24 25 20 22 28 30 30 32
|
92
|
+
32 33 28 29 30 31 26 28
|
93
|
+
34 36 36 38 38 39 34 35
|
94
|
+
36 37 32 34 40 42 42 44
|
95
|
+
44 45 40 41 42 43 38 40
|
96
|
+
46 48 48 50 50 51 46 47
|
97
|
+
48 49 44 46 52 54 54 56
|
98
|
+
56 57 52 53 54 55 50 52
|
99
|
+
58 60 60 62 62 63 58 59
|
100
|
+
60 61 56 58 64 66 64 65
|
101
|
+
62 64
|
102
|
+
|
103
|
+
96 !NTHETA: angles
|
104
|
+
1 2 3 4 6 8 6 4 5
|
105
|
+
4 6 7 6 8 9 8 6 7
|
106
|
+
1 2 4 3 2 4 2 4 6
|
107
|
+
2 4 5 10 12 14 12 10 11
|
108
|
+
10 12 13 12 14 15 14 12 13
|
109
|
+
6 8 10 9 8 10 8 10 12
|
110
|
+
8 10 11 16 18 20 18 16 17
|
111
|
+
16 18 19 18 20 21 20 18 19
|
112
|
+
12 14 16 15 14 16 14 16 18
|
113
|
+
14 16 17 22 24 26 24 22 23
|
114
|
+
22 24 25 24 26 27 26 24 25
|
115
|
+
18 20 22 21 20 22 20 22 24
|
116
|
+
20 22 23 28 30 32 30 28 29
|
117
|
+
28 30 31 30 32 33 32 30 31
|
118
|
+
24 26 28 27 26 28 26 28 30
|
119
|
+
26 28 29 34 36 38 36 34 35
|
120
|
+
34 36 37 36 38 39 38 36 37
|
121
|
+
30 32 34 33 32 34 32 34 36
|
122
|
+
32 34 35 40 42 44 42 40 41
|
123
|
+
40 42 43 42 44 45 44 42 43
|
124
|
+
36 38 40 39 38 40 38 40 42
|
125
|
+
38 40 41 46 48 50 48 46 47
|
126
|
+
46 48 49 48 50 51 50 48 49
|
127
|
+
42 44 46 45 44 46 44 46 48
|
128
|
+
44 46 47 52 54 56 54 52 53
|
129
|
+
52 54 55 54 56 57 56 54 55
|
130
|
+
48 50 52 51 50 52 50 52 54
|
131
|
+
50 52 53 58 60 62 60 58 59
|
132
|
+
58 60 61 60 62 63 62 60 61
|
133
|
+
54 56 58 57 56 58 56 58 60
|
134
|
+
56 58 59 66 64 65 60 62 64
|
135
|
+
63 62 64 62 64 66 62 64 65
|
136
|
+
|
137
|
+
31 !NPHI: dihedrals
|
138
|
+
2 4 6 8 1 2 4 6
|
139
|
+
8 10 12 14 4 6 8 10
|
140
|
+
6 8 10 12 14 16 18 20
|
141
|
+
10 12 14 16 12 14 16 18
|
142
|
+
20 22 24 26 16 18 20 22
|
143
|
+
18 20 22 24 26 28 30 32
|
144
|
+
22 24 26 28 24 26 28 30
|
145
|
+
32 34 36 38 28 30 32 34
|
146
|
+
30 32 34 36 38 40 42 44
|
147
|
+
34 36 38 40 36 38 40 42
|
148
|
+
44 46 48 50 40 42 44 46
|
149
|
+
42 44 46 48 50 52 54 56
|
150
|
+
46 48 50 52 48 50 52 54
|
151
|
+
56 58 60 62 52 54 56 58
|
152
|
+
54 56 58 60 58 60 62 64
|
153
|
+
60 62 64 66
|
154
|
+
|
155
|
+
32 !NIMPHI: impropers
|
156
|
+
6 4 8 7 2 1 4 3
|
157
|
+
4 2 6 5 12 10 14 13
|
158
|
+
8 6 10 9 10 8 12 11
|
159
|
+
18 16 20 19 14 12 16 15
|
160
|
+
16 14 18 17 24 22 26 25
|
161
|
+
20 18 22 21 22 20 24 23
|
162
|
+
30 28 32 31 26 24 28 27
|
163
|
+
28 26 30 29 36 34 38 37
|
164
|
+
32 30 34 33 34 32 36 35
|
165
|
+
42 40 44 43 38 36 40 39
|
166
|
+
40 38 42 41 48 46 50 49
|
167
|
+
44 42 46 45 46 44 48 47
|
168
|
+
54 52 56 55 50 48 52 51
|
169
|
+
52 50 54 53 60 58 62 61
|
170
|
+
56 54 58 57 58 56 60 59
|
171
|
+
62 60 64 63 64 62 66 65
|
172
|
+
|
173
|
+
11 !NDON: donors
|
174
|
+
4 5 10 11 16 17 22 23
|
175
|
+
28 29 34 35 40 41 46 47
|
176
|
+
52 53 58 59 64 65
|
177
|
+
|
178
|
+
11 !NACC: acceptors
|
179
|
+
3 2 9 8 15 14 21 20
|
180
|
+
27 26 33 32 39 38 45 44
|
181
|
+
51 50 57 56 63 62
|
182
|
+
|
183
|
+
0 !NNB
|
184
|
+
|
185
|
+
0 0 0 0 0 0 0 0
|
186
|
+
0 0 0 0 0 0 0 0
|
187
|
+
0 0 0 0 0 0 0 0
|
188
|
+
0 0 0 0 0 0 0 0
|
189
|
+
0 0 0 0 0 0 0 0
|
190
|
+
0 0 0 0 0 0 0 0
|
191
|
+
0 0 0 0 0 0 0 0
|
192
|
+
0 0 0 0 0 0 0 0
|
193
|
+
0 0
|
194
|
+
|
195
|
+
33 0 !NGRP
|
196
|
+
0 0 0 1 0 0 3 0 0
|
197
|
+
6 0 0 7 0 0 9 0 0
|
198
|
+
12 0 0 13 0 0 15 0 0
|
199
|
+
18 0 0 19 0 0 21 0 0
|
200
|
+
24 0 0 25 0 0 27 0 0
|
201
|
+
30 0 0 31 0 0 33 0 0
|
202
|
+
36 0 0 37 0 0 39 0 0
|
203
|
+
42 0 0 43 0 0 45 0 0
|
204
|
+
48 0 0 49 0 0 51 0 0
|
205
|
+
54 0 0 55 0 0 57 0 0
|
206
|
+
60 0 0 61 0 0 63 0 0
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# This is a test namd configuration file
|
2
|
+
|
3
|
+
timestep 0.5
|
4
|
+
numsteps 10
|
5
|
+
structure alanin.psf
|
6
|
+
parameters alanin.params
|
7
|
+
coordinates alanin.pdb
|
8
|
+
exclude scaled1-4
|
9
|
+
1-4scaling 0.4
|
10
|
+
outputname output[myReplica]
|
11
|
+
margin 1.0
|
12
|
+
stepspercycle 3
|
13
|
+
temperature 0
|
14
|
+
|
15
|
+
switching on
|
16
|
+
switchdist 7.0
|
17
|
+
cutoff 8.0
|
18
|
+
pairlistdist 9.0
|
19
|
+
|
20
|
+
dcdfile alanin.dcd
|
21
|
+
dcdfreq 1
|
22
|
+
|
23
|
+
#restartname alanin.restart
|
24
|
+
#restartfreq 10
|
25
|
+
|
26
|
+
#langevin on
|
27
|
+
#langevinTemp 300.0
|
28
|
+
#langevincol O
|
29
|
+
|
30
|
+
#constraints on
|
31
|
+
|
32
|
+
#fma on
|
33
|
+
|
34
|
+
seed 12345
|
35
|
+
|
36
|
+
IMDon yes
|
37
|
+
IMDport 8888
|
38
|
+
IMDfreq 1
|
39
|
+
IMDwait on
|
40
|
+
IMDversion 3
|
41
|
+
IMDsendPositions yes
|
42
|
+
IMDsendEnergies yes
|
43
|
+
#IMDsendTime yes
|
44
|
+
#IMDsendBoxDimensions yes
|
45
|
+
IMDsendVelocities yes
|
46
|
+
#IMDsendForces yes
|
47
|
+
IMDwrapPositions yes
|
imdclient/results.py
ADDED
@@ -0,0 +1,332 @@
|
|
1
|
+
# Copy of MDAnalysis.analysis.results from 2.8.0
|
2
|
+
|
3
|
+
"""Analysis results and their aggregation --- :mod:`MDAnalysis.analysis.results`
|
4
|
+
================================================================================
|
5
|
+
|
6
|
+
Module introduces two classes, :class:`Results` and :class:`ResultsGroup`,
|
7
|
+
used for storing and aggregating data in
|
8
|
+
:meth:`MDAnalysis.analysis.base.AnalysisBase.run()`, respectively.
|
9
|
+
|
10
|
+
|
11
|
+
Classes
|
12
|
+
-------
|
13
|
+
|
14
|
+
The :class:`Results` class is an extension of a built-in dictionary
|
15
|
+
type, that holds all assigned attributes in :attr:`self.data` and
|
16
|
+
allows for access either via dict-like syntax, or via class-like syntax:
|
17
|
+
|
18
|
+
.. code-block:: python
|
19
|
+
|
20
|
+
from MDAnalysis.analysis.results import Results
|
21
|
+
r = Results()
|
22
|
+
r.array = [1, 2, 3, 4]
|
23
|
+
assert r['array'] == r.array == [1, 2, 3, 4]
|
24
|
+
|
25
|
+
|
26
|
+
The :class:`ResultsGroup` can merge multiple :class:`Results` objects.
|
27
|
+
It is mainly used by :class:`MDAnalysis.analysis.base.AnalysisBase` class,
|
28
|
+
that uses :meth:`ResultsGroup.merge()` method to aggregate results from
|
29
|
+
multiple workers, initialized during a parallel run:
|
30
|
+
|
31
|
+
.. code-block:: python
|
32
|
+
|
33
|
+
from MDAnalysis.analysis.results import Results, ResultsGroup
|
34
|
+
import numpy as np
|
35
|
+
|
36
|
+
r1, r2 = Results(), Results()
|
37
|
+
r1.masses = [1, 2, 3, 4, 5]
|
38
|
+
r2.masses = [0, 0, 0, 0]
|
39
|
+
r1.vectors = np.arange(10).reshape(5, 2)
|
40
|
+
r2.vectors = np.arange(8).reshape(4, 2)
|
41
|
+
|
42
|
+
group = ResultsGroup(
|
43
|
+
lookup = {
|
44
|
+
'masses': ResultsGroup.flatten_sequence,
|
45
|
+
'vectors': ResultsGroup.ndarray_vstack
|
46
|
+
}
|
47
|
+
)
|
48
|
+
|
49
|
+
r = group.merge([r1, r2])
|
50
|
+
assert r.masses == list((*r1.masses, *r2.masses))
|
51
|
+
assert (r.vectors == np.vstack([r1.vectors, r2.vectors])).all()
|
52
|
+
"""
|
53
|
+
|
54
|
+
from collections import UserDict
|
55
|
+
import numpy as np
|
56
|
+
from typing import Callable, Sequence
|
57
|
+
|
58
|
+
|
59
|
+
class Results(UserDict):
|
60
|
+
r"""Container object for storing results.
|
61
|
+
|
62
|
+
:class:`Results` are dictionaries that provide two ways by which values
|
63
|
+
can be accessed: by dictionary key ``results["value_key"]`` or by object
|
64
|
+
attribute, ``results.value_key``. :class:`Results` stores all results
|
65
|
+
obtained from an analysis after calling :meth:`~AnalysisBase.run()`.
|
66
|
+
|
67
|
+
The implementation is similar to the :class:`sklearn.utils.Bunch`
|
68
|
+
class in `scikit-learn`_.
|
69
|
+
|
70
|
+
.. _`scikit-learn`: https://scikit-learn.org/
|
71
|
+
.. _`sklearn.utils.Bunch`: https://scikit-learn.org/stable/modules/generated/sklearn.utils.Bunch.html
|
72
|
+
|
73
|
+
Raises
|
74
|
+
------
|
75
|
+
AttributeError
|
76
|
+
If an assigned attribute has the same name as a default attribute.
|
77
|
+
|
78
|
+
ValueError
|
79
|
+
If a key is not of type ``str`` and therefore is not able to be
|
80
|
+
accessed by attribute.
|
81
|
+
|
82
|
+
Examples
|
83
|
+
--------
|
84
|
+
>>> from MDAnalysis.analysis.base import Results
|
85
|
+
>>> results = Results(a=1, b=2)
|
86
|
+
>>> results['b']
|
87
|
+
2
|
88
|
+
>>> results.b
|
89
|
+
2
|
90
|
+
>>> results.a = 3
|
91
|
+
>>> results['a']
|
92
|
+
3
|
93
|
+
>>> results.c = [1, 2, 3, 4]
|
94
|
+
>>> results['c']
|
95
|
+
[1, 2, 3, 4]
|
96
|
+
|
97
|
+
|
98
|
+
.. versionadded:: 2.0.0
|
99
|
+
|
100
|
+
.. versionchanged:: 2.8.0
|
101
|
+
Moved :class:`Results` to :mod:`MDAnalysis.analysis.results`
|
102
|
+
"""
|
103
|
+
|
104
|
+
def _validate_key(self, key):
|
105
|
+
if key in dir(self):
|
106
|
+
raise AttributeError(
|
107
|
+
f"'{key}' is a protected dictionary attribute"
|
108
|
+
)
|
109
|
+
elif isinstance(key, str) and not key.isidentifier():
|
110
|
+
raise ValueError(f"'{key}' is not a valid attribute")
|
111
|
+
|
112
|
+
def __init__(self, *args, **kwargs):
|
113
|
+
kwargs = dict(*args, **kwargs)
|
114
|
+
if "data" in kwargs.keys():
|
115
|
+
raise AttributeError(f"'data' is a protected dictionary attribute")
|
116
|
+
self.__dict__["data"] = {}
|
117
|
+
self.update(kwargs)
|
118
|
+
|
119
|
+
def __setitem__(self, key, item):
|
120
|
+
self._validate_key(key)
|
121
|
+
super().__setitem__(key, item)
|
122
|
+
|
123
|
+
def __setattr__(self, attr, val):
|
124
|
+
if attr == "data":
|
125
|
+
super().__setattr__(attr, val)
|
126
|
+
else:
|
127
|
+
self.__setitem__(attr, val)
|
128
|
+
|
129
|
+
def __getattr__(self, attr):
|
130
|
+
try:
|
131
|
+
return self[attr]
|
132
|
+
except KeyError as err:
|
133
|
+
raise AttributeError(
|
134
|
+
f"'Results' object has no attribute '{attr}'"
|
135
|
+
) from err
|
136
|
+
|
137
|
+
def __delattr__(self, attr):
|
138
|
+
try:
|
139
|
+
del self[attr]
|
140
|
+
except KeyError as err:
|
141
|
+
raise AttributeError(
|
142
|
+
f"'Results' object has no attribute '{attr}'"
|
143
|
+
) from err
|
144
|
+
|
145
|
+
def __getstate__(self):
|
146
|
+
return self.data
|
147
|
+
|
148
|
+
def __setstate__(self, state):
|
149
|
+
self.data = state
|
150
|
+
|
151
|
+
|
152
|
+
class ResultsGroup:
|
153
|
+
"""
|
154
|
+
Management and aggregation of results stored in :class:`Results` instances.
|
155
|
+
|
156
|
+
A :class:`ResultsGroup` is an optional description for :class:`Result` "dictionaries"
|
157
|
+
that are used in analysis classes based on :class:`AnalysisBase`. For each *key* in a
|
158
|
+
:class:`Result` it describes how multiple pieces of the data held under the key are
|
159
|
+
to be aggregated. This approach is necessary when parts of a trajectory are analyzed
|
160
|
+
independently (e.g., in parallel) and then need to me merged (with :meth:`merge`) to
|
161
|
+
obtain a complete data set.
|
162
|
+
|
163
|
+
Parameters
|
164
|
+
----------
|
165
|
+
lookup : dict[str, Callable], optional
|
166
|
+
aggregation functions lookup dict, by default None
|
167
|
+
|
168
|
+
Examples
|
169
|
+
--------
|
170
|
+
|
171
|
+
.. code-block:: python
|
172
|
+
|
173
|
+
from MDAnalysis.analysis.results import ResultsGroup, Results
|
174
|
+
group = ResultsGroup(lookup={'mass': ResultsGroup.float_mean})
|
175
|
+
obj1 = Results(mass=1)
|
176
|
+
obj2 = Results(mass=3)
|
177
|
+
assert {'mass': 2.0} == group.merge([obj1, obj2])
|
178
|
+
|
179
|
+
|
180
|
+
.. code-block:: python
|
181
|
+
|
182
|
+
# you can also set `None` for those attributes that you want to skip
|
183
|
+
lookup = {'mass': ResultsGroup.float_mean, 'trajectory': None}
|
184
|
+
group = ResultsGroup(lookup)
|
185
|
+
objects = [Results(mass=1, skip=None), Results(mass=3, skip=object)]
|
186
|
+
assert group.merge(objects, require_all_aggregators=False) == {'mass': 2.0}
|
187
|
+
|
188
|
+
.. versionadded:: 2.8.0
|
189
|
+
"""
|
190
|
+
|
191
|
+
def __init__(self, lookup: dict[str, Callable] = None):
|
192
|
+
self._lookup = lookup
|
193
|
+
|
194
|
+
def merge(
|
195
|
+
self, objects: Sequence[Results], require_all_aggregators: bool = True
|
196
|
+
) -> Results:
|
197
|
+
"""Merge multiple Results into a single Results instance.
|
198
|
+
|
199
|
+
Merge multiple :class:`Results` instances into a single one, using the
|
200
|
+
`lookup` dictionary to determine the appropriate aggregator functions for
|
201
|
+
each named results attribute. If the resulting object only contains a single
|
202
|
+
element, it just returns it without using any aggregators.
|
203
|
+
|
204
|
+
Parameters
|
205
|
+
----------
|
206
|
+
objects : Sequence[Results]
|
207
|
+
Multiple :class:`Results` instances with the same data attributes.
|
208
|
+
require_all_aggregators : bool, optional
|
209
|
+
if True, raise an exception when no aggregation function for a
|
210
|
+
particular argument is found. Allows to skip aggregation for the
|
211
|
+
parameters that aren't needed in the final object --
|
212
|
+
see :class:`ResultsGroup`.
|
213
|
+
|
214
|
+
Returns
|
215
|
+
-------
|
216
|
+
Results
|
217
|
+
merged :class:`Results`
|
218
|
+
|
219
|
+
Raises
|
220
|
+
------
|
221
|
+
ValueError
|
222
|
+
if no aggregation function for a key is found and ``require_all_aggregators=True``
|
223
|
+
"""
|
224
|
+
if len(objects) == 1:
|
225
|
+
merged_results = objects[0]
|
226
|
+
return merged_results
|
227
|
+
|
228
|
+
merged_results = Results()
|
229
|
+
for key in objects[0].keys():
|
230
|
+
agg_function = self._lookup.get(key, None)
|
231
|
+
if agg_function is not None:
|
232
|
+
results_of_t = [obj[key] for obj in objects]
|
233
|
+
merged_results[key] = agg_function(results_of_t)
|
234
|
+
elif require_all_aggregators:
|
235
|
+
raise ValueError(f"No aggregation function for {key=}")
|
236
|
+
return merged_results
|
237
|
+
|
238
|
+
@staticmethod
|
239
|
+
def flatten_sequence(arrs: list[list]):
|
240
|
+
"""Flatten a list of lists into a list
|
241
|
+
|
242
|
+
Parameters
|
243
|
+
----------
|
244
|
+
arrs : list[list]
|
245
|
+
list of lists
|
246
|
+
|
247
|
+
Returns
|
248
|
+
-------
|
249
|
+
list
|
250
|
+
flattened list
|
251
|
+
"""
|
252
|
+
return [item for sublist in arrs for item in sublist]
|
253
|
+
|
254
|
+
@staticmethod
|
255
|
+
def ndarray_sum(arrs: list[np.ndarray]):
|
256
|
+
"""sums an ndarray along ``axis=0``
|
257
|
+
|
258
|
+
Parameters
|
259
|
+
----------
|
260
|
+
arrs : list[np.ndarray]
|
261
|
+
list of input arrays. Must have the same shape.
|
262
|
+
|
263
|
+
Returns
|
264
|
+
-------
|
265
|
+
np.ndarray
|
266
|
+
sum of input arrays
|
267
|
+
"""
|
268
|
+
return np.array(arrs).sum(axis=0)
|
269
|
+
|
270
|
+
@staticmethod
|
271
|
+
def ndarray_mean(arrs: list[np.ndarray]):
|
272
|
+
"""calculates mean of input ndarrays along ``axis=0``
|
273
|
+
|
274
|
+
Parameters
|
275
|
+
----------
|
276
|
+
arrs : list[np.ndarray]
|
277
|
+
list of input arrays. Must have the same shape.
|
278
|
+
|
279
|
+
Returns
|
280
|
+
-------
|
281
|
+
np.ndarray
|
282
|
+
mean of input arrays
|
283
|
+
"""
|
284
|
+
return np.array(arrs).mean(axis=0)
|
285
|
+
|
286
|
+
@staticmethod
|
287
|
+
def float_mean(floats: list[float]):
|
288
|
+
"""calculates mean of input float values
|
289
|
+
|
290
|
+
Parameters
|
291
|
+
----------
|
292
|
+
floats : list[float]
|
293
|
+
list of float values
|
294
|
+
|
295
|
+
Returns
|
296
|
+
-------
|
297
|
+
float
|
298
|
+
mean value
|
299
|
+
"""
|
300
|
+
return np.array(floats).mean()
|
301
|
+
|
302
|
+
@staticmethod
|
303
|
+
def ndarray_hstack(arrs: list[np.ndarray]):
|
304
|
+
"""Performs horizontal stack of input arrays
|
305
|
+
|
306
|
+
Parameters
|
307
|
+
----------
|
308
|
+
arrs : list[np.ndarray]
|
309
|
+
input numpy arrays
|
310
|
+
|
311
|
+
Returns
|
312
|
+
-------
|
313
|
+
np.ndarray
|
314
|
+
result of stacking
|
315
|
+
"""
|
316
|
+
return np.hstack(arrs)
|
317
|
+
|
318
|
+
@staticmethod
|
319
|
+
def ndarray_vstack(arrs: list[np.ndarray]):
|
320
|
+
"""Performs vertical stack of input arrays
|
321
|
+
|
322
|
+
Parameters
|
323
|
+
----------
|
324
|
+
arrs : list[np.ndarray]
|
325
|
+
input numpy arrays
|
326
|
+
|
327
|
+
Returns
|
328
|
+
-------
|
329
|
+
np.ndarray
|
330
|
+
result of stacking
|
331
|
+
"""
|
332
|
+
return np.vstack(arrs)
|