erislib 0.1.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 (124) hide show
  1. erislib-0.1.0/.gitignore +214 -0
  2. erislib-0.1.0/LICENSE +21 -0
  3. erislib-0.1.0/PKG-INFO +251 -0
  4. erislib-0.1.0/README.md +210 -0
  5. erislib-0.1.0/eris/__init__.py +43 -0
  6. erislib-0.1.0/eris/__main__.py +5 -0
  7. erislib-0.1.0/eris/_provenance.py +104 -0
  8. erislib-0.1.0/eris/_version.py +3 -0
  9. erislib-0.1.0/eris/api.py +203 -0
  10. erislib-0.1.0/eris/cli/__init__.py +1 -0
  11. erislib-0.1.0/eris/cli/_config_file.py +83 -0
  12. erislib-0.1.0/eris/cli/_shared.py +119 -0
  13. erislib-0.1.0/eris/cli/_utils.py +29 -0
  14. erislib-0.1.0/eris/cli/batch.py +204 -0
  15. erislib-0.1.0/eris/cli/cache.py +152 -0
  16. erislib-0.1.0/eris/cli/discovery.py +80 -0
  17. erislib-0.1.0/eris/cli/embed.py +83 -0
  18. erislib-0.1.0/eris/cli/encode.py +67 -0
  19. erislib-0.1.0/eris/cli/export.py +75 -0
  20. erislib-0.1.0/eris/cli/features.py +35 -0
  21. erislib-0.1.0/eris/cli/info_cmd.py +108 -0
  22. erislib-0.1.0/eris/cli/main.py +92 -0
  23. erislib-0.1.0/eris/cli/models.py +64 -0
  24. erislib-0.1.0/eris/cli/pack.py +28 -0
  25. erislib-0.1.0/eris/cli/validate.py +76 -0
  26. erislib-0.1.0/eris/core/__init__.py +1 -0
  27. erislib-0.1.0/eris/core/aminoacids.py +30 -0
  28. erislib-0.1.0/eris/core/artifact_schema.py +903 -0
  29. erislib-0.1.0/eris/core/artifacts.py +185 -0
  30. erislib-0.1.0/eris/core/base_encoder/__init__.py +7 -0
  31. erislib-0.1.0/eris/core/base_encoder/base_atom_encoder.py +32 -0
  32. erislib-0.1.0/eris/core/base_encoder/base_encoder.py +373 -0
  33. erislib-0.1.0/eris/core/base_encoder/base_residue_encoder.py +68 -0
  34. erislib-0.1.0/eris/core/cache.py +147 -0
  35. erislib-0.1.0/eris/core/config.py +935 -0
  36. erislib-0.1.0/eris/core/hashing.py +23 -0
  37. erislib-0.1.0/eris/core/io.py +869 -0
  38. erislib-0.1.0/eris/core/learned/__init__.py +50 -0
  39. erislib-0.1.0/eris/core/learned/artifacts.py +147 -0
  40. erislib-0.1.0/eris/core/learned/backends/__init__.py +1 -0
  41. erislib-0.1.0/eris/core/learned/backends/gearnet/__init__.py +21 -0
  42. erislib-0.1.0/eris/core/learned/backends/gearnet/backend.py +134 -0
  43. erislib-0.1.0/eris/core/learned/backends/gearnet/config.py +37 -0
  44. erislib-0.1.0/eris/core/learned/backends/gearnet/dependencies.py +64 -0
  45. erislib-0.1.0/eris/core/learned/backends/gearnet/loading.py +83 -0
  46. erislib-0.1.0/eris/core/learned/backends/gearnet/metadata.py +140 -0
  47. erislib-0.1.0/eris/core/learned/backends/gearnet/native_graph.py +365 -0
  48. erislib-0.1.0/eris/core/learned/backends/gearnet/native_model.py +178 -0
  49. erislib-0.1.0/eris/core/learned/backends/gearnet/preprocessing.py +294 -0
  50. erislib-0.1.0/eris/core/learned/checkpoint_acquisition.py +126 -0
  51. erislib-0.1.0/eris/core/learned/checkpoint_cache.py +124 -0
  52. erislib-0.1.0/eris/core/learned/checkpoints.py +171 -0
  53. erislib-0.1.0/eris/core/learned/config.py +39 -0
  54. erislib-0.1.0/eris/core/learned/execution.py +72 -0
  55. erislib-0.1.0/eris/core/learned/registry.py +63 -0
  56. erislib-0.1.0/eris/core/learned/runner.py +376 -0
  57. erislib-0.1.0/eris/core/learned/types.py +126 -0
  58. erislib-0.1.0/eris/core/registry.py +266 -0
  59. erislib-0.1.0/eris/core/representations/__init__.py +13 -0
  60. erislib-0.1.0/eris/core/representations/graph_rep.py +38 -0
  61. erislib-0.1.0/eris/core/representations/matrix_rep.py +33 -0
  62. erislib-0.1.0/eris/core/representations/output_declarations.py +147 -0
  63. erislib-0.1.0/eris/core/representations/point_cloud_rep.py +29 -0
  64. erislib-0.1.0/eris/core/representations/voxel_grid_rep.py +24 -0
  65. erislib-0.1.0/eris/core/residue_identity.py +18 -0
  66. erislib-0.1.0/eris/core/types.py +48 -0
  67. erislib-0.1.0/eris/datasets/__init__.py +29 -0
  68. erislib-0.1.0/eris/datasets/collate.py +585 -0
  69. erislib-0.1.0/eris/datasets/torch_dataset.py +156 -0
  70. erislib-0.1.0/eris/discovery.py +158 -0
  71. erislib-0.1.0/eris/encoders/__init__.py +7 -0
  72. erislib-0.1.0/eris/encoders/_context.py +21 -0
  73. erislib-0.1.0/eris/encoders/clouds/__init__.py +20 -0
  74. erislib-0.1.0/eris/encoders/clouds/atom_point_cloud.py +76 -0
  75. erislib-0.1.0/eris/encoders/clouds/residue_point_cloud.py +71 -0
  76. erislib-0.1.0/eris/encoders/geometry/__init__.py +37 -0
  77. erislib-0.1.0/eris/encoders/geometry/contact_map_bins_ca.py +34 -0
  78. erislib-0.1.0/eris/encoders/geometry/contact_map_ca.py +35 -0
  79. erislib-0.1.0/eris/encoders/geometry/distogram_bins_ca.py +92 -0
  80. erislib-0.1.0/eris/encoders/geometry/distogram_ca.py +54 -0
  81. erislib-0.1.0/eris/encoders/graphs/__init__.py +38 -0
  82. erislib-0.1.0/eris/encoders/graphs/atom_knn_graph.py +103 -0
  83. erislib-0.1.0/eris/encoders/graphs/residue_contact_graph.py +157 -0
  84. erislib-0.1.0/eris/encoders/graphs/residue_knn_graph.py +159 -0
  85. erislib-0.1.0/eris/encoders/grids/__init__.py +14 -0
  86. erislib-0.1.0/eris/encoders/grids/voxel_grid_ca.py +68 -0
  87. erislib-0.1.0/eris/exceptions.py +25 -0
  88. erislib-0.1.0/eris/export/__init__.py +6 -0
  89. erislib-0.1.0/eris/export/pyg.py +211 -0
  90. erislib-0.1.0/eris/export/table.py +116 -0
  91. erislib-0.1.0/eris/export/torch.py +362 -0
  92. erislib-0.1.0/eris/features/__init__.py +7 -0
  93. erislib-0.1.0/eris/features/edge/__init__.py +3 -0
  94. erislib-0.1.0/eris/features/edge/edge.py +110 -0
  95. erislib-0.1.0/eris/features/edge/features_edge.py +319 -0
  96. erislib-0.1.0/eris/features/feature_builders.py +240 -0
  97. erislib-0.1.0/eris/features/feature_registry.py +134 -0
  98. erislib-0.1.0/eris/features/geometry.py +375 -0
  99. erislib-0.1.0/eris/features/graph_stats.py +144 -0
  100. erislib-0.1.0/eris/features/grid/__init__.py +3 -0
  101. erislib-0.1.0/eris/features/grid/features_grid.py +360 -0
  102. erislib-0.1.0/eris/features/grid/grid.py +101 -0
  103. erislib-0.1.0/eris/features/interface.py +129 -0
  104. erislib-0.1.0/eris/features/node/__init__.py +4 -0
  105. erislib-0.1.0/eris/features/node/atom.py +46 -0
  106. erislib-0.1.0/eris/features/node/constants.py +435 -0
  107. erislib-0.1.0/eris/features/node/external.py +513 -0
  108. erislib-0.1.0/eris/features/node/features_atom.py +130 -0
  109. erislib-0.1.0/eris/features/node/features_residue.py +900 -0
  110. erislib-0.1.0/eris/features/node/residue.py +125 -0
  111. erislib-0.1.0/eris/features/rbf.py +37 -0
  112. erislib-0.1.0/eris/features/structure_annotations.py +307 -0
  113. erislib-0.1.0/eris/features/utils.py +120 -0
  114. erislib-0.1.0/eris/pipelines/__init__.py +12 -0
  115. erislib-0.1.0/eris/pipelines/batch_encode.py +558 -0
  116. erislib-0.1.0/eris/pipelines/manifest.py +238 -0
  117. erislib-0.1.0/eris/pipelines/pack.py +413 -0
  118. erislib-0.1.0/eris/pooling.py +242 -0
  119. erislib-0.1.0/eris/py.typed +0 -0
  120. erislib-0.1.0/eris/spatial/__init__.py +1 -0
  121. erislib-0.1.0/eris/spatial/contact_graph.py +38 -0
  122. erislib-0.1.0/eris/spatial/knn.py +145 -0
  123. erislib-0.1.0/eris/spatial/spatial_index.py +54 -0
  124. erislib-0.1.0/pyproject.toml +183 -0
@@ -0,0 +1,214 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ /out/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py.cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+ cover/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # VScode stuff
73
+ .vscode/
74
+
75
+ # Visual Studio local state
76
+ .vs/
77
+
78
+ # Sphinx documentation
79
+ docs/_build/
80
+
81
+ # PyBuilder
82
+ .pybuilder/
83
+ target/
84
+
85
+ # Jupyter Notebook
86
+ .ipynb_checkpoints
87
+
88
+ # IPython
89
+ profile_default/
90
+ ipython_config.py
91
+
92
+ # pyenv
93
+ # For a library or package, you might want to ignore these files since the code is
94
+ # intended to run in multiple environments; otherwise, check them in:
95
+ # .python-version
96
+
97
+ # pipenv
98
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
99
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
100
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
101
+ # install all needed dependencies.
102
+ #Pipfile.lock
103
+
104
+ # UV
105
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
106
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
107
+ # commonly ignored for libraries.
108
+ #uv.lock
109
+
110
+ # poetry
111
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
112
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
113
+ # commonly ignored for libraries.
114
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
115
+ #poetry.lock
116
+ #poetry.toml
117
+
118
+ # pdm
119
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
120
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
121
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
122
+ #pdm.lock
123
+ #pdm.toml
124
+ .pdm-python
125
+ .pdm-build/
126
+
127
+ # pixi
128
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
129
+ #pixi.lock
130
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
131
+ # in the .venv directory. It is recommended not to include this directory in version control.
132
+ .pixi
133
+
134
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
135
+ __pypackages__/
136
+
137
+ # Celery stuff
138
+ celerybeat-schedule
139
+ celerybeat.pid
140
+
141
+ # SageMath parsed files
142
+ *.sage.py
143
+
144
+ # Environments
145
+ .env
146
+ .envrc
147
+ .venv
148
+ env/
149
+ venv/
150
+ ENV/
151
+ env.bak/
152
+ venv.bak/
153
+
154
+ # Spyder project settings
155
+ .spyderproject
156
+ .spyproject
157
+
158
+ # Rope project settings
159
+ .ropeproject
160
+
161
+ # mkdocs documentation
162
+ /site
163
+
164
+ # mypy
165
+ .mypy_cache/
166
+ .dmypy.json
167
+ dmypy.json
168
+
169
+ # Pyre type checker
170
+ .pyre/
171
+
172
+ # pytype static type analyzer
173
+ .pytype/
174
+
175
+ # Cython debug symbols
176
+ cython_debug/
177
+
178
+ # PyCharm
179
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
180
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
181
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
182
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
183
+ #.idea/
184
+
185
+ # Abstra
186
+ # Abstra is an AI-powered process automation framework.
187
+ # Ignore directories containing user credentials, local state, and settings.
188
+ # Learn more at https://abstra.io/docs
189
+ .abstra/
190
+
191
+ # Visual Studio Code
192
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
193
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
194
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
195
+ # you could uncomment the following to ignore the entire vscode folder
196
+ # .vscode/
197
+
198
+ # Ruff stuff:
199
+ .ruff_cache/
200
+
201
+ # PyPI configuration file
202
+ .pypirc
203
+
204
+ # Cursor
205
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
206
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
207
+ # refer to https://docs.cursor.com/context/ignore-files
208
+ .cursorignore
209
+ .cursorindexingignore
210
+
211
+ # Marimo
212
+ marimo/_static/
213
+ marimo/_lsp/
214
+ __marimo__/
erislib-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kren-AI Lab
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.
erislib-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,251 @@
1
+ Metadata-Version: 2.5
2
+ Name: erislib
3
+ Version: 0.1.0
4
+ Summary: Eris: A modular library for protein structural representations and graph-based encoders.
5
+ Project-URL: Homepage, https://github.com/kren-ai-lab/eris
6
+ Project-URL: Repository, https://github.com/kren-ai-lab/eris
7
+ Project-URL: Issues, https://github.com/kren-ai-lab/eris/issues
8
+ Project-URL: Documentation, https://github.com/kren-ai-lab/eris#readme
9
+ Author: Diego Fernández Villegas, Diego Alvarez-Saravia, David Medina-Ortiz
10
+ Maintainer: Diego Fernández Villegas, Diego Alvarez-Saravia, David Medina-Ortiz
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: bioinformatics,geometric-deep-learning,graph-neural-networks,machine-learning,point-cloud,protein,protein-graphs,structural-biology,voxel
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: <3.15,>=3.11
26
+ Requires-Dist: aaindex<2,>=1.3.2
27
+ Requires-Dist: biotite<2,>=1.6
28
+ Requires-Dist: gemmi<1,>=0.7
29
+ Requires-Dist: numpy<3,>=2.0
30
+ Requires-Dist: platformdirs<5,>=4.0
31
+ Requires-Dist: polars<2,>=1.44
32
+ Requires-Dist: pyyaml<7,>=6
33
+ Requires-Dist: rich<16,>=13.0
34
+ Requires-Dist: typer<1,>=0.27
35
+ Provides-Extra: gearnet
36
+ Requires-Dist: torch<3,>=2.11; extra == 'gearnet'
37
+ Provides-Extra: pyg
38
+ Requires-Dist: torch-geometric<3,>=2.6; extra == 'pyg'
39
+ Requires-Dist: torch<3,>=2.11; extra == 'pyg'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # Eris
43
+
44
+ [![PyPI](https://img.shields.io/pypi/v/erislib?style=flat-square)](https://pypi.org/project/erislib/)
45
+ [![PyVersions](https://img.shields.io/pypi/pyversions/erislib?style=flat-square)](https://github.com/kren-ai-lab/eris)
46
+ [![Tests](https://img.shields.io/github/actions/workflow/status/kren-ai-lab/eris/tests.yml?style=flat-square)](https://github.com/kren-ai-lab/eris/actions/workflows/tests.yml)
47
+ ![License](https://img.shields.io/github/license/kren-ai-lab/eris?style=flat-square)
48
+
49
+ Eris is a Python library that turns protein structures (PDB and mmCIF) into numerical
50
+ representations for machine learning. It builds point clouds, graphs, contact maps, distograms and
51
+ voxel grids, and GearNet-Edge embeddings. Every result is a validated `StructureArtifact` that keeps
52
+ the arrays together with the structure selection, parameters and provenance that produced them.
53
+
54
+ Eris doesn't train models. Its artifacts feed PyTorch, PyTorch Geometric or any NumPy-based
55
+ pipeline.
56
+
57
+ ## Installation
58
+
59
+ Eris supports Python 3.11 to 3.14.
60
+
61
+ ```bash
62
+ pip install erislib
63
+ # or with uv:
64
+ uv add erislib
65
+ ```
66
+
67
+ Optional extras:
68
+
69
+ ```bash
70
+ pip install "erislib[gearnet]" # GearNet-Edge embeddings (PyTorch)
71
+ pip install "erislib[pyg]" # PyTorch Geometric export
72
+ ```
73
+
74
+ For development setup with `uv`, see
75
+ [DEVELOPMENT.md](https://github.com/kren-ai-lab/eris/blob/main/DEVELOPMENT.md).
76
+
77
+ ## Encode a structure
78
+
79
+ ```python
80
+ import eris
81
+
82
+ artifact = eris.encode(
83
+ "protein.pdb",
84
+ representation="residue_knn_graph",
85
+ chain_id="A",
86
+ k=8,
87
+ output="artifacts/protein_knn",
88
+ )
89
+ artifact.data["edge_index"].shape # (2, n_edges)
90
+ artifact.meta["parameters"] # canonical parameters, including defaults
91
+ ```
92
+
93
+ Representation parameters are passed as keyword arguments and validated against the
94
+ representation's config. `eris.list_representations()` lists the representations and
95
+ `eris.get_representation_info(name)` shows one with its parameters and defaults. `output=` writes
96
+ the artifact as a directory (`meta.json` plus `data.npz`) that
97
+ `eris.core.artifacts.StructureArtifact.load(path)` reads back and validates.
98
+
99
+ | Name | Type | Granularity | Primary output |
100
+ | -------------------------- | ------ | ----------- | -------------------------------- |
101
+ | `atom_point_cloud` | cloud | atom | atom coordinates and features |
102
+ | `residue_point_cloud` | cloud | residue | residue coordinates and features |
103
+ | `atom_knn_graph` | graph | atom | atom k-nearest-neighbor graph |
104
+ | `residue_knn_graph` | graph | residue | residue k-nearest-neighbor graph |
105
+ | `residue_contact_graph` | graph | residue | distance-cutoff residue graph |
106
+ | `residue_distogram` | matrix | residue | pairwise distances |
107
+ | `residue_distogram_bins` | matrix | residue | distance-bin classes |
108
+ | `residue_contact_map` | matrix | residue | binary contacts |
109
+ | `residue_contact_map_bins` | matrix | residue | distance-bin contact classes |
110
+ | `residue_voxel_grid` | grid | residue | multi-channel 3D grid |
111
+
112
+ Residue coordinates can use the alpha carbon, the residue-atom mean or the center of mass. Residue
113
+ features can combine amino-acid identity, physicochemical descriptors, AAIndex1 records, raw
114
+ B-factor, explicitly interpreted pLDDT, backbone and side-chain torsions, local structural features,
115
+ and aligned external values. Residue graphs can add chain relations, relative directions and
116
+ interface annotations. `eris.pool(...)` turns residue features into one structure-level vector.
117
+
118
+ ## Learned embeddings
119
+
120
+ ```python
121
+ artifact = eris.embed("protein.pdb", representation="gearnet_edge", output_mode="both")
122
+ ```
123
+
124
+ `gearnet_edge` emits residue embeddings (`node`), one structure embedding (`global`), or both. It
125
+ runs the official `mc_gearnet_edge.pth` checkpoint on CPU in fp32. The checkpoint isn't bundled: on
126
+ first use, Eris downloads it over HTTPS, checks its registered SHA-256 and caches it. To work
127
+ offline, pass a local copy with `checkpoint_path=` (`--checkpoint` in the CLI).
128
+
129
+ ## Batches, datasets and export
130
+
131
+ ```python
132
+ import polars as pl
133
+ import eris
134
+ from eris.datasets import ErisFolderDataset
135
+
136
+ manifest = pl.DataFrame({"id": ["p1", "p2"], "path": ["p1.pdb", "p2.cif"], "chain": ["A", None]})
137
+ results = eris.batch_encode(manifest, representation="residue_knn_graph", artifact_root="artifacts")
138
+ index = eris.pack("artifacts", "artifacts/index.csv")
139
+ dataset = ErisFolderDataset("artifacts/index.csv") # loads each artifact on access
140
+ graph = eris.to_pyg(eris.encode("p1.pdb", representation="residue_knn_graph"))
141
+ ```
142
+
143
+ A manifest is a CSV or JSONL file or a Polars DataFrame with `id` and `path` columns, and optional
144
+ `chain` and `model` (default: all chains of the first model). `batch_encode` and `batch_embed`
145
+ return one result row per input, record failures without stopping (unless `fail_fast=True`) and
146
+ can resume an interrupted run. `pack` writes a CSV index over the artifact directories.
147
+ `to_torch` converts any artifact to tensors; `to_pyg` only accepts graphs with an explicit
148
+ `edge_index`.
149
+
150
+ ### Feature tables
151
+
152
+ `feature_table` turns one structure-level vector per artifact into a Polars DataFrame with an `id`
153
+ column and one column per feature, ready for tabular models such as
154
+ [Saber](https://github.com/kren-ai-lab/saber):
155
+
156
+ ```python
157
+ embeddings = eris.batch_embed(manifest, representation="gearnet_edge", artifact_root="emb", output_mode="global")
158
+ eris.pack("emb", "emb/index.csv")
159
+ features = eris.feature_table("emb/index.csv") # id, p_0 ... p_3071
160
+
161
+ dataset = saber.DatasetBundle(X=features.drop("id"), y=labels, sample_ids=features["id"])
162
+ ```
163
+
164
+ It reads GearNet global embeddings (`p_0`, `p_1`, …) or `eris.pool(...)` vectors (named after
165
+ their features), or graph statistics with `source="graph_attr"`. It also accepts a mapping from id
166
+ to artifact. Every row must come from the same representation, parameters and model; mixing them
167
+ is an error.
168
+
169
+ ## Command line
170
+
171
+ ```bash
172
+ eris representations list
173
+ eris encode protein.pdb --representation residue_knn_graph --params '{"k": 8}' --out artifact_knn
174
+ eris embed protein.pdb --representation gearnet_edge --out embedding
175
+ eris batch encode manifest.csv --representation residue_contact_map --out artifacts
176
+ eris pack artifacts --out artifacts/index.csv
177
+ eris features emb/index.csv --out features.csv
178
+ eris info validate artifact_knn
179
+ ```
180
+
181
+ Each command calls the matching Python function.
182
+
183
+ `encode`, `embed` and the `batch` commands accept `--config PATH`, a YAML or JSON file whose keys are the option names (`representation`, `device`, ...). Representation parameters go under `params:`. Precedence is defaults < file < flags, and a `--params` flag replaces the file's `params` as a whole. Paths (input, `out`, `results`, `checkpoint`) stay on the command line.
184
+
185
+ ```yaml
186
+ representation: residue_knn_graph
187
+ params:
188
+ k: 8
189
+ ```
190
+
191
+ `eris validate-config COMMAND CONFIG [--json]` checks such a file without reading structures (`COMMAND` is `encode`, `embed`, `batch-encode`, `batch-embed` or `batch-from-folder`). It prints one `path: message` line per problem to stderr, or with `--json` a JSON array of `{path, message}` on stdout, and exits `0` if valid or `2` if not.
192
+
193
+ Validate a config from Python (no structures read, no model code imported):
194
+
195
+ ```python
196
+ from eris import validate_config
197
+
198
+ issues = validate_config("config.yaml", "encode") # or a mapping; target as on the CLI
199
+ for issue in issues: # ConfigIssue(path, message); empty when valid
200
+ print(issue.path or "<root>", issue.message)
201
+ ```
202
+
203
+ Every successful run also writes `<out>.provenance.json` next to the output (shared ecosystem CLI contract): tool version, effective parameters and their fingerprint, input and output hashes, and the environment. The artifact's own `meta.json` is unchanged in format.
204
+
205
+ Exit codes:
206
+
207
+ | Code | Meaning |
208
+ | ---- | -------------------------------------------------------------------------------------------------------------------- |
209
+ | `0` | Success (batch commands also exit `0` when some rows fail; see the results file) |
210
+ | `2` | Invalid usage or configuration (missing argument or config file, unknown representation, invalid parameters) |
211
+ | `3` | The operation failed (missing or unreadable structure, manifest or folder, invalid artifact, backend or cache error) |
212
+ | `4` | Unexpected internal error |
213
+
214
+ ## Design principles
215
+
216
+ - Eris never silently pads, truncates, resizes, normalizes or clips values, and never invents
217
+ identifiers or drops failed samples. Graph edges come only from the documented neighbor or
218
+ cutoff rule, and exports never add topology that the artifact doesn't already contain.
219
+ - Inputs that don't make scientific sense fail with a clear error instead of being coerced.
220
+ - Sample identity, array order, feature order and keys are deterministic.
221
+ - An artifact records the structure selection, canonical parameters and provenance, and is validated
222
+ every time it is saved or loaded.
223
+ - The cache is keyed by the input file's content and the full configuration, so a changed input or
224
+ parameter never returns a stale result.
225
+ - `import eris` doesn't load PyTorch, PyTorch Geometric or the GearNet runtime; they load only when
226
+ a feature needs them.
227
+ - At runtime, the only network access is the download of the registered GearNet checkpoint.
228
+
229
+ ## Documentation and examples
230
+
231
+ The [documentation index](https://github.com/kren-ai-lab/eris/blob/main/docs/README.md) links the
232
+ technical references: representation defaults, structural features, artifact schema, external
233
+ residue features and the GearNet-Edge backend. The
234
+ [example notebooks](https://github.com/kren-ai-lab/eris/blob/main/examples/README.md) are written
235
+ in marimo. To open one:
236
+
237
+ ```bash
238
+ uv sync --all-extras --group examples
239
+ uv run marimo edit examples/01_explicit_representations.py
240
+ ```
241
+
242
+ ## Citing and license
243
+
244
+ If you use Eris in published work, please cite it using
245
+ [`CITATION.cff`](https://github.com/kren-ai-lab/eris/blob/main/CITATION.cff), or the "Cite this
246
+ repository" button on GitHub. Eris is released under the
247
+ [MIT license](https://github.com/kren-ai-lab/eris/blob/main/LICENSE).
248
+
249
+ GearNet-Edge uses the official Multiview Contrast checkpoint from
250
+ [Zenodo record 10.5281/zenodo.7723075](https://doi.org/10.5281/zenodo.7723075). Eris provides a
251
+ native runtime for that checkpoint and did not train it.