""" Builds the HTML visualization block shown after a prediction — the sequence node grid, metrics cards, alignment view, and info/fun-fact card. """ import html def build_result_html(sequence, pred_str, true_ss=None, q3_score=None, description="", fun_fact=""): """Renders the custom HTML result panel matching the app's design system.""" # 1. Interactive Node Grid (first 60 residues shown as scannable nodes) grid_nodes_html = "
" display_limit = min(len(sequence), 60) for i in range(display_limit): aa = sequence[i] st = pred_str[i] grid_nodes_html += f"""
{aa} {st}
""" grid_nodes_html += "
" if len(sequence) > 60: grid_nodes_html += f"""

+ {len(sequence) - 60} additional amino acid residues sequence mapped below

""" # 2. Structure Composition Analysis h_cnt, e_cnt, c_cnt = pred_str.count('H'), pred_str.count('E'), pred_str.count('C') tot = max(len(pred_str), 1) h_pct, e_pct, c_pct = (h_cnt / tot) * 100, (e_cnt / tot) * 100, (c_cnt / tot) * 100 # 3. Alignment Rows (Monospaced Sequence Alignment) pred_align_html = "" truth_align_html = "" for i in range(len(sequence)): p_char = pred_str[i] if true_ss and i < len(true_ss): t_char = true_ss[i] if p_char == t_char: pred_align_html += f"{p_char}" else: pred_align_html += f"{p_char}" truth_align_html += t_char else: pred_align_html += p_char alignment_card_html = f"""
{f'''
Ground Truth
{truth_align_html}
''' if true_ss else ''}
SERAPH Pred
{pred_align_html}
AA Sequence
{sequence}
""" # 4. Metric Header Card if q3_score is not None: metrics_card_html = f"""
{q3_score:.1f}%
Q3 Accuracy Score
{len(sequence)}
Residue Length
""" else: metrics_card_html = f"""
{len(sequence)}
Residues Analyzed
{h_pct:.0f}% / {e_pct:.0f}% / {c_pct:.0f}%
Helix / Sheet / Coil
""" # 5. Protein Info & Fun Fact Card info_card_html = "" if description or fun_fact: info_card_html = f"""
{f'

Overview: {html.escape(description)}

' if description else ''} {f'

💡 Fun Fact: {html.escape(fun_fact)}

' if fun_fact else ''}
""" # Full Combined Output Block return f"""
{metrics_card_html}
Helix (H) {h_cnt} ({h_pct:.0f}%)
Sheet (E) {e_cnt} ({e_pct:.0f}%)
Coil (C) {c_cnt} ({c_pct:.0f}%)
{grid_nodes_html}
{alignment_card_html} {info_card_html}
"""