Conversation
New optional transcript keys, data schema 0.2.35:
- transl_except: amino acid -> codon numbers in the CDS (1-based, ie
protein positions), eg {"Sec": [48]}. From RefSeq transl_except on
the CDS rows and from Ensembl GTF Selenocysteine rows. RefSeq stop
codons completed by the poly(A) tail are "TERM".
- transl_table: the RefSeq genetic code of the CDS, eg 2 on chrMT.
A consumer can then read UGA as selenocysteine only at the annotated
codons, instead of at every UGA of a selenoprotein.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 cdot JSON gets two optional transcript keys:
transl_except(e.g.{"Sec": [48]}) andtransl_table(e.g.2). With them, a client can read UGA as selenocysteine only at the annotated codons, can see which stop codons the poly(A) tail completes, and can pick the genetic code per transcript. Older clients ignore both keys. The data schema goes to 0.2.35, a patch bump.Why
selenotag. A client can then only switch the whole transcript to a selenocysteine table. Every UGA then reads as selenocysteine, including a UGA that a variant creates. A TGG>TGA variant then givesp.Trp5Secinstead ofp.Trp5Ter.transl_except=(pos:...,aa:TERM)on these CDS rows. cdot JSON has only the note text, so clients guess from(stop_codon - start_codon) % 3.transl_table=2on the mitochondrial CDS rows. Clients hardcode the mitochondrial contigs instead.Changes
gff_parser.pytransl_exceptandtransl_tablefrom CDS rows, next to the existingNotehandling. This covers RefSeq GFF3, and GTF files that carry these attributes.GTFParserreads EnsemblSelenocysteinerows asSec._get_transcript_position, so alignment gaps and coordinate holes (start_codon/stop_codon: documented 1-based, and undefined across an inter-exon transcript gap #123) are handled as forstart_codon. A codon that is not a codon of the CDS is skipped with a warning.cdot/models.py:Transcripthas the optional fieldstransl_exceptandtransl_table.docs/json_data_format.mdanddocs/cdot-json-schema.jsonare regenerated.JSON_SCHEMA_VERSIONis 0.2.35. Both changelogs have an entry.JSON
start_codonandstop_codon. They describe the transcript and its protein, not the alignment to one build.transl_exceptmaps an amino acid to codon numbers, i.e. positions in the protein. Codon numbers do not depend on the genome build. They match HGVSp.numbering, the GENCODE IDs such asselenocysteine:ENST00000400518.5:493, and the RefSeq protein.transl_except:Sec,TERM,Met,Otherand so on. All of them are kept, not onlySecandTERM. The RefSeq GRCh38 annotation RS_2025_08 has 109 distincttransl_exceptvalues with 14 amino acid names.transl_tableis written only when the source names one. Without it, the code is the standard one or unknown. Ensembl GTF has no such attribute.Compatibility
Both keys are optional and absent for transcripts without such data. The
modelsstructs useforbid_unknown_fields=False, so older clients ignore the keys. Clients check only major.minor of the data schema, so a patch bump is enough, as forccdsandtranscript_support_levelin 0.2.33.Tests
test_refseq_gff3_selenocysteine: SELENOM from RefSeq annotation release 110 (minus strand, selenocysteine codon in exon 2) gives{"Sec": [48]}and notransl_table.test_ensembl_gtf_selenocysteine: SELENOM from the Ensembl 108 GTF gives{"Sec": [48]}. TheSelenocysteinerow leaves the exons and the CDS unchanged.test_mito_transl_except_and_transl_table: all 13 RefSeq mitochondrial transcripts gettransl_table2. ND1 (CDS of 956 bases) gets{"TERM": [319]}, ATP8 gets notransl_except.test_transcript_translation_fields: the model keeps both fields when present and givesNonewhen absent.python -m pytest tests/: 416 passed, 5 skipped. Before: 412 passed, 5 skipped.Checked on real subsets, outside the tests:
stop_codon_redefined_as_selenocysteineIDs, e.g. ENST00000400518.5 at 493.{"TERM": [220]}.Not included
stop_codon_redefined_as_selenocysteinerows.GFF3Parsercannot read GENCODE GFF3 today: it stops at the firststart_codonrow, whose parent is a transcript. cdot builds its Ensembl data from GTF, which has theSelenocysteinerows.Closes #131