Skip to content

Commit

Permalink
Merge pull request #20 from glycojones/onemodel
Browse files Browse the repository at this point in the history
Merge onemodel branch into master
  • Loading branch information
glycojones authored Sep 19, 2024
2 parents e3b4aed + 0a3a5c6 commit 6d18fbf
Show file tree
Hide file tree
Showing 43 changed files with 291,421 additions and 23,721 deletions.
24 changes: 21 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
build/
.vscode
# Byte-compiled / optimized / DLL files
__pycache__/
PKG-INFO
*.py[co]
*$py.class

# Mac meta stuff
# DS_Store
.DS_Store

# Ignore build related files
/dist
/build
/.eggs/
/pyrun/

# Ignore accidental test data
/*.cif
/*.pdb
/*.ent
/*.json
/*.mtz
/*.crd
44 changes: 44 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[build-system]
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"

[project]
name = "iris_validation"
dynamic=["version"]
description = "A package for interactive all-in-one graphical validation of 3D protein model iterations"
readme = "README.md"
requires-python = ">=3.8"
classifiers = [
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.8",
]
authors = [
{ name = "William Rochira", email = "[email protected]" },
{ name = "Jon Agirre", email = "[email protected]" }
]
maintainers = [
{ name = "Jon Agirre", email = "[email protected]" },
]
dependencies = [
"svgwrite == 1.3.1"
]

[tool.setuptools]
include-package-data = true

[tool.setuptools_scm]
version_file = "src/iris_validation/_version.py"

[project.urls]
Homepage = "https://github.com/glycojones/iris-validation"
Issues = "https://github.com/glycojones/iris-validation/issues"

[tool.pytest.ini_options]
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"simple: a simple test to get output quickly (deselect with '-m \"not simple\"')",
"tortoize: runs tortoize tests (deselect with '-m \"not tortoize\"')",
"molprobity: runs molprobity tests (deselect with '-m \"not molprobity\"')",
"problem",
]
1 change: 0 additions & 1 deletion requirements.txt

This file was deleted.

29 changes: 0 additions & 29 deletions setup.py

This file was deleted.

43 changes: 25 additions & 18 deletions iris_validation/__init__.py → src/iris_validation/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import os
import sys
import json

from iris_validation.graphics import Panel
from iris_validation.metrics import metrics_model_series_from_files

PYTEST_RUN = 'pytest' in sys.modules

def generate_report(
latest_model_path,
Expand All @@ -27,34 +30,38 @@ def generate_report(
percentile_bar_range=None,
wrap_in_html=True,
output_dir=None,
output_name_prefix="report",
custom_labels={'Latest':'Latest', 'Previous':'Previous'}
):

model_paths = (previous_model_path, latest_model_path)
reflections_paths = (previous_reflections_path, latest_reflections_path)
sequence_paths = (previous_sequence_path, latest_sequence_path)
distpred_paths = (previous_distpred_path, latest_distpred_path)
model_json_paths = (previous_model_metrics_json, latest_model_metrics_json)
# sanitise output file name
output_name_prefix = output_name_prefix.replace('/','_').replace('.','_')

model_series = metrics_model_series_from_files(
model_paths,
reflections_paths,
sequence_paths,
distpred_paths,
run_covariance,
run_molprobity,
calculate_rama_z,
model_json_paths,
data_with_percentiles,
multiprocessing,
)
model_series = metrics_model_series_from_files((previous_model_path, latest_model_path),
(previous_reflections_path, latest_reflections_path),
(previous_sequence_path, latest_sequence_path),
(previous_distpred_path, latest_distpred_path),
(previous_model_metrics_json, latest_model_metrics_json),
run_covariance,
run_molprobity,
calculate_rama_z,
data_with_percentiles,
multiprocessing)

model_series_data = model_series.get_raw_data()

if PYTEST_RUN :
with open(os.path.join(output_dir, output_name_prefix + ".json"), 'w', encoding='utf8') as json_output :
json.dump(model_series_data, json_output, indent=2)

panel = Panel(
model_series_data,
continuous_metrics_to_display=continuous_metrics_to_display,
discrete_metrics_to_display=discrete_metrics_to_display,
residue_bars_to_display=residue_bars_to_display,
percentile_bar_label=percentile_bar_label,
percentile_bar_range=percentile_bar_range,
custom_labels=custom_labels
)
panel_string = panel.dwg.tostring()

Expand All @@ -68,5 +75,5 @@ def generate_report(
os.mkdir(output_dir)

extension = 'html' if wrap_in_html else 'svg'
with open(os.path.join(output_dir, f'report.{extension}'), 'w', encoding='utf8') as outfile:
with open(os.path.join(output_dir, f"{output_name_prefix}.{extension}"), 'w', encoding='utf8') as outfile:
outfile.write(panel_string)
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from svgwrite.animate import Animate

from iris_validation._defs import COLORS, CHAIN_VIEW_RINGS, CHAIN_VIEW_GAP_ANGLE
from iris_validation._version import version_tuple


class ChainView:
Expand Down Expand Up @@ -142,21 +143,35 @@ def _draw(self):

# Draw center text
self.dwg.add(self.dwg.text(text='Iris',
insert=(self.center[0], self.center[1]-24),
font_size=1.5*16,
insert=(self.center[0], self.center[1]-22),
font_size=1.5*18,
font_family='Arial',
font_weight='bold',
text_anchor='middle',
alignment_baseline='central'))
self.dwg.add(self.dwg.text(text='Release ' + '.'.join(map(str, version_tuple[:3])),
insert=(self.center[0], self.center[1]),
font_size=14,
font_family='Arial',
text_anchor='middle',
alignment_baseline='central'))
self.dwg.add(self.dwg.text(text='Chain ' + self.data['chain_id'],
insert=(self.center[0], self.center[1]+16),
insert=(self.center[0], self.center[1]+18),
font_size=16,
font_family='Arial',
text_anchor='middle',
alignment_baseline='central'))
if self.data['has_molprobity']:
self.dwg.add(self.dwg.text(text='MolProbity',
insert=(self.center[0], self.center[1]+48),
insert=(self.center[0], self.center[1]+50),
font_size=16,
font_family='Arial',
text_anchor='middle',
alignment_baseline='central',
fill=COLORS['L_GREY']))
elif self.data['has_rama_z']:
self.dwg.add(self.dwg.text(text='Tortoize',
insert=(self.center[0], self.center[1]+50),
font_size=16,
font_family='Arial',
text_anchor='middle',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const modelData = {model_data};
const numVersions = {num_versions};
const numChains = {num_chains};
const boxMetricIDs = {box_metric_ids};
const barMetricIDs = {bar_metric_ids};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
let selectedVersion = 1;
let selectedVersion = numVersions - 1;
let selectedChain = 0;
let selectedResidue = 0;

Expand Down Expand Up @@ -294,7 +294,7 @@ function updateSelectedResidue() {
// Set summary text
let seqNum = modelData[selectedChain]['residue_seqnos'][selectedVersion][selectedResidue];
let aaCode = modelData[selectedChain]['residue_codes'][selectedVersion][selectedResidue];
residueSummary.textContent = 'Residue ' + seqNum + ' (' + aaCode + ')';
residueSummary.textContent = seqNum + ' (' + aaCode + ')';
};


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ def __init__(
residue_bars_to_display=None,
percentile_bar_label=None,
percentile_bar_range=None,
custom_labels={'Latest':'Latest', 'Previous':'Previous'}
):
self.data = data
self.canvas_size = canvas_size
self.custom_labels = custom_labels
self.chain_view_rings = CHAIN_VIEW_RINGS
if continuous_metrics_to_display:
self.chain_view_rings = self.get_chain_view_rings(
Expand Down Expand Up @@ -91,6 +93,7 @@ def _verify_chosen_metrics(self):

def _generate_javascript(self):
json_data = json.dumps(self.data)
num_versions = self.num_models
num_chains = len(self.chain_ids)
bar_metric_ids = [metric["id"] for metric in self.residue_view_bars]
box_metric_ids = [ metric['id'] for metric in RESIDUE_VIEW_BOXES ]
Expand All @@ -106,6 +109,7 @@ def _generate_javascript(self):

js_constants = js_constants.format(
model_data=json_data,
num_versions=num_versions,
num_chains=num_chains,
bar_metric_ids=bar_metric_ids,
box_metric_ids=box_metric_ids,
Expand Down Expand Up @@ -138,8 +142,8 @@ def _draw(self):
middle_gap = 30
view_border = 10
view_title_font = 24
button_width = 38
button_height = 32
button_width = 26
button_height = 26
view_width, view_height = [ dim - view_border for dim in self.canvas_size ]
view_divider_x = round(2/3 * view_width, 2)
chain_view_bounds = (view_border,
Expand Down Expand Up @@ -179,9 +183,15 @@ def _draw(self):
font_size=view_title_font,
font_family='Arial'))

self.dwg.add(self.dwg.text(text='Residue',

self.dwg.add(self.dwg.text(text='Amino acid',
insert=(residue_view_bounds[0], residue_view_bounds[1]+view_title_font),
font_size=view_title_font,
font_family='Arial'))

self.dwg.add(self.dwg.text(text='',
insert=(residue_view_bounds[0]+130, residue_view_bounds[1]+view_title_font),
font_size=16,
font_family='Arial',
id=f'{self.svg_id}-residue-summary'))

Expand All @@ -196,9 +206,9 @@ def _draw(self):
stroke_width=2))

# Chain selector buttons
for chain_index, chain_id in enumerate(self.chain_ids[:12]):
for chain_index, chain_id in enumerate(self.chain_ids[:16]):
selector_color = self.swtich_colors[1] if chain_index == 0 else self.swtich_colors[0]
self.dwg.add(self.dwg.rect(insert=(chain_view_bounds[0] + 75 + 50*chain_index, chain_view_bounds[1]),
self.dwg.add(self.dwg.rect(insert=(chain_view_bounds[0] + 75 + 30*chain_index, chain_view_bounds[1]+5),
size=(button_width, button_height),
rx=5,
stroke_opacity=0,
Expand All @@ -207,13 +217,13 @@ def _draw(self):
id=f'{self.svg_id}-chain-selector-{chain_index}'))

self.dwg.add(self.dwg.text(text=chain_id,
insert=(chain_view_bounds[0] + 75 + button_width/2 + 50*chain_index, chain_view_bounds[1] + button_height/2),
font_size=view_title_font,
insert=(chain_view_bounds[0] + 75 + button_width/2 + 30*chain_index, chain_view_bounds[1] + 5 + button_height/2),
font_size=16,
font_family='Arial',
text_anchor='middle',
alignment_baseline='central'))

self.dwg.add(self.dwg.rect(insert=(chain_view_bounds[0] + 75 + 50*chain_index, chain_view_bounds[1]),
self.dwg.add(self.dwg.rect(insert=(chain_view_bounds[0] + 75 + 30*chain_index, chain_view_bounds[1]+5),
size=(button_width, button_height),
rx=5,
stroke_opacity=0,
Expand All @@ -224,24 +234,24 @@ def _draw(self):

# Extra chains dropdown
# TODO: finish this
if len(self.chain_ids) > 12:
chain_index = 12
if len(self.chain_ids) > 16:
chain_index = 16
selector_color = self.swtich_colors[0]
self.dwg.add(self.dwg.rect(insert=(chain_view_bounds[0] + 75 + 50*chain_index, chain_view_bounds[1]),
size=(38, 32),
self.dwg.add(self.dwg.rect(insert=(chain_view_bounds[0] + 75 + 30*chain_index, chain_view_bounds[1] +5),
size=(26, 26),
rx=5,
stroke_opacity=0,
fill_opacity=0.5,
fill=selector_color,
id=f'{self.svg_id}-chain-selector-dropdown'))

self.dwg.add(self.dwg.text(text='...',
insert=(chain_view_bounds[0] + 85 + 50*chain_index, chain_view_bounds[1]+view_title_font),
font_size=view_title_font,
insert=(chain_view_bounds[0] + 80 + 30*chain_index, chain_view_bounds[1]+24),
font_size=16,
font_family='Arial'))

self.dwg.add(self.dwg.rect(insert=(chain_view_bounds[0] + 75 + 50*chain_index, chain_view_bounds[1]),
size=(38, 32),
self.dwg.add(self.dwg.rect(insert=(chain_view_bounds[0] + 75 + 30*chain_index, chain_view_bounds[1]+5),
size=(26, 26),
rx=5,
stroke_opacity=0,
fill_opacity=0,
Expand All @@ -250,12 +260,17 @@ def _draw(self):
onclick=f'toggleDropdown();'))

# Version toggle switch
self.dwg.add(self.dwg.text(text='Previous',
self.dwg.add(self.dwg.text(text='Model version',
insert=(chain_view_bounds[2]-380, chain_view_bounds[1]+20),
font_size=view_title_font,
font_family='Arial'))

self.dwg.add(self.dwg.text(text=self.custom_labels['Previous'],
insert=(chain_view_bounds[2]-215, chain_view_bounds[1]+20),
font_size=16,
font_family='Arial'))

self.dwg.add(self.dwg.text(text='Latest',
self.dwg.add(self.dwg.text(text=self.custom_labels['Latest'],
insert=(chain_view_bounds[2]-55, chain_view_bounds[1]+20),
font_size=16,
font_family='Arial'))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ def _draw(self):
self.dwg.add(
self.dwg.text(
self.percentile_bar_label,
insert=(self.canvas_size[0] / 2, bar_charts_bounds[3] + 50),
font_size=18,
insert=((self.canvas_size[0] / 2)+20, bar_charts_bounds[3] + 60),
font_size=24,
font_family="Arial",
fill=COLORS["BLACK"],
fill_opacity=1,
Expand Down
Loading

0 comments on commit 6d18fbf

Please sign in to comment.