polyphys 1.0.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.
Files changed (69) hide show
  1. polyphys/__init__.py +7 -0
  2. polyphys/__version__.py +22 -0
  3. polyphys/analyze/__init__.py +51 -0
  4. polyphys/analyze/clusters.py +1738 -0
  5. polyphys/analyze/correlations.py +995 -0
  6. polyphys/analyze/density.py +1138 -0
  7. polyphys/analyze/measurer.py +1338 -0
  8. polyphys/analyze/pipeline.py +1868 -0
  9. polyphys/analyze/stats.py +810 -0
  10. polyphys/analyze/sumrule.py +1159 -0
  11. polyphys/manage/__init__.py +11 -0
  12. polyphys/manage/organizer.py +2188 -0
  13. polyphys/manage/parser.py +1264 -0
  14. polyphys/manage/types.py +171 -0
  15. polyphys/manage/utils.py +777 -0
  16. polyphys/probe/__init__.py +25 -0
  17. polyphys/probe/binders.py +711 -0
  18. polyphys/probe/chain_size.py +583 -0
  19. polyphys/probe/core.py +437 -0
  20. polyphys/probe/histograms.py +863 -0
  21. polyphys/probe/pairs.py +555 -0
  22. polyphys/simulate/__init__.py +48 -0
  23. polyphys/simulate/build.py +1231 -0
  24. polyphys/simulate/core.py +237 -0
  25. polyphys/simulate/data.py +977 -0
  26. polyphys/simulate/dump.py +752 -0
  27. polyphys/simulate/log.py +788 -0
  28. polyphys/spec.py +1359 -0
  29. polyphys/tests/analyze/test_clusters.py +1058 -0
  30. polyphys/tests/analyze/test_correlations.py +708 -0
  31. polyphys/tests/analyze/test_density.py +813 -0
  32. polyphys/tests/analyze/test_measurer.py +785 -0
  33. polyphys/tests/analyze/test_pipeline.py +1881 -0
  34. polyphys/tests/analyze/test_stats.py +732 -0
  35. polyphys/tests/analyze/test_sumrule.py +917 -0
  36. polyphys/tests/conftest.py +753 -0
  37. polyphys/tests/data/lammps_build/make_starts.py +70 -0
  38. polyphys/tests/manage/test_organizer.py +1495 -0
  39. polyphys/tests/manage/test_parser.py +1222 -0
  40. polyphys/tests/manage/test_utils.py +498 -0
  41. polyphys/tests/probe/conftest.py +407 -0
  42. polyphys/tests/probe/test_binders.py +686 -0
  43. polyphys/tests/probe/test_chain_size.py +557 -0
  44. polyphys/tests/probe/test_core.py +391 -0
  45. polyphys/tests/probe/test_histograms.py +779 -0
  46. polyphys/tests/probe/test_pairs.py +475 -0
  47. polyphys/tests/simulate/test_build.py +1042 -0
  48. polyphys/tests/simulate/test_core.py +106 -0
  49. polyphys/tests/simulate/test_data.py +858 -0
  50. polyphys/tests/simulate/test_dump.py +487 -0
  51. polyphys/tests/simulate/test_log.py +667 -0
  52. polyphys/tests/strategies.py +120 -0
  53. polyphys/tests/synthetic.py +410 -0
  54. polyphys/tests/test_conftest.py +414 -0
  55. polyphys/tests/test_docs.py +82 -0
  56. polyphys/tests/test_packaging.py +97 -0
  57. polyphys/tests/test_spec.py +772 -0
  58. polyphys/tests/viz/conftest.py +32 -0
  59. polyphys/tests/viz/test_colors.py +113 -0
  60. polyphys/tests/viz/test_helpers.py +292 -0
  61. polyphys/viz/__init__.py +15 -0
  62. polyphys/viz/colors.py +204 -0
  63. polyphys/viz/helpers.py +549 -0
  64. polyphys-1.0.0.dist-info/METADATA +339 -0
  65. polyphys-1.0.0.dist-info/RECORD +69 -0
  66. polyphys-1.0.0.dist-info/WHEEL +5 -0
  67. polyphys-1.0.0.dist-info/licenses/AUTHORS.rst +13 -0
  68. polyphys-1.0.0.dist-info/licenses/LICENSE +22 -0
  69. polyphys-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,120 @@
1
+ """\
2
+ ==========================================================
3
+ :mod:`polyphys.tests.strategies`
4
+ ==========================================================
5
+
6
+ Hypothesis strategies shared by the package's tests and the study tests in
7
+ ``projects/``.
8
+
9
+ :func:`lineage_names` draws an artifact name of one lineage of a parser
10
+ class from the parser's own declaration: one value per keyword of the
11
+ lineage's pattern, written in the text a parser rebuilds a short name with,
12
+ so that parsing the name and rebuilding it is the identity.
13
+
14
+ Examples
15
+ ========
16
+ >>> from hypothesis import find
17
+ >>> from polyphys.tests.strategies import lineage_names
18
+ >>> from polyphys.tests.synthetic import ChainCyl
19
+ >>> name, values = find(lineage_names(ChainCyl, 'space'), lambda _: True)
20
+ >>> sorted(values)
21
+ ['D', 'N', 'ac']
22
+ """
23
+ from decimal import Decimal
24
+
25
+ from hypothesis import assume
26
+ from hypothesis import strategies as st
27
+
28
+ from polyphys.manage.parser import KeywordSpec, ParserBase
29
+ from polyphys.manage.types import LineageT
30
+
31
+ __all__ = ['keyword_text', 'lineage_names', 'stored_values']
32
+
33
+
34
+ def keyword_text(value: int | Decimal) -> str:
35
+ """
36
+ Return the text of a keyword value as a parser rebuilds it in a short
37
+ name: an `int` unchanged, and a float that is a whole number as an
38
+ integer, any other as its :func:`repr`.
39
+
40
+ Examples
41
+ --------
42
+ >>> from decimal import Decimal
43
+ >>> keyword_text(200), keyword_text(Decimal('2.000')), \\
44
+ ... keyword_text(Decimal('1.250'))
45
+ ('200', '2', '1.25')
46
+ """
47
+ if isinstance(value, int):
48
+ return str(value)
49
+ number = float(value)
50
+ return str(int(number)) if number.is_integer() else repr(number)
51
+
52
+
53
+ def _values(spec: KeywordSpec) -> st.SearchStrategy[int | Decimal]:
54
+ """The values of one keyword: integers from 0 to 100000, or decimals
55
+ with up to three places from 0.001 to 1000."""
56
+ if spec.kind is int:
57
+ return st.integers(min_value=0, max_value=100_000)
58
+ return st.decimals(min_value=Decimal('0.001'), max_value=Decimal('1000'),
59
+ places=3, allow_nan=False, allow_infinity=False)
60
+
61
+
62
+ @st.composite
63
+ def lineage_names(
64
+ draw: st.DrawFn, parser_class: type[ParserBase], lineage: LineageT
65
+ ) -> tuple[str, dict[str, int | Decimal]]:
66
+ """
67
+ Draw a name of `lineage` for `parser_class` and the value of each of
68
+ its keywords.
69
+
70
+ The keywords follow the lineage's pattern, each followed by the text of
71
+ its value (:func:`keyword_text`); in a ``segment`` name the segment
72
+ keyword ``j`` follows a dot, as the probes write it. In a cylinder,
73
+ a name is kept only when the cylinder size exceeds every species' size,
74
+ so that each species' centers have room and the parser's bulk values
75
+ exist (:func:`~polyphys.manage.utils.number_density_cylinder`).
76
+
77
+ Returns
78
+ -------
79
+ tuple of (str, dict)
80
+ The name, and each keyword of the pattern mapped to its value.
81
+ """
82
+ keywords = parser_class._keywords
83
+ patterns = parser_class._patterns
84
+ assert keywords is not None and patterns is not None
85
+ values = {keyword: draw(_values(keywords[keyword]))
86
+ for keyword in patterns[lineage]}
87
+ if parser_class._geometry == 'cylindrical':
88
+ stored = {**parser_class._defaults,
89
+ **stored_values(parser_class, values)}
90
+ if 'dcyl' in stored:
91
+ assume(all(stored.get(species.size, 0.0) < stored['dcyl']
92
+ for species in parser_class._species))
93
+ parts = [('.' if keyword == 'j' else '') + keyword + keyword_text(value)
94
+ for keyword, value in values.items()]
95
+ return ''.join(parts), values
96
+
97
+
98
+ def stored_values(
99
+ parser_class: type[ParserBase], values: dict[str, int | Decimal]
100
+ ) -> dict[str, int | float]:
101
+ """
102
+ Map each keyword's attribute to the value a parser stores for it,
103
+ :math:`y = s x + c` (:class:`~polyphys.manage.parser.KeywordSpec`), in
104
+ float arithmetic.
105
+
106
+ Examples
107
+ --------
108
+ >>> from decimal import Decimal
109
+ >>> from polyphys.tests.synthetic import ChainCyl
110
+ >>> stored_values(ChainCyl, {'N': 200, 'r': Decimal('10.5')})
111
+ {'nmon': 200, 'dcyl': 20.0}
112
+ """
113
+ keywords = parser_class._keywords
114
+ assert keywords is not None
115
+ stored: dict[str, int | float] = {}
116
+ for keyword, value in values.items():
117
+ spec = keywords[keyword]
118
+ stored[spec.attr] = (value if isinstance(value, int)
119
+ else spec.scale * float(value) + spec.offset)
120
+ return stored
@@ -0,0 +1,410 @@
1
+ """\
2
+ ==========================================================
3
+ :mod:`polyphys.tests.synthetic`
4
+ ==========================================================
5
+
6
+ Synthetic parsers for the package's own tests and examples. PolyPhys ships
7
+ no study parser (see the "Studies" page); these classes declare made-up
8
+ studies, so that the tests and the examples of the library do not depend on
9
+ any study's naming scheme.
10
+
11
+ - :class:`ChainCyl`: a linear chain among crowders in a cylinder that is
12
+ periodic along its axis.
13
+ - :class:`RingCub`: a ring of small and large monomers among crowders in a
14
+ periodic cube.
15
+ - :class:`RingCubTwoCrowders`: a ring of small and large monomers among
16
+ crowders of two sizes in a periodic cube.
17
+ - :class:`RingCubBinders`: a ring of monomers with binders and crowders in
18
+ a periodic cube.
19
+ - :class:`RingCyl`: a ring of small and large monomers among crowders in a
20
+ cylinder that is periodic along its axis.
21
+ - :class:`RingCylBinders`: a ring of monomers with binders and crowders in
22
+ a cylinder that is periodic along its axis.
23
+
24
+ In each name, ``#`` stands for a value. The cylinder size is
25
+ :math:`D = 2r - 1` from the radius :math:`r` (keyword ``r``) of a wall of
26
+ beads of size 1, the cylinder length :math:`Z = 2 l_z` from the half-length
27
+ :math:`l_z` (keyword ``lz``), and the cube side :math:`L = 2l` from the
28
+ half-side :math:`l` (keyword ``l``).
29
+
30
+ Examples
31
+ ========
32
+ >>> from polyphys.tests.synthetic import ChainCyl
33
+ >>> artifact = ChainCyl('N200D10.0ac2.0nc0', 'ensemble', 'all')
34
+ >>> artifact.nmon, artifact.dcyl, artifact.dcrowd
35
+ (200, 10.0, 2.0)
36
+ """
37
+ from polyphys.manage.parser import KeywordSpec, ParserBase, Species
38
+
39
+ __all__ = [
40
+ 'ChainCyl', 'RingCub', 'RingCubBinders', 'RingCubTwoCrowders', 'RingCyl',
41
+ 'RingCylBinders',
42
+ ]
43
+
44
+ _MONOMER_BULK = ['phi_bulk_m', 'rho_bulk_m']
45
+ _RING_BULK = ['phi_bulk_m_small', 'rho_bulk_m_small', 'phi_bulk_m_large',
46
+ 'rho_bulk_m_large', 'phi_bulk_m', 'rho_bulk_m']
47
+
48
+
49
+ class ChainCyl(ParserBase):
50
+ """
51
+ Parse a name of the synthetic *ChainCyl* study: a linear chain among
52
+ crowders in a cylinder that is periodic along its axis.
53
+
54
+ - ``segment``: N#r#lz#ac#nc#dt#bdump#adump#ens#.j#
55
+ - ``whole``: N#r#lz#ac#nc#dt#bdump#adump#ens#
56
+ - ``ensemble_long``: N#r#lz#ac#nc#dt#bdump#adump#
57
+ - ``ensemble``: N#D#ac#nc#
58
+ - ``space``: N#D#ac#
59
+
60
+ The monomer diameter `dmon` is 1 and not in the name. The bulk number
61
+ densities and volume fractions of monomers and crowders exist at
62
+ ``segment``, ``whole``, and ``ensemble_long``.
63
+
64
+ Examples
65
+ --------
66
+ >>> artifact = ChainCyl(
67
+ ... 'N200r10.5lz25.0ac2.0nc100dt0.005bdump1000adump5000ens1',
68
+ ... 'whole', 'bug')
69
+ >>> artifact.dcyl, artifact.lcyl, artifact.ensemble
70
+ (20.0, 50.0, 'N200D20ac2nc100')
71
+ """
72
+ _geometry = 'cylindrical'
73
+ _topology = 'linear'
74
+ _groups = ['bug', 'all']
75
+ _dump_keywords = {'bug': 'bdump', 'all': 'adump'}
76
+ _keywords = {
77
+ 'N': KeywordSpec('nmon', int),
78
+ 'r': KeywordSpec('dcyl', float, scale=2.0, offset=-1.0),
79
+ 'D': KeywordSpec('dcyl', float),
80
+ 'lz': KeywordSpec('lcyl', float, scale=2.0),
81
+ 'ac': KeywordSpec('dcrowd', float),
82
+ 'nc': KeywordSpec('ncrowd', int),
83
+ 'dt': KeywordSpec('dt', float),
84
+ 'bdump': KeywordSpec('bdump', int),
85
+ 'adump': KeywordSpec('adump', int),
86
+ 'ens': KeywordSpec('ensemble_id', int),
87
+ 'j': KeywordSpec('segment_id', int),
88
+ }
89
+ _patterns = {
90
+ 'segment': ('N', 'r', 'lz', 'ac', 'nc', 'dt', 'bdump', 'adump',
91
+ 'ens', 'j'),
92
+ 'whole': ('N', 'r', 'lz', 'ac', 'nc', 'dt', 'bdump', 'adump', 'ens'),
93
+ 'ensemble_long': ('N', 'r', 'lz', 'ac', 'nc', 'dt', 'bdump',
94
+ 'adump'),
95
+ 'ensemble': ('N', 'D', 'ac', 'nc'),
96
+ 'space': ('N', 'D', 'ac'),
97
+ }
98
+ _defaults = {'dmon': 1}
99
+ _species = (Species('m', 'nmon', 'dmon'), Species('c', 'ncrowd', 'dcrowd'))
100
+ _project_attributes = {
101
+ 'segment': ['dmon', *_MONOMER_BULK, 'phi_bulk_c', 'rho_bulk_c'],
102
+ 'whole': ['dmon', *_MONOMER_BULK, 'phi_bulk_c', 'rho_bulk_c'],
103
+ 'ensemble_long': ['dmon', *_MONOMER_BULK, 'phi_bulk_c',
104
+ 'rho_bulk_c'],
105
+ 'ensemble': ['dmon'],
106
+ 'space': ['dmon'],
107
+ }
108
+
109
+
110
+ class RingCub(ParserBase):
111
+ """
112
+ Parse a name of the synthetic *RingCub* study: a ring of small and large
113
+ monomers among crowders in a periodic cube.
114
+
115
+ - ``segment``: al#nl#ml#ns#ac#nc#l#dt#bdump#adump#ens#.j#
116
+ - ``whole``: al#nl#ml#ns#ac#nc#l#dt#bdump#adump#ens#
117
+ - ``ensemble_long``: al#nl#ml#ns#ac#nc#l#dt#bdump#adump#
118
+ - ``ensemble``: ns#nl#al#ac#nc#
119
+ - ``space``: ns#nl#al#ac#
120
+
121
+ The small monomers have diameter and mass 1, and the crowders a mass
122
+ set by their diameter; none is in the name.
123
+
124
+ Examples
125
+ --------
126
+ >>> artifact = RingCub(
127
+ ... 'al2.0nl2ml8.0ns20ac1.0nc100l10.0dt0.005bdump1000adump5000ens1',
128
+ ... 'whole', 'bug')
129
+ >>> artifact.nmon_small, artifact.nmon_large, artifact.lcube
130
+ (20, 2, 20.0)
131
+ """
132
+ _geometry = 'cubic'
133
+ _topology = 'ring'
134
+ _groups = ['bug', 'all']
135
+ _dump_keywords = {'bug': 'bdump', 'all': 'adump'}
136
+ _keywords = {
137
+ 'al': KeywordSpec('dmon_large', float),
138
+ 'nl': KeywordSpec('nmon_large', int),
139
+ 'ml': KeywordSpec('mmon_large', float),
140
+ 'ns': KeywordSpec('nmon_small', int),
141
+ 'ac': KeywordSpec('dcrowd', float),
142
+ 'nc': KeywordSpec('ncrowd', int),
143
+ 'l': KeywordSpec('lcube', float, scale=2.0),
144
+ 'dt': KeywordSpec('dt', float),
145
+ 'bdump': KeywordSpec('bdump', int),
146
+ 'adump': KeywordSpec('adump', int),
147
+ 'ens': KeywordSpec('ensemble_id', int),
148
+ 'j': KeywordSpec('segment_id', int),
149
+ }
150
+ _patterns = {
151
+ 'segment': ('al', 'nl', 'ml', 'ns', 'ac', 'nc', 'l', 'dt', 'bdump',
152
+ 'adump', 'ens', 'j'),
153
+ 'whole': ('al', 'nl', 'ml', 'ns', 'ac', 'nc', 'l', 'dt', 'bdump',
154
+ 'adump', 'ens'),
155
+ 'ensemble_long': ('al', 'nl', 'ml', 'ns', 'ac', 'nc', 'l', 'dt',
156
+ 'bdump', 'adump'),
157
+ 'ensemble': ('ns', 'nl', 'al', 'ac', 'nc'),
158
+ 'space': ('ns', 'nl', 'al', 'ac'),
159
+ }
160
+ _defaults = {'dmon_small': 1, 'mmon_small': 1, 'mcrowd': -1}
161
+ _species = (Species('m_small', 'nmon_small', 'dmon_small'),
162
+ Species('m_large', 'nmon_large', 'dmon_large'),
163
+ Species('c', 'ncrowd', 'dcrowd'))
164
+ _totals = {'m': ('m_small', 'm_large')}
165
+ _masses = {'mcrowd': 'dcrowd'}
166
+ _project_attributes = {
167
+ 'segment': ['dmon_small', 'mmon_small', 'mcrowd', *_RING_BULK,
168
+ 'phi_bulk_c', 'rho_bulk_c'],
169
+ 'whole': ['dmon_small', 'mmon_small', 'mcrowd', *_RING_BULK,
170
+ 'phi_bulk_c', 'rho_bulk_c'],
171
+ 'ensemble_long': ['dmon_small', 'mmon_small', 'mcrowd', *_RING_BULK,
172
+ 'phi_bulk_c', 'rho_bulk_c'],
173
+ 'ensemble': ['dmon_small', 'mmon_small', 'mcrowd'],
174
+ 'space': ['dmon_small', 'mmon_small', 'mcrowd'],
175
+ }
176
+
177
+
178
+ class RingCubTwoCrowders(ParserBase):
179
+ """
180
+ Parse a name of the synthetic *RingCubTwoCrowders* study: a ring of
181
+ small and large monomers among crowders of two sizes in a periodic cube.
182
+
183
+ - ``segment``: al#nl#ns#ac#ab#nc#nb#l#dt#bdump#adump#ens#.j#
184
+ - ``whole``: al#nl#ns#ac#ab#nc#nb#l#dt#bdump#adump#ens#
185
+ - ``ensemble_long``: al#nl#ns#ac#ab#nc#nb#l#dt#bdump#adump#
186
+ - ``ensemble``: al#nl#ns#ac#ab#nc#nb#
187
+ - ``space``: al#nl#ns#ac#ab#
188
+
189
+ The crowders of type one have diameter `dcrowd_one` (keyword ``ac``)
190
+ and number `ncrowd_one` (``nc``); those of type two `dcrowd_two`
191
+ (``ab``) and `ncrowd_two` (``nb``). `phi_bulk_c` sums the two.
192
+
193
+ Examples
194
+ --------
195
+ >>> artifact = RingCubTwoCrowders(
196
+ ... 'al2.0nl2ns20ac1.0ab2.0nc100nb10l10.0dt0.005bdump1000adump5000',
197
+ ... 'ensemble_long', 'all')
198
+ >>> artifact.dcrowd_one, artifact.dcrowd_two, artifact.ncrowd_two
199
+ (1.0, 2.0, 10)
200
+ """
201
+ _geometry = 'cubic'
202
+ _topology = 'ring'
203
+ _groups = ['bug', 'all']
204
+ _dump_keywords = {'bug': 'bdump', 'all': 'adump'}
205
+ _keywords = {
206
+ 'al': KeywordSpec('dmon_large', float),
207
+ 'nl': KeywordSpec('nmon_large', int),
208
+ 'ns': KeywordSpec('nmon_small', int),
209
+ 'ac': KeywordSpec('dcrowd_one', float),
210
+ 'ab': KeywordSpec('dcrowd_two', float),
211
+ 'nc': KeywordSpec('ncrowd_one', int),
212
+ 'nb': KeywordSpec('ncrowd_two', int),
213
+ 'l': KeywordSpec('lcube', float, scale=2.0),
214
+ 'dt': KeywordSpec('dt', float),
215
+ 'bdump': KeywordSpec('bdump', int),
216
+ 'adump': KeywordSpec('adump', int),
217
+ 'ens': KeywordSpec('ensemble_id', int),
218
+ 'j': KeywordSpec('segment_id', int),
219
+ }
220
+ _patterns = {
221
+ 'segment': ('al', 'nl', 'ns', 'ac', 'ab', 'nc', 'nb', 'l', 'dt',
222
+ 'bdump', 'adump', 'ens', 'j'),
223
+ 'whole': ('al', 'nl', 'ns', 'ac', 'ab', 'nc', 'nb', 'l', 'dt',
224
+ 'bdump', 'adump', 'ens'),
225
+ 'ensemble_long': ('al', 'nl', 'ns', 'ac', 'ab', 'nc', 'nb', 'l',
226
+ 'dt', 'bdump', 'adump'),
227
+ 'ensemble': ('al', 'nl', 'ns', 'ac', 'ab', 'nc', 'nb'),
228
+ 'space': ('al', 'nl', 'ns', 'ac', 'ab'),
229
+ }
230
+ _defaults = {'dmon_small': 1}
231
+ _species = (Species('m_small', 'nmon_small', 'dmon_small'),
232
+ Species('m_large', 'nmon_large', 'dmon_large'),
233
+ Species('c_one', 'ncrowd_one', 'dcrowd_one'),
234
+ Species('c_two', 'ncrowd_two', 'dcrowd_two'))
235
+ _totals = {'m': ('m_small', 'm_large'), 'c': ('c_one', 'c_two')}
236
+ _project_attributes = {
237
+ 'segment': ['dmon_small', *_RING_BULK, 'phi_bulk_c_one',
238
+ 'rho_bulk_c_one', 'phi_bulk_c_two', 'rho_bulk_c_two',
239
+ 'phi_bulk_c', 'rho_bulk_c'],
240
+ 'whole': ['dmon_small', *_RING_BULK, 'phi_bulk_c_one',
241
+ 'rho_bulk_c_one', 'phi_bulk_c_two', 'rho_bulk_c_two',
242
+ 'phi_bulk_c', 'rho_bulk_c'],
243
+ 'ensemble_long': ['dmon_small', *_RING_BULK, 'phi_bulk_c_one',
244
+ 'rho_bulk_c_one', 'phi_bulk_c_two',
245
+ 'rho_bulk_c_two', 'phi_bulk_c', 'rho_bulk_c'],
246
+ 'ensemble': ['dmon_small'],
247
+ 'space': ['dmon_small'],
248
+ }
249
+
250
+
251
+ class RingCubBinders(ParserBase):
252
+ """
253
+ Parse a name of the synthetic *RingCubBinders* study: a ring of
254
+ monomers with binders and crowders in a periodic cube, whose particle
255
+ groups are ``nucleoid`` (the ring and the binders) and ``all``.
256
+
257
+ - ``segment``: N#nh#ac#nc#l#ens#.j#
258
+ - ``whole``: N#nh#ac#nc#l#ens#
259
+ - ``ensemble_long``: N#nh#ac#nc#l#
260
+ - ``ensemble``: N#nh#ac#nc#
261
+ - ``space``: N#nh#ac#
262
+
263
+ The monomers and the binder cores have diameter 1, and the time step
264
+ and dump periods are fixed; none is in the name.
265
+
266
+ Examples
267
+ --------
268
+ >>> artifact = RingCubBinders('N200nh30ac2.0nc0l25.0ens1', 'whole',
269
+ ... 'nucleoid')
270
+ >>> artifact.nmon, artifact.nhns, artifact.lcube
271
+ (200, 30, 50.0)
272
+ """
273
+ _geometry = 'cubic'
274
+ _topology = 'ring'
275
+ _groups = ['nucleoid', 'all']
276
+ _dump_keywords = {'nucleoid': 'ndump', 'all': 'adump'}
277
+ _keywords = {
278
+ 'N': KeywordSpec('nmon', int),
279
+ 'nh': KeywordSpec('nhns', int),
280
+ 'ac': KeywordSpec('dcrowd', float),
281
+ 'nc': KeywordSpec('ncrowd', int),
282
+ 'l': KeywordSpec('lcube', float, scale=2.0),
283
+ 'ens': KeywordSpec('ensemble_id', int),
284
+ 'j': KeywordSpec('segment_id', int),
285
+ }
286
+ _patterns = {
287
+ 'segment': ('N', 'nh', 'ac', 'nc', 'l', 'ens', 'j'),
288
+ 'whole': ('N', 'nh', 'ac', 'nc', 'l', 'ens'),
289
+ 'ensemble_long': ('N', 'nh', 'ac', 'nc', 'l'),
290
+ 'ensemble': ('N', 'nh', 'ac', 'nc'),
291
+ 'space': ('N', 'nh', 'ac'),
292
+ }
293
+ _defaults = {'dmon': 1, 'dhns': 1, 'dt': 0.005, 'ndump': 5000,
294
+ 'adump': 10000}
295
+ _species = (Species('m', 'nmon', 'dmon'), Species('hns', 'nhns', 'dhns'),
296
+ Species('c', 'ncrowd', 'dcrowd'))
297
+ _project_attributes = {
298
+ 'segment': ['dmon', 'dhns', *_MONOMER_BULK, 'phi_bulk_c',
299
+ 'rho_bulk_c', 'phi_bulk_hns', 'rho_bulk_hns', 'dt',
300
+ 'ndump', 'adump'],
301
+ 'whole': ['dmon', 'dhns', *_MONOMER_BULK, 'phi_bulk_c', 'rho_bulk_c',
302
+ 'phi_bulk_hns', 'rho_bulk_hns', 'dt', 'ndump', 'adump'],
303
+ 'ensemble_long': ['dmon', 'dhns', *_MONOMER_BULK, 'phi_bulk_c',
304
+ 'rho_bulk_c', 'phi_bulk_hns', 'rho_bulk_hns', 'dt',
305
+ 'ndump', 'adump'],
306
+ 'ensemble': ['dmon', 'dhns', 'dt', 'ndump', 'adump'],
307
+ 'space': ['dmon', 'dhns', 'dt', 'ndump', 'adump'],
308
+ }
309
+
310
+
311
+ class RingCyl(ParserBase):
312
+ """
313
+ Parse a name of the synthetic *RingCyl* study: a ring of small and large
314
+ monomers among crowders in a cylinder that is periodic along its axis.
315
+
316
+ - ``segment``: r#al#nl#ml#ns#ac#nc#lz#dt#bdump#adump#ens#.j#
317
+ - ``whole``: r#al#nl#ml#ns#ac#nc#lz#dt#bdump#adump#ens#
318
+ - ``ensemble_long``: r#al#nl#ml#ns#ac#nc#lz#dt#bdump#adump#
319
+ - ``ensemble``: ns#nl#al#D#ac#nc#
320
+ - ``space``: ns#nl#al#D#ac#
321
+
322
+ Examples
323
+ --------
324
+ >>> artifact = RingCyl(
325
+ ... 'r5al2nl3ml8ns7ac1.5nc0lz10dt0.005bdump1adump1ens1', 'whole',
326
+ ... 'bug')
327
+ >>> artifact.dcyl, artifact.dmon_large, artifact.space
328
+ (9.0, 2.0, 'ns7nl3al2D9ac1.5')
329
+ """
330
+ _geometry = 'cylindrical'
331
+ _topology = 'ring'
332
+ _groups = ['bug', 'all']
333
+ _dump_keywords = {'bug': 'bdump', 'all': 'adump'}
334
+ _keywords = {
335
+ 'r': KeywordSpec('dcyl', float, scale=2.0, offset=-1.0),
336
+ 'D': KeywordSpec('dcyl', float),
337
+ 'al': KeywordSpec('dmon_large', float),
338
+ 'nl': KeywordSpec('nmon_large', int),
339
+ 'ml': KeywordSpec('mmon_large', float),
340
+ 'ns': KeywordSpec('nmon_small', int),
341
+ 'ac': KeywordSpec('dcrowd', float),
342
+ 'nc': KeywordSpec('ncrowd', int),
343
+ 'lz': KeywordSpec('lcyl', float, scale=2.0),
344
+ 'dt': KeywordSpec('dt', float),
345
+ 'bdump': KeywordSpec('bdump', int),
346
+ 'adump': KeywordSpec('adump', int),
347
+ 'ens': KeywordSpec('ensemble_id', int),
348
+ 'j': KeywordSpec('segment_id', int),
349
+ }
350
+ _patterns = {
351
+ 'segment': ('r', 'al', 'nl', 'ml', 'ns', 'ac', 'nc', 'lz', 'dt',
352
+ 'bdump', 'adump', 'ens', 'j'),
353
+ 'whole': ('r', 'al', 'nl', 'ml', 'ns', 'ac', 'nc', 'lz', 'dt',
354
+ 'bdump', 'adump', 'ens'),
355
+ 'ensemble_long': ('r', 'al', 'nl', 'ml', 'ns', 'ac', 'nc', 'lz',
356
+ 'dt', 'bdump', 'adump'),
357
+ 'ensemble': ('ns', 'nl', 'al', 'D', 'ac', 'nc'),
358
+ 'space': ('ns', 'nl', 'al', 'D', 'ac'),
359
+ }
360
+ _defaults = {'dmon_small': 1, 'mmon_small': 1, 'mcrowd': -1}
361
+ _species = RingCub._species
362
+ _totals = {'m': ('m_small', 'm_large')}
363
+ _masses = {'mcrowd': 'dcrowd'}
364
+ _project_attributes = RingCub._project_attributes
365
+
366
+
367
+ class RingCylBinders(ParserBase):
368
+ """
369
+ Parse a name of the synthetic *RingCylBinders* study: a ring of
370
+ monomers with binders and crowders in a cylinder that is periodic along
371
+ its axis, with the groups ``nucleoid`` and ``all``.
372
+
373
+ - ``segment``: N#r#nh#ac#nc#lz#ens#.j#
374
+ - ``whole``: N#r#nh#ac#nc#lz#ens#
375
+ - ``ensemble_long``: N#r#nh#ac#nc#lz#
376
+ - ``ensemble``: N#D#nh#ac#nc#
377
+ - ``space``: N#D#nh#ac#
378
+
379
+ Examples
380
+ --------
381
+ >>> artifact = RingCylBinders('N200r4.5nh30ac2.0nc0lz75.0ens1', 'whole',
382
+ ... 'nucleoid')
383
+ >>> artifact.dcyl, artifact.lcyl, artifact.space
384
+ (8.0, 150.0, 'N200D8nh30ac2')
385
+ """
386
+ _geometry = 'cylindrical'
387
+ _topology = 'ring'
388
+ _groups = ['nucleoid', 'all']
389
+ _dump_keywords = {'nucleoid': 'ndump', 'all': 'adump'}
390
+ _keywords = {
391
+ 'N': KeywordSpec('nmon', int),
392
+ 'r': KeywordSpec('dcyl', float, scale=2.0, offset=-1.0),
393
+ 'D': KeywordSpec('dcyl', float),
394
+ 'nh': KeywordSpec('nhns', int),
395
+ 'ac': KeywordSpec('dcrowd', float),
396
+ 'nc': KeywordSpec('ncrowd', int),
397
+ 'lz': KeywordSpec('lcyl', float, scale=2.0),
398
+ 'ens': KeywordSpec('ensemble_id', int),
399
+ 'j': KeywordSpec('segment_id', int),
400
+ }
401
+ _patterns = {
402
+ 'segment': ('N', 'r', 'nh', 'ac', 'nc', 'lz', 'ens', 'j'),
403
+ 'whole': ('N', 'r', 'nh', 'ac', 'nc', 'lz', 'ens'),
404
+ 'ensemble_long': ('N', 'r', 'nh', 'ac', 'nc', 'lz'),
405
+ 'ensemble': ('N', 'D', 'nh', 'ac', 'nc'),
406
+ 'space': ('N', 'D', 'nh', 'ac'),
407
+ }
408
+ _defaults = RingCubBinders._defaults
409
+ _species = RingCubBinders._species
410
+ _project_attributes = RingCubBinders._project_attributes