phasepred 1.0.0__tar.gz → 1.0.2__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.
- phasepred-1.0.2/CHANGELOG.md +40 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/MANIFEST.in +2 -1
- {phasepred-1.0.0/src/phasepred.egg-info → phasepred-1.0.2}/PKG-INFO +19 -14
- {phasepred-1.0.0 → phasepred-1.0.2}/README-pypi.md +18 -13
- {phasepred-1.0.0 → phasepred-1.0.2}/README.md +43 -10
- {phasepred-1.0.0 → phasepred-1.0.2}/pyproject.toml +1 -1
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/__init__.py +1 -1
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/cli.py +33 -3
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/DeepCoil/README.md +7 -7
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/DeepCoil/manifest.toml +1 -1
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PScore/README.md +4 -3
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PScore/install.sh +1 -1
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PScore/manifest.toml +1 -1
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PScore/run +38 -1
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/features.py +9 -1
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/predictor.py +4 -3
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/tool_features.py +5 -2
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/tools.py +84 -68
- {phasepred-1.0.0 → phasepred-1.0.2/src/phasepred.egg-info}/PKG-INFO +19 -14
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred.egg-info/SOURCES.txt +1 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_check_tools_table.py +6 -2
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_cli.py +14 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_features.py +28 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_tool_contract_drift.py +77 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_v2022.py +46 -1
- {phasepred-1.0.0 → phasepred-1.0.2}/LICENSE +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/NOTICE +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/environment.yml +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/CHANGELOG.md +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/README.md +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/pyproject.toml +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/scripts/_s4_numeric.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/scripts/bootstrap_web_benchmark.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/scripts/eval_routes.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/scripts/reproduce_distilled.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/__init__.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/_distill.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/cli.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/scoring.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/surrogate.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/weights/catgranule_distilled_weights.json +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/weights/catgranule_paper_weights.json +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/weights/catgranule_v1_weights.json +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/weights/distilled_xgb_model.ubj +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/src/catgranule/weights.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/tests/fixtures/P35637.fasta +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/tests/fixtures/Q08211.fasta +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/tests/test_catgranule_cli.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/packages/catgranule/tests/test_scoring.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/scripts/check_no_proprietary.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/scripts/train_phasepred.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/scripts/validate_phasepred.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/setup.cfg +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/deepphase/LICENSE +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/deepphase/NOTICE +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/deepphase/deepphase_scores.tsv +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_0.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_1.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_2.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_3.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_4.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_5.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_6.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_7.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_8.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/8f_model_9.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/PdPS/manifest.json +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_0.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_1.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_2.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_3.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_4.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_5.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_6.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_7.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_8.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/8f_model_9.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/SaPS/manifest.json +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_0.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_1.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_2.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_3.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_4.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_5.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_6.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_7.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_8.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/8f_model_9.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hPdPS/manifest.json +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_0.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_1.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_2.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_3.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_4.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_5.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_6.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_7.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_8.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/8f_model_9.joblib +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/models/hSaPS/manifest.json +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/DeepCoil/install.sh +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/DeepCoil/run +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/ESpritz/README.md +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/ESpritz/install.sh +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/ESpritz/manifest.toml +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/ESpritz/run +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/LocalCIDER/README.md +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/LocalCIDER/install.sh +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/LocalCIDER/manifest.toml +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/LocalCIDER/run +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PLAAC/README.md +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PLAAC/install.sh +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PLAAC/manifest.toml +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PLAAC/plaac-master/web/bin/plaac.jar +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PLAAC/run +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PScore/SourceCodeS2/README.txt +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/PScore/SourceCodeS2/elife_phase_separation_predictor.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/README.md +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/SEG/README.md +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/SEG/install.sh +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/SEG/manifest.toml +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/SEG/run +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data/tools/SEG/seg +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/data.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/espritz.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/legacy_features.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/models.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/paper.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/sequences.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/tool_paths.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/training.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/training_data.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/updated_data.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred/validation.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred.egg-info/dependency_links.txt +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred.egg-info/entry_points.txt +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred.egg-info/requires.txt +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/src/phasepred.egg-info/top_level.txt +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_cwd.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_data_resolution.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_demo_scripts.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_golden_fixtures.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_models.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_paper.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_sequences.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_train_phasepred.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_training.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_training_data.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_training_data_integrity.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_training_data_real.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_validation.py +0 -0
- {phasepred-1.0.0 → phasepred-1.0.2}/tests/test_version_consistency.py +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.0.2] - 2026-09-28
|
|
4
|
+
|
|
5
|
+
Patch release for the 1.0.1 installation feedback. Model artifacts and
|
|
6
|
+
training data are unchanged.
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- Use `python3` in the Ubuntu venv examples.
|
|
11
|
+
- Document DeepCoil's user-data installation path and show it in missing-tool
|
|
12
|
+
guidance; keep the legacy checkout environment as a fallback.
|
|
13
|
+
- Show the PScore install command when `check-tools` reports it missing.
|
|
14
|
+
- Let the checkout PScore runner find DBS in the installed user-data copy and
|
|
15
|
+
accept relative FASTA and output paths when invoked on its own.
|
|
16
|
+
|
|
17
|
+
## [1.0.1] - 2026-09-28
|
|
18
|
+
|
|
19
|
+
Patch release based on installation and prediction feedback. Model artifacts
|
|
20
|
+
and training data are unchanged.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- PScore's `install.sh --check` now checks the installed user-data copy instead
|
|
25
|
+
of mistakenly checking for DBS files in the repository.
|
|
26
|
+
- PhaSePred sends DeepCoil smaller sequence groups to reduce peak memory use
|
|
27
|
+
during batch prediction. A failed group reports a warning without discarding
|
|
28
|
+
successful groups; sequences shorter than 20 residues get a specific warning.
|
|
29
|
+
- FCR remains available for sequences containing selenocysteine (`U`) even
|
|
30
|
+
when the Hydropathy scale cannot score that residue.
|
|
31
|
+
|
|
32
|
+
### Improved
|
|
33
|
+
|
|
34
|
+
- `predict` identifies proteins with missing features before the model imputes
|
|
35
|
+
those values and calculates a score.
|
|
36
|
+
- The READMEs clarify that `features-from-fasta` computes four features and
|
|
37
|
+
that individual tool checks can be silent on success.
|
|
38
|
+
|
|
39
|
+
The local catGRANULE scale has no value for `U`, so catGRANULE remains missing
|
|
40
|
+
for such sequences and is imputed during prediction.
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
# pixi.toml/pixi.lock, and the CI workflow. pip installs the package from the
|
|
21
21
|
# index; the repository remains the route for training on the paper data.
|
|
22
22
|
include environment.yml
|
|
23
|
+
include CHANGELOG.md
|
|
23
24
|
include NOTICE
|
|
24
25
|
include README-pypi.md
|
|
25
26
|
recursive-include scripts *.py *.sh *.md
|
|
@@ -31,4 +32,4 @@ recursive-include packages/catgranule/src *.py *.json *.ubj
|
|
|
31
32
|
recursive-include packages/catgranule/tests *.py *.fasta
|
|
32
33
|
recursive-include packages/catgranule/scripts *.py
|
|
33
34
|
|
|
34
|
-
global-exclude *.py[cod]
|
|
35
|
+
global-exclude *.py[cod]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: phasepred
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
4
4
|
Summary: Paper-faithful re-implementation of the PhaSePred phase-separation predictor (Chen et al. 2022, PNAS).
|
|
5
5
|
Author: Tingting Li Lab, Department of Biochemistry and Molecular Biology, School of Basic Medical Sciences, Peking University
|
|
6
6
|
License-Expression: MIT
|
|
@@ -48,7 +48,24 @@ Implementation of [Chen et al. 2022 *PNAS*](https://doi.org/10.1073/pnas.2115369
|
|
|
48
48
|
pip install phasepred
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
Requires Python >= 3.12.
|
|
51
|
+
Requires Python >= 3.12. The models and the DeepPhase table ship inside the
|
|
52
|
+
package.
|
|
53
|
+
|
|
54
|
+
Four feature components cannot be redistributed and need a one-time install from
|
|
55
|
+
the repository:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone https://github.com/notwhiteblank/PhaSePred.git && cd PhaSePred
|
|
59
|
+
bash tools/PScore/install.sh
|
|
60
|
+
bash tools/ESpritz/install.sh
|
|
61
|
+
bash tools/DeepCoil/install.sh
|
|
62
|
+
bash tools/PhosphoSitePlus/install.sh # only needed for hSaPS / hPdPS
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The installers put their data under `~/.local/share/phasepred/`, where the
|
|
66
|
+
package finds it automatically. `phasepred check-tools` prints a status row per
|
|
67
|
+
component, and for every missing one the exact command that installs it. A
|
|
68
|
+
complete install reports `9 OK`.
|
|
52
69
|
|
|
53
70
|
## Use
|
|
54
71
|
|
|
@@ -65,18 +82,6 @@ Input can also be UniProt accessions:
|
|
|
65
82
|
phasepred predict --ids "P35637,Q9Y2W1" --mode SaPS --output scores.csv
|
|
66
83
|
```
|
|
67
84
|
|
|
68
|
-
## Feature tools
|
|
69
|
-
|
|
70
|
-
Five of the nine feature components ship with the package and work immediately.
|
|
71
|
-
The rest need a one-time install:
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
phasepred check-tools
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
This prints a status row per component, and for every missing one the exact
|
|
78
|
-
command that installs it.
|
|
79
|
-
|
|
80
85
|
## More
|
|
81
86
|
|
|
82
87
|
Source, training data, retraining and AUC validation against the paper:
|
|
@@ -9,7 +9,24 @@ Implementation of [Chen et al. 2022 *PNAS*](https://doi.org/10.1073/pnas.2115369
|
|
|
9
9
|
pip install phasepred
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
Requires Python >= 3.12.
|
|
12
|
+
Requires Python >= 3.12. The models and the DeepPhase table ship inside the
|
|
13
|
+
package.
|
|
14
|
+
|
|
15
|
+
Four feature components cannot be redistributed and need a one-time install from
|
|
16
|
+
the repository:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git clone https://github.com/notwhiteblank/PhaSePred.git && cd PhaSePred
|
|
20
|
+
bash tools/PScore/install.sh
|
|
21
|
+
bash tools/ESpritz/install.sh
|
|
22
|
+
bash tools/DeepCoil/install.sh
|
|
23
|
+
bash tools/PhosphoSitePlus/install.sh # only needed for hSaPS / hPdPS
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The installers put their data under `~/.local/share/phasepred/`, where the
|
|
27
|
+
package finds it automatically. `phasepred check-tools` prints a status row per
|
|
28
|
+
component, and for every missing one the exact command that installs it. A
|
|
29
|
+
complete install reports `9 OK`.
|
|
13
30
|
|
|
14
31
|
## Use
|
|
15
32
|
|
|
@@ -26,18 +43,6 @@ Input can also be UniProt accessions:
|
|
|
26
43
|
phasepred predict --ids "P35637,Q9Y2W1" --mode SaPS --output scores.csv
|
|
27
44
|
```
|
|
28
45
|
|
|
29
|
-
## Feature tools
|
|
30
|
-
|
|
31
|
-
Five of the nine feature components ship with the package and work immediately.
|
|
32
|
-
The rest need a one-time install:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
phasepred check-tools
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
This prints a status row per component, and for every missing one the exact
|
|
39
|
-
command that installs it.
|
|
40
|
-
|
|
41
46
|
## More
|
|
42
47
|
|
|
43
48
|
Source, training data, retraining and AUC validation against the paper:
|
|
@@ -40,16 +40,24 @@ The ten features, of which the 8-feature modes use all but the last two:
|
|
|
40
40
|
|
|
41
41
|
### Install
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Python `>=3.12`. Clone the repository and install:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
conda env create -f environment.yml && conda activate phasepred # conda
|
|
49
|
-
python -m venv .venv && .venv/bin/pip install -e . -e packages/catgranule # plain venv
|
|
46
|
+
git clone https://github.com/notwhiteblank/PhaSePred.git && cd PhaSePred
|
|
47
|
+
pixi install
|
|
50
48
|
```
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
`uv`, `conda` and a plain venv work just as well:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
uv venv --python 3.12 && uv pip install .
|
|
54
|
+
conda env create -f environment.yml && conda activate phasepred
|
|
55
|
+
python3 -m venv .venv && .venv/bin/pip install -e . -e packages/catgranule
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Then install the external feature tools. Each installer is idempotent and puts
|
|
59
|
+
its data under `~/.local/share/phasepred/`, where the package finds it
|
|
60
|
+
automatically:
|
|
53
61
|
|
|
54
62
|
```bash
|
|
55
63
|
bash tools/SEG/install.sh
|
|
@@ -61,14 +69,21 @@ bash tools/LocalCIDER/install.sh
|
|
|
61
69
|
bash tools/PhosphoSitePlus/install.sh # only needed for hSaPS / hPdPS
|
|
62
70
|
```
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
`check-tools` confirms the result; a complete install reports `9 OK`:
|
|
65
73
|
|
|
66
74
|
```bash
|
|
67
|
-
phasepred check-tools # table, with an install hint
|
|
75
|
+
phasepred check-tools # status table, with an install hint per missing component
|
|
68
76
|
phasepred check-tools --strict # exits 1 when a required tool is missing; use this in scripts and CI
|
|
69
77
|
```
|
|
70
78
|
|
|
71
|
-
|
|
79
|
+
The models and the DeepPhase table ship inside the package, so nothing else is
|
|
80
|
+
needed to predict. `SEG`, `PLAAC`, `LocalCIDER` and `catGRANULE` also ship with
|
|
81
|
+
it; the installers above cover the four components that cannot be redistributed.
|
|
82
|
+
|
|
83
|
+
Installing from PyPI instead (`pip install phasepred`) gives you the same
|
|
84
|
+
package. The tool installers live in `tools/`, which is part of the repository
|
|
85
|
+
rather than the wheel, so clone it to run them — after that everything resolves
|
|
86
|
+
the same way.
|
|
72
87
|
|
|
73
88
|
### Run
|
|
74
89
|
|
|
@@ -93,7 +108,25 @@ phasepred predict --fasta my.fasta --ids "P35637" --mode SaPS --output scores.cs
|
|
|
93
108
|
phasepred features-from-fasta --input my.fasta --output features.csv
|
|
94
109
|
```
|
|
95
110
|
|
|
96
|
-
The output CSV carries
|
|
111
|
+
The `predict` output CSV carries every model feature alongside `score`. If a
|
|
112
|
+
feature is unavailable for a protein, `predict` lists the missing columns on
|
|
113
|
+
stderr and the model imputes them before scoring. A score with missing features
|
|
114
|
+
should be interpreted with that limitation. For example, selenocysteine (`U`)
|
|
115
|
+
has no value in the local catGRANULE scale, so that feature stays empty; FCR
|
|
116
|
+
is still computed from the charged residues in the original sequence.
|
|
117
|
+
|
|
118
|
+
`features-from-fasta` is a smaller four-feature command: Hydropathy, FCR,
|
|
119
|
+
ESpritz IDR fraction, and SEG LCR fraction. Use `predict` when the complete
|
|
120
|
+
model feature table is needed.
|
|
121
|
+
|
|
122
|
+
DeepCoil predictions are sent in bounded groups (at most four proteins and
|
|
123
|
+
normally 4,000 residues per call; a single longer protein stays intact) to
|
|
124
|
+
reduce peak memory use. A failed group emits a
|
|
125
|
+
warning and its DeepCoil values are imputed. If the operating system still
|
|
126
|
+
kills a group for memory, split the FASTA into smaller files or increase the
|
|
127
|
+
available memory. Sequences shorter than 20 residues are skipped with a
|
|
128
|
+
specific warning. `phasepred check-tools` is the consolidated status display;
|
|
129
|
+
individual `run --check` commands may be silent when they succeed.
|
|
97
130
|
|
|
98
131
|
## Reproduction
|
|
99
132
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "phasepred"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.2"
|
|
4
4
|
description = "Paper-faithful re-implementation of the PhaSePred phase-separation predictor (Chen et al. 2022, PNAS)."
|
|
5
5
|
readme = { file = "README-pypi.md", content-type = "text/markdown" }
|
|
6
6
|
license = "MIT"
|
|
@@ -18,7 +18,7 @@ from sklearn.metrics import average_precision_score, roc_auc_score
|
|
|
18
18
|
|
|
19
19
|
from phasepred import __version__ as _phasepred_version
|
|
20
20
|
from phasepred import data
|
|
21
|
-
from phasepred.features import FeatureSchemaError, compute_native_features
|
|
21
|
+
from phasepred.features import FeatureSchemaError, compute_fcr, compute_native_features
|
|
22
22
|
from phasepred.legacy_features import (
|
|
23
23
|
compute_lcr_features,
|
|
24
24
|
compute_phosphosite_frequencies,
|
|
@@ -143,10 +143,23 @@ def features_from_fasta(
|
|
|
143
143
|
idr_rows = _compute_espritz_idr_fraction(records)
|
|
144
144
|
lcr_rows = _compute_lcr_fraction(records)
|
|
145
145
|
for record in records:
|
|
146
|
+
try:
|
|
147
|
+
native = compute_native_features(record.sequence)
|
|
148
|
+
except FeatureSchemaError as exc:
|
|
149
|
+
native = {
|
|
150
|
+
"length": float(len(record.sequence)),
|
|
151
|
+
"Hydropathy": float("nan"),
|
|
152
|
+
"FCR": compute_fcr(record.sequence),
|
|
153
|
+
}
|
|
154
|
+
typer.echo(
|
|
155
|
+
f"WARNING: {record.accession}: Hydropathy unavailable ({exc}); "
|
|
156
|
+
"FCR was computed from the original sequence.",
|
|
157
|
+
err=True,
|
|
158
|
+
)
|
|
146
159
|
row = {
|
|
147
160
|
"UniprotEntry": record.accession,
|
|
148
161
|
"sequence": record.sequence,
|
|
149
|
-
**
|
|
162
|
+
**native,
|
|
150
163
|
}
|
|
151
164
|
row["espritz-idr-fraction"] = idr_rows.get(record.accession, float("nan"))
|
|
152
165
|
row["lcr-fraction"] = lcr_rows.get(record.accession, float("nan"))
|
|
@@ -593,6 +606,24 @@ def predict(
|
|
|
593
606
|
typer.echo(f"Computing features for {len(records)} protein(s), mode={mode}...")
|
|
594
607
|
feature_df = compute_all_features(records, include_human=is_human)
|
|
595
608
|
|
|
609
|
+
columns = HUMAN_FEATURE_COLUMNS if is_human else BASE_FEATURE_COLUMNS
|
|
610
|
+
missing_by_row = feature_df[list(columns)].isna()
|
|
611
|
+
affected = missing_by_row.any(axis=1)
|
|
612
|
+
if affected.any():
|
|
613
|
+
typer.echo(
|
|
614
|
+
f"WARNING: {int(affected.sum())}/{len(feature_df)} protein(s) have missing "
|
|
615
|
+
"features; the model will impute them before scoring.",
|
|
616
|
+
err=True,
|
|
617
|
+
)
|
|
618
|
+
for index in feature_df.index[affected][:8]:
|
|
619
|
+
absent = [column for column in columns if missing_by_row.loc[index, column]]
|
|
620
|
+
typer.echo(
|
|
621
|
+
f" {feature_df.loc[index, 'UniprotEntry']}: {', '.join(absent)}",
|
|
622
|
+
err=True,
|
|
623
|
+
)
|
|
624
|
+
if affected.sum() > 8:
|
|
625
|
+
typer.echo(f" ... and {int(affected.sum()) - 8} more", err=True)
|
|
626
|
+
|
|
596
627
|
# Load model(s)
|
|
597
628
|
model_path_or_dir = chosen_models_dir / f"{mode}.joblib"
|
|
598
629
|
if model_path_or_dir.exists():
|
|
@@ -632,7 +663,6 @@ def predict(
|
|
|
632
663
|
)
|
|
633
664
|
|
|
634
665
|
# Predict
|
|
635
|
-
columns = HUMAN_FEATURE_COLUMNS if is_human else BASE_FEATURE_COLUMNS
|
|
636
666
|
predictions = predict_scores(models, feature_df, list(columns))
|
|
637
667
|
|
|
638
668
|
# Merge features for informative output
|
|
@@ -27,8 +27,10 @@ tools/DeepCoil/
|
|
|
27
27
|
└── README.md this file
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
No entity is vendored — the tool lives in an isolated Python 3.8 conda env
|
|
31
|
-
|
|
30
|
+
No entity is vendored — the tool lives in an isolated Python 3.8 conda env.
|
|
31
|
+
New installations use `~/.local/share/phasepred/envs/deepcoil` by default,
|
|
32
|
+
or `$XDG_DATA_HOME/phasepred/envs/deepcoil` / `$PHASEPRED_DATA_ROOT/envs/deepcoil`
|
|
33
|
+
when set. Existing `.external_envs/deepcoil` environments remain supported.
|
|
32
34
|
|
|
33
35
|
## Install
|
|
34
36
|
|
|
@@ -38,14 +40,12 @@ bash tools/DeepCoil/install.sh --check # verify env/bin/deepcoil present
|
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
Overrides: `DEEPCOIL_ENV_PREFIX=/path/to/env DEEPCOIL_PYTHON_VERSION=3.8
|
|
41
|
-
DEEPCOIL_VERSION=2.0.2`. The
|
|
42
|
-
|
|
43
|
-
`env_prefix` and the wrapper's `DEEPCOIL_ENV_PREFIX` override agree.
|
|
43
|
+
DEEPCOIL_VERSION=2.0.2`. The `manifest.toml` `[runtime]` prefix names the
|
|
44
|
+
legacy checkout fallback; the installer and runner prefer the user data root.
|
|
44
45
|
|
|
45
46
|
## Usage
|
|
46
47
|
|
|
47
48
|
```bash
|
|
48
|
-
DEEPCOIL_ENV_PREFIX="$PWD/.external_envs/deepcoil" \
|
|
49
49
|
tools/DeepCoil/run -i in.fasta -out_path /tmp/dc_out -n_cpu 4
|
|
50
50
|
tools/DeepCoil/run --check
|
|
51
51
|
```
|
|
@@ -58,4 +58,4 @@ DeepCoil sanitizes output filenames (alnum + `_`). Writes
|
|
|
58
58
|
## Attribution
|
|
59
59
|
|
|
60
60
|
Reference the DeepCoil meta-server page / Ludwiczak et al. (2019) when
|
|
61
|
-
publishing scores produced by this tool.
|
|
61
|
+
publishing scores produced by this tool.
|
|
@@ -15,4 +15,4 @@ description = "Writes per-accession '<safe_id>.out' tab-separated files (aa, cc,
|
|
|
15
15
|
|
|
16
16
|
[install]
|
|
17
17
|
command = "bash tools/DeepCoil/install.sh"
|
|
18
|
-
hint = "DeepCoil has no upstream license (not redistributable).
|
|
18
|
+
hint = "DeepCoil has no upstream license (not redistributable). Install the isolated Python 3.8 env with deepcoil==2.0.2: bash tools/DeepCoil/install.sh (default: ~/.local/share/phasepred/envs/deepcoil; override with DEEPCOIL_ENV_PREFIX)."
|
|
@@ -43,8 +43,9 @@ bash tools/PScore/install.sh --check # verify predictor + DBS present
|
|
|
43
43
|
|
|
44
44
|
## Usage
|
|
45
45
|
|
|
46
|
-
Run from anywhere
|
|
47
|
-
|
|
46
|
+
Run from anywhere with relative or absolute FASTA and output paths. The wrapper
|
|
47
|
+
uses the installed user-data `SourceCodeS2/DBS/` when the checkout has no DBS,
|
|
48
|
+
then changes into `SourceCodeS2/` as required by the predictor:
|
|
48
49
|
|
|
49
50
|
```bash
|
|
50
51
|
tools/PScore/run input.fasta -output pscore.tsv -overwrite -mute
|
|
@@ -62,4 +63,4 @@ Standard output: one `PScore: <value> >ACC` line per scored accession
|
|
|
62
63
|
|
|
63
64
|
Carry the reference above and the CC-BY 4.0 notice. The archived
|
|
64
65
|
`SourceCodeS2/README.txt` documents the original authors. Data derived from
|
|
65
|
-
the upstream `DBS/` must be attributed to Vernon et al. (2018).
|
|
66
|
+
the upstream `DBS/` must be attributed to Vernon et al. (2018).
|
|
@@ -85,7 +85,7 @@ policy="$(manifest_get sha256_policy)"
|
|
|
85
85
|
if [[ "$mode" == "check" ]]; then
|
|
86
86
|
if available_in "$target"; then
|
|
87
87
|
echo "PScore: ok ($target)"
|
|
88
|
-
exec "$
|
|
88
|
+
exec "$target/run" --check
|
|
89
89
|
fi
|
|
90
90
|
if available_in "$pkg_dir"; then
|
|
91
91
|
echo "PScore: ok ($pkg_dir, vendored checkout)"
|
|
@@ -28,4 +28,4 @@ description = "One 'PScore: <value> >ACC' line per scored accession (via stdou
|
|
|
28
28
|
|
|
29
29
|
[install]
|
|
30
30
|
command = "bash tools/PScore/install.sh"
|
|
31
|
-
hint = "PScore
|
|
31
|
+
hint = "PScore is unavailable. Install its code and DBS with: bash tools/PScore/install.sh (then verify: bash tools/PScore/install.sh --check)."
|
|
@@ -12,6 +12,27 @@ pkg_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
12
12
|
src_dir="$pkg_dir/SourceCodeS2"
|
|
13
13
|
script="$src_dir/elife_phase_separation_predictor.py"
|
|
14
14
|
|
|
15
|
+
# The installer writes DBS into the user data root, not the checkout. A
|
|
16
|
+
# checkout runner can use that complete installation when its local DBS is
|
|
17
|
+
# absent. An installed runner continues to use its adjacent SourceCodeS2.
|
|
18
|
+
if [[ ! -d "$src_dir/DBS" ]]; then
|
|
19
|
+
data_root=""
|
|
20
|
+
if [[ -n "${PHASEPRED_DATA_ROOT:-}" ]]; then
|
|
21
|
+
data_root="$PHASEPRED_DATA_ROOT"
|
|
22
|
+
elif [[ -n "${XDG_DATA_HOME:-}" ]]; then
|
|
23
|
+
data_root="$XDG_DATA_HOME/phasepred"
|
|
24
|
+
elif [[ -n "${HOME:-}" ]]; then
|
|
25
|
+
data_root="$HOME/.local/share/phasepred"
|
|
26
|
+
fi
|
|
27
|
+
if [[ -n "$data_root" ]]; then
|
|
28
|
+
installed_src="$data_root/pscore/SourceCodeS2"
|
|
29
|
+
if [[ -f "$installed_src/elife_phase_separation_predictor.py" && -d "$installed_src/DBS" ]]; then
|
|
30
|
+
src_dir="$(cd "$installed_src" && pwd -P)"
|
|
31
|
+
script="$src_dir/elife_phase_separation_predictor.py"
|
|
32
|
+
fi
|
|
33
|
+
fi
|
|
34
|
+
fi
|
|
35
|
+
|
|
15
36
|
if [[ "${1:-}" == "--check" ]]; then
|
|
16
37
|
if [[ ! -f "$script" ]]; then
|
|
17
38
|
echo "PScore predictor script missing: $script" >&2
|
|
@@ -38,6 +59,10 @@ if [[ ! -f "$script" ]]; then
|
|
|
38
59
|
echo "PScore predictor script missing: $script" >&2
|
|
39
60
|
exit 1
|
|
40
61
|
fi
|
|
62
|
+
if [[ ! -d "$src_dir/DBS" ]]; then
|
|
63
|
+
echo "PScore DBS data missing: $src_dir/DBS (gitignored). Install with: bash $pkg_dir/install.sh" >&2
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
41
66
|
|
|
42
67
|
python_cmd=""
|
|
43
68
|
for cand in "${PHASEPRED_PYTHON:-}" python3 python; do
|
|
@@ -52,5 +77,17 @@ if [[ -z "$python_cmd" ]]; then
|
|
|
52
77
|
exit 1
|
|
53
78
|
fi
|
|
54
79
|
|
|
80
|
+
# The predictor must run from SourceCodeS2 so its relative DBS path works.
|
|
81
|
+
# Resolve the caller's relative FASTA and -output paths before changing cwd.
|
|
82
|
+
args=("$@")
|
|
83
|
+
if [[ "${args[0]}" != /* ]]; then
|
|
84
|
+
args[0]="$PWD/${args[0]}"
|
|
85
|
+
fi
|
|
86
|
+
for ((i = 1; i < ${#args[@]} - 1; i++)); do
|
|
87
|
+
if [[ "${args[i]}" == "-output" && "${args[i+1]}" != /* ]]; then
|
|
88
|
+
args[i+1]="$PWD/${args[i+1]}"
|
|
89
|
+
fi
|
|
90
|
+
done
|
|
91
|
+
|
|
55
92
|
cd "$src_dir"
|
|
56
|
-
exec "$python_cmd" "$script" "
|
|
93
|
+
exec "$python_cmd" "$script" "${args[@]}"
|
|
@@ -58,6 +58,14 @@ class FeatureSchemaError(ValueError):
|
|
|
58
58
|
"""Raised when feature inputs do not satisfy a model schema."""
|
|
59
59
|
|
|
60
60
|
|
|
61
|
+
def compute_fcr(sequence: str) -> float:
|
|
62
|
+
"""Charged-residue fraction; defined even when another scale lacks a residue."""
|
|
63
|
+
normalized = sequence.upper()
|
|
64
|
+
if not normalized:
|
|
65
|
+
raise FeatureSchemaError("Cannot compute features for an empty sequence")
|
|
66
|
+
return sum(residue in CHARGED_RESIDUES for residue in normalized) / len(normalized)
|
|
67
|
+
|
|
68
|
+
|
|
61
69
|
def compute_native_features(sequence: str) -> dict[str, float]:
|
|
62
70
|
normalized = sequence.upper()
|
|
63
71
|
if not normalized:
|
|
@@ -69,7 +77,7 @@ def compute_native_features(sequence: str) -> dict[str, float]:
|
|
|
69
77
|
return {
|
|
70
78
|
"length": float(length),
|
|
71
79
|
"Hydropathy": SequenceParameters(normalized).get_uversky_hydropathy(),
|
|
72
|
-
"FCR":
|
|
80
|
+
"FCR": compute_fcr(normalized),
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
|
|
@@ -33,6 +33,7 @@ def compute_all_features(
|
|
|
33
33
|
from catgranule import CatGranuleInputError, score_sequence
|
|
34
34
|
|
|
35
35
|
from phasepred import tools
|
|
36
|
+
from phasepred.features import compute_fcr
|
|
36
37
|
from phasepred.features import compute_native_features as _native
|
|
37
38
|
|
|
38
39
|
t_start = time.time()
|
|
@@ -55,9 +56,9 @@ def compute_all_features(
|
|
|
55
56
|
native_rows.append(
|
|
56
57
|
{
|
|
57
58
|
"UniprotEntry": r["accession"],
|
|
58
|
-
"length": float(
|
|
59
|
+
"length": float(len(seq)),
|
|
59
60
|
"Hydropathy": float("nan"),
|
|
60
|
-
"FCR": float("nan"),
|
|
61
|
+
"FCR": compute_fcr(seq) if seq else float("nan"),
|
|
61
62
|
}
|
|
62
63
|
)
|
|
63
64
|
|
|
@@ -212,4 +213,4 @@ def _model_predict_proba(model, X: pd.DataFrame) -> np.ndarray:
|
|
|
212
213
|
if hasattr(model, "estimator"):
|
|
213
214
|
# ModelArtifact wrapper
|
|
214
215
|
return model.estimator.predict_proba(X)
|
|
215
|
-
return model.predict_proba(X)
|
|
216
|
+
return model.predict_proba(X)
|
|
@@ -23,7 +23,7 @@ from typing import cast
|
|
|
23
23
|
import pandas as pd
|
|
24
24
|
|
|
25
25
|
from phasepred import tools
|
|
26
|
-
from phasepred.features import CHARGED_RESIDUES, compute_native_features
|
|
26
|
+
from phasepred.features import CHARGED_RESIDUES, compute_fcr, compute_native_features
|
|
27
27
|
|
|
28
28
|
# Tool vocabulary (web API order).
|
|
29
29
|
TOOL_NAMES = [
|
|
@@ -94,7 +94,10 @@ def compute_tool_features(
|
|
|
94
94
|
try:
|
|
95
95
|
native[r["accession"]] = compute_native_features(str(r["sequence"]).upper())
|
|
96
96
|
except Exception:
|
|
97
|
-
|
|
97
|
+
seq = str(r["sequence"]).upper()
|
|
98
|
+
native[r["accession"]] = {
|
|
99
|
+
"FCR": compute_fcr(seq) if seq else float("nan")
|
|
100
|
+
}
|
|
98
101
|
|
|
99
102
|
if "hydropathy" in requested:
|
|
100
103
|
for i, r in enumerate(records):
|