Skip to content

Commit

Permalink
feat(pretty print): breaking up creation of each line in display into…
Browse files Browse the repository at this point in the history
… subclasses
  • Loading branch information
andreasprlic committed May 28, 2024
1 parent e9fde79 commit d3a5e6e
Show file tree
Hide file tree
Showing 10 changed files with 536 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/hgvs/pretty/renderer/chrom_seq_renderer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from hgvs.pretty.models import VariantData
from hgvs.pretty.renderer.renderer import BasicRenderer


class ChromSeqRendered(BasicRenderer):

def legend(self)->str:
return "seq -> : "

def display(self, data:VariantData)->str:
"""colors the ref sequences with adenine (A, green), thymine (T, red), cytosine (C, yellow), and guanine (G, blue)"""
from hgvs.pretty_print import ENDC, TBLUE, TGREEN, TRED, TYELLOW

var_seq = ""
for p in data.position_details:
c = p.ref

if not c:
var_seq += "."
continue

if self.config.useColor:
if c == "A":
var_seq += TGREEN
elif c == "T":
var_seq += TRED
elif c == "C":
var_seq += TYELLOW
elif c == "G":
var_seq += TBLUE

var_seq += c

if self.config.useColor:
var_seq += ENDC

return var_seq
33 changes: 33 additions & 0 deletions src/hgvs/pretty/renderer/pos_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from hgvs.pretty.models import VariantData
from hgvs.pretty.renderer.renderer import BasicRenderer


class ChrPositionInfo(BasicRenderer):

def legend(self):
return " : "

def display(self, data: VariantData) -> str:

count = -1
var_seq = ""
for pdata in data.position_details:
count += 1
g = pdata.chromosome_pos

total_chars = len(var_seq)

if total_chars > count:
continue

if not g:
var_seq += " "
continue

if g % 10 == 0:
var_seq += f"{g:,} "

else:
var_seq += " "

return var_seq.rstrip()
75 changes: 75 additions & 0 deletions src/hgvs/pretty/renderer/prot_seq_renderer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from hgvs.pretty.models import VariantData
from hgvs.pretty.renderer.renderer import BasicRenderer


class ProtSeqRenderer(BasicRenderer):

def legend(self):
legend = "aa seq -> : "
if self.orientation < 0:
legend = "aa seq <- : "
return legend

def display(self, data: VariantData) -> str:
if not data.var_c_or_n:
return ""

from hgvs.pretty_print import ENDC, TGREEN, TRED

var_str = ""
for pdata in data.position_details:

p = pdata.chromosome_pos

if not pdata.mapped_pos:
var_str += " "
continue

ref_base = pdata.ref

c_interval = pdata.c_interval
if not c_interval:
var_str += " "
continue

cig = pdata.cigar_ref
c_offset = pdata.c_offset
if cig == "N" or c_offset != 0:
var_str += " "
continue

if cig == "I":
var_str += "-"
continue

if not ref_base or pdata.tx:
ref_base = pdata.tx

protein_data = pdata.protein_data

if not protein_data:
var_str += " "
continue

aa_char = protein_data.aa_char

# color init met and stop codon if using color:
if protein_data.is_init_met:
if self.config.useColor:
aa_char = TGREEN + aa_char + ENDC
var_str += aa_char
continue
if protein_data.is_stop_codon:
if self.config.useColor:
aa_char = TRED + aa_char + ENDC
var_str += aa_char
continue

if not protein_data.var_p.posedit:
var_str += " "
continue

var_str += aa_char
continue

return var_str
14 changes: 14 additions & 0 deletions src/hgvs/pretty/renderer/renderer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from abc import ABC, abstractmethod

class BasicRenderer(ABC):
def __init__(self, config, orientation:int):
self.config = config
self.orientation = orientation

@abstractmethod
def legend(self):
pass

@abstractmethod
def display(self):
pass
31 changes: 31 additions & 0 deletions src/hgvs/pretty/renderer/ruler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from hgvs.pretty.models import VariantData
from hgvs.pretty.renderer.renderer import BasicRenderer


class ChrRuler(BasicRenderer):

def legend(self):
""" returns the legend for this category of display"""
return "chrom pos : "

def display(self, data: VariantData) -> str:
"""Draw a position indicator that diplays | every 10 bases and a . every 5
seq_start/end in interbase
"""

ruler = ""

for pd in data.position_details:
p = pd.chromosome_pos
if not p:
ruler += "_"
continue

if p % 10 == 0:
ruler += "|"
elif p % 5 == 0:
ruler += "."
else:
ruler += " "
return ruler
93 changes: 93 additions & 0 deletions src/hgvs/pretty/renderer/shuffled_variant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@


from hgvs.pretty.models import VariantCoords, VariantData
from hgvs.pretty.renderer.renderer import BasicRenderer
from hgvs.sequencevariant import SequenceVariant


class ShuffledVariant(BasicRenderer):

def __init__(self, config, orientation:int, var_g: SequenceVariant, vc: VariantCoords)->None:
super().__init__(config, orientation)

self.var_g = var_g
self.vc = vc

def legend(self
) ->str:

return "region : "

def display(
self, data: VariantData
) -> str:

from hgvs.pretty_print import ENDC, TBLUE, TGREEN, TRED, TYELLOW

seq_start = data.display_start
seq_end = data.display_end

split_char = "|"

start = self.vc.start
end = self.vc.end

# map interbase coordinates to 1-based display coords:
start = start + 1

if self.var_g.posedit.edit.type == "sub":
end = start
if len(self.vc.alt) == 1:
split_char = self.vc.alt
l = end - start + 1
if self.var_g.posedit.edit.type == "ins" and l == 0:
start = start - 1
end = end + 1
split_char = "^"

if self.var_g.posedit.edit.type == "del":
split_char = ""
if self.config.useColor:
split_char = TRED
split_char += "x"
if self.config.useColor:
split_char += ENDC

elif self.var_g.posedit.edit.type == "identity":
split_char = "="
# print(l,start, end , vc)

if start < seq_start:
# raise ValueError(f"Can't create shuffled representation, since start {start} < seq_start {seq_start} ")
return ""
if end > seq_end:
return ""
# raise ValueError(f"Can't create shuffled representation, since end {end} > seq_end {seq_end} ")

var_str = ""
in_range = False
for pdata in data.position_details:
p = pdata.chromosome_pos

if not p:
if in_range:
var_str += "-"
else:
var_str += " "
continue

if p == start:
var_str += split_char
in_range = True
elif p == end:
var_str += split_char
in_range = False
elif p > end and in_range:
in_range = False
var_str += " "
elif in_range:
var_str += "-"
else:
var_str += " "

return var_str
96 changes: 96 additions & 0 deletions src/hgvs/pretty/renderer/tx_alig_renderer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import math
from hgvs.pretty.models import VariantData
from hgvs.pretty.renderer.renderer import BasicRenderer


class TxAligRenderer(BasicRenderer):

def legend(self)->str:
orientation = "->"
if self.orientation < 0:
orientation = "<-"
return f"tx seq {orientation} : "


def display(self, data: VariantData) -> str:
"""If transcript info is available show the details of the tx for the region."""
if not data.var_c_or_n:
return ""

from hgvs.pretty_print import ENDC, TYELLOW, TPURPLE
var_str = ""

first_c = None
last_c = None

coding = False
c_pos = None

counter = -1
for pdata in data.position_details:

counter += 1

if not pdata.mapped_pos:
var_str += " "
continue


n_pos = pdata.n_pos
c_pos = pdata.c_pos
cig = pdata.cigar_ref
c_offset = pdata.c_offset

if cig == "N" or (c_offset is not None and c_offset != 0):
coding = False
var_str += " "
continue


if c_pos:
# if we get here we are coding...
last_c = f"c.{c_pos}"
else:
last_c = f"n.{n_pos}"
c_pos = n_pos
if not coding:

if not first_c:
first_c = last_c

coding = True

if cig == "=":
#c3 = (c_pos - 1) % 3
if c_pos:
bg_col = math.ceil(c_pos / 3) % 2
elif n_pos:
bg_col = math.ceil(n_pos / 3) % 2
else:
var_str += " "
continue

# print(p, c_pos, c3, bg_col )
if n_pos >= 0:
base = pdata.tx
if self.config.useColor and c_pos > 0:
if bg_col:
var_str += TPURPLE + base + ENDC
else:
var_str += TYELLOW + base + ENDC
else:
if c_pos is None or c_pos < 0:
var_str += base.lower()
else:
var_str += base
continue

elif cig == "X" or cig == "D":
# for mismatches and tx-insertions show sequence
var_str += pdata.tx
continue

else:
var_str += "-"

return var_str
Loading

0 comments on commit d3a5e6e

Please sign in to comment.