scigantic-msa 0.2.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.
- scigantic_msa-0.2.0/LICENSE +21 -0
- scigantic_msa-0.2.0/PKG-INFO +234 -0
- scigantic_msa-0.2.0/README.md +202 -0
- scigantic_msa-0.2.0/pyproject.toml +64 -0
- scigantic_msa-0.2.0/setup.cfg +4 -0
- scigantic_msa-0.2.0/src/scigantic_msa/__init__.py +25 -0
- scigantic_msa-0.2.0/src/scigantic_msa/a3m.py +366 -0
- scigantic_msa-0.2.0/src/scigantic_msa/adapters.py +568 -0
- scigantic_msa-0.2.0/src/scigantic_msa/alignment.py +218 -0
- scigantic_msa-0.2.0/src/scigantic_msa/cache.py +203 -0
- scigantic_msa-0.2.0/src/scigantic_msa/cli.py +227 -0
- scigantic_msa-0.2.0/src/scigantic_msa/http.py +184 -0
- scigantic_msa-0.2.0/src/scigantic_msa/pairing.py +89 -0
- scigantic_msa-0.2.0/src/scigantic_msa/py.typed +0 -0
- scigantic_msa-0.2.0/src/scigantic_msa/remote/__init__.py +49 -0
- scigantic_msa-0.2.0/src/scigantic_msa/remote/colabfold.py +326 -0
- scigantic_msa-0.2.0/src/scigantic_msa/remote/nvidia.py +132 -0
- scigantic_msa-0.2.0/src/scigantic_msa/seqkey.py +37 -0
- scigantic_msa-0.2.0/src/scigantic_msa/tool.py +227 -0
- scigantic_msa-0.2.0/src/scigantic_msa/writers.py +449 -0
- scigantic_msa-0.2.0/src/scigantic_msa.egg-info/PKG-INFO +234 -0
- scigantic_msa-0.2.0/src/scigantic_msa.egg-info/SOURCES.txt +36 -0
- scigantic_msa-0.2.0/src/scigantic_msa.egg-info/dependency_links.txt +1 -0
- scigantic_msa-0.2.0/src/scigantic_msa.egg-info/entry_points.txt +2 -0
- scigantic_msa-0.2.0/src/scigantic_msa.egg-info/requires.txt +9 -0
- scigantic_msa-0.2.0/src/scigantic_msa.egg-info/top_level.txt +1 -0
- scigantic_msa-0.2.0/tests/test_a3m.py +152 -0
- scigantic_msa-0.2.0/tests/test_adapters.py +340 -0
- scigantic_msa-0.2.0/tests/test_cache.py +86 -0
- scigantic_msa-0.2.0/tests/test_cli.py +138 -0
- scigantic_msa-0.2.0/tests/test_colabfold.py +211 -0
- scigantic_msa-0.2.0/tests/test_http.py +115 -0
- scigantic_msa-0.2.0/tests/test_network.py +95 -0
- scigantic_msa-0.2.0/tests/test_nvidia.py +57 -0
- scigantic_msa-0.2.0/tests/test_predictors.py +107 -0
- scigantic_msa-0.2.0/tests/test_seqkey.py +46 -0
- scigantic_msa-0.2.0/tests/test_tool.py +143 -0
- scigantic_msa-0.2.0/tests/test_writers.py +199 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Scigantic
|
|
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.
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: scigantic-msa
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Get a protein MSA once from the ColabFold MMseqs2 server, or bring your own A3M, and write the input files for AlphaFold 3, Boltz, Chai-1, ColabFold, OpenFold3 or Protenix.
|
|
5
|
+
Author: Scigantic
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Scigantic/scigantic-msa
|
|
8
|
+
Project-URL: Repository, https://github.com/Scigantic/scigantic-msa
|
|
9
|
+
Project-URL: Issues, https://github.com/Scigantic/scigantic-msa/issues
|
|
10
|
+
Keywords: msa,a3m,protein,alphafold3,boltz,chai,colabfold,openfold,protenix,structure-prediction
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Environment :: Console
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Provides-Extra: chai
|
|
25
|
+
Requires-Dist: pyarrow>=12; extra == "chai"
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
28
|
+
Requires-Dist: pyarrow>=12; extra == "dev"
|
|
29
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
# scigantic-msa
|
|
34
|
+
|
|
35
|
+
Get a multiple sequence alignment (MSA) for a protein sequence once, and
|
|
36
|
+
write the input files for the structure predictor you are about to run:
|
|
37
|
+
AlphaFold 3, Boltz, Chai-1, ColabFold, OpenFold3 or Protenix.
|
|
38
|
+
|
|
39
|
+
The alignment comes from the ColabFold MMseqs2 server (or NVIDIA's MSA
|
|
40
|
+
Search, if you have a key), or from an A3M file you already have. There is
|
|
41
|
+
no account and no login, and nothing is stored on our side.
|
|
42
|
+
|
|
43
|
+
## Install
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
pip install scigantic-msa # or: uv tool install scigantic-msa
|
|
47
|
+
pip install 'scigantic-msa[chai]' # adds pyarrow, needed for Chai-1 files
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Python 3.10 or newer. The core has no dependencies.
|
|
51
|
+
|
|
52
|
+
## Privacy
|
|
53
|
+
|
|
54
|
+
Your sequence may be unpublished, so read this before you run a search.
|
|
55
|
+
|
|
56
|
+
- `run` and `MSA().get()` send the sequence to a third-party server:
|
|
57
|
+
api.colabfold.com by default. The public ColabFold server needs no login
|
|
58
|
+
to read a result, and the job id is a hash of the sequence, so anyone who
|
|
59
|
+
knows the sequence can download the result. Treat a submission there as
|
|
60
|
+
publishing the sequence.
|
|
61
|
+
- The Python API refuses to send anything unless you pass `remote=True`.
|
|
62
|
+
The command line says which server will receive the sequence and asks
|
|
63
|
+
once; `--yes` skips the question for scripts. Without a terminal and
|
|
64
|
+
without `--yes`, it stops and sends nothing.
|
|
65
|
+
- `convert` and `MSA().from_a3m()` make no network connection at all.
|
|
66
|
+
- The only network traffic is to the server you chose. The tool never
|
|
67
|
+
contacts a Scigantic server.
|
|
68
|
+
- The sequence is never written to a log. Results are kept in a local cache
|
|
69
|
+
(`~/.cache/scigantic-msa`, or `SCIGANTIC_MSA_CACHE`) so the same sequence
|
|
70
|
+
is not submitted twice; delete the directory to forget them, or pass
|
|
71
|
+
`--no-cache`.
|
|
72
|
+
- `SCIGANTIC_MSA_NO_REMOTE=1` blocks every search, whatever the code asks.
|
|
73
|
+
|
|
74
|
+
The public ColabFold server is a shared resource with a rate limit of about
|
|
75
|
+
one new job per minute per IP address. This client backs off, honours
|
|
76
|
+
Retry-After, resumes a job from its id instead of submitting it again, and
|
|
77
|
+
gives up after a bounded wait. To use your own server, pass `--host URL`
|
|
78
|
+
(or `MSA(host=URL)`).
|
|
79
|
+
|
|
80
|
+
## Command line
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
scigantic-msa run SEQ_OR_FASTA --model boltz --out job/
|
|
84
|
+
scigantic-msa run chains.fasta --model af3 --out job/ --yes
|
|
85
|
+
scigantic-msa convert my_alignment.a3m --model protenix --out job/
|
|
86
|
+
scigantic-msa version
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`--model` is one of `af3`, `boltz`, `chai`, `colabfold`, `openfold3`,
|
|
90
|
+
`protenix`. A FASTA file with several records is one complex, one chain per
|
|
91
|
+
record; `:` inside a sequence also separates chains. `convert` takes one
|
|
92
|
+
A3M (or `.a3m.gz`, or Stockholm `.sto`) per chain, in chain order.
|
|
93
|
+
`--server nvidia` uses NVIDIA's hosted MSA Search and needs
|
|
94
|
+
`NVIDIA_API_KEY`.
|
|
95
|
+
|
|
96
|
+
After writing the files, the command prints the command to run the model
|
|
97
|
+
on them.
|
|
98
|
+
|
|
99
|
+
## Python
|
|
100
|
+
|
|
101
|
+
Every adapter takes one result, or a list of results for the chains of a
|
|
102
|
+
complex. The result carries its sequence; if you also pass the sequence,
|
|
103
|
+
it must match.
|
|
104
|
+
|
|
105
|
+
AlphaFold 3:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
import json
|
|
109
|
+
from scigantic_msa import MSA
|
|
110
|
+
from scigantic_msa.adapters import AlphaFold3
|
|
111
|
+
result = MSA().get(sequence, remote=True)
|
|
112
|
+
json.dump(AlphaFold3.prepare(result, name="job"), open("job.json", "w"))
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Boltz:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from scigantic_msa import MSA
|
|
119
|
+
from scigantic_msa.adapters import Boltz
|
|
120
|
+
result = MSA().get(sequence, remote=True)
|
|
121
|
+
yaml_text = Boltz.prepare(result, out_dir="boltz/")
|
|
122
|
+
open("job.yaml", "w").write(yaml_text) # then: boltz predict job.yaml
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Chai-1:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from scigantic_msa import MSA
|
|
129
|
+
from scigantic_msa.adapters import Chai
|
|
130
|
+
result = MSA().get(sequence, remote=True)
|
|
131
|
+
msa_dir = Chai.prepare(result, out_dir="chai_msas/")
|
|
132
|
+
open("job.fasta", "w").write(Chai.fasta(result)) # chai-lab fold --msa-directory chai_msas/ job.fasta out/
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Protenix:
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
import json
|
|
139
|
+
from scigantic_msa import MSA
|
|
140
|
+
from scigantic_msa.adapters import Protenix
|
|
141
|
+
result = MSA().get(sequence, remote=True)
|
|
142
|
+
json.dump(Protenix.prepare(result, out_dir="protenix_msas/"), open("job.json", "w"))
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
ColabFold and OpenFold3 work the same way: `ColabFold.prepare(result,
|
|
146
|
+
out_dir=...)` returns the path of the A3M for `colabfold_batch`, and
|
|
147
|
+
`OpenFold3.prepare(result, out_dir=...)` returns the query JSON as a dict.
|
|
148
|
+
|
|
149
|
+
With an alignment you already have, and no network:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
result = MSA().from_a3m("my_alignment.a3m", sequence=sequence)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Checks
|
|
156
|
+
|
|
157
|
+
- An A3M is checked strictly: the first record must be the query (no gaps,
|
|
158
|
+
no lowercase), only `A-Z`, `a-z` and `-` are allowed, and every row must
|
|
159
|
+
have as many match columns as the query has residues.
|
|
160
|
+
- Each adapter reads back what it wrote: every file it names exists, is not
|
|
161
|
+
empty, starts with the chain's sequence, and has the name the model looks
|
|
162
|
+
for. Chai-1 skips a chain's MSA without an error when the file name is
|
|
163
|
+
wrong, and Protenix ignores a file in `precomputed_msa_dir` that is not
|
|
164
|
+
called `pairing.a3m` or `non_pairing.a3m`; here both are errors.
|
|
165
|
+
- `Protenix.check(path_or_jobs)` runs the same checks on any Protenix input
|
|
166
|
+
JSON, including a missing `*MsaPath`, which would make Protenix start its
|
|
167
|
+
own MSA search and send the sequence to a server.
|
|
168
|
+
|
|
169
|
+
## Complexes
|
|
170
|
+
|
|
171
|
+
Each chain gets its own unpaired MSA. Rows are paired across chains only
|
|
172
|
+
where the rows say the species: an NCBI taxid (from ColabFold's taxonomy
|
|
173
|
+
output, or `TaxID=` / `OX=` in headers) or a UniProt species code.
|
|
174
|
+
Environmental and metagenomic hits have none and stay unpaired. When
|
|
175
|
+
pairing is not possible the tool says why, for example "no species is
|
|
176
|
+
shared by all chains; the chains get unpaired MSAs".
|
|
177
|
+
|
|
178
|
+
| model | how pairing is passed on |
|
|
179
|
+
| --- | --- |
|
|
180
|
+
| AlphaFold 3 | paired rows first in `unpairedMsa`; run with `--resolve_msa_overlaps=false` (UniProt rows go in `pairedMsa` instead, and AF3 pairs them) |
|
|
181
|
+
| Boltz | one CSV per chain; paired rows share a key |
|
|
182
|
+
| Chai-1 | `pairing_key` column |
|
|
183
|
+
| ColabFold | the complex A3M layout, paired rows first |
|
|
184
|
+
| OpenFold3 | `colabfold_paired.a3m` per chain |
|
|
185
|
+
| Protenix | `pairing.a3m` per chain, with headers Protenix reads the species from; Protenix pairs them |
|
|
186
|
+
|
|
187
|
+
## Formats
|
|
188
|
+
|
|
189
|
+
The file layouts follow the models' own code: AlphaFold 3
|
|
190
|
+
`folding_input.py`, Boltz `main.py` and `parse/csv.py`, Chai-1
|
|
191
|
+
`aligned_pqt.py`, ColabFold `input.py`, OpenFold3 0.5.1
|
|
192
|
+
`inference_query_format.py`, and Protenix 2.0.0 `runner/msa_search.py`,
|
|
193
|
+
`protenix/data/msa/msa_featurizer.py` and `msa_utils.py`.
|
|
194
|
+
|
|
195
|
+
## Data sources and attribution
|
|
196
|
+
|
|
197
|
+
The alignments come from the server you chose, under its terms:
|
|
198
|
+
|
|
199
|
+
- ColabFold MMseqs2 server, run by the ColabFold team. Cite Mirdita et al.,
|
|
200
|
+
ColabFold: making protein folding accessible to all, Nature Methods 19,
|
|
201
|
+
679-682 (2022), and the databases it searches (UniRef30 and the ColabFold
|
|
202
|
+
environmental database).
|
|
203
|
+
- NVIDIA MSA Search (experimental here), under NVIDIA's API trial terms.
|
|
204
|
+
|
|
205
|
+
Every adapter that writes files also writes `scigantic-msa-attribution.json`
|
|
206
|
+
next to them, with the server, mode, date and the terms to credit.
|
|
207
|
+
|
|
208
|
+
## Settings
|
|
209
|
+
|
|
210
|
+
| variable | meaning |
|
|
211
|
+
| --- | --- |
|
|
212
|
+
| `SCIGANTIC_MSA_CACHE` | cache directory (default `~/.cache/scigantic-msa`) |
|
|
213
|
+
| `SCIGANTIC_MSA_NO_REMOTE=1` | never send a sequence to any server |
|
|
214
|
+
| `SCIGANTIC_MSA_COLABFOLD_URL` | another ColabFold MMseqs2 server |
|
|
215
|
+
| `SCIGANTIC_MSA_CONTACT` | text added to the User-Agent sent to the server, such as an email address |
|
|
216
|
+
| `NVIDIA_API_KEY` | key for `--server nvidia` |
|
|
217
|
+
|
|
218
|
+
## Development
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
pip install -e '.[dev]'
|
|
222
|
+
pytest
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
The tests run offline against small real alignment files in
|
|
226
|
+
`tests/fixtures/real` and a local HTTP server standing in for the ColabFold
|
|
227
|
+
and NVIDIA APIs. `tests/test_predictors.py` loads the output with Boltz's
|
|
228
|
+
and Chai-1's own parsers when interpreters with those packages are given;
|
|
229
|
+
see the file for how.
|
|
230
|
+
|
|
231
|
+
## License
|
|
232
|
+
|
|
233
|
+
MIT. The alignments are under the terms of the server and databases they
|
|
234
|
+
came from.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# scigantic-msa
|
|
2
|
+
|
|
3
|
+
Get a multiple sequence alignment (MSA) for a protein sequence once, and
|
|
4
|
+
write the input files for the structure predictor you are about to run:
|
|
5
|
+
AlphaFold 3, Boltz, Chai-1, ColabFold, OpenFold3 or Protenix.
|
|
6
|
+
|
|
7
|
+
The alignment comes from the ColabFold MMseqs2 server (or NVIDIA's MSA
|
|
8
|
+
Search, if you have a key), or from an A3M file you already have. There is
|
|
9
|
+
no account and no login, and nothing is stored on our side.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
pip install scigantic-msa # or: uv tool install scigantic-msa
|
|
15
|
+
pip install 'scigantic-msa[chai]' # adds pyarrow, needed for Chai-1 files
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Python 3.10 or newer. The core has no dependencies.
|
|
19
|
+
|
|
20
|
+
## Privacy
|
|
21
|
+
|
|
22
|
+
Your sequence may be unpublished, so read this before you run a search.
|
|
23
|
+
|
|
24
|
+
- `run` and `MSA().get()` send the sequence to a third-party server:
|
|
25
|
+
api.colabfold.com by default. The public ColabFold server needs no login
|
|
26
|
+
to read a result, and the job id is a hash of the sequence, so anyone who
|
|
27
|
+
knows the sequence can download the result. Treat a submission there as
|
|
28
|
+
publishing the sequence.
|
|
29
|
+
- The Python API refuses to send anything unless you pass `remote=True`.
|
|
30
|
+
The command line says which server will receive the sequence and asks
|
|
31
|
+
once; `--yes` skips the question for scripts. Without a terminal and
|
|
32
|
+
without `--yes`, it stops and sends nothing.
|
|
33
|
+
- `convert` and `MSA().from_a3m()` make no network connection at all.
|
|
34
|
+
- The only network traffic is to the server you chose. The tool never
|
|
35
|
+
contacts a Scigantic server.
|
|
36
|
+
- The sequence is never written to a log. Results are kept in a local cache
|
|
37
|
+
(`~/.cache/scigantic-msa`, or `SCIGANTIC_MSA_CACHE`) so the same sequence
|
|
38
|
+
is not submitted twice; delete the directory to forget them, or pass
|
|
39
|
+
`--no-cache`.
|
|
40
|
+
- `SCIGANTIC_MSA_NO_REMOTE=1` blocks every search, whatever the code asks.
|
|
41
|
+
|
|
42
|
+
The public ColabFold server is a shared resource with a rate limit of about
|
|
43
|
+
one new job per minute per IP address. This client backs off, honours
|
|
44
|
+
Retry-After, resumes a job from its id instead of submitting it again, and
|
|
45
|
+
gives up after a bounded wait. To use your own server, pass `--host URL`
|
|
46
|
+
(or `MSA(host=URL)`).
|
|
47
|
+
|
|
48
|
+
## Command line
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
scigantic-msa run SEQ_OR_FASTA --model boltz --out job/
|
|
52
|
+
scigantic-msa run chains.fasta --model af3 --out job/ --yes
|
|
53
|
+
scigantic-msa convert my_alignment.a3m --model protenix --out job/
|
|
54
|
+
scigantic-msa version
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`--model` is one of `af3`, `boltz`, `chai`, `colabfold`, `openfold3`,
|
|
58
|
+
`protenix`. A FASTA file with several records is one complex, one chain per
|
|
59
|
+
record; `:` inside a sequence also separates chains. `convert` takes one
|
|
60
|
+
A3M (or `.a3m.gz`, or Stockholm `.sto`) per chain, in chain order.
|
|
61
|
+
`--server nvidia` uses NVIDIA's hosted MSA Search and needs
|
|
62
|
+
`NVIDIA_API_KEY`.
|
|
63
|
+
|
|
64
|
+
After writing the files, the command prints the command to run the model
|
|
65
|
+
on them.
|
|
66
|
+
|
|
67
|
+
## Python
|
|
68
|
+
|
|
69
|
+
Every adapter takes one result, or a list of results for the chains of a
|
|
70
|
+
complex. The result carries its sequence; if you also pass the sequence,
|
|
71
|
+
it must match.
|
|
72
|
+
|
|
73
|
+
AlphaFold 3:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import json
|
|
77
|
+
from scigantic_msa import MSA
|
|
78
|
+
from scigantic_msa.adapters import AlphaFold3
|
|
79
|
+
result = MSA().get(sequence, remote=True)
|
|
80
|
+
json.dump(AlphaFold3.prepare(result, name="job"), open("job.json", "w"))
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Boltz:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from scigantic_msa import MSA
|
|
87
|
+
from scigantic_msa.adapters import Boltz
|
|
88
|
+
result = MSA().get(sequence, remote=True)
|
|
89
|
+
yaml_text = Boltz.prepare(result, out_dir="boltz/")
|
|
90
|
+
open("job.yaml", "w").write(yaml_text) # then: boltz predict job.yaml
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Chai-1:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from scigantic_msa import MSA
|
|
97
|
+
from scigantic_msa.adapters import Chai
|
|
98
|
+
result = MSA().get(sequence, remote=True)
|
|
99
|
+
msa_dir = Chai.prepare(result, out_dir="chai_msas/")
|
|
100
|
+
open("job.fasta", "w").write(Chai.fasta(result)) # chai-lab fold --msa-directory chai_msas/ job.fasta out/
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Protenix:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
import json
|
|
107
|
+
from scigantic_msa import MSA
|
|
108
|
+
from scigantic_msa.adapters import Protenix
|
|
109
|
+
result = MSA().get(sequence, remote=True)
|
|
110
|
+
json.dump(Protenix.prepare(result, out_dir="protenix_msas/"), open("job.json", "w"))
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
ColabFold and OpenFold3 work the same way: `ColabFold.prepare(result,
|
|
114
|
+
out_dir=...)` returns the path of the A3M for `colabfold_batch`, and
|
|
115
|
+
`OpenFold3.prepare(result, out_dir=...)` returns the query JSON as a dict.
|
|
116
|
+
|
|
117
|
+
With an alignment you already have, and no network:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
result = MSA().from_a3m("my_alignment.a3m", sequence=sequence)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Checks
|
|
124
|
+
|
|
125
|
+
- An A3M is checked strictly: the first record must be the query (no gaps,
|
|
126
|
+
no lowercase), only `A-Z`, `a-z` and `-` are allowed, and every row must
|
|
127
|
+
have as many match columns as the query has residues.
|
|
128
|
+
- Each adapter reads back what it wrote: every file it names exists, is not
|
|
129
|
+
empty, starts with the chain's sequence, and has the name the model looks
|
|
130
|
+
for. Chai-1 skips a chain's MSA without an error when the file name is
|
|
131
|
+
wrong, and Protenix ignores a file in `precomputed_msa_dir` that is not
|
|
132
|
+
called `pairing.a3m` or `non_pairing.a3m`; here both are errors.
|
|
133
|
+
- `Protenix.check(path_or_jobs)` runs the same checks on any Protenix input
|
|
134
|
+
JSON, including a missing `*MsaPath`, which would make Protenix start its
|
|
135
|
+
own MSA search and send the sequence to a server.
|
|
136
|
+
|
|
137
|
+
## Complexes
|
|
138
|
+
|
|
139
|
+
Each chain gets its own unpaired MSA. Rows are paired across chains only
|
|
140
|
+
where the rows say the species: an NCBI taxid (from ColabFold's taxonomy
|
|
141
|
+
output, or `TaxID=` / `OX=` in headers) or a UniProt species code.
|
|
142
|
+
Environmental and metagenomic hits have none and stay unpaired. When
|
|
143
|
+
pairing is not possible the tool says why, for example "no species is
|
|
144
|
+
shared by all chains; the chains get unpaired MSAs".
|
|
145
|
+
|
|
146
|
+
| model | how pairing is passed on |
|
|
147
|
+
| --- | --- |
|
|
148
|
+
| AlphaFold 3 | paired rows first in `unpairedMsa`; run with `--resolve_msa_overlaps=false` (UniProt rows go in `pairedMsa` instead, and AF3 pairs them) |
|
|
149
|
+
| Boltz | one CSV per chain; paired rows share a key |
|
|
150
|
+
| Chai-1 | `pairing_key` column |
|
|
151
|
+
| ColabFold | the complex A3M layout, paired rows first |
|
|
152
|
+
| OpenFold3 | `colabfold_paired.a3m` per chain |
|
|
153
|
+
| Protenix | `pairing.a3m` per chain, with headers Protenix reads the species from; Protenix pairs them |
|
|
154
|
+
|
|
155
|
+
## Formats
|
|
156
|
+
|
|
157
|
+
The file layouts follow the models' own code: AlphaFold 3
|
|
158
|
+
`folding_input.py`, Boltz `main.py` and `parse/csv.py`, Chai-1
|
|
159
|
+
`aligned_pqt.py`, ColabFold `input.py`, OpenFold3 0.5.1
|
|
160
|
+
`inference_query_format.py`, and Protenix 2.0.0 `runner/msa_search.py`,
|
|
161
|
+
`protenix/data/msa/msa_featurizer.py` and `msa_utils.py`.
|
|
162
|
+
|
|
163
|
+
## Data sources and attribution
|
|
164
|
+
|
|
165
|
+
The alignments come from the server you chose, under its terms:
|
|
166
|
+
|
|
167
|
+
- ColabFold MMseqs2 server, run by the ColabFold team. Cite Mirdita et al.,
|
|
168
|
+
ColabFold: making protein folding accessible to all, Nature Methods 19,
|
|
169
|
+
679-682 (2022), and the databases it searches (UniRef30 and the ColabFold
|
|
170
|
+
environmental database).
|
|
171
|
+
- NVIDIA MSA Search (experimental here), under NVIDIA's API trial terms.
|
|
172
|
+
|
|
173
|
+
Every adapter that writes files also writes `scigantic-msa-attribution.json`
|
|
174
|
+
next to them, with the server, mode, date and the terms to credit.
|
|
175
|
+
|
|
176
|
+
## Settings
|
|
177
|
+
|
|
178
|
+
| variable | meaning |
|
|
179
|
+
| --- | --- |
|
|
180
|
+
| `SCIGANTIC_MSA_CACHE` | cache directory (default `~/.cache/scigantic-msa`) |
|
|
181
|
+
| `SCIGANTIC_MSA_NO_REMOTE=1` | never send a sequence to any server |
|
|
182
|
+
| `SCIGANTIC_MSA_COLABFOLD_URL` | another ColabFold MMseqs2 server |
|
|
183
|
+
| `SCIGANTIC_MSA_CONTACT` | text added to the User-Agent sent to the server, such as an email address |
|
|
184
|
+
| `NVIDIA_API_KEY` | key for `--server nvidia` |
|
|
185
|
+
|
|
186
|
+
## Development
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
pip install -e '.[dev]'
|
|
190
|
+
pytest
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The tests run offline against small real alignment files in
|
|
194
|
+
`tests/fixtures/real` and a local HTTP server standing in for the ColabFold
|
|
195
|
+
and NVIDIA APIs. `tests/test_predictors.py` loads the output with Boltz's
|
|
196
|
+
and Chai-1's own parsers when interpreters with those packages are given;
|
|
197
|
+
see the file for how.
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
MIT. The alignments are under the terms of the server and databases they
|
|
202
|
+
came from.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "scigantic-msa"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Get a protein MSA once from the ColabFold MMseqs2 server, or bring your own A3M, and write the input files for AlphaFold 3, Boltz, Chai-1, ColabFold, OpenFold3 or Protenix."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Scigantic" }]
|
|
13
|
+
keywords = ["msa", "a3m", "protein", "alphafold3", "boltz", "chai", "colabfold", "openfold", "protenix", "structure-prediction"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
"Environment :: Console",
|
|
23
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
24
|
+
"Typing :: Typed",
|
|
25
|
+
]
|
|
26
|
+
dependencies = []
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
# Chai-1 reads aligned parquet files.
|
|
30
|
+
chai = ["pyarrow>=12"]
|
|
31
|
+
dev = ["pytest>=7", "pyarrow>=12", "mypy>=1.10", "ruff>=0.5"]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/Scigantic/scigantic-msa"
|
|
35
|
+
Repository = "https://github.com/Scigantic/scigantic-msa"
|
|
36
|
+
Issues = "https://github.com/Scigantic/scigantic-msa/issues"
|
|
37
|
+
|
|
38
|
+
[project.scripts]
|
|
39
|
+
scigantic-msa = "scigantic_msa.cli:main"
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.packages.find]
|
|
42
|
+
where = ["src"]
|
|
43
|
+
|
|
44
|
+
[tool.setuptools.package-data]
|
|
45
|
+
scigantic_msa = ["py.typed"]
|
|
46
|
+
|
|
47
|
+
[tool.pytest.ini_options]
|
|
48
|
+
testpaths = ["tests"]
|
|
49
|
+
markers = [
|
|
50
|
+
"predictors: loads outputs with the predictors' own parsers (needs them installed)",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[tool.ruff]
|
|
54
|
+
line-length = 120
|
|
55
|
+
target-version = "py310"
|
|
56
|
+
|
|
57
|
+
[tool.ruff.lint]
|
|
58
|
+
select = ["E", "F", "W", "B"]
|
|
59
|
+
ignore = ["E501", "E741", "B904", "B008", "B905"]
|
|
60
|
+
|
|
61
|
+
[tool.mypy]
|
|
62
|
+
python_version = "3.10"
|
|
63
|
+
warn_unused_ignores = false
|
|
64
|
+
ignore_missing_imports = true
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""scigantic-msa: one command from a protein sequence to the MSA input files
|
|
2
|
+
a structure predictor reads.
|
|
3
|
+
|
|
4
|
+
from scigantic_msa import MSA
|
|
5
|
+
from scigantic_msa.adapters import AlphaFold3, Boltz
|
|
6
|
+
|
|
7
|
+
result = MSA().get(sequence, remote=True) # sends the sequence to api.colabfold.com
|
|
8
|
+
af3_input = AlphaFold3.prepare(result) # dict ready for json.dump
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
__version__ = "0.2.0"
|
|
12
|
+
|
|
13
|
+
from .seqkey import InvalidSequence, canonical_sequence, seq_sha256 # noqa: E402
|
|
14
|
+
from .a3m import A3MError, Row, parse_a3m, parse_stockholm # noqa: E402
|
|
15
|
+
from .alignment import Alignment, SOURCES # noqa: E402
|
|
16
|
+
from .remote import ColabFoldClient, NvidiaClient, RemoteError # noqa: E402
|
|
17
|
+
from .tool import MSA, RemoteNotAllowed # noqa: E402
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"__version__",
|
|
21
|
+
"MSA", "Alignment", "SOURCES", "RemoteNotAllowed", "RemoteError",
|
|
22
|
+
"seq_sha256", "canonical_sequence", "InvalidSequence",
|
|
23
|
+
"parse_a3m", "parse_stockholm", "Row", "A3MError",
|
|
24
|
+
"ColabFoldClient", "NvidiaClient",
|
|
25
|
+
]
|