In [1]:
######## snakemake preamble start (automatically inserted, do not edit) ########
import sys;sys.path.extend(['/fh/fast/bloom_j/software/miniforge3/envs/dms-vep-pipeline-3_v3.17/lib/python3.11/site-packages', '/fh/fast/bloom_j/computational_notebooks/jbloom/2024/RABV_Pasteur_G_DMS/dms-vep-pipeline-3/..', '/fh/fast/bloom_j/computational_notebooks/jbloom/2024/RABV_Pasteur_G_DMS/dms-vep-pipeline-3', '/fh/fast/bloom_j/software/miniforge3/envs/dms-vep-pipeline-3_v3.17/bin', '/fh/fast/bloom_j/software/miniforge3/envs/dms-vep-pipeline-3_v3.17/lib/python3.11', '/fh/fast/bloom_j/software/miniforge3/envs/dms-vep-pipeline-3_v3.17/lib/python3.11/lib-dynload', '/home/jbloom/.local/lib/python3.11/site-packages', '/fh/fast/bloom_j/software/miniforge3/envs/dms-vep-pipeline-3_v3.17/lib/python3.11/site-packages', '/home/jbloom/.cache/snakemake/snakemake/source-cache/runtime-cache/tmp0j08q3w9/file/fh/fast/bloom_j/computational_notebooks/jbloom/2024/RABV_Pasteur_G_DMS/notebooks', '/fh/fast/bloom_j/computational_notebooks/jbloom/2024/RABV_Pasteur_G_DMS/notebooks']);import pickle;from snakemake import script;script.snakemake = pickle.loads(b'\x80\x04\x95L\x10\x00\x00\x00\x00\x00\x00\x8c\x10snakemake.script\x94\x8c\tSnakemake\x94\x93\x94)\x81\x94}\x94(\x8c\x05input\x94\x8c\x0csnakemake.io\x94\x8c\nInputFiles\x94\x93\x94)\x81\x94(\x8cGresults/summaries/all_antibodies_and_cell_entry_per_antibody_escape.csv\x94\x8c3results/summaries/all_antibodies_and_cell_entry.csv\x94e}\x94(\x8c\x06_names\x94}\x94(\x8c\x17per_antibody_escape_csv\x94K\x00N\x86\x94\x8c\x0ephenotypes_csv\x94K\x01N\x86\x94u\x8c\x12_allowed_overrides\x94]\x94(\x8c\x05index\x94\x8c\x04sort\x94eh\x15h\x06\x8c\x0eAttributeGuard\x94\x93\x94)\x81\x94}\x94\x8c\x04name\x94h\x15sbh\x16h\x18)\x81\x94}\x94h\x1bh\x16sbh\x0fh\nh\x11h\x0bub\x8c\x06output\x94h\x06\x8c\x0bOutputFiles\x94\x93\x94)\x81\x94(\x8c*results/dms-viz/domainIII_CR57_escape.json\x94\x8c9results/dms-viz/domainIII_CR57_escape_no_description.json\x94\x8c1results/dms-viz/domainIII_CR57_escape_sitemap.csv\x94\x8c4results/dms-viz/domainIII_CR57_escape_phenotypes.csv\x94\x8c4results/dms-viz/domainIII_CR57_escape_description.md\x94\x8c)results/dms-viz/domainIII_CR57_escape.pdb\x94e}\x94(h\r}\x94(\x8c\x04json\x94K\x00N\x86\x94\x8c\x13json_no_description\x94K\x01N\x86\x94\x8c\x07sitemap\x94K\x02N\x86\x94\x8c\nphenotypes\x94K\x03N\x86\x94\x8c\x0edescription_md\x94K\x04N\x86\x94\x8c\x08pdb_file\x94K\x05N\x86\x94uh\x13]\x94(h\x15h\x16eh\x15h\x18)\x81\x94}\x94h\x1bh\x15sbh\x16h\x18)\x81\x94}\x94h\x1bh\x16sbh*h"h,h#h.h$h0h%h2h&h4h\'ub\x8c\x06params\x94h\x06\x8c\x06Params\x94\x93\x94)\x81\x94(}\x94(\x8c\x06pdb_id\x94\x8c\x048r40\x94\x8c\x13escape_or_phenotype\x94\x8c\x06escape\x94\x8c\nphenotypes\x94N\x8c\nantibodies\x94]\x94\x8c\x04CR57\x94a\x8c\x0fincluded-chains\x94]\x94\x8c\x01C\x94a\x8c\x0fexcluded-chains\x94]\x94\x8c\x08alphabet\x94\x8c\x14RKHDEQNSTYWFAILMVGPC\x94\x8c\x05floor\x94\x88\x8c\x0csummary-stat\x94\x8c\x03sum\x94\x8c\x0ctooltip-cols\x94}\x94\x8c\ncell entry\x94\x8c\ncell entry\x94s\x8c\x0bfilter-cols\x94}\x94\x8c\ncell entry\x94\x8c\ncell entry\x94s\x8c\rfilter-limits\x94}\x94\x8c\ncell entry\x94]\x94(J\xf8\xff\xff\xffJ\xfb\xff\xff\xffK\x00es\x8c\x0eheatmap-limits\x94]\x94K\x00a\x8c\x05title\x94\x8c=Effects of mutations to rabies G on escape from antibody CR57\x94\x8c\x0bdescription\x94\x8c\x84Pseudovirus deep mutational scanning of how mutations to rabies G affect\nneutralization by antibody CR57 shown on domain III (8r40)\n\x94u\x8c\xcaStudy by [Aditham et al](https://www.biorxiv.org/content/10.1101/2024.12.17.628970v1) (2024).\nSee [https://github.com/dms-vep/RABV_Pasteur_G_DMS](https://github.com/dms-vep/RABV_Pasteur_G_DMS) for code.\x94e}\x94(h\r}\x94(\x8c\x06config\x94K\x00N\x86\x94\x8c\x12description_suffix\x94K\x01N\x86\x94uh\x13]\x94(h\x15h\x16eh\x15h\x18)\x81\x94}\x94h\x1bh\x15sbh\x16h\x18)\x81\x94}\x94h\x1bh\x16sbhgh?hihdub\x8c\twildcards\x94h\x06\x8c\tWildcards\x94\x93\x94)\x81\x94\x8c\x15domainIII_CR57_escape\x94a}\x94(h\r}\x94\x8c\x06struct\x94K\x00N\x86\x94sh\x13]\x94(h\x15h\x16eh\x15h\x18)\x81\x94}\x94h\x1bh\x15sbh\x16h\x18)\x81\x94}\x94h\x1bh\x16sb\x8c\x06struct\x94htub\x8c\x07threads\x94K\x01\x8c\tresources\x94h\x06\x8c\tResources\x94\x93\x94)\x81\x94(K\x01K\x01\x8c\x14/loc/scratch/3868073\x94e}\x94(h\r}\x94(\x8c\x06_cores\x94K\x00N\x86\x94\x8c\x06_nodes\x94K\x01N\x86\x94\x8c\x06tmpdir\x94K\x02N\x86\x94uh\x13]\x94(h\x15h\x16eh\x15h\x18)\x81\x94}\x94h\x1bh\x15sbh\x16h\x18)\x81\x94}\x94h\x1bh\x16sbh\x87K\x01h\x89K\x01h\x8bh\x84ub\x8c\x03log\x94h\x06\x8c\x03Log\x94\x93\x94)\x81\x94\x8c?results/notebooks/configure_dms_viz_domainIII_CR57_escape.ipynb\x94a}\x94(h\r}\x94\x8c\x08notebook\x94K\x00N\x86\x94sh\x13]\x94(h\x15h\x16eh\x15h\x18)\x81\x94}\x94h\x1bh\x15sbh\x16h\x18)\x81\x94}\x94h\x1bh\x16sbh\x99h\x96ubhg}\x94(\x8c\rpipeline_path\x94\x8c\x12dms-vep-pipeline-3\x94\x8c\x04docs\x94\x8c\x04docs\x94\x8c\x08homepage\x94\x8c\x0fhomepage/public\x94\x8c\x18build_vitepress_homepage\x94\x88\x8c\x0fgithub_repo_url\x94\x8c-https://github.com/dms-vep/RABV_Pasteur_G_DMS\x94\x8c\x0fgithub_blob_url\x94\x8c7https://github.com/dms-vep/RABV_Pasteur_G_DMS/blob/main\x94\x8c\x0bdescription\x94\x8c5Deep mutational scanning of rabies G (Pasteur strain)\x94\x8c\x04year\x94M\xe8\x07\x8c\x07authors\x94\x8cL[Aditham et al](https://www.biorxiv.org/content/10.1101/2024.12.17.628970v1)\x94\x8c\x1euse_precomputed_barcode_counts\x94\x89\x8c\x12site_numbering_map\x94\x8c\x1bdata/site_numbering_map.csv\x94\x8c\x1emutation_design_classification\x94}\x94(\x8c\x03csv\x94\x8c\x1bdata/designed_mutations.csv\x94\x8c\x08site_col\x94\x8c\x0fsequential_site\x94u\x8c\x16neut_standard_barcodes\x94\x8c)data/neutralization_standard_barcodes.csv\x94\x8c\x11prebuilt_variants\x94N\x8c\x10prebuilt_geneseq\x94N\x8c\x0bpacbio_runs\x94\x8c\x14data/PacBio_runs.csv\x94\x8c\x0fpacbio_amplicon\x94\x8c\x17data/PacBio_amplicon.gb\x94\x8c\x15pacbio_amplicon_specs\x94\x8c$data/PacBio_feature_parse_specs.yaml\x94\x8c\x0cvariant_tags\x94}\x94(\x8c\x0cvariant_tag5\x94}\x94(\x8c\tvariant_1\x94\x8c\x01G\x94\x8c\tvariant_2\x94hJ\x8c\x08wildtype\x94\x8c\x01A\x94u\x8c\x0cvariant_tag3\x94}\x94(\x8c\tvariant_1\x94h\xc9\x8c\tvariant_2\x94hJ\x8c\x08wildtype\x94h\xccuu\x8c\x12max_ccs_error_rate\x94G?\x1a6\xe2\xeb\x1cC-\x8c\x10consensus_params\x94}\x94(\x8c\rmax_sub_diffs\x94N\x8c\x0fmax_indel_diffs\x94N\x8c\x12max_minor_sub_frac\x94G?\xc9\x99\x99\x99\x99\x99\x9a\x8c\x14max_minor_indel_frac\x94G?\xc9\x99\x99\x99\x99\x99\x9a\x8c\x0bmin_support\x94K\x03u\x8c\x13gene_sequence_codon\x94\x8c\x1edata/gene_sequence/codon.fasta\x94\x8c\x15gene_sequence_protein\x94\x8c data/gene_sequence/protein.fasta\x94\x8c\x0ecodon_variants\x94\x8c#results/variants/codon_variants.csv\x94\x8c\x0cbarcode_runs\x94\x8c\x15data/barcode_runs.csv\x94\x8c\x12duplicate_fastq_R1\x94\x8c\x04warn\x94\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\x08upstream\x94\x8c"ACTCCACTAGGAACATTTCTCTCTCGAATCTAGA\x94\x8c\ndownstream\x94\x8c\x00\x94\x8c\x04minq\x94K\x14\x8c\x11upstream_mismatch\x94K\x02u\x8c\x13func_effects_config\x94\x8c\x1cdata/func_effects_config.yml\x94\x8c\x16antibody_escape_config\x94\x8c\x1fdata/antibody_escape_config.yml\x94\x8c\x10summaries_config\x94\x8c\x19data/summaries_config.yml\x94\x8c\x0edms_viz_config\x94\x8c\x17data/dms_viz_config.yml\x94u\x8c\x04rule\x94\x8c\x11configure_dms_viz\x94\x8c\x0fbench_iteration\x94N\x8c\tscriptdir\x94\x8cQ/fh/fast/bloom_j/computational_notebooks/jbloom/2024/RABV_Pasteur_G_DMS/notebooks\x94ub.');del script;from snakemake.logging import logger;from snakemake.script import snakemake; logger.printshellcmds = False;import os; os.chdir(r'/fh/fast/bloom_j/computational_notebooks/jbloom/2024/RABV_Pasteur_G_DMS');
######## snakemake preamble end #########
Configure dms-viz
JSONs¶
Imports:
In [2]:
import gzip
import os
import requests
import subprocess
import warnings
import Bio.PDB.PDBParser
import Bio.PDB.Polypeptide
import matplotlib.colors
import pandas as pd
import seaborn
Get variables from snakemake
:
In [3]:
config = snakemake.params.config
pdb_id = config["pdb_id"]
escape_or_phenotype = config["escape_or_phenotype"]
phenotypes_list = config["phenotypes"]
antibody_list = config["antibodies"]
phenotypes_csv = snakemake.input.phenotypes_csv
if escape_or_phenotype == "escape":
per_antibody_escape_csv = snakemake.input.per_antibody_escape_csv
dms_viz_json = snakemake.output.json
dms_viz_json_no_description = snakemake.output.json_no_description
dms_viz_sitemap = snakemake.output.sitemap
dms_viz_phenotypes = snakemake.output.phenotypes
pdb_file = snakemake.output.pdb_file
description_md = snakemake.output.description_md
description_suffix = snakemake.params.description_suffix
name = snakemake.wildcards.struct
Build the sitemap used by dms-viz
:
In [4]:
phenotypes_all = pd.read_csv(phenotypes_csv)
sitemap = (
phenotypes_all
[["sequential_site", "site", "wildtype"]]
.rename(columns={"site": "reference_site"})
.drop_duplicates()
.sort_values("sequential_site")
)
assert len(sitemap) == sitemap["sequential_site"].nunique() == sitemap["reference_site"].nunique()
sitemap.to_csv(dms_viz_sitemap, index=False)
Get the biological assembly (see https://pdb101.rcsb.org/learn/guide-to-understanding-pdb-data/biological-assemblies#Anchor-download) in case the crystallographic unit doesn't correspond to that:
In [5]:
pdb_id = config["pdb_id"]
print(f"Getting PDB file for {pdb_id}")
r = requests.get(f"https://files.rcsb.org/download/{pdb_id}.pdb1.gz")
assert r.status_code == 200
pdb_content = gzip.decompress(r.content).decode("utf-8")
with open(pdb_file, "w") as f:
f.write(pdb_content)
Getting PDB file for 8r40
Check the sites mismatched between the sitemap and the protein structure in terms of residue identity:
In [6]:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
pdb_obj = Bio.PDB.PDBParser().get_structure(id=pdb_id, file=pdb_file)[0]
all_chains = [chain.id for chain in pdb_obj]
print(f"PDB has {all_chains=}")
if "included-chains" in config:
included_chains = config["included-chains"]
print(f"{included_chains=}")
assert set(included_chains).issubset(all_chains)
else:
included_chains = all_chains
records = []
for chain in included_chains:
for res in pdb_obj[chain].get_residues():
if not res.id[0].isspace():
continue
aa = Bio.PDB.Polypeptide.protein_letters_3to1[res.resname]
r = res.id[1]
records.append((chain, r, aa))
pdb_df = pd.DataFrame(records, columns=["chain", "reference_site", "pdb_aa"])
mismatched_sites = sitemap.merge(pdb_df, how="left")
print(
f"Of {len(sitemap)} sites, {len(mismatched_sites.query('wildtype == pdb_aa'))} match, "
f"{len(mismatched_sites.query('pdb_aa.isnull()'))} are missing from PDB, and "
f"{len(mismatched_sites.query('pdb_aa.notnull()').query('wildtype != pdb_aa'))} differ."
)
print("Sites that differ:")
display(mismatched_sites.query("pdb_aa.notnull() and (wildtype != pdb_aa)").reset_index(drop=True))
PDB has all_chains=['R', 'A', 'G', 'C'] included_chains=['C'] Of 433 sites, 81 match, 344 are missing from PDB, and 8 differ. Sites that differ:
sequential_site | reference_site | wildtype | chain | pdb_aa | |
---|---|---|---|---|---|
0 | 42 | 40 | G | C | E |
1 | 189 | 187 | M | C | T |
2 | 190 | 188 | S | C | P |
3 | 206 | 204 | S | C | N |
4 | 207 | 205 | E | C | K |
5 | 226 | 224 | K | C | R |
6 | 249 | 247 | N | C | D |
7 | 257 | 255 | G | C | D |
Process the different phenotypes and escape if relevant:
In [7]:
# get extra columns dealing with fact `dms-viz` does not allow them to have spaces
extra_cols = []
for coltype in ["tooltip-cols", "filter-cols"]:
for col in list(config[coltype]):
col_nospace = col.replace(" ", "_")
assert (col in phenotypes_all.columns) or (col_nospace in phenotypes_all.columns), f"no column {col} in {phenotypes_all.columns=}"
if col != col_nospace:
assert (col_nospace not in phenotypes_all.columns) or (col not in phenotypes_all.columns)
assert col_nospace not in config[coltype]
phenotypes_all = phenotypes_all.rename(columns={col: col_nospace}, errors="ignore")
config[coltype][col_nospace] = config[coltype][col]
del config[coltype][col]
extra_cols.append(col_nospace)
if coltype == "filter-cols":
if col in config["filter-limits"]:
config["filter-limits"][col_nospace] = config["filter-limits"][col]
del config["filter-limits"][col]
else:
extra_cols.append(col)
print(f"Keeping {extra_cols=} for filters and tooltips")
assert set(extra_cols).issubset(phenotypes_all.columns)
id_cols = ["site", "wildtype", "mutant"]
if escape_or_phenotype == "phenotype":
assert phenotypes_list and not antibody_list, f"{phenotypes_list=}, {antibody_list=}"
assert set(phenotypes_list).issubset(phenotypes_all.columns), f"{phenotypes_list=}\n{phenotypes_all.columns=}"
metric_column = "effect"
condition_column = "phenotype"
phenotypes = (
phenotypes_all
.melt(
id_vars=id_cols + extra_cols,
value_vars=phenotypes_list,
var_name=condition_column,
value_name=metric_column,
)
)
elif escape_or_phenotype == "escape":
assert not phenotypes_list
phenotypes = pd.read_csv(per_antibody_escape_csv)
antibodies_all = list(phenotypes["antibody"].unique())
if antibody_list is not None:
antibodies = antibody_list
print(f"Using just {antibodies=} from {antibodies_all=}")
assert set(antibodies).issubset(antibodies_all), f"{antibodies=}\n{antibodies_all=}"
assert len(antibodies) >= 1
else:
antibodies = antibodies_all
print(f"Using all {antibodies=}")
antibodies = antibodies
metric_column = "escape"
condition_column = "antibody"
phenotypes = phenotypes[id_cols + [metric_column, condition_column]]
phenotypes = phenotypes[phenotypes[condition_column].isin(antibodies)]
if extra_cols:
join_data = phenotypes_all[id_cols + extra_cols]
assert len(join_data) == len(join_data.groupby(id_cols))
assert set(join_data.columns).intersection(phenotypes.columns) == set(id_cols)
phenotypes = phenotypes.merge(join_data, on=id_cols, validate="many_to_one", how="left")
else:
raise ValueError(f"invalid {escape_or_phenotype=}")
print(f"Writing the phenotypes to {dms_viz_phenotypes}")
phenotypes.to_csv(dms_viz_phenotypes, index=False)
display(phenotypes)
Keeping extra_cols=['cell_entry', 'cell_entry'] for filters and tooltips
Using just antibodies=['CR57'] from antibodies_all=['17C7', 'CR4098', 'CR57', 'CTB012', 'RVA122', 'RVC20', 'RVC58', 'RVC68']
Writing the phenotypes to results/dms-viz/domainIII_CR57_escape_phenotypes.csv
site | wildtype | mutant | escape | antibody | cell_entry | cell_entry | |
---|---|---|---|---|---|---|---|
0 | -2 | F | A | -0.014410 | CR57 | -0.44860 | -0.44860 |
1 | -2 | F | C | 0.027760 | CR57 | -0.18730 | -0.18730 |
2 | -2 | F | D | -0.012160 | CR57 | 0.01876 | 0.01876 |
3 | -2 | F | E | -0.030880 | CR57 | -0.79690 | -0.79690 |
4 | -2 | F | G | -0.074570 | CR57 | -0.02989 | -0.02989 |
... | ... | ... | ... | ... | ... | ... | ... |
6242 | 431 | D | S | -0.024780 | CR57 | -0.26610 | -0.26610 |
6243 | 431 | D | T | -0.021390 | CR57 | -0.17420 | -0.17420 |
6244 | 431 | D | V | -0.012870 | CR57 | -0.76310 | -0.76310 |
6245 | 431 | D | W | 0.029020 | CR57 | -0.56050 | -0.56050 |
6246 | 431 | D | Y | -0.008859 | CR57 | -0.72370 | -0.72370 |
6247 rows × 7 columns
Get enough colors:
In [8]:
def get_hex_color_palette(num_colors):
colors = seaborn.color_palette("hls", num_colors)
hex_colors = [matplotlib.colors.to_hex(color) for color in colors]
return hex_colors
nconditions = phenotypes[condition_column].nunique()
if nconditions > 4:
colors = ",".join(get_hex_color_palette(nconditions))
else:
colors = "#0072B2,#CC79A7,#4C3549,#009E73"
print(f"Using {colors=}")
seaborn.palplot(seaborn.color_palette(colors.split(",")))
Using colors='#0072B2,#CC79A7,#4C3549,#009E73'
Get the description:
In [9]:
description_text = "\n\n".join(
[
f"## {config['title']}",
config["description"] if config["description"] is not None else "",
f"Structure shown is from PDB {pdb_id}.",
description_suffix,
]
).lstrip()
print(description_text)
with open(description_md, "w") as f:
f.write(description_text)
## Effects of mutations to rabies G on escape from antibody CR57 Pseudovirus deep mutational scanning of how mutations to rabies G affect neutralization by antibody CR57 shown on domain III (8r40) Structure shown is from PDB 8r40. Study by [Aditham et al](https://www.biorxiv.org/content/10.1101/2024.12.17.628970v1) (2024). See [https://github.com/dms-vep/RABV_Pasteur_G_DMS](https://github.com/dms-vep/RABV_Pasteur_G_DMS) for code.
Now run configure-dms-viz:
In [10]:
cmds = [
"configure-dms-viz", "format",
"--name", name,
"--input", dms_viz_phenotypes,
"--output", dms_viz_json_no_description,
"--structure", pdb_file,
"--metric", metric_column,
"--condition", condition_column,
"--sitemap", dms_viz_sitemap,
"--colors", colors,
]
for col in [
"included-chains",
"excluded-chains",
]:
val = config[col]
if val:
cmds += [f"--{col}", " ".join(val)]
if config["heatmap-limits"]:
cmds += ["--heatmap-limits", ", ".join(str(x) for x in config["heatmap-limits"])]
for col in [
"alphabet",
"floor",
"summary-stat",
"tooltip-cols",
"filter-cols",
"filter-limits",
"title",
"description",
]:
cmds += [f"--{col}", str(config[col])]
print(f"Running the following commands:\n{cmds}")
subprocess.run(cmds, check=True)
cmds_join = [
"configure-dms-viz", "join",
"--input", dms_viz_json_no_description,
"--description", description_md,
"--output", dms_viz_json,
]
print(f"Running the following commands:\n{cmds_join}")
subprocess.run(cmds_join, check=True)
Running the following commands: ['configure-dms-viz', 'format', '--name', 'domainIII_CR57_escape', '--input', 'results/dms-viz/domainIII_CR57_escape_phenotypes.csv', '--output', 'results/dms-viz/domainIII_CR57_escape_no_description.json', '--structure', 'results/dms-viz/domainIII_CR57_escape.pdb', '--metric', 'escape', '--condition', 'antibody', '--sitemap', 'results/dms-viz/domainIII_CR57_escape_sitemap.csv', '--colors', '#0072B2,#CC79A7,#4C3549,#009E73', '--included-chains', 'C', '--heatmap-limits', '0', '--alphabet', 'RKHDEQNSTYWFAILMVGPC', '--floor', 'True', '--summary-stat', 'sum', '--tooltip-cols', "{'cell_entry': 'cell entry'}", '--filter-cols', "{'cell_entry': 'cell entry'}", '--filter-limits', "{'cell_entry': [-8, -5, 0]}", '--title', 'Effects of mutations to rabies G on escape from antibody CR57', '--description', 'Pseudovirus deep mutational scanning of how mutations to rabies G affect\nneutralization by antibody CR57 shown on domain III (8r40)\n']
Formatting data for visualization using the 'escape' column from 'results/dms-viz/domainIII_CR57_escape_phenotypes.csv'... Using sitemap from 'results/dms-viz/domainIII_CR57_escape_sitemap.csv'.
'protein_site' column is not present in the sitemap. Assuming that the reference sites correspond to protein sites. One value was provided for heatmap limits, this will be the center value of the scale. Warning: The 'cell_entry' filter limit '-8' is less than the minimum value of -7.526. Setting the min value to -7.526.
About 90.91% (80 of 88) of the wildtype residues in the data match the corresponding residues in the structure. Warning: 79.58% (343 of 431) of the data sites are missing from the structure.
Success! The visualization JSON was written to 'results/dms-viz/domainIII_CR57_escape_no_description.json'
Running the following commands: ['configure-dms-viz', 'join', '--input', 'results/dms-viz/domainIII_CR57_escape_no_description.json', '--description', 'results/dms-viz/domainIII_CR57_escape_description.md', '--output', 'results/dms-viz/domainIII_CR57_escape.json']
Success! 1 JSON files were merged and saved to 'results/dms-viz/domainIII_CR57_escape.json'
Out[10]:
CompletedProcess(args=['configure-dms-viz', 'join', '--input', 'results/dms-viz/domainIII_CR57_escape_no_description.json', '--description', 'results/dms-viz/domainIII_CR57_escape_description.md', '--output', 'results/dms-viz/domainIII_CR57_escape.json'], returncode=0)
In [ ]: