bindsight 0.3.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bindsight/README.md +44 -0
- bindsight/__init__.py +15 -0
- bindsight/benchmark/__init__.py +71 -0
- bindsight/benchmark/core.py +497 -0
- bindsight/benchmark/defaults.py +28 -0
- bindsight/benchmark/designer_bench.py +899 -0
- bindsight/benchmark/outcomes.py +508 -0
- bindsight/benchmark/panel.py +621 -0
- bindsight/benchmark/rediscovery.py +1153 -0
- bindsight/benchmark/statistics.py +622 -0
- bindsight/benchmark/study.py +1153 -0
- bindsight/benchmark/study_figures.py +164 -0
- bindsight/benchmark/study_report.py +607 -0
- bindsight/cli.py +2429 -0
- bindsight/config.py +451 -0
- bindsight/cost.py +258 -0
- bindsight/deg/__init__.py +7 -0
- bindsight/deg/pydeseq2_runner.py +285 -0
- bindsight/design/__init__.py +23 -0
- bindsight/design/_common.py +501 -0
- bindsight/design/bindcraft.py +78 -0
- bindsight/design/boltzgen.py +79 -0
- bindsight/design/developability.py +140 -0
- bindsight/design/embeddings.py +165 -0
- bindsight/design/prescreen.py +169 -0
- bindsight/design/protocol.py +111 -0
- bindsight/design/rfdiff_mpnn.py +93 -0
- bindsight/epitopes/__init__.py +7 -0
- bindsight/epitopes/surface_bind.py +134 -0
- bindsight/export/__init__.py +7 -0
- bindsight/export/ro_crate.py +595 -0
- bindsight/io/__init__.py +19 -0
- bindsight/io/cbioportal.py +118 -0
- bindsight/io/gdc.py +343 -0
- bindsight/io/paths.py +124 -0
- bindsight/pipelines/__init__.py +9 -0
- bindsight/pipelines/caveats.py +60 -0
- bindsight/pipelines/discover.py +1443 -0
- bindsight/pipelines/full_run.py +410 -0
- bindsight/plugins.py +335 -0
- bindsight/provenance/__init__.py +34 -0
- bindsight/provenance/append.py +199 -0
- bindsight/provenance/fragments.py +216 -0
- bindsight/provenance/manifest.py +506 -0
- bindsight/rank/__init__.py +7 -0
- bindsight/rank/scoring.py +355 -0
- bindsight/report/__init__.py +39 -0
- bindsight/report/format.py +100 -0
- bindsight/report/html.py +645 -0
- bindsight/report/showcase.py +653 -0
- bindsight/report/templates/report.css +67 -0
- bindsight/report/templates/report.html.j2 +420 -0
- bindsight/report/theme.py +231 -0
- bindsight/report/web/__init__.py +35 -0
- bindsight/report/web/app.py +624 -0
- bindsight/report/web/static/binder_viewer.js +245 -0
- bindsight/report/web/static/bindsight.css +455 -0
- bindsight/report/web/static/charts.js +425 -0
- bindsight/report/web/static/vendor/3Dmol-min.js +2 -0
- bindsight/report/web/static/vendor/3Dmol.LICENSE +90 -0
- bindsight/report/web/static/your_data_check.js +370 -0
- bindsight/report/web/templates/base.html.j2 +48 -0
- bindsight/report/web/templates/evidence.html.j2 +341 -0
- bindsight/report/web/templates/overview.html.j2 +140 -0
- bindsight/report/web/templates/runs.html.j2 +125 -0
- bindsight/report/web/templates/try.html.j2 +155 -0
- bindsight/report/web/templates/your_data.html.j2 +46 -0
- bindsight/runners/__init__.py +7 -0
- bindsight/runners/colab.py +158 -0
- bindsight/runners/job_exec.py +1110 -0
- bindsight/runners/kaggle.py +425 -0
- bindsight/runners/kaggle_kernel.py +489 -0
- bindsight/runners/local_docker.py +154 -0
- bindsight/runners/mock.py +167 -0
- bindsight/runners/modal_runner.py +199 -0
- bindsight/runners/notebook.py +116 -0
- bindsight/runners/notebook_content.py +217 -0
- bindsight/runners/protocol.py +81 -0
- bindsight/runners/source_wheel.py +104 -0
- bindsight/runners/tools.py +997 -0
- bindsight/structures/__init__.py +7 -0
- bindsight/structures/alphafolddb.py +93 -0
- bindsight/structures/plddt.py +92 -0
- bindsight/structures/topology.py +227 -0
- bindsight/surfaceome/__init__.py +42 -0
- bindsight/surfaceome/data/surfaceome_extended.tsv +4814 -0
- bindsight/surfaceome/data/surfy_offline.txt +17 -0
- bindsight/surfaceome/data/surfy_v1.ensembl.tsv +3380 -0
- bindsight/surfaceome/data/surfy_v1.uniprot.txt +2901 -0
- bindsight/surfaceome/surfy.py +441 -0
- bindsight/targets/__init__.py +7 -0
- bindsight/targets/ensembl_uniprot.py +56 -0
- bindsight/targets/gtex.py +250 -0
- bindsight/targets/open_targets.py +239 -0
- bindsight/validate/__init__.py +7 -0
- bindsight/validate/af2_ig.py +49 -0
- bindsight/validate/boltz2.py +256 -0
- bindsight/validate/chai1r.py +42 -0
- bindsight/validate/protocol.py +188 -0
- bindsight-0.3.5.data/data/bindsight_demo/config.yaml +54 -0
- bindsight-0.3.5.dist-info/METADATA +495 -0
- bindsight-0.3.5.dist-info/RECORD +106 -0
- bindsight-0.3.5.dist-info/WHEEL +4 -0
- bindsight-0.3.5.dist-info/entry_points.txt +20 -0
- bindsight-0.3.5.dist-info/licenses/COPYRIGHT +24 -0
- bindsight-0.3.5.dist-info/licenses/LICENSE +681 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mikhaeel Atef Rizk Wahba
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
"""Shared brand constants and CSS for every bindsight presentation surface.
|
|
4
|
+
|
|
5
|
+
Before this module the brand navy, the page title, and the page icon were
|
|
6
|
+
re-declared independently in the app and the report
|
|
7
|
+
and ``report/templates/report.css``, and the docs site used an unrelated teal.
|
|
8
|
+
Three surfaces of one product drifted apart.
|
|
9
|
+
|
|
10
|
+
This is the single source of truth, in the same spirit as
|
|
11
|
+
:mod:`bindsight.pipelines.caveats` — which already shares one limitations list
|
|
12
|
+
between the pipeline logs, the manifest, and the HTML report.
|
|
13
|
+
|
|
14
|
+
The module deliberately imports nothing beyond the standard library so it stays
|
|
15
|
+
importable without the web extra (see ``tests/test_package_imports.py``).
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
# --- Identity --------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
TAGLINE = (
|
|
23
|
+
"RNA-seq counts → ranked de novo protein binder candidates, "
|
|
24
|
+
"with full provenance back to the patient cohort."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# --- Palette ---------------------------------------------------------------
|
|
28
|
+
# The navy is the established brand colour (report.css and the web interface
|
|
29
|
+
# already used it); everything else is derived from it.
|
|
30
|
+
|
|
31
|
+
NAVY = "#0b5394"
|
|
32
|
+
NAVY_DARK = "#083b6b"
|
|
33
|
+
NAVY_TINT = "#e8f0fb"
|
|
34
|
+
ACCENT = "#0f9d8f"
|
|
35
|
+
|
|
36
|
+
INK = "#1b1f24"
|
|
37
|
+
# Moved with docs/stylesheets/extra.css's --bs-muted, which mirrors this
|
|
38
|
+
# table. At #6c757d it was 4.08:1 on NAVY_TINT and 4.45:1 on CANVAS, both
|
|
39
|
+
# under WCAG AA, and it is used for the label under a headline number --
|
|
40
|
+
# the caveat, not the claim, which is the wrong half to make unreadable.
|
|
41
|
+
MUTED = "#5f6873"
|
|
42
|
+
RULE = "#e3e6ea"
|
|
43
|
+
SURFACE = "#ffffff"
|
|
44
|
+
CANVAS = "#f7f9fc"
|
|
45
|
+
|
|
46
|
+
# The web interface chose these six for contrast and its own tests hold them
|
|
47
|
+
# there; the values below were chosen separately and drifted, so the success
|
|
48
|
+
# colour ended up as #2e7d32 here, #1f7a3d on the documentation site and
|
|
49
|
+
# #1f6f35 in the app -- one product, three greens. The app's are now the
|
|
50
|
+
# shared ones, and docs/stylesheets/extra.css names all six as --bs- tokens so
|
|
51
|
+
# TestTheTwoPalettesAgree holds this file to them instead of parsing them and
|
|
52
|
+
# comparing nothing.
|
|
53
|
+
OK = "#1f6f35"
|
|
54
|
+
OK_TINT = "#e8f4ea"
|
|
55
|
+
WARN = "#8a6100"
|
|
56
|
+
WARN_TINT = "#fdf3dd"
|
|
57
|
+
ERR = "#a32020"
|
|
58
|
+
ERR_TINT = "#fbeaea"
|
|
59
|
+
|
|
60
|
+
# --- Canonical URLs --------------------------------------------------------
|
|
61
|
+
# These were previously hardcoded (and in the About page, pointed at raw GitHub
|
|
62
|
+
# blob URLs rather than the deployed documentation site).
|
|
63
|
+
|
|
64
|
+
GITHUB_URL = "https://github.com/mikhaeelatefrizk/bindsight"
|
|
65
|
+
DOCS_URL = "https://mikhaeelatefrizk.github.io/bindsight/"
|
|
66
|
+
|
|
67
|
+
# There was a third URL here, for a hosted deployment, and a flag recording
|
|
68
|
+
# whether that deployment was serving this build. It never was: the sync
|
|
69
|
+
# workflow uploaded nothing without a secret and reported success anyway. The
|
|
70
|
+
# deployment is retired and both are gone -- ``tests/test_no_hosted_space.py``
|
|
71
|
+
# asserts they stay gone, because a URL nothing points at is a URL something
|
|
72
|
+
# points at again.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def citation_line() -> str:
|
|
76
|
+
"""How to cite: the repository, the tag and the checksums, since there is no DOI.
|
|
77
|
+
|
|
78
|
+
This function used to hold a DOI and return it as a *Markdown* link. Its
|
|
79
|
+
one consumer, ``overview.html.j2``, interpolates the result into HTML under
|
|
80
|
+
Jinja's autoescape with no Markdown filter, so the paragraph would have
|
|
81
|
+
rendered the brackets. It never did: the identifier was a placeholder, the
|
|
82
|
+
placeholder branch returned prose, and the branch that returned Markdown
|
|
83
|
+
never ran. The test of this very paragraph was written as
|
|
84
|
+
``if theme.DOI_IS_PENDING:``, so it would have stopped running at the
|
|
85
|
+
instant the bug started rendering. Plain text now; the template makes the
|
|
86
|
+
link, and the test of it is unconditional.
|
|
87
|
+
"""
|
|
88
|
+
return (
|
|
89
|
+
"This release is not archived under a DOI. Cite the repository, the "
|
|
90
|
+
"tag you ran and the checksums attached to the release: "
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
LICENSE_NAME = "AGPL-3.0-or-later"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# --- Plain-language framing ------------------------------------------------
|
|
98
|
+
# A one-paragraph, jargon-free description for a non-specialist visitor. Kept
|
|
99
|
+
# here so the web app and the docs site tell the same story. This is the
|
|
100
|
+
# on-ramp; the technical framing (TAGLINE) sits directly beneath it.
|
|
101
|
+
PLAIN_SUMMARY = (
|
|
102
|
+
"In plain terms: bindsight reads a tumour's gene-activity data and looks for "
|
|
103
|
+
"proteins that stud the surface of cancer cells but not healthy ones. It then "
|
|
104
|
+
"designs small custom proteins — molecular “keys” — shaped to latch onto those "
|
|
105
|
+
"targets, checks each design with an AI structure model to see whether it would "
|
|
106
|
+
"actually stick, ranks the best candidates, and keeps a complete record of how "
|
|
107
|
+
"it reached every answer."
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
#: Plain-English glossary of the core terms this project uses.
|
|
111
|
+
#:
|
|
112
|
+
#: ``scripts/build_docs_results.py`` regenerates ``docs/glossary.md`` from this
|
|
113
|
+
#: tuple and ``tests/test_docs_results.py`` fails when the committed file drifts
|
|
114
|
+
#: from it, so the definitions a reader sees are these ones.
|
|
115
|
+
#:
|
|
116
|
+
#: This said "single source of truth: the web app's Glossary page renders this"
|
|
117
|
+
#: as well, which described a second renderer that the served interface does not
|
|
118
|
+
#: have. One sink is not a drift risk; it is just a source.
|
|
119
|
+
#:
|
|
120
|
+
#: It lives in the package rather than beside the generator so the vocabulary
|
|
121
|
+
#: travels with the software, and a reader who has the package has the
|
|
122
|
+
#: definitions. Each entry is ``(term, plain-language definition)``.
|
|
123
|
+
GLOSSARY: tuple[tuple[str, str], ...] = (
|
|
124
|
+
(
|
|
125
|
+
"RNA-seq",
|
|
126
|
+
"A lab method that measures which genes are switched on in a tissue sample, "
|
|
127
|
+
"and how strongly, by sequencing its RNA. It is the starting input to bindsight.",
|
|
128
|
+
),
|
|
129
|
+
(
|
|
130
|
+
"Differential expression (DEG)",
|
|
131
|
+
"Comparing gene activity between two groups — here tumour versus healthy "
|
|
132
|
+
"tissue — to find the genes turned notably up or down in disease.",
|
|
133
|
+
),
|
|
134
|
+
(
|
|
135
|
+
"log2 fold-change (log2FC)",
|
|
136
|
+
"How many times higher or lower a gene's activity is between the two groups, "
|
|
137
|
+
"on a log2 scale: a value of 4 means about 16× higher in tumour.",
|
|
138
|
+
),
|
|
139
|
+
(
|
|
140
|
+
"padj / FDR",
|
|
141
|
+
"A confidence figure that a difference is real rather than chance, adjusted "
|
|
142
|
+
"for testing thousands of genes at once. Smaller is stronger (e.g. 1e-59 is "
|
|
143
|
+
"overwhelming evidence).",
|
|
144
|
+
),
|
|
145
|
+
(
|
|
146
|
+
"Antigen",
|
|
147
|
+
"A molecule a drug or the immune system can recognise and target. In bindsight "
|
|
148
|
+
"the antigens of interest are proteins sitting on the cell surface.",
|
|
149
|
+
),
|
|
150
|
+
(
|
|
151
|
+
"Surfaceome",
|
|
152
|
+
"The full set of proteins that sit on the outer surface of cells — the ones a "
|
|
153
|
+
"binder could physically reach. bindsight keeps only surface proteins as targets.",
|
|
154
|
+
),
|
|
155
|
+
(
|
|
156
|
+
"De novo protein binder",
|
|
157
|
+
"A small protein designed from scratch (rather than borrowed from nature) to "
|
|
158
|
+
"stick tightly and specifically to a chosen target protein.",
|
|
159
|
+
),
|
|
160
|
+
(
|
|
161
|
+
"RFdiffusion + ProteinMPNN",
|
|
162
|
+
"Two AI models used together: RFdiffusion invents a plausible 3-D shape for a "
|
|
163
|
+
"binder against the target, and ProteinMPNN chooses an amino-acid sequence that "
|
|
164
|
+
"would fold into that shape.",
|
|
165
|
+
),
|
|
166
|
+
(
|
|
167
|
+
"Boltz-2",
|
|
168
|
+
"An AI model that predicts the 3-D structure of the binder and target locked "
|
|
169
|
+
"together, and reports how confident it is in that predicted interface. "
|
|
170
|
+
"Confidence is not a binding measurement: bindsight's own paired control "
|
|
171
|
+
"folded each design beside a shuffle of its own sequence, and the shuffles "
|
|
172
|
+
"scored as well. Treat these numbers as a filter to triage wet-lab work, "
|
|
173
|
+
"never as evidence that a design binds.",
|
|
174
|
+
),
|
|
175
|
+
(
|
|
176
|
+
"ipTM",
|
|
177
|
+
"A 0–1 score of how confident the structure model is in the predicted "
|
|
178
|
+
"interface between two proteins. 0.65 is the threshold the de novo design "
|
|
179
|
+
"literature commonly uses, and bindsight reports against it for "
|
|
180
|
+
"comparability — but its own scramble control could not separate real "
|
|
181
|
+
"designs from shuffles of the same composition at that cutoff, so a value "
|
|
182
|
+
"above 0.65 is not on its own evidence of a binder. See the calibration.",
|
|
183
|
+
),
|
|
184
|
+
(
|
|
185
|
+
"PAE (interaction)",
|
|
186
|
+
"Predicted Aligned Error at the binding interface, in ångströms — how uncertain "
|
|
187
|
+
"the model is about the contact. Lower means a more trustworthy predicted grip.",
|
|
188
|
+
),
|
|
189
|
+
(
|
|
190
|
+
"Developability",
|
|
191
|
+
"How practical a designed protein would be to actually make and use: is it "
|
|
192
|
+
"stable, soluble, and free of trouble-prone residues? Good scores mean fewer "
|
|
193
|
+
"surprises in the lab.",
|
|
194
|
+
),
|
|
195
|
+
(
|
|
196
|
+
"Provenance / RO-Crate",
|
|
197
|
+
"A complete, machine-readable record of every input, tool version and step, "
|
|
198
|
+
"packaged (as an RO-Crate) so anyone can retrace and reproduce a result — and "
|
|
199
|
+
"cite it.",
|
|
200
|
+
),
|
|
201
|
+
(
|
|
202
|
+
"ERBB2 (HER2)",
|
|
203
|
+
"A well-known breast-cancer cell-surface antigen and an approved drug target — "
|
|
204
|
+
"the canonical positive control for a discovery pipeline. bindsight does *not* "
|
|
205
|
+
"rediscover it: in the whole unstratified TCGA-BRCA cohort it measures log2fc "
|
|
206
|
+
"0.92, below the fold-change floor, so it does not clear the "
|
|
207
|
+
"significance rule. That is a limit of bulk differential expression, not of "
|
|
208
|
+
"the ranking; see benchmarks/study/RESULTS.md.",
|
|
209
|
+
),
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def docs_url(page: str = "") -> str:
|
|
214
|
+
"""Build a URL into the deployed documentation site.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
page: Page slug without extension, e.g. ``"what-is-bindsight"``.
|
|
218
|
+
Empty string returns the docs home.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
Absolute URL on the GitHub Pages documentation site.
|
|
222
|
+
"""
|
|
223
|
+
if not page:
|
|
224
|
+
return DOCS_URL
|
|
225
|
+
return f"{DOCS_URL}{page.strip('/')}/"
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
# No stylesheet is emitted from this module. The design system is one CSS file
|
|
229
|
+
# under ``report/web/static/``, shared between the served interface and the
|
|
230
|
+
# standalone HTML report, so the two cannot drift apart. What lives here is the
|
|
231
|
+
# palette and the vocabulary those surfaces are built from.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 Mikhaeel Atef Rizk Wahba
|
|
2
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
3
|
+
"""The bindsight web interface.
|
|
4
|
+
|
|
5
|
+
Server-rendered HTML over the same data layer the standalone report reads
|
|
6
|
+
(:mod:`bindsight.report.showcase`), with one stylesheet shared between them so
|
|
7
|
+
the interactive app and the file a collaborator opens from an email look like
|
|
8
|
+
the same instrument.
|
|
9
|
+
|
|
10
|
+
Replaces the Streamlit app. That is a reduction, not an addition: Streamlit
|
|
11
|
+
declares 34 requirements against this stack's handful, and every number on a
|
|
12
|
+
Streamlit page had to be expressed through a widget whose layout the caller does
|
|
13
|
+
not control -- which is how confidence intervals ended up inside hover tooltips
|
|
14
|
+
underneath a paragraph promising every rate carried its interval.
|
|
15
|
+
|
|
16
|
+
Nothing here needs a build step, a package manager, or a network. The one
|
|
17
|
+
third-party asset is 3Dmol.js, vendored under ``static/vendor/`` so the
|
|
18
|
+
structure viewer works offline; the previous viewer fetched it from a CDN, so it
|
|
19
|
+
silently required internet.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
__all__ = ["create_app", "serve"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def __getattr__(name: str) -> object:
|
|
28
|
+
# Imported lazily so ``import bindsight.report`` does not require the web
|
|
29
|
+
# extra. ``bindsight doctor`` and the CLI's non-UI paths must work on an
|
|
30
|
+
# install that never asked for a server.
|
|
31
|
+
if name in __all__:
|
|
32
|
+
from bindsight.report.web.app import create_app, serve
|
|
33
|
+
|
|
34
|
+
return {"create_app": create_app, "serve": serve}[name]
|
|
35
|
+
raise AttributeError(name)
|