Spaces:
Sleeping
Sleeping
Align logo with the text beneath it
Browse files- app.py +33 -27
- docs/assets/icon.png +2 -2
- docs/assets/logo-banner.png +2 -2
- docs/assets/logo-dark.png +2 -2
- docs/assets/logo-header.png +2 -2
- scripts/make_logo_assets.py +12 -5
app.py
CHANGED
|
@@ -916,14 +916,25 @@ preload_model()
|
|
| 916 |
|
| 917 |
|
| 918 |
CSS = f"""
|
| 919 |
-
.dm-header {{ margin: 2px 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 920 |
.dm-tagline {{
|
| 921 |
-
margin: 0;
|
| 922 |
font-size: 15px;
|
| 923 |
font-weight: 600;
|
| 924 |
line-height: 1.35;
|
| 925 |
}}
|
| 926 |
-
.dm-intro
|
|
|
|
|
|
|
|
|
|
|
|
|
| 927 |
.dm-inline-action {{ align-self: flex-end; margin-bottom: 0; }}
|
| 928 |
body, .gradio-container, .gradio-container * {{
|
| 929 |
font-family: {FONT_STACK} !important;
|
|
@@ -946,40 +957,35 @@ BLOCKS_KWARGS = {} if _LAUNCH_ACCEPTS_THEME else {"theme": _THEME, "css": CSS}
|
|
| 946 |
|
| 947 |
|
| 948 |
with gr.Blocks(title="DeepMutate-3D", **BLOCKS_KWARGS) as demo:
|
| 949 |
-
#
|
| 950 |
-
#
|
| 951 |
-
#
|
| 952 |
-
|
| 953 |
-
|
| 954 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 955 |
if LOGO_DATA_URI:
|
| 956 |
gr.HTML(
|
| 957 |
'<div class="dm-header">'
|
| 958 |
-
'<h1
|
| 959 |
-
f'<img src="{LOGO_DATA_URI}" alt="DeepMutate-3D" '
|
| 960 |
-
'style="max-width:340px;width:100%;height:auto;display:block"></h1>'
|
| 961 |
'<p class="dm-tagline">Protein language model mutation scanning, '
|
| 962 |
"painted onto the AlphaFold fold.</p>"
|
|
|
|
| 963 |
"</div>"
|
| 964 |
)
|
| 965 |
else:
|
| 966 |
-
gr.
|
| 967 |
-
|
| 968 |
-
"
|
| 969 |
-
|
|
|
|
|
|
|
|
|
|
| 970 |
)
|
| 971 |
|
| 972 |
-
# The explanation of how to read the colours is guidance, not identity, so
|
| 973 |
-
# it is set below the header in muted body text rather than competing with
|
| 974 |
-
# the tagline for emphasis.
|
| 975 |
-
gr.Markdown(
|
| 976 |
-
"ESM-2 scores every possible point mutation as a log-likelihood ratio "
|
| 977 |
-
"against the wildtype residue. Positions the model refuses to change "
|
| 978 |
-
"are evolutionarily constrained, likely structural or functional cores, "
|
| 979 |
-
"and glow **red**. Positions it happily swaps glow **blue**.",
|
| 980 |
-
elem_classes="dm-intro",
|
| 981 |
-
)
|
| 982 |
-
|
| 983 |
with gr.Row(equal_height=True):
|
| 984 |
example_dropdown = gr.Dropdown(
|
| 985 |
choices=list(EXAMPLE_PROTEINS.keys()),
|
|
|
|
| 916 |
|
| 917 |
|
| 918 |
CSS = f"""
|
| 919 |
+
.dm-header {{ margin: 2px 0 14px; }}
|
| 920 |
+
.dm-header h1 {{ margin: 0 0 10px; }}
|
| 921 |
+
.dm-header h1 img {{
|
| 922 |
+
max-width: 340px;
|
| 923 |
+
width: 100%;
|
| 924 |
+
height: auto;
|
| 925 |
+
display: block;
|
| 926 |
+
}}
|
| 927 |
.dm-tagline {{
|
| 928 |
+
margin: 0 0 10px;
|
| 929 |
font-size: 15px;
|
| 930 |
font-weight: 600;
|
| 931 |
line-height: 1.35;
|
| 932 |
}}
|
| 933 |
+
.dm-intro {{
|
| 934 |
+
margin: 0;
|
| 935 |
+
max-width: 74ch;
|
| 936 |
+
line-height: 1.55;
|
| 937 |
+
}}
|
| 938 |
.dm-inline-action {{ align-self: flex-end; margin-bottom: 0; }}
|
| 939 |
body, .gradio-container, .gradio-container * {{
|
| 940 |
font-family: {FONT_STACK} !important;
|
|
|
|
| 957 |
|
| 958 |
|
| 959 |
with gr.Blocks(title="DeepMutate-3D", **BLOCKS_KWARGS) as demo:
|
| 960 |
+
# Logo, tagline and intro live in ONE html block. Splitting them across a
|
| 961 |
+
# gr.HTML and a gr.Markdown gave each its own container padding, so the
|
| 962 |
+
# three lines started at three different left edges. One block, one edge.
|
| 963 |
+
intro = (
|
| 964 |
+
"ESM-2 scores every possible point mutation as a log-likelihood ratio "
|
| 965 |
+
"against the wildtype residue. Positions the model refuses to change "
|
| 966 |
+
"are evolutionarily constrained, likely structural or functional cores, "
|
| 967 |
+
"and glow <strong>red</strong>. Positions it happily swaps glow "
|
| 968 |
+
"<strong>blue</strong>."
|
| 969 |
+
)
|
| 970 |
if LOGO_DATA_URI:
|
| 971 |
gr.HTML(
|
| 972 |
'<div class="dm-header">'
|
| 973 |
+
'<h1><img src="' + LOGO_DATA_URI + '" alt="DeepMutate-3D"></h1>'
|
|
|
|
|
|
|
| 974 |
'<p class="dm-tagline">Protein language model mutation scanning, '
|
| 975 |
"painted onto the AlphaFold fold.</p>"
|
| 976 |
+
f'<p class="dm-intro">{intro}</p>'
|
| 977 |
"</div>"
|
| 978 |
)
|
| 979 |
else:
|
| 980 |
+
gr.HTML(
|
| 981 |
+
'<div class="dm-header">'
|
| 982 |
+
"<h1>DeepMutate-3D</h1>"
|
| 983 |
+
'<p class="dm-tagline">Protein language model mutation scanning, '
|
| 984 |
+
"painted onto the AlphaFold fold.</p>"
|
| 985 |
+
f'<p class="dm-intro">{intro}</p>'
|
| 986 |
+
"</div>"
|
| 987 |
)
|
| 988 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 989 |
with gr.Row(equal_height=True):
|
| 990 |
example_dropdown = gr.Dropdown(
|
| 991 |
choices=list(EXAMPLE_PROTEINS.keys()),
|
docs/assets/icon.png
CHANGED
|
|
Git LFS Details
|
|
|
Git LFS Details
|
docs/assets/logo-banner.png
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
docs/assets/logo-dark.png
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
docs/assets/logo-header.png
CHANGED
|
Git LFS Details
|
|
Git LFS Details
|
scripts/make_logo_assets.py
CHANGED
|
@@ -33,8 +33,13 @@ HEADER_CSS_WIDTH = 340
|
|
| 33 |
BANNER_CSS_WIDTH = 620
|
| 34 |
|
| 35 |
|
| 36 |
-
def content_box(rgb: np.ndarray, background: np.ndarray, pad: int =
|
| 37 |
-
"""Bounding box of everything meaningfully different from the backdrop.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
diff = np.abs(rgb.astype(int) - background.astype(int)).sum(axis=2)
|
| 39 |
ys, xs = np.where(diff > 30)
|
| 40 |
h, w, _ = rgb.shape
|
|
@@ -79,9 +84,11 @@ def main() -> int:
|
|
| 79 |
# The dark artwork sits on near-black, so brightness alone finds the content.
|
| 80 |
lum = np.array(dark_src).sum(axis=2)
|
| 81 |
ys, xs = np.where(lum > 120)
|
| 82 |
-
dark
|
| 83 |
-
|
| 84 |
-
|
|
|
|
|
|
|
| 85 |
|
| 86 |
written = []
|
| 87 |
for name, img, width in [
|
|
|
|
| 33 |
BANNER_CSS_WIDTH = 620
|
| 34 |
|
| 35 |
|
| 36 |
+
def content_box(rgb: np.ndarray, background: np.ndarray, pad: int = 0) -> tuple:
|
| 37 |
+
"""Bounding box of everything meaningfully different from the backdrop.
|
| 38 |
+
|
| 39 |
+
`pad` defaults to 0 deliberately. Padding baked into a transparent asset is
|
| 40 |
+
invisible but still occupies layout width, which indents the artwork
|
| 41 |
+
relative to the text beneath it.
|
| 42 |
+
"""
|
| 43 |
diff = np.abs(rgb.astype(int) - background.astype(int)).sum(axis=2)
|
| 44 |
ys, xs = np.where(diff > 30)
|
| 45 |
h, w, _ = rgb.shape
|
|
|
|
| 84 |
# The dark artwork sits on near-black, so brightness alone finds the content.
|
| 85 |
lum = np.array(dark_src).sum(axis=2)
|
| 86 |
ys, xs = np.where(lum > 120)
|
| 87 |
+
# The dark variant keeps a small margin: its backdrop is opaque, so the
|
| 88 |
+
# padding reads as part of the panel rather than as dead space.
|
| 89 |
+
dark = dark_src.crop((max(int(xs.min()) - 30, 0), max(int(ys.min()) - 30, 0),
|
| 90 |
+
min(int(xs.max()) + 30, dark_src.width),
|
| 91 |
+
min(int(ys.max()) + 30, dark_src.height)))
|
| 92 |
|
| 93 |
written = []
|
| 94 |
for name, img, width in [
|