Skip to content

Commit 15293f6

Browse files
committed
stash
1 parent 1d7de3c commit 15293f6

5 files changed

Lines changed: 147 additions & 305 deletions

File tree

src/cool_seq_tool/mappers/exon_genomic_coords.py

Lines changed: 13 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
)
2121
from cool_seq_tool.sources.mane_transcript_mappings import ManeTranscriptMappings
2222
from cool_seq_tool.sources.uta_database import (
23+
ExonCoord,
2324
GenomicAlnData,
2425
NoMatchingAlignmentError,
2526
UtaDatabase,
@@ -29,39 +30,6 @@
2930
_logger = logging.getLogger(__name__)
3031

3132

32-
class _ExonCoord(BaseModelForbidExtra):
33-
"""Model for representing exon coordinate data"""
34-
35-
ord: StrictInt = Field(..., description="Exon number. 0-based.")
36-
tx_start_i: StrictInt = Field(
37-
...,
38-
description="Transcript start index of the exon. Inter-residue coordinates.",
39-
)
40-
tx_end_i: StrictInt = Field(
41-
..., description="Transcript end index of the exon. Inter-residue coordinates."
42-
)
43-
alt_start_i: StrictInt = Field(
44-
..., description="Genomic start index of the exon. Inter-residue coordinates."
45-
)
46-
alt_end_i: StrictInt = Field(
47-
..., description="Genomic end index of the exon. Inter-residue coordinates."
48-
)
49-
alt_strand: Strand = Field(..., description="Strand.")
50-
51-
model_config = ConfigDict(
52-
json_schema_extra={
53-
"example": {
54-
"ord": 0,
55-
"tx_start_i": 0,
56-
"tx_end_i": 234,
57-
"alt_start_i": 154191901,
58-
"alt_end_i": 154192135,
59-
"alt_strand": Strand.NEGATIVE,
60-
}
61-
}
62-
)
63-
64-
6533
class TxSegment(BaseModelForbidExtra):
6634
"""Model for representing transcript segment data."""
6735

@@ -602,7 +570,7 @@ async def _get_start_end_exon_coords(
602570
exon_start: int | None = None,
603571
exon_end: int | None = None,
604572
genomic_ac: str | None = None,
605-
) -> tuple[_ExonCoord | None, _ExonCoord | None, list[str]]:
573+
) -> tuple[ExonCoord | None, ExonCoord | None, list[str]]:
606574
"""Get exon coordinates for a transcript given exon start and exon end.
607575
608576
If ``genomic_ac`` is NOT provided, this method will use the GRCh38 accession
@@ -617,7 +585,8 @@ async def _get_start_end_exon_coords(
617585
transcript and genomic positions for the start and end of the exon, and
618586
strand.
619587
"""
620-
tx_exons = await self._get_all_exon_coords(tx_ac, genomic_ac=genomic_ac)
588+
async with self.uta_db.repository() as uta:
589+
tx_exons = await uta.get_all_exon_coords(tx_ac, genomic_ac=genomic_ac)
621590
if not tx_exons:
622591
return None, None, [f"Transcript does not exist in UTA: {tx_ac}"]
623592

@@ -637,65 +606,11 @@ async def _get_start_end_exon_coords(
637606

638607
return *start_end_exons, errors
639608

640-
async def _get_all_exon_coords(
641-
self, tx_ac: str, genomic_ac: str | None = None
642-
) -> list[_ExonCoord]:
643-
"""Get all exon coordinate data for a transcript.
644-
645-
If ``genomic_ac`` is NOT provided, this method will use the GRCh38 accession
646-
associated to ``tx_ac``.
647-
648-
:param tx_ac: The RefSeq transcript accession to get exon data for.
649-
:param genomic_ac: The RefSeq genomic accession to get exon data for.
650-
:return: List of all exon coordinate data for ``tx_ac`` and ``genomic_ac``.
651-
The exon coordinate data will include the exon number, transcript and
652-
genomic positions for the start and end of the exon, and strand.
653-
The list will be ordered by ascending exon number.
654-
"""
655-
if genomic_ac:
656-
query = """
657-
SELECT DISTINCT ord, tx_start_i, tx_end_i, alt_start_i, alt_end_i, alt_strand
658-
FROM tx_exon_aln_mv
659-
WHERE tx_ac = %(tx_ac)s
660-
AND alt_aln_method = 'splign'
661-
AND alt_ac = %(genomic_ac)s
662-
ORDER BY ord ASC;
663-
"""
664-
else:
665-
query = """
666-
SELECT DISTINCT ord, tx_start_i, tx_end_i, alt_start_i, alt_end_i, alt_strand
667-
FROM tx_exon_aln_mv as t
668-
INNER JOIN _seq_anno_most_recent as s
669-
ON t.alt_ac = s.ac
670-
WHERE s.descr = ''
671-
AND t.tx_ac = %(tx_ac)s
672-
AND t.alt_aln_method = 'splign'
673-
AND t.alt_ac like 'NC_000%%'
674-
ORDER BY ord ASC;
675-
"""
676-
677-
async with self.uta_db.repository() as uta:
678-
cursor = await uta.execute_query(
679-
query, {"tx_ac": tx_ac, "genomic_ac": genomic_ac}
680-
)
681-
results = await cursor.fetchall()
682-
return [
683-
_ExonCoord(
684-
ord=r[0],
685-
tx_start_i=r[1],
686-
tx_end_i=r[2],
687-
alt_start_i=r[3],
688-
alt_end_i=r[4],
689-
alt_strand=r[5],
690-
)
691-
for r in results
692-
]
693-
694609
async def _get_genomic_aln_coords(
695610
self,
696611
tx_ac: str,
697-
tx_exon_start: _ExonCoord | None = None,
698-
tx_exon_end: _ExonCoord | None = None,
612+
tx_exon_start: ExonCoord | None = None,
613+
tx_exon_end: ExonCoord | None = None,
699614
gene: str | None = None,
700615
) -> tuple[GenomicAlnData | None, GenomicAlnData | None, str | None]:
701616
"""Get aligned genomic coordinates for transcript exon start and end.
@@ -736,7 +651,7 @@ def _get_tx_segment(
736651
genomic_ac: str,
737652
strand: Strand,
738653
offset: int,
739-
genomic_ac_data: _ExonCoord,
654+
genomic_ac_data: ExonCoord,
740655
is_seg_start: bool = False,
741656
) -> tuple[TxSegment | None, str | None]:
742657
"""Get transcript segment data given ``genomic_ac`` and offset data
@@ -949,9 +864,10 @@ async def _genomic_to_tx_segment(
949864
if not gene:
950865
return GenomicTxSeg(errors=[f"No gene(s) found given {transcript}"])
951866

952-
tx_exons = await self._get_all_exon_coords(
953-
tx_ac=transcript, genomic_ac=genomic_ac
954-
)
867+
async with self.uta_db.repository() as uta:
868+
tx_exons = await uta.get_all_exon_coords(
869+
tx_ac=transcript, genomic_ac=genomic_ac
870+
)
955871
if not tx_exons:
956872
return GenomicTxSeg(
957873
errors=[f"No exons found given transcript: {transcript}"]
@@ -1055,7 +971,7 @@ async def _get_grch38_pos(
1055971
return liftover_data[1] if liftover_data else None
1056972

1057973
@staticmethod
1058-
def _is_exonic_breakpoint(pos: int, tx_genomic_coords: list[_ExonCoord]) -> bool:
974+
def _is_exonic_breakpoint(pos: int, tx_genomic_coords: list[ExonCoord]) -> bool:
1059975
"""Check if a breakpoint occurs on an exon
1060976
1061977
:param pos: Genomic breakpoint
@@ -1083,7 +999,7 @@ def _use_alt_start_i(is_seg_start: bool, strand: Strand) -> bool:
1083999

10841000
@staticmethod
10851001
def _get_adjacent_exon(
1086-
tx_exons_genomic_coords: list[_ExonCoord],
1002+
tx_exons_genomic_coords: list[ExonCoord],
10871003
strand: Strand,
10881004
start: int | None = None,
10891005
end: int | None = None,

src/cool_seq_tool/sources/uta_database.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,26 @@ class TxExonAlnData(GenomicAlnData):
8181
alt_exon_id: StrictInt = Field(..., description="`alt_ac` exon identifier.")
8282

8383

84+
class ExonCoord(BaseModelForbidExtra):
85+
"""Model for representing exon coordinate data"""
86+
87+
ord: StrictInt = Field(..., description="Exon number. 0-based.")
88+
tx_start_i: StrictInt = Field(
89+
...,
90+
description="Transcript start index of the exon. Inter-residue coordinates.",
91+
)
92+
tx_end_i: StrictInt = Field(
93+
..., description="Transcript end index of the exon. Inter-residue coordinates."
94+
)
95+
alt_start_i: StrictInt = Field(
96+
..., description="Genomic start index of the exon. Inter-residue coordinates."
97+
)
98+
alt_end_i: StrictInt = Field(
99+
..., description="Genomic end index of the exon. Inter-residue coordinates."
100+
)
101+
alt_strand: Strand = Field(..., description="Strand.")
102+
103+
84104
class NoMatchingAlignmentError(Exception):
85105
"""Raise for failure to find alignment matching user parameters"""
86106

@@ -916,6 +936,59 @@ async def validate_genomic_breakpoint(
916936
result = await cursor.fetchone()
917937
return bool(result)
918938

939+
async def get_all_exon_coords(
940+
self, tx_ac: str, genomic_ac: str | None = None
941+
) -> list[ExonCoord]:
942+
"""Get all exon coordinate data for a transcript.
943+
944+
If ``genomic_ac`` is NOT provided, this method will use the GRCh38 accession
945+
associated to ``tx_ac``.
946+
947+
:param tx_ac: The RefSeq transcript accession to get exon data for.
948+
:param genomic_ac: The RefSeq genomic accession to get exon data for.
949+
:return: List of all exon coordinate data for ``tx_ac`` and ``genomic_ac``.
950+
The exon coordinate data will include the exon number, transcript and
951+
genomic positions for the start and end of the exon, and strand.
952+
The list will be ordered by ascending exon number.
953+
"""
954+
if genomic_ac:
955+
query = """
956+
SELECT DISTINCT ord, tx_start_i, tx_end_i, alt_start_i, alt_end_i, alt_strand
957+
FROM tx_exon_aln_mv
958+
WHERE tx_ac = %(tx_ac)s
959+
AND alt_aln_method = 'splign'
960+
AND alt_ac = %(genomic_ac)s
961+
ORDER BY ord ASC;
962+
"""
963+
else:
964+
query = """
965+
SELECT DISTINCT ord, tx_start_i, tx_end_i, alt_start_i, alt_end_i, alt_strand
966+
FROM tx_exon_aln_mv as t
967+
INNER JOIN _seq_anno_most_recent as s
968+
ON t.alt_ac = s.ac
969+
WHERE s.descr = ''
970+
AND t.tx_ac = %(tx_ac)s
971+
AND t.alt_aln_method = 'splign'
972+
AND t.alt_ac like 'NC_000%%'
973+
ORDER BY ord ASC;
974+
"""
975+
976+
cursor = await self.execute_query(
977+
query, {"tx_ac": tx_ac, "genomic_ac": genomic_ac}
978+
)
979+
results = await cursor.fetchall()
980+
return [
981+
ExonCoord(
982+
ord=r[0],
983+
tx_start_i=r[1],
984+
tx_end_i=r[2],
985+
alt_start_i=r[3],
986+
alt_end_i=r[4],
987+
alt_strand=r[5],
988+
)
989+
for r in results
990+
]
991+
919992

920993
class ParseResult(UrlLibParseResult):
921994
"""Subclass of url.ParseResult that adds database and schema methods, and provides stringification.

0 commit comments

Comments
 (0)