Skip to content

Implement HG-DT Visual Interpretation & Causal Dashboard#8

Open
AkeBoss-tech wants to merge 1 commit intofeat/dna-to-protein-pipeline-13697527110041319258from
implement-causal-dashboard-382463070580210348
Open

Implement HG-DT Visual Interpretation & Causal Dashboard#8
AkeBoss-tech wants to merge 1 commit intofeat/dna-to-protein-pipeline-13697527110041319258from
implement-causal-dashboard-382463070580210348

Conversation

@AkeBoss-tech
Copy link
Copy Markdown
Owner

Implemented the Work Order 04 (Visual Interpretation & Causal Dashboard). This includes building an interactive Streamlit app and creating the necessary visualization and analysis modules. Addressed user's follow-up request to include gene selection and time-course accessibility plotting during transitions.


PR created automatically by Jules for task 382463070580210348 started by @AkeBoss-tech

- Added `app.py` Streamlit dashboard with tabs for Specification, Genome Tracks, 3D Organization, Protein Structure, Trajectory Animation, and Mechanistic Attribution.
- Created `src/hg_dt/viz/tracks_plotter.py` for 1D track comparison.
- Created `src/hg_dt/viz/hic_plotter.py` for 3D contact map comparison.
- Created `src/hg_dt/viz/protein_viz.py` for 3D protein structure visualization using py3Dmol/stmol.
- Created `src/hg_dt/analyze/attribution.py` for generating mechanistic insights.
- Addressed follow-up to support multiple gene selections and temporal visualization of gene accessibility.

Co-authored-by: AkeBoss-tech <69588353+AkeBoss-tech@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Copilot AI review requested due to automatic review settings April 5, 2026 05:16
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an HG-DT “Visual Interpretation & Causal Dashboard” Streamlit UI plus supporting visualization/attribution helpers to explore ref-vs-mutant deltas across 1D tracks, Hi-C contact maps, protein structure, and a simple mechanistic summary.

Changes:

  • Introduces a new Streamlit dashboard entrypoint (app.py) with multi-tab views and mock-data generators.
  • Adds lightweight matplotlib-based plotting utilities for 1D tracks and Hi-C delta maps.
  • Adds a protein 3D viewer component and a mechanistic attribution text generator.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
app.py New Streamlit dashboard wiring together mock data, plots, and attribution output.
src/hg_dt/viz/tracks_plotter.py Matplotlib helper to render ref/mut/Δ genome tracks.
src/hg_dt/viz/hic_plotter.py Matplotlib helper to render ref/mut/Δ Hi-C heatmaps (upper-triangular).
src/hg_dt/viz/protein_viz.py Streamlit component for 3D protein visualization/comparison using py3Dmol/stmol.
src/hg_dt/analyze/attribution.py Mechanistic insight string builder from delta summary stats.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,39 @@
import os
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os is imported but never used in this module; consider removing it to avoid lint noise and keep dependencies minimal.

Suggested change
import os

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +31
# Mut track
axes[1].fill_between(range(len(mut_track)), mut_track, color="orange", alpha=0.7)
axes[1].set_ylabel("Mutant")

# Delta track
delta = mut_track - ref_track
axes[2].fill_between(range(len(delta)), delta, where=(delta >= 0), color="red", alpha=0.7, label="Gain")
axes[2].fill_between(range(len(delta)), delta, where=(delta < 0), color="green", alpha=0.7, label="Loss")
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delta = mut_track - ref_track assumes both inputs are 1D arrays of the same length; if shapes differ this will raise a broadcasting error (or silently misbehave if one is length-1). Add explicit validation (ndim == 1, same length) and raise a clear ValueError early.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +4
import os
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os and LinearSegmentedColormap are imported but unused in this file; please remove them to keep the module clean and avoid unused-import warnings.

Suggested change
import os
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
import matplotlib.pyplot as plt
import numpy as np

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +22
# We rotate the matrix to make it triangular for standard Hi-C view.
# To keep it simple, we just plot the 2D matrix directly but use upper triangle.
ref_tri = np.triu(ref_map)
mut_tri = np.triu(mut_map)
delta_tri = mut_tri - ref_tri
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np.triu(ref_map)/np.triu(mut_map) and the subsequent subtraction assume both maps are 2D and the same shape (and typically square for Hi-C). Add input validation (ndim == 2, same shape, optionally square) and raise a clear error if not.

Copilot uses AI. Check for mistakes.
plt.colorbar(im1, ax=axes[1], fraction=0.046, pad=0.04)

vmax = np.max(np.abs(delta_tri))
im2 = axes[2].imshow(delta_tri, cmap=cmap_delta, vmin=-vmax, vmax=vmax, interpolation='nearest')
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vmax = np.max(np.abs(delta_tri)) can be 0 when the maps are identical, which makes vmin=-vmax, vmax=vmax invalid (matplotlib warns about identical limits and the colormap scaling becomes meaningless). Guard for vmax == 0 (e.g., skip setting vmin/vmax or use a small epsilon).

Suggested change
im2 = axes[2].imshow(delta_tri, cmap=cmap_delta, vmin=-vmax, vmax=vmax, interpolation='nearest')
if vmax > 0:
im2 = axes[2].imshow(delta_tri, cmap=cmap_delta, vmin=-vmax, vmax=vmax, interpolation='nearest')
else:
im2 = axes[2].imshow(delta_tri, cmap=cmap_delta, interpolation='nearest')

Copilot uses AI. Check for mistakes.
Comment thread app.py
Comment on lines +109 to +112
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
track_img_path = plot_tracks(ref_track, mut_track, tmp.name, title=f"1D Tracks: {st.session_state.gene} {st.session_state.mod_type}")
st.image(Image.open(track_img_path), use_column_width=True)

Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Streamlit app writes plot images to NamedTemporaryFile(..., delete=False) but never removes them, which will leak temp files over time on repeated runs. Prefer rendering figures directly to memory (e.g., BytesIO) or explicitly os.unlink(...) after st.image; also ensure any Image.open(...) objects are closed to avoid file-handle leaks.

Copilot uses AI. Check for mistakes.
Comment thread app.py
Comment on lines +116 to +118
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
hic_img_path = plot_hic_triangle(ref_hic, mut_hic, tmp.name, title=f"3D Contact Map: {st.session_state.gene} {st.session_state.mod_type}")
st.image(Image.open(hic_img_path), use_column_width=True)
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same temp-file leak issue as above: this creates another delete=False image file and leaves it behind after rendering. Please clean up the temp file (or switch to in-memory rendering) to avoid accumulating files in the temp directory.

Copilot uses AI. Check for mistakes.
Comment thread app.py
Comment on lines +138 to +143
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
fig.tight_layout()
fig.savefig(tmp.name, dpi=150)
plt.close(fig)
st.image(Image.open(tmp.name), use_column_width=True)

Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same temp-file leak issue again for the trajectory plot: delete=False plus no cleanup will accumulate files across reruns. Consider using an in-memory buffer or deleting the temp file after st.image.

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +24
def generate_mechanistic_insight(mod_details: Dict[str, Any], delta_stats: Dict[str, Any]) -> str:
"""
Generate a 'Mechanistic Insight' text string summarizing the multi-scale delta.

Args:
mod_details: Dictionary containing modification details like 'type', 'target', 'locus'.
delta_stats: Dictionary containing computed deltas, e.g.,
{'accessibility_drop': 0.28, 'expression_drop': 0.35, 'loop_weakened': True}

Returns:
A human-readable string attributing the structural consequence.
"""
mod_type = mod_details.get("type", "modification")
target = mod_details.get("target", "element")

insight_parts = [f"This {mod_type} affects {target}"]

if delta_stats.get("loop_weakened"):
insight_parts.append("weakens enhancer-promoter loop")
elif delta_stats.get("loop_strengthened"):
insight_parts.append("strengthens enhancer-promoter loop")

Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate_mechanistic_insight is new behavior but has no unit tests. Given this repo already tests similar analysis helpers under src/hg_dt/analyze (e.g., tests/test_alphagenome_integration.py covers src/hg_dt/analyze/deltas.py), please add focused tests that assert the generated string for key cases (loop weakened/strengthened, positive vs negative deltas, missing keys/defaults).

Copilot uses AI. Check for mistakes.
Comment thread app.py
@@ -0,0 +1,176 @@
import streamlit as st
import numpy as np
import os
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os is imported but unused in this file; remove it to avoid unused-import warnings.

Suggested change
import os

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants