polyphys 1.0.0__tar.gz

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 (74) hide show
  1. polyphys-1.0.0/AUTHORS.rst +13 -0
  2. polyphys-1.0.0/LICENSE +22 -0
  3. polyphys-1.0.0/PKG-INFO +339 -0
  4. polyphys-1.0.0/README.md +291 -0
  5. polyphys-1.0.0/polyphys/__init__.py +7 -0
  6. polyphys-1.0.0/polyphys/__version__.py +22 -0
  7. polyphys-1.0.0/polyphys/analyze/__init__.py +51 -0
  8. polyphys-1.0.0/polyphys/analyze/clusters.py +1738 -0
  9. polyphys-1.0.0/polyphys/analyze/correlations.py +995 -0
  10. polyphys-1.0.0/polyphys/analyze/density.py +1138 -0
  11. polyphys-1.0.0/polyphys/analyze/measurer.py +1338 -0
  12. polyphys-1.0.0/polyphys/analyze/pipeline.py +1868 -0
  13. polyphys-1.0.0/polyphys/analyze/stats.py +810 -0
  14. polyphys-1.0.0/polyphys/analyze/sumrule.py +1159 -0
  15. polyphys-1.0.0/polyphys/manage/__init__.py +11 -0
  16. polyphys-1.0.0/polyphys/manage/organizer.py +2188 -0
  17. polyphys-1.0.0/polyphys/manage/parser.py +1264 -0
  18. polyphys-1.0.0/polyphys/manage/types.py +171 -0
  19. polyphys-1.0.0/polyphys/manage/utils.py +777 -0
  20. polyphys-1.0.0/polyphys/probe/__init__.py +25 -0
  21. polyphys-1.0.0/polyphys/probe/binders.py +711 -0
  22. polyphys-1.0.0/polyphys/probe/chain_size.py +583 -0
  23. polyphys-1.0.0/polyphys/probe/core.py +437 -0
  24. polyphys-1.0.0/polyphys/probe/histograms.py +863 -0
  25. polyphys-1.0.0/polyphys/probe/pairs.py +555 -0
  26. polyphys-1.0.0/polyphys/simulate/__init__.py +48 -0
  27. polyphys-1.0.0/polyphys/simulate/build.py +1231 -0
  28. polyphys-1.0.0/polyphys/simulate/core.py +237 -0
  29. polyphys-1.0.0/polyphys/simulate/data.py +977 -0
  30. polyphys-1.0.0/polyphys/simulate/dump.py +752 -0
  31. polyphys-1.0.0/polyphys/simulate/log.py +788 -0
  32. polyphys-1.0.0/polyphys/spec.py +1359 -0
  33. polyphys-1.0.0/polyphys/tests/analyze/test_clusters.py +1058 -0
  34. polyphys-1.0.0/polyphys/tests/analyze/test_correlations.py +708 -0
  35. polyphys-1.0.0/polyphys/tests/analyze/test_density.py +813 -0
  36. polyphys-1.0.0/polyphys/tests/analyze/test_measurer.py +785 -0
  37. polyphys-1.0.0/polyphys/tests/analyze/test_pipeline.py +1881 -0
  38. polyphys-1.0.0/polyphys/tests/analyze/test_stats.py +732 -0
  39. polyphys-1.0.0/polyphys/tests/analyze/test_sumrule.py +917 -0
  40. polyphys-1.0.0/polyphys/tests/conftest.py +753 -0
  41. polyphys-1.0.0/polyphys/tests/data/lammps_build/make_starts.py +70 -0
  42. polyphys-1.0.0/polyphys/tests/manage/test_organizer.py +1495 -0
  43. polyphys-1.0.0/polyphys/tests/manage/test_parser.py +1222 -0
  44. polyphys-1.0.0/polyphys/tests/manage/test_utils.py +498 -0
  45. polyphys-1.0.0/polyphys/tests/probe/conftest.py +407 -0
  46. polyphys-1.0.0/polyphys/tests/probe/test_binders.py +686 -0
  47. polyphys-1.0.0/polyphys/tests/probe/test_chain_size.py +557 -0
  48. polyphys-1.0.0/polyphys/tests/probe/test_core.py +391 -0
  49. polyphys-1.0.0/polyphys/tests/probe/test_histograms.py +779 -0
  50. polyphys-1.0.0/polyphys/tests/probe/test_pairs.py +475 -0
  51. polyphys-1.0.0/polyphys/tests/simulate/test_build.py +1042 -0
  52. polyphys-1.0.0/polyphys/tests/simulate/test_core.py +106 -0
  53. polyphys-1.0.0/polyphys/tests/simulate/test_data.py +858 -0
  54. polyphys-1.0.0/polyphys/tests/simulate/test_dump.py +487 -0
  55. polyphys-1.0.0/polyphys/tests/simulate/test_log.py +667 -0
  56. polyphys-1.0.0/polyphys/tests/strategies.py +120 -0
  57. polyphys-1.0.0/polyphys/tests/synthetic.py +410 -0
  58. polyphys-1.0.0/polyphys/tests/test_conftest.py +414 -0
  59. polyphys-1.0.0/polyphys/tests/test_docs.py +82 -0
  60. polyphys-1.0.0/polyphys/tests/test_packaging.py +97 -0
  61. polyphys-1.0.0/polyphys/tests/test_spec.py +772 -0
  62. polyphys-1.0.0/polyphys/tests/viz/conftest.py +32 -0
  63. polyphys-1.0.0/polyphys/tests/viz/test_colors.py +113 -0
  64. polyphys-1.0.0/polyphys/tests/viz/test_helpers.py +292 -0
  65. polyphys-1.0.0/polyphys/viz/__init__.py +15 -0
  66. polyphys-1.0.0/polyphys/viz/colors.py +204 -0
  67. polyphys-1.0.0/polyphys/viz/helpers.py +549 -0
  68. polyphys-1.0.0/polyphys.egg-info/PKG-INFO +339 -0
  69. polyphys-1.0.0/polyphys.egg-info/SOURCES.txt +72 -0
  70. polyphys-1.0.0/polyphys.egg-info/dependency_links.txt +1 -0
  71. polyphys-1.0.0/polyphys.egg-info/requires.txt +27 -0
  72. polyphys-1.0.0/polyphys.egg-info/top_level.txt +1 -0
  73. polyphys-1.0.0/pyproject.toml +110 -0
  74. polyphys-1.0.0/setup.cfg +4 -0
@@ -0,0 +1,13 @@
1
+ =======
2
+ Credits
3
+ =======
4
+
5
+ Development Lead
6
+ ----------------
7
+
8
+ * Amir Sadeghi
9
+
10
+ Contributors
11
+ ------------
12
+
13
+ None yet. Why not be the first?
polyphys-1.0.0/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022-2024, Amir Sadeghi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,339 @@
1
+ Metadata-Version: 2.4
2
+ Name: polyphys
3
+ Version: 1.0.0
4
+ Summary: Computer Simulation Data Management and Analysis.
5
+ Author: Amir Sadeghi
6
+ License-Expression: MIT
7
+ Project-URL: Documentation, https://polyphys.readthedocs.io/en/latest/
8
+ Project-URL: Source, https://github.com/amirhs1/PolyPhys
9
+ Project-URL: Issues, https://github.com/amirhs1/PolyPhys/issues
10
+ Project-URL: Changelog, https://github.com/amirhs1/PolyPhys/blob/main/CHANGELOG.md
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Topic :: Scientific/Engineering :: Physics
14
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ License-File: AUTHORS.rst
24
+ Requires-Dist: numpy>=2.0
25
+ Requires-Dist: pandas>=3.0
26
+ Requires-Dist: scipy>=1.14.1
27
+ Provides-Extra: docs
28
+ Requires-Dist: sphinx; extra == "docs"
29
+ Requires-Dist: sphinx_sitemap; extra == "docs"
30
+ Requires-Dist: pydata-sphinx-theme; extra == "docs"
31
+ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
32
+ Requires-Dist: myst-parser; extra == "docs"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest; extra == "dev"
35
+ Requires-Dist: pytest-cov; extra == "dev"
36
+ Requires-Dist: hypothesis; extra == "dev"
37
+ Requires-Dist: flake8; extra == "dev"
38
+ Requires-Dist: mypy; extra == "dev"
39
+ Requires-Dist: pandas-stubs; extra == "dev"
40
+ Requires-Dist: scipy-stubs; extra == "dev"
41
+ Requires-Dist: build; extra == "dev"
42
+ Requires-Dist: sphinx; extra == "dev"
43
+ Provides-Extra: mda
44
+ Requires-Dist: MDAnalysis>=2.8; extra == "mda"
45
+ Provides-Extra: viz
46
+ Requires-Dist: matplotlib>=3.8.4; extra == "viz"
47
+ Dynamic: license-file
48
+
49
+ # PolyPhys
50
+
51
+ [![CI](https://github.com/amirhs1/PolyPhys/actions/workflows/ci.yaml/badge.svg)](https://github.com/amirhs1/PolyPhys/actions/workflows/ci.yaml)
52
+ [![codecov](https://codecov.io/gh/amirhs1/PolyPhys/branch/main/graph/badge.svg)](https://app.codecov.io/gh/amirhs1/PolyPhys)
53
+ [![Docs](https://img.shields.io/readthedocs/polyphys/latest)](https://polyphys.readthedocs.io/en/latest/)
54
+ [![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)](https://github.com/amirhs1/PolyPhys)
55
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](https://github.com/amirhs1/PolyPhys/blob/main/LICENSE)
56
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.15858407.svg)](https://doi.org/10.5281/zenodo.15858407)
57
+
58
+ **Research data management and analysis for large-scale polymer
59
+ molecular-dynamics simulations**, built around the study of bacterial
60
+ chromosome organization under macromolecular crowding.
61
+
62
+ ## The problem
63
+
64
+ A single parameter sweep in a coarse-grained LAMMPS study produces tens of
65
+ thousands of files. The physics of each run — chain length, confinement
66
+ geometry, crowder size and count, timestep, dump frequency — is encoded in its
67
+ _filename_, and each physical state point is repeated across independent
68
+ replicates that must eventually collapse into one number with an honest error
69
+ bar.
70
+
71
+ That leaves two recurring problems, and PolyPhys is built around them:
72
+
73
+ 1. **The filesystem is the database, but nothing can query it.** Filenames
74
+ carry the physics, yet they are opaque strings.
75
+ 2. **Replicates must be reduced correctly.** Averaging correlated
76
+ molecular-dynamics frames with a naive standard error understates the
77
+ uncertainty.
78
+
79
+ ## The core idea: artifact lineage
80
+
81
+ Every simulation artifact sits at one of five levels of a hierarchy, and each
82
+ level is a well-defined aggregation of the one before it:
83
+
84
+ ```text
85
+ segment → whole → ensemble_long → ensemble → space
86
+ a chunk a full one state replicates the whole
87
+ of a run trajectory point, verbose collapsed parameter sweep
88
+ ```
89
+
90
+ `polyphys.manage.parser` decodes a filename into typed physical attributes
91
+ _and_ derives that artifact's ancestry, so a file knows which state point and
92
+ which sweep it belongs to. Once artifacts know their lineage,
93
+ `polyphys.manage.organizer` can walk the hierarchy and reduce it level by
94
+ level.
95
+
96
+ ## Installation
97
+
98
+ From v1.0.0, PolyPhys is on PyPI, and each release is archived on Zenodo:
99
+
100
+ ```bash
101
+ python -m pip install polyphys
102
+ ```
103
+
104
+ With [uv](https://docs.astral.sh/uv/), install it into the active environment,
105
+ or add it as a dependency of a uv project:
106
+
107
+ ```bash
108
+ uv pip install polyphys
109
+ uv add polyphys
110
+ ```
111
+
112
+ PolyPhys is not on conda-forge yet; a conda-forge package is planned after
113
+ v1.0.0 is on PyPI. Until it is listed, create a conda environment with the
114
+ dependencies from conda-forge, then install PolyPhys into it with pip, as
115
+ [conda's guide](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html)
116
+ advises: conda packages first, then pip. `mdanalysis` is needed only by the
117
+ probe layer and `matplotlib-base` only by the viz layer's figure helpers; leave
118
+ out the ones you do not need:
119
+
120
+ ```bash
121
+ conda create -n polyphys -c conda-forge "python>=3.11" "numpy>=2.0" "pandas>=3.0" "scipy>=1.14.1" "mdanalysis>=2.8" "matplotlib-base>=3.8.4"
122
+ conda activate polyphys
123
+ python -m pip install polyphys
124
+ ```
125
+
126
+ Releases before v1.0.0 are not on PyPI; install one from its tag:
127
+
128
+ ```bash
129
+ python -m pip install "git+https://github.com/amirhs1/PolyPhys.git@v1.0.0"
130
+ ```
131
+
132
+ For a development checkout:
133
+
134
+ ```bash
135
+ git clone https://github.com/amirhs1/PolyPhys.git
136
+ cd PolyPhys
137
+ python -m pip install -e ".[dev,viz]"
138
+ ```
139
+
140
+ The `viz` extra installs matplotlib, which the doctests of `polyphys/viz/`
141
+ import; without it the documented test command stops with an `ImportError`.
142
+
143
+ Requires Python 3.11+. The runtime dependencies are NumPy 2.0 or newer, pandas
144
+ 3.0 or newer, and SciPy 1.14.1 or newer. The probe layer, which reads LAMMPS
145
+ trajectories, needs MDAnalysis as well; the `mda` extra installs it:
146
+
147
+ ```bash
148
+ python -m pip install "polyphys[mda]"
149
+ ```
150
+
151
+ The viz layer's figure helpers need matplotlib 3.8.4 or newer; the `viz` extra
152
+ installs it (the color lists in `viz.colors` need nothing extra):
153
+
154
+ ```bash
155
+ python -m pip install "polyphys[viz]"
156
+ ```
157
+
158
+ ## Quickstart
159
+
160
+ A study declares a parser, a subclass of `ParserBase` that lists the
161
+ keywords of its file names. This short one reads a linear chain among
162
+ crowders in a cylinder; the
163
+ [Studies](https://polyphys.readthedocs.io/en/latest/studies.html) page shows
164
+ the full declaration:
165
+
166
+ ```python
167
+ >>> from polyphys.manage.parser import KeywordSpec, ParserBase
168
+ >>> keys = ('N', 'D', 'ac', 'nc', 'bdump')
169
+ >>> class ChainCyl(ParserBase):
170
+ ... """A linear chain among crowders in a cylinder."""
171
+ ... _geometry = 'cylindrical'
172
+ ... _topology = 'linear'
173
+ ... _groups = ['bug']
174
+ ... _dump_keywords = {'bug': 'bdump'}
175
+ ... _keywords = {
176
+ ... 'N': KeywordSpec('nmon', int),
177
+ ... 'D': KeywordSpec('dcyl', float),
178
+ ... 'ac': KeywordSpec('dcrowd', float),
179
+ ... 'nc': KeywordSpec('ncrowd', int),
180
+ ... 'bdump': KeywordSpec('bdump', int),
181
+ ... 'ens': KeywordSpec('ensemble_id', int),
182
+ ... 'j': KeywordSpec('segment_id', int),
183
+ ... }
184
+ ... _patterns = {
185
+ ... 'segment': (*keys, 'ens', 'j'), 'whole': (*keys, 'ens'),
186
+ ... 'ensemble_long': keys, 'ensemble': ('N', 'D', 'ac', 'nc'),
187
+ ... 'space': ('N', 'D', 'ac'),
188
+ ... }
189
+ ... _project_attributes = dict.fromkeys(
190
+ ... ('segment', 'whole', 'ensemble_long', 'ensemble', 'space'), [])
191
+
192
+ ```
193
+
194
+ A file name then decodes into typed physical attributes, and into the name of
195
+ the artifact at every level of the lineage above it, without touching the
196
+ file system:
197
+
198
+ ```python
199
+ >>> artifact = ChainCyl('N200D20ac2nc1000bdump2000ens1.j03',
200
+ ... lineage='segment', group='bug')
201
+ >>> artifact.nmon, artifact.ncrowd, float(artifact.dcrowd)
202
+ (200, 1000, 2.0)
203
+ >>> for level in artifact.lineage_genealogy:
204
+ ... print(f'{level:13} {getattr(artifact, level)}')
205
+ segment N200D20ac2nc1000bdump2000ens1.j03
206
+ whole N200D20ac2nc1000bdump2000ens1
207
+ ensemble_long N200D20ac2nc1000bdump2000
208
+ ensemble N200D20ac2nc1000
209
+ space N200D20ac2
210
+
211
+ ```
212
+
213
+ The segments of one run share their `whole` name, the replicates of one
214
+ state point their `ensemble_long` name, and the state points of one sweep
215
+ their `space` name, so the organizer groups and averages them by name. The
216
+ [quickstart](https://polyphys.readthedocs.io/en/latest/quickstart.html) of
217
+ the documentation runs a small synthetic sweep from its segments to its
218
+ `space` table, and the
219
+ [Lineage](https://polyphys.readthedocs.io/en/latest/lineage.html) page shows
220
+ what else a parser derives, such as the cylinder size and the bulk volume
221
+ fractions.
222
+
223
+ ## What's in the package
224
+
225
+ One short purpose per module; each guide page and the API reference give the
226
+ details. `probe` needs the `mda` extra and `viz.helpers` the `viz` extra.
227
+
228
+ | Module | Purpose | Guide |
229
+ | --- | --- | --- |
230
+ | `spec` | Study, probe, and analysis records shared across the workflow; no MDAnalysis. | [Studies](https://polyphys.readthedocs.io/en/latest/studies.html) |
231
+ | `manage.parser` | File name to typed physical attributes and lineage names. | [Lineage](https://polyphys.readthedocs.io/en/latest/lineage.html) |
232
+ | `manage.organizer` | Join segments into wholes and reduce replicates to ensemble averages. | [Workflow](https://polyphys.readthedocs.io/en/latest/workflow.html) |
233
+ | `manage.utils` | File sorting, file opening, and number-density and volume-fraction conversions. | [API](https://polyphys.readthedocs.io/en/latest/api.html) |
234
+ | `manage.types` | Type aliases of the vocabulary, such as `LineageT` and `PhaseT`. | [API](https://polyphys.readthedocs.io/en/latest/api.html) |
235
+ | `simulate.core` | The LAMMPS box and the readers' base error. | [Simulate](https://polyphys.readthedocs.io/en/latest/simulate.html) |
236
+ | `simulate.log` | Read LAMMPS log files into DataFrames. | [Simulate](https://polyphys.readthedocs.io/en/latest/simulate.html) |
237
+ | `simulate.dump` | Read LAMMPS text dumps, one frame at a time. | [Simulate](https://polyphys.readthedocs.io/en/latest/simulate.html) |
238
+ | `simulate.data` | Read and write LAMMPS data files. | [Simulate](https://polyphys.readthedocs.io/en/latest/simulate.html) |
239
+ | `simulate.build` | Build bead-spring start configurations for LAMMPS. | [Simulate](https://polyphys.readthedocs.io/en/latest/simulate.html) |
240
+ | `probe.core` | Open a whole's data file and dump as an MDAnalysis universe. | [Probe](https://polyphys.readthedocs.io/en/latest/probe.html) |
241
+ | `probe.chain_size` | Chain size and shape in every frame. | [Probe](https://polyphys.readthedocs.io/en/latest/probe.html) |
242
+ | `probe.binders` | Binding of two-patch binders to the chain in every frame. | [Probe](https://polyphys.readthedocs.io/en/latest/probe.html) |
243
+ | `probe.histograms` | Spatial histograms of every species. | [Probe](https://polyphys.readthedocs.io/en/latest/probe.html) |
244
+ | `probe.pairs` | Pair distances, contacts, and clusters of one species. | [Probe](https://polyphys.readthedocs.io/en/latest/probe.html) |
245
+ | `analyze.measurer` | Per-frame structural measures and histograms of one frame. | [Usage](https://polyphys.readthedocs.io/en/latest/usage.html) |
246
+ | `analyze.stats` | Errors of time averages over correlated frames, by blocking. | [Statistics](https://polyphys.readthedocs.io/en/latest/statistics.html) |
247
+ | `analyze.clusters` | Contacts, clusters, and binding statistics of one frame. | [Clusters](https://polyphys.readthedocs.io/en/latest/clusters.html) |
248
+ | `analyze.correlations` | Autocorrelations, decay fits, and bond correlations. | [Correlations](https://polyphys.readthedocs.io/en/latest/correlations.html) |
249
+ | `analyze.sumrule` | The density sum rule on a space's density profiles. | [Density](https://polyphys.readthedocs.io/en/latest/density.html) |
250
+ | `analyze.density` | Local number-density and volume-fraction profiles. | [Density](https://polyphys.readthedocs.io/en/latest/density.html) |
251
+ | `analyze.pipeline` | Reduce a space's probe artifacts down the lineage. | [Pipeline](https://polyphys.readthedocs.io/en/latest/pipeline.html) |
252
+ | `viz.colors` | The color lists of the studies' figures. | [Viz](https://polyphys.readthedocs.io/en/latest/viz.html) |
253
+ | `viz.helpers` | Matplotlib helpers for ticks, legends, and bands. | [Viz](https://polyphys.readthedocs.io/en/latest/viz.html) |
254
+
255
+ The package ships no study's parser: each study declares its own
256
+ `ParserBase` subclass in its own folder. The parsers of the maintainer's
257
+ published studies are in `projects/`, outside the installed package.
258
+
259
+ ## Documentation
260
+
261
+ The full documentation, including the API reference, is at
262
+ [polyphys.readthedocs.io](https://polyphys.readthedocs.io/en/latest/). Its
263
+ quickstart runs a synthetic sweep from segments to a `space` table, and its
264
+ lineage, workflow, and studies pages explain the phases, the steps from
265
+ trajectories to a space, and how to add a study. To build it locally:
266
+
267
+ ```bash
268
+ python -m pip install -e ".[docs]"
269
+ python -m sphinx -W -b html docs/source docs/_build
270
+ ```
271
+
272
+ ## Project status
273
+
274
+ From 1.0.0, PolyPhys follows semantic versioning: a backward-incompatible
275
+ change to a stable module comes only in a major release, while `polyphys.probe`
276
+ and `polyphys.viz` stay provisional, as the
277
+ [API stability](https://polyphys.readthedocs.io/en/latest/stability.html) page
278
+ sets out. It is used to produce published research results, and the parsing
279
+ and measurement layers are covered by tests that run against Python 3.11,
280
+ 3.12, 3.13, and 3.14 on every pull request and every push to `main`; the probe
281
+ layer's tests run on Python 3.14 with MDAnalysis.
282
+
283
+ The Python examples above run as doctests in the test suite.
284
+
285
+ A study _uses_ PolyPhys from outside the package rather than extending it:
286
+ its parser and its specs live in its own folder, as `projects/` shows.
287
+
288
+ ## Citation
289
+
290
+ If you use PolyPhys in published work, please cite the archived release. The
291
+ DOI above resolves to the latest version; see [`CITATION.cff`](https://github.com/amirhs1/PolyPhys/blob/main/CITATION.cff)
292
+ for machine-readable metadata, or use GitHub's _Cite this repository_ button.
293
+
294
+ ## AI assistance
295
+
296
+ PolyPhys is developed with the help of AI coding assistants. Every change is
297
+ reviewed and merged by the maintainer, who is accountable for the result; no AI
298
+ system is an author of this software or of any release. Numerical fixtures,
299
+ formulas, and citations are derived or verified rather than accepted from a
300
+ model — see [`AI-POLICY.md`](https://github.com/amirhs1/PolyPhys/blob/main/AI-POLICY.md) for the full policy, including what
301
+ is expected of AI-assisted contributions.
302
+
303
+ Each part has a tier, set by whether I can evaluate AI output there. The table
304
+ records the checks or human review applied to each part:
305
+
306
+ - **Instrumented** — I could write it myself. AI is used for review,
307
+ refactoring, and alternative implementations, not first drafts of core logic.
308
+ - **Supervised** — AI drafts; I read every line and set the acceptance criteria
309
+ and test values.
310
+ - **Delegated** — AI generates; I can't fully evaluate it. It is covered by
311
+ tests, kept isolated and low-risk, and not presented as my work.
312
+
313
+ | Part | Tier | Checks or human review |
314
+ | --------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
315
+ | `polyphys/analyze/` | Instrumented | CI: flake8, mypy, pytest with doctests on Python 3.11–3.14; maintainer review |
316
+ | `polyphys/manage/` | Instrumented | CI: flake8, mypy, pytest with doctests on Python 3.11–3.14; parser tests for filename-parsing changes; maintainer review |
317
+ | `polyphys/simulate/` | Instrumented | CI: flake8, mypy, pytest with doctests on Python 3.11–3.14; tests against LAMMPS-written files; maintainer review |
318
+ | `polyphys/probe/` | Instrumented | CI: flake8, mypy; pytest with doctests on Python 3.14 with MDAnalysis installed; maintainer review |
319
+ | `polyphys/viz/` | Instrumented | CI: flake8, pytest with doctests on Python 3.11–3.14 with matplotlib installed; maintainer review |
320
+ | `polyphys/tests/`, `.github/workflows/`, `pyproject.toml` | Instrumented | CI on every pull request: lint, type-check, tests, docs build, package build; maintainer review |
321
+ | `projects/` | Supervised | CI: flake8, mypy, pytest of each spec against its parser and the research code's values; maintainer review of every line |
322
+ | `docs/` | Instrumented | CI: Sphinx build with warnings as errors for `docs/source/`; maintainer review |
323
+
324
+ Nothing that handles security, credentials, private data, or published results,
325
+ or that can block a merge, is Delegated. Where a tier is unclear, I treat the
326
+ part as Supervised. Tiers last reviewed: 2026-11-06.
327
+
328
+ Instructions for AI agents: [`AGENTS.md`](https://github.com/amirhs1/PolyPhys/blob/main/AGENTS.md).
329
+
330
+ ## Contributing
331
+
332
+ Bug reports and questions are welcome via
333
+ [issues](https://github.com/amirhs1/PolyPhys/issues). Please see
334
+ [`SECURITY.md`](https://github.com/amirhs1/PolyPhys/blob/main/SECURITY.md) for reporting suspected vulnerabilities privately.
335
+ See [`CONTRIBUTING.md`](https://github.com/amirhs1/PolyPhys/blob/main/CONTRIBUTING.md) for how to contribute.
336
+
337
+ ## License
338
+
339
+ MIT — see [`LICENSE`](https://github.com/amirhs1/PolyPhys/blob/main/LICENSE).