pytransdecoder 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. pytransdecoder-0.2.1/LICENSE +28 -0
  2. pytransdecoder-0.2.1/PKG-INFO +307 -0
  3. pytransdecoder-0.2.1/README.md +287 -0
  4. pytransdecoder-0.2.1/pyproject.toml +52 -0
  5. pytransdecoder-0.2.1/pytransdecoder/__init__.py +7 -0
  6. pytransdecoder-0.2.1/pytransdecoder/__main__.py +6 -0
  7. pytransdecoder-0.2.1/pytransdecoder/cli.py +781 -0
  8. pytransdecoder-0.2.1/pytransdecoder/core/__init__.py +1 -0
  9. pytransdecoder-0.2.1/pytransdecoder/core/base_freqs.py +71 -0
  10. pytransdecoder-0.2.1/pytransdecoder/core/decoys.py +113 -0
  11. pytransdecoder-0.2.1/pytransdecoder/core/fasta.py +55 -0
  12. pytransdecoder-0.2.1/pytransdecoder/core/gene_model.py +143 -0
  13. pytransdecoder-0.2.1/pytransdecoder/core/gff3_parser.py +58 -0
  14. pytransdecoder-0.2.1/pytransdecoder/core/homology_starts.py +54 -0
  15. pytransdecoder-0.2.1/pytransdecoder/core/kozak.py +180 -0
  16. pytransdecoder-0.2.1/pytransdecoder/core/models.py +123 -0
  17. pytransdecoder-0.2.1/pytransdecoder/core/orf_finder.py +317 -0
  18. pytransdecoder-0.2.1/pytransdecoder/core/presets.py +152 -0
  19. pytransdecoder-0.2.1/pytransdecoder/core/prng.py +54 -0
  20. pytransdecoder-0.2.1/pytransdecoder/core/pwm.py +174 -0
  21. pytransdecoder-0.2.1/pytransdecoder/core/sequence.py +19 -0
  22. pytransdecoder-0.2.1/pytransdecoder/core/translator.py +143 -0
  23. pytransdecoder-0.2.1/pytransdecoder/core/writers.py +69 -0
  24. pytransdecoder-0.2.1/pytransdecoder/genome.py +338 -0
  25. pytransdecoder-0.2.1/pytransdecoder/longorfs.py +180 -0
  26. pytransdecoder-0.2.1/pytransdecoder/predict.py +1621 -0
  27. pytransdecoder-0.2.1/pytransdecoder/presets/apicomplexan/hexamer.scores.gz +0 -0
  28. pytransdecoder-0.2.1/pytransdecoder/presets/apicomplexan/kozak.tsv +9 -0
  29. pytransdecoder-0.2.1/pytransdecoder/presets/apicomplexan/preset.json +20 -0
  30. pytransdecoder-0.2.1/pytransdecoder/presets/apicomplexan/thresholds.tsv.gz +0 -0
  31. pytransdecoder-0.2.1/pytransdecoder/presets/apicomplexan/training_orfs.cds.gz +0 -0
  32. pytransdecoder-0.2.1/pytransdecoder/presets/ciliate/hexamer.scores.gz +0 -0
  33. pytransdecoder-0.2.1/pytransdecoder/presets/ciliate/kozak.tsv +9 -0
  34. pytransdecoder-0.2.1/pytransdecoder/presets/ciliate/preset.json +20 -0
  35. pytransdecoder-0.2.1/pytransdecoder/presets/ciliate/thresholds.tsv.gz +0 -0
  36. pytransdecoder-0.2.1/pytransdecoder/presets/ciliate/training_orfs.cds.gz +0 -0
  37. pytransdecoder-0.2.1/pytransdecoder/presets/fungus/hexamer.scores.gz +0 -0
  38. pytransdecoder-0.2.1/pytransdecoder/presets/fungus/kozak.tsv +9 -0
  39. pytransdecoder-0.2.1/pytransdecoder/presets/fungus/preset.json +20 -0
  40. pytransdecoder-0.2.1/pytransdecoder/presets/fungus/thresholds.tsv.gz +0 -0
  41. pytransdecoder-0.2.1/pytransdecoder/presets/fungus/training_orfs.cds.gz +0 -0
  42. pytransdecoder-0.2.1/pytransdecoder/presets/green_alga/hexamer.scores.gz +0 -0
  43. pytransdecoder-0.2.1/pytransdecoder/presets/green_alga/kozak.tsv +9 -0
  44. pytransdecoder-0.2.1/pytransdecoder/presets/green_alga/preset.json +20 -0
  45. pytransdecoder-0.2.1/pytransdecoder/presets/green_alga/thresholds.tsv.gz +0 -0
  46. pytransdecoder-0.2.1/pytransdecoder/presets/green_alga/training_orfs.cds.gz +0 -0
  47. pytransdecoder-0.2.1/pytransdecoder/presets/insect/hexamer.scores.gz +0 -0
  48. pytransdecoder-0.2.1/pytransdecoder/presets/insect/kozak.tsv +9 -0
  49. pytransdecoder-0.2.1/pytransdecoder/presets/insect/preset.json +20 -0
  50. pytransdecoder-0.2.1/pytransdecoder/presets/insect/thresholds.tsv.gz +0 -0
  51. pytransdecoder-0.2.1/pytransdecoder/presets/insect/training_orfs.cds.gz +0 -0
  52. pytransdecoder-0.2.1/pytransdecoder/presets/mammal/hexamer.scores.gz +0 -0
  53. pytransdecoder-0.2.1/pytransdecoder/presets/mammal/kozak.tsv +9 -0
  54. pytransdecoder-0.2.1/pytransdecoder/presets/mammal/preset.json +20 -0
  55. pytransdecoder-0.2.1/pytransdecoder/presets/mammal/thresholds.tsv.gz +0 -0
  56. pytransdecoder-0.2.1/pytransdecoder/presets/mammal/training_orfs.cds.gz +0 -0
  57. pytransdecoder-0.2.1/pytransdecoder/presets/plant/hexamer.scores.gz +0 -0
  58. pytransdecoder-0.2.1/pytransdecoder/presets/plant/kozak.tsv +9 -0
  59. pytransdecoder-0.2.1/pytransdecoder/presets/plant/preset.json +20 -0
  60. pytransdecoder-0.2.1/pytransdecoder/presets/plant/thresholds.tsv.gz +0 -0
  61. pytransdecoder-0.2.1/pytransdecoder/presets/plant/training_orfs.cds.gz +0 -0
  62. pytransdecoder-0.2.1/pytransdecoder.egg-info/PKG-INFO +307 -0
  63. pytransdecoder-0.2.1/pytransdecoder.egg-info/SOURCES.txt +73 -0
  64. pytransdecoder-0.2.1/pytransdecoder.egg-info/dependency_links.txt +1 -0
  65. pytransdecoder-0.2.1/pytransdecoder.egg-info/entry_points.txt +3 -0
  66. pytransdecoder-0.2.1/pytransdecoder.egg-info/requires.txt +8 -0
  67. pytransdecoder-0.2.1/pytransdecoder.egg-info/top_level.txt +1 -0
  68. pytransdecoder-0.2.1/setup.cfg +4 -0
  69. pytransdecoder-0.2.1/setup.py +6 -0
  70. pytransdecoder-0.2.1/tests/test_basic.py +684 -0
  71. pytransdecoder-0.2.1/tests/test_decoys.py +58 -0
  72. pytransdecoder-0.2.1/tests/test_fasta.py +52 -0
  73. pytransdecoder-0.2.1/tests/test_genome_bed.py +24 -0
  74. pytransdecoder-0.2.1/tests/test_homology_starts.py +113 -0
  75. pytransdecoder-0.2.1/tests/test_qvalue_modes.py +25 -0
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, TransDecoder
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,307 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytransdecoder
3
+ Version: 0.2.1
4
+ Summary: TransDecoder, the original Perl version ported to Python by AI/LLMs with new features integrated
5
+ Author: Brian Haas, ported to python by AI/LLMs
6
+ License: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/TransDecoder/PyTransDecoder
8
+ Project-URL: Repository, https://github.com/TransDecoder/PyTransDecoder
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: biopython>=1.81
13
+ Requires-Dist: tqdm>=4.65
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest>=7.4; extra == "dev"
16
+ Requires-Dist: pytest-cov>=4.1; extra == "dev"
17
+ Requires-Dist: black>=23.0; extra == "dev"
18
+ Requires-Dist: mypy>=1.0; extra == "dev"
19
+ Dynamic: license-file
20
+
21
+ # PyTransDecoder
22
+
23
+ Python port of [TransDecoder](https://github.com/TransDecoder/TransDecoder) - identify candidate coding regions within transcript sequences.
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install pytransdecoder
29
+ ```
30
+
31
+ or from a clone of this repository:
32
+
33
+ ```bash
34
+ cd PyTransDecoder
35
+ pip install -e .
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ Use `pyTransdecoder` as the primary interface when you want the standard end-to-end pipeline:
41
+
42
+ ```bash
43
+ pyTransdecoder -t transcripts.fasta
44
+ ```
45
+
46
+ This runs LongOrfs followed by Predict and writes the usual `*.transdecoder.{gff3,bed,pep,cds}` outputs.
47
+
48
+ You can also have the pipeline run homology support searches directly:
49
+
50
+ ```bash
51
+ pyTransdecoder -t transcripts.fasta \
52
+ --blast-search-pep uniprot_sprot.pep \
53
+ --pfam-search-db Pfam-A.hmm
54
+ ```
55
+
56
+ ## Phase-Specific Commands
57
+
58
+ If you want to run the phases separately, use the subcommand CLI:
59
+
60
+ ### Phase 1: Extract Long ORFs
61
+
62
+ ```bash
63
+ pytransdecoder longorfs -t transcripts.fasta
64
+ ```
65
+
66
+ This creates a directory `transcripts.fasta.transdecoder_dir/` with:
67
+ - `longest_orfs.pep` - Protein sequences
68
+ - `longest_orfs.cds` - CDS sequences
69
+ - `longest_orfs.gff3` - ORF annotations
70
+ - `base_freqs.dat` - Nucleotide frequencies
71
+
72
+ ### Options
73
+
74
+ ```
75
+ -t, --transcripts PATH Input transcripts FASTA file [required]
76
+ -m, --min-protein-length INT Minimum protein length (default: 50 aa; Predict's target-decoy
77
+ test, not this cutoff, controls chance ORFs)
78
+ -G, --genetic-code TEXT Genetic code (default: Standard)
79
+ -S, --strand-specific Only analyze top strand
80
+ -O, --output-dir PATH Output directory
81
+ --gene-trans-map PATH Gene-to-transcript mapping file
82
+ --complete-orfs-only Only output complete ORFs
83
+ -v, --verbose Verbose output
84
+ ```
85
+
86
+ ## CLI Compatibility
87
+
88
+ PyTransDecoder's CLI accepts **both underscore and dash formats** for option names, ensuring compatibility with existing Perl TransDecoder workflows:
89
+
90
+ ```bash
91
+ # Both of these work identically:
92
+ pytransdecoder predict -t transcripts.fasta --retain-pfam-hits pfam.domtblout
93
+ pytransdecoder predict -t transcripts.fasta --retain_pfam_hits pfam.domtblout
94
+ ```
95
+
96
+ This means you can use existing scripts and Makefiles without modification.
97
+
98
+ Legacy compatibility wrappers for `TransDecoder.LongOrfs` and `TransDecoder.Predict` now live under [`util/`](https://github.com/TransDecoder/PyTransDecoder/tree/main/util) instead of the repository root.
99
+
100
+ ## Supported Genetic Codes
101
+
102
+ - universal/standard
103
+ - vertebrate_mitochondrial
104
+ - yeast_mitochondrial
105
+ - invertebrate_mitochondrial
106
+ - ciliate/tetrahymena/dasycladacean
107
+ - euplotid
108
+ - bacterial
109
+ - candida
110
+ - And 15+ more...
111
+
112
+ ## Phase 2: Predict Likely Coding Regions
113
+
114
+ ### Basic Usage
115
+
116
+ ```bash
117
+ pytransdecoder predict -t transcripts.fasta
118
+ ```
119
+
120
+ This creates final output files in the same directory as your transcripts:
121
+ - `transcripts.fasta.transdecoder.gff3` - Gene predictions
122
+ - `transcripts.fasta.transdecoder.bed` - BED format
123
+ - `transcripts.fasta.transdecoder.pep` - Protein sequences
124
+ - `transcripts.fasta.transdecoder.cds` - CDS sequences
125
+
126
+ ### With Homology Support
127
+
128
+ ```bash
129
+ # Run BLASTP against UniProt
130
+ blastp -query transcripts.fasta.transdecoder_dir/longest_orfs.pep \
131
+ -db uniprot_sprot.pep -max_target_seqs 1 \
132
+ -outfmt 6 -evalue 1e-5 -num_threads 4 > blastp.outfmt6
133
+
134
+ # Run Pfam domain search
135
+ hmmscan --cpu 4 --domtblout pfam.domtblout Pfam-A.hmm \
136
+ transcripts.fasta.transdecoder_dir/longest_orfs.pep
137
+
138
+ # Run predict with homology data
139
+ pytransdecoder predict -t transcripts.fasta \
140
+ --retain-blastp-hits blastp.outfmt6 \
141
+ --retain-pfam-hits pfam.domtblout
142
+ ```
143
+
144
+ ORFs with a hit are kept even when their coding signal alone would not keep them. Hits to
145
+ transposable-element proteins (or to host proteins with a TE-derived segment) can therefore keep
146
+ short ORFs in TE-containing transcripts. These are kept on purpose; to find and remove them by
147
+ best-hit protein or by repeat overlap, see
148
+ [docs/homology_te_screen.md](https://github.com/TransDecoder/PyTransDecoder/blob/main/docs/homology_te_screen.md).
149
+
150
+ For the full pipeline entrypoint, you can skip the separate Pfam step and let
151
+ `pyTransdecoder` prepare and search the HMM database for you:
152
+
153
+ ```bash
154
+ pyTransdecoder -t transcripts.fasta --pfam-search-db Pfam-A.hmm
155
+ ```
156
+
157
+ ### Options
158
+
159
+ ```
160
+ -t, --transcripts PATH Input transcripts FASTA file [required]
161
+ -O, --output-dir PATH Output directory
162
+ -T, --top-orfs-train INT Training ORFs (default: 500)
163
+ --retain-long-orfs-mode 'dynamic' or 'strict' (default: dynamic)
164
+ --retain-pfam-hits PATH Pfam domain hits (domtblout format)
165
+ --retain-blastp-hits PATH BLAST hits (outfmt 6 format)
166
+ --retain-multiple-orfs Report all non-overlapping ORFs passing selection
167
+ (default: the best ORF per transcript)
168
+ --no-refine-starts Skip start codon refinement
169
+ --no-homology-start-assist Do not let BLASTP/Pfam hits decide 5'-partial vs trimmed starts
170
+ (default: they do whenever hits are supplied)
171
+ --start-contrast-alpha FLOAT Start refinement: UTR score per base of upstream segment (default: 0.4)
172
+ --start-kozak-weight FLOAT Start refinement: bases of coding signal per bit of Kozak score (default: 17)
173
+ --max-qvalue FLOAT Keep ORFs (without homology) with target-decoy q-value <= this
174
+ (default: 0.05)
175
+ --precise Same as --max-qvalue 0.01: fewer calls on noncoding sequence
176
+ --sensitive Same as --max-qvalue 0.2: more short and partial ORFs
177
+ --decoy-shuffles INT Shuffled copies per transcript (default: 0 = automatic)
178
+ --decoy-seed INT Seed of the decoy shuffles (default: 42)
179
+ --preset NAME|DIR Models and thresholds from a preset instead of the input
180
+ (recommended below ~1,000 transcripts or for mostly partial sets)
181
+ -G, --genetic-code TEXT Genetic code (default: Standard)
182
+ -v, --verbose Verbose output
183
+ ```
184
+
185
+ ### How It Works
186
+
187
+ 1. **Training**: Selects top longest unique ORFs to train hexamer scoring model
188
+ 2. **Scoring**: Scores all ORFs using Markov chain model (hexamer composition)
189
+ 3. **Selection**: Chooses best ORFs based on:
190
+ - Homology support (BLAST/Pfam hits)
191
+ - Coding potential score
192
+ - ORF length
193
+ - GC content-based thresholds (ORFs long enough to be unlikely in random sequence of the
194
+ transcriptome's GC content are kept regardless of score; applied only when the genetic
195
+ code's stop codons are TAA/TAG/TGA, the set the thresholds were simulated with)
196
+ - A false discovery rate against decoys: each input transcript is shuffled keeping its
197
+ dinucleotide counts (so length and base composition are kept), decoy ORFs are found in the
198
+ shuffles with the LongOrfs settings and genetic code, and scored with the same model. Within
199
+ strata of ORF length, transcript length and ORF type (complete or partial), an ORF's q-value
200
+ is the lowest estimated FDR (decoys / targets at or above its frame contrast) of any cutoff
201
+ that accepts it. Without homology support an ORF needs in-frame score > 0, a higher score
202
+ than the shifted frames, and q <= `--max-qvalue` (0.05; `--precise` 0.01, `--sensitive` 0.2).
203
+ Short ORFs, which are far more frequent by chance, therefore need more coding evidence, with
204
+ no fixed length cutoff. The decoys are reproducible (`--decoy-seed`) and identical in
205
+ TransDecoder (Perl).
206
+ - Translated noncanonical ORFs (Ribo-seq ORFs) mostly lack codon-usage signal, so finding
207
+ them needs translation evidence.
208
+ - **Small inputs**: below ~1,000 transcripts the coding model and the decoy statistics learned
209
+ from the input are unreliable. `--preset NAME` uses a coding model, start model and q-value
210
+ thresholds learned from a reference transcriptome instead (bundled: see `--help`;
211
+ `pytransdecoder build-preset` makes one from a Predict run on a related species).
212
+ 4. **Start refinement**: an ORF that runs to the 5' end of its transcript (no start codon) is
213
+ either a truncated (5'-partial) ORF or one that extends into the 5' UTR. For the segment
214
+ before its first in-frame ATG, two scores are compared, both in bases' worth of typical coding
215
+ signal (the training ORFs' median per-base frame contrast):
216
+ - **coding score**: the segment's frame contrast (coding score in frame minus the better
217
+ shifted frame) divided by that typical per-base value;
218
+ - **UTR score**: `--start-contrast-alpha` (0.4) x segment length + `--start-kozak-weight` (17)
219
+ x the ATG's Kozak score in bits (log2-odds of -6..-1, +4..+5 against in-frame ATGs inside
220
+ the training ORFs).
221
+ If the UTR score is higher, the ORF is trimmed to start at the ATG; otherwise it stays 5'
222
+ partial. Each bit of Kozak score lets the ATG overrule 17 bases of coding signal. See
223
+ [docs/start_codon_refinement.md](https://github.com/TransDecoder/PyTransDecoder/blob/main/docs/start_codon_refinement.md) for a step-by-step
224
+ walkthrough with examples and advice on choosing alpha. The Kozak model is written to the
225
+ work directory as `start_refinement.kozak.tsv` (bits), `.kozak.counts.tsv` and a sequence
226
+ logo, `.kozak.logo.svg`.
227
+ **With homology hits** (`--retain-blastp-hits` and/or `--retain-pfam-hits`), the hits of the
228
+ ORF's longest-ORF peptide decide first (PyTransDecoder only; turn off with
229
+ `--no-homology-start-assist`):
230
+ - BLASTP, trim: the best hit's subject N-terminus (subject start <= 3) aligns within 5 aa of the
231
+ first ATG;
232
+ - BLASTP, keep 5' partial: the alignment starts >= 5 aa upstream of the ATG and the subject
233
+ continues further N-terminal (subject start > 1);
234
+ - Pfam, keep 5' partial: a domain envelope starts upstream of the ATG.
235
+ Where no rule fires, or a trim and a keep call conflict, the coding-vs-UTR rule above decides.
236
+ Each rule is used only if its hits file was given. Per-ORF evidence and decisions are written
237
+ to `start_refinement.homology.tsv` in the work directory, and ORFs trimmed by homology carry
238
+ `start_homology=R2` in the GFF3. See [docs/start_codon_refinement.md](https://github.com/TransDecoder/PyTransDecoder/blob/main/docs/start_codon_refinement.md).
239
+ 5. **Output**: Generates final predictions in multiple formats
240
+
241
+ ## Annotating a Genome from Transcript Structures
242
+
243
+ Transcripts reconstructed from RNA-seq (StringTie, LRAA, Cufflinks, PASA, or Trinity aligned to
244
+ the genome) can be annotated with coding regions on the genome: ORFs predicted on the transcript
245
+ sequences are propagated through each transcript's exon structure, giving gene / mRNA / exon /
246
+ CDS / five_prime_UTR / three_prime_UTR models in GFF3.
247
+
248
+ From a genome and a GTF (transcript sequences are extracted with gffread):
249
+
250
+ ```bash
251
+ pyTransdecoder --genome genome.fa --gtf stringtie.gtf -O out
252
+ # -> out/stringtie.cDNA.fasta.transdecoder.genome.gff3 (and .genome.bed)
253
+ ```
254
+
255
+ From transcript sequences and their structures (GTF, alignment GFF3 from GMAP/PASA with
256
+ `Target=`, or minimap2 SAM/BAM spliced alignments):
257
+
258
+ ```bash
259
+ pyTransdecoder -t Trinity.fasta --structures Trinity.minimap2.bam -O out
260
+ # or, after LongOrfs + Predict:
261
+ pytransdecoder genome-map --orfs Trinity.fasta.transdecoder.gff3 --structures Trinity.minimap2.bam \
262
+ -t Trinity.fasta -o Trinity.fasta.transdecoder.genome.gff3
263
+ ```
264
+
265
+ Notes:
266
+ - ORFs on the opposite strand of a spliced transcript are not propagated; single-exon
267
+ transcripts take the ORF's orientation.
268
+ - Alignment blocks carry transcript coordinates (GFF3 `Target`, SAM CIGAR), so transcripts with
269
+ indels or clipped ends map base-accurately; an ORF whose CDS is not within the aligned part of
270
+ its transcript is not propagated. Only primary SAM/BAM alignments are used.
271
+ - GTF transcripts with strand `.` are taken as `+`, as gffread extracts them; use
272
+ `--unstranded-as minus` for sequences extracted with TransDecoder's
273
+ `util/gtf_genome_to_cdna_fasta.pl`.
274
+ - Isoforms are grouped by the GTF `gene_id` (or the TransDecoder gene id, e.g. with
275
+ `--gene-trans-map`), with the chromosome and strand appended.
276
+
277
+ ## Development Status
278
+
279
+ - ✅ Phase 1 (LongOrfs): Implemented and validated
280
+ - ✅ Phase 2 (Predict): Implemented and tested
281
+ - ⏳ Performance benchmarking on large datasets
282
+
283
+ ## Testing Against Perl Version
284
+
285
+ To validate output matches the Perl version:
286
+
287
+ ```bash
288
+ # Run Perl version
289
+ cd ../TransDecoder
290
+ ./TransDecoder.LongOrfs -t test.fasta
291
+
292
+ # Run Python version
293
+ cd ../PyTransDecoder
294
+ pytransdecoder longorfs -t test.fasta
295
+
296
+ # Compare outputs
297
+ diff ../TransDecoder/test.fasta.transdecoder_dir/longest_orfs.pep \
298
+ test.fasta.transdecoder_dir/longest_orfs.pep
299
+ ```
300
+
301
+ ## Requirements
302
+
303
+ - Python 3.8+
304
+ - BioPython >= 1.81
305
+ - tqdm >= 4.65
306
+
307
+ **Note**: Ported by Claude.io Sonnet 4.5 under guidance by bhaas. Jan 24, 2026.
@@ -0,0 +1,287 @@
1
+ # PyTransDecoder
2
+
3
+ Python port of [TransDecoder](https://github.com/TransDecoder/TransDecoder) - identify candidate coding regions within transcript sequences.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install pytransdecoder
9
+ ```
10
+
11
+ or from a clone of this repository:
12
+
13
+ ```bash
14
+ cd PyTransDecoder
15
+ pip install -e .
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ Use `pyTransdecoder` as the primary interface when you want the standard end-to-end pipeline:
21
+
22
+ ```bash
23
+ pyTransdecoder -t transcripts.fasta
24
+ ```
25
+
26
+ This runs LongOrfs followed by Predict and writes the usual `*.transdecoder.{gff3,bed,pep,cds}` outputs.
27
+
28
+ You can also have the pipeline run homology support searches directly:
29
+
30
+ ```bash
31
+ pyTransdecoder -t transcripts.fasta \
32
+ --blast-search-pep uniprot_sprot.pep \
33
+ --pfam-search-db Pfam-A.hmm
34
+ ```
35
+
36
+ ## Phase-Specific Commands
37
+
38
+ If you want to run the phases separately, use the subcommand CLI:
39
+
40
+ ### Phase 1: Extract Long ORFs
41
+
42
+ ```bash
43
+ pytransdecoder longorfs -t transcripts.fasta
44
+ ```
45
+
46
+ This creates a directory `transcripts.fasta.transdecoder_dir/` with:
47
+ - `longest_orfs.pep` - Protein sequences
48
+ - `longest_orfs.cds` - CDS sequences
49
+ - `longest_orfs.gff3` - ORF annotations
50
+ - `base_freqs.dat` - Nucleotide frequencies
51
+
52
+ ### Options
53
+
54
+ ```
55
+ -t, --transcripts PATH Input transcripts FASTA file [required]
56
+ -m, --min-protein-length INT Minimum protein length (default: 50 aa; Predict's target-decoy
57
+ test, not this cutoff, controls chance ORFs)
58
+ -G, --genetic-code TEXT Genetic code (default: Standard)
59
+ -S, --strand-specific Only analyze top strand
60
+ -O, --output-dir PATH Output directory
61
+ --gene-trans-map PATH Gene-to-transcript mapping file
62
+ --complete-orfs-only Only output complete ORFs
63
+ -v, --verbose Verbose output
64
+ ```
65
+
66
+ ## CLI Compatibility
67
+
68
+ PyTransDecoder's CLI accepts **both underscore and dash formats** for option names, ensuring compatibility with existing Perl TransDecoder workflows:
69
+
70
+ ```bash
71
+ # Both of these work identically:
72
+ pytransdecoder predict -t transcripts.fasta --retain-pfam-hits pfam.domtblout
73
+ pytransdecoder predict -t transcripts.fasta --retain_pfam_hits pfam.domtblout
74
+ ```
75
+
76
+ This means you can use existing scripts and Makefiles without modification.
77
+
78
+ Legacy compatibility wrappers for `TransDecoder.LongOrfs` and `TransDecoder.Predict` now live under [`util/`](https://github.com/TransDecoder/PyTransDecoder/tree/main/util) instead of the repository root.
79
+
80
+ ## Supported Genetic Codes
81
+
82
+ - universal/standard
83
+ - vertebrate_mitochondrial
84
+ - yeast_mitochondrial
85
+ - invertebrate_mitochondrial
86
+ - ciliate/tetrahymena/dasycladacean
87
+ - euplotid
88
+ - bacterial
89
+ - candida
90
+ - And 15+ more...
91
+
92
+ ## Phase 2: Predict Likely Coding Regions
93
+
94
+ ### Basic Usage
95
+
96
+ ```bash
97
+ pytransdecoder predict -t transcripts.fasta
98
+ ```
99
+
100
+ This creates final output files in the same directory as your transcripts:
101
+ - `transcripts.fasta.transdecoder.gff3` - Gene predictions
102
+ - `transcripts.fasta.transdecoder.bed` - BED format
103
+ - `transcripts.fasta.transdecoder.pep` - Protein sequences
104
+ - `transcripts.fasta.transdecoder.cds` - CDS sequences
105
+
106
+ ### With Homology Support
107
+
108
+ ```bash
109
+ # Run BLASTP against UniProt
110
+ blastp -query transcripts.fasta.transdecoder_dir/longest_orfs.pep \
111
+ -db uniprot_sprot.pep -max_target_seqs 1 \
112
+ -outfmt 6 -evalue 1e-5 -num_threads 4 > blastp.outfmt6
113
+
114
+ # Run Pfam domain search
115
+ hmmscan --cpu 4 --domtblout pfam.domtblout Pfam-A.hmm \
116
+ transcripts.fasta.transdecoder_dir/longest_orfs.pep
117
+
118
+ # Run predict with homology data
119
+ pytransdecoder predict -t transcripts.fasta \
120
+ --retain-blastp-hits blastp.outfmt6 \
121
+ --retain-pfam-hits pfam.domtblout
122
+ ```
123
+
124
+ ORFs with a hit are kept even when their coding signal alone would not keep them. Hits to
125
+ transposable-element proteins (or to host proteins with a TE-derived segment) can therefore keep
126
+ short ORFs in TE-containing transcripts. These are kept on purpose; to find and remove them by
127
+ best-hit protein or by repeat overlap, see
128
+ [docs/homology_te_screen.md](https://github.com/TransDecoder/PyTransDecoder/blob/main/docs/homology_te_screen.md).
129
+
130
+ For the full pipeline entrypoint, you can skip the separate Pfam step and let
131
+ `pyTransdecoder` prepare and search the HMM database for you:
132
+
133
+ ```bash
134
+ pyTransdecoder -t transcripts.fasta --pfam-search-db Pfam-A.hmm
135
+ ```
136
+
137
+ ### Options
138
+
139
+ ```
140
+ -t, --transcripts PATH Input transcripts FASTA file [required]
141
+ -O, --output-dir PATH Output directory
142
+ -T, --top-orfs-train INT Training ORFs (default: 500)
143
+ --retain-long-orfs-mode 'dynamic' or 'strict' (default: dynamic)
144
+ --retain-pfam-hits PATH Pfam domain hits (domtblout format)
145
+ --retain-blastp-hits PATH BLAST hits (outfmt 6 format)
146
+ --retain-multiple-orfs Report all non-overlapping ORFs passing selection
147
+ (default: the best ORF per transcript)
148
+ --no-refine-starts Skip start codon refinement
149
+ --no-homology-start-assist Do not let BLASTP/Pfam hits decide 5'-partial vs trimmed starts
150
+ (default: they do whenever hits are supplied)
151
+ --start-contrast-alpha FLOAT Start refinement: UTR score per base of upstream segment (default: 0.4)
152
+ --start-kozak-weight FLOAT Start refinement: bases of coding signal per bit of Kozak score (default: 17)
153
+ --max-qvalue FLOAT Keep ORFs (without homology) with target-decoy q-value <= this
154
+ (default: 0.05)
155
+ --precise Same as --max-qvalue 0.01: fewer calls on noncoding sequence
156
+ --sensitive Same as --max-qvalue 0.2: more short and partial ORFs
157
+ --decoy-shuffles INT Shuffled copies per transcript (default: 0 = automatic)
158
+ --decoy-seed INT Seed of the decoy shuffles (default: 42)
159
+ --preset NAME|DIR Models and thresholds from a preset instead of the input
160
+ (recommended below ~1,000 transcripts or for mostly partial sets)
161
+ -G, --genetic-code TEXT Genetic code (default: Standard)
162
+ -v, --verbose Verbose output
163
+ ```
164
+
165
+ ### How It Works
166
+
167
+ 1. **Training**: Selects top longest unique ORFs to train hexamer scoring model
168
+ 2. **Scoring**: Scores all ORFs using Markov chain model (hexamer composition)
169
+ 3. **Selection**: Chooses best ORFs based on:
170
+ - Homology support (BLAST/Pfam hits)
171
+ - Coding potential score
172
+ - ORF length
173
+ - GC content-based thresholds (ORFs long enough to be unlikely in random sequence of the
174
+ transcriptome's GC content are kept regardless of score; applied only when the genetic
175
+ code's stop codons are TAA/TAG/TGA, the set the thresholds were simulated with)
176
+ - A false discovery rate against decoys: each input transcript is shuffled keeping its
177
+ dinucleotide counts (so length and base composition are kept), decoy ORFs are found in the
178
+ shuffles with the LongOrfs settings and genetic code, and scored with the same model. Within
179
+ strata of ORF length, transcript length and ORF type (complete or partial), an ORF's q-value
180
+ is the lowest estimated FDR (decoys / targets at or above its frame contrast) of any cutoff
181
+ that accepts it. Without homology support an ORF needs in-frame score > 0, a higher score
182
+ than the shifted frames, and q <= `--max-qvalue` (0.05; `--precise` 0.01, `--sensitive` 0.2).
183
+ Short ORFs, which are far more frequent by chance, therefore need more coding evidence, with
184
+ no fixed length cutoff. The decoys are reproducible (`--decoy-seed`) and identical in
185
+ TransDecoder (Perl).
186
+ - Translated noncanonical ORFs (Ribo-seq ORFs) mostly lack codon-usage signal, so finding
187
+ them needs translation evidence.
188
+ - **Small inputs**: below ~1,000 transcripts the coding model and the decoy statistics learned
189
+ from the input are unreliable. `--preset NAME` uses a coding model, start model and q-value
190
+ thresholds learned from a reference transcriptome instead (bundled: see `--help`;
191
+ `pytransdecoder build-preset` makes one from a Predict run on a related species).
192
+ 4. **Start refinement**: an ORF that runs to the 5' end of its transcript (no start codon) is
193
+ either a truncated (5'-partial) ORF or one that extends into the 5' UTR. For the segment
194
+ before its first in-frame ATG, two scores are compared, both in bases' worth of typical coding
195
+ signal (the training ORFs' median per-base frame contrast):
196
+ - **coding score**: the segment's frame contrast (coding score in frame minus the better
197
+ shifted frame) divided by that typical per-base value;
198
+ - **UTR score**: `--start-contrast-alpha` (0.4) x segment length + `--start-kozak-weight` (17)
199
+ x the ATG's Kozak score in bits (log2-odds of -6..-1, +4..+5 against in-frame ATGs inside
200
+ the training ORFs).
201
+ If the UTR score is higher, the ORF is trimmed to start at the ATG; otherwise it stays 5'
202
+ partial. Each bit of Kozak score lets the ATG overrule 17 bases of coding signal. See
203
+ [docs/start_codon_refinement.md](https://github.com/TransDecoder/PyTransDecoder/blob/main/docs/start_codon_refinement.md) for a step-by-step
204
+ walkthrough with examples and advice on choosing alpha. The Kozak model is written to the
205
+ work directory as `start_refinement.kozak.tsv` (bits), `.kozak.counts.tsv` and a sequence
206
+ logo, `.kozak.logo.svg`.
207
+ **With homology hits** (`--retain-blastp-hits` and/or `--retain-pfam-hits`), the hits of the
208
+ ORF's longest-ORF peptide decide first (PyTransDecoder only; turn off with
209
+ `--no-homology-start-assist`):
210
+ - BLASTP, trim: the best hit's subject N-terminus (subject start <= 3) aligns within 5 aa of the
211
+ first ATG;
212
+ - BLASTP, keep 5' partial: the alignment starts >= 5 aa upstream of the ATG and the subject
213
+ continues further N-terminal (subject start > 1);
214
+ - Pfam, keep 5' partial: a domain envelope starts upstream of the ATG.
215
+ Where no rule fires, or a trim and a keep call conflict, the coding-vs-UTR rule above decides.
216
+ Each rule is used only if its hits file was given. Per-ORF evidence and decisions are written
217
+ to `start_refinement.homology.tsv` in the work directory, and ORFs trimmed by homology carry
218
+ `start_homology=R2` in the GFF3. See [docs/start_codon_refinement.md](https://github.com/TransDecoder/PyTransDecoder/blob/main/docs/start_codon_refinement.md).
219
+ 5. **Output**: Generates final predictions in multiple formats
220
+
221
+ ## Annotating a Genome from Transcript Structures
222
+
223
+ Transcripts reconstructed from RNA-seq (StringTie, LRAA, Cufflinks, PASA, or Trinity aligned to
224
+ the genome) can be annotated with coding regions on the genome: ORFs predicted on the transcript
225
+ sequences are propagated through each transcript's exon structure, giving gene / mRNA / exon /
226
+ CDS / five_prime_UTR / three_prime_UTR models in GFF3.
227
+
228
+ From a genome and a GTF (transcript sequences are extracted with gffread):
229
+
230
+ ```bash
231
+ pyTransdecoder --genome genome.fa --gtf stringtie.gtf -O out
232
+ # -> out/stringtie.cDNA.fasta.transdecoder.genome.gff3 (and .genome.bed)
233
+ ```
234
+
235
+ From transcript sequences and their structures (GTF, alignment GFF3 from GMAP/PASA with
236
+ `Target=`, or minimap2 SAM/BAM spliced alignments):
237
+
238
+ ```bash
239
+ pyTransdecoder -t Trinity.fasta --structures Trinity.minimap2.bam -O out
240
+ # or, after LongOrfs + Predict:
241
+ pytransdecoder genome-map --orfs Trinity.fasta.transdecoder.gff3 --structures Trinity.minimap2.bam \
242
+ -t Trinity.fasta -o Trinity.fasta.transdecoder.genome.gff3
243
+ ```
244
+
245
+ Notes:
246
+ - ORFs on the opposite strand of a spliced transcript are not propagated; single-exon
247
+ transcripts take the ORF's orientation.
248
+ - Alignment blocks carry transcript coordinates (GFF3 `Target`, SAM CIGAR), so transcripts with
249
+ indels or clipped ends map base-accurately; an ORF whose CDS is not within the aligned part of
250
+ its transcript is not propagated. Only primary SAM/BAM alignments are used.
251
+ - GTF transcripts with strand `.` are taken as `+`, as gffread extracts them; use
252
+ `--unstranded-as minus` for sequences extracted with TransDecoder's
253
+ `util/gtf_genome_to_cdna_fasta.pl`.
254
+ - Isoforms are grouped by the GTF `gene_id` (or the TransDecoder gene id, e.g. with
255
+ `--gene-trans-map`), with the chromosome and strand appended.
256
+
257
+ ## Development Status
258
+
259
+ - ✅ Phase 1 (LongOrfs): Implemented and validated
260
+ - ✅ Phase 2 (Predict): Implemented and tested
261
+ - ⏳ Performance benchmarking on large datasets
262
+
263
+ ## Testing Against Perl Version
264
+
265
+ To validate output matches the Perl version:
266
+
267
+ ```bash
268
+ # Run Perl version
269
+ cd ../TransDecoder
270
+ ./TransDecoder.LongOrfs -t test.fasta
271
+
272
+ # Run Python version
273
+ cd ../PyTransDecoder
274
+ pytransdecoder longorfs -t test.fasta
275
+
276
+ # Compare outputs
277
+ diff ../TransDecoder/test.fasta.transdecoder_dir/longest_orfs.pep \
278
+ test.fasta.transdecoder_dir/longest_orfs.pep
279
+ ```
280
+
281
+ ## Requirements
282
+
283
+ - Python 3.8+
284
+ - BioPython >= 1.81
285
+ - tqdm >= 4.65
286
+
287
+ **Note**: Ported by Claude.io Sonnet 4.5 under guidance by bhaas. Jan 24, 2026.
@@ -0,0 +1,52 @@
1
+ [build-system]
2
+ requires = ["setuptools>=65.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pytransdecoder"
7
+ version = "0.2.1"
8
+ description = "TransDecoder, the original Perl version ported to Python by AI/LLMs with new features integrated"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "BSD-3-Clause"}
12
+ authors = [
13
+ {name = "Brian Haas, ported to python by AI/LLMs"}
14
+ ]
15
+ dependencies = [
16
+ "biopython>=1.81",
17
+ "tqdm>=4.65",
18
+ ]
19
+
20
+ [project.urls]
21
+ Homepage = "https://github.com/TransDecoder/PyTransDecoder"
22
+ Repository = "https://github.com/TransDecoder/PyTransDecoder"
23
+
24
+ [project.optional-dependencies]
25
+ dev = [
26
+ "pytest>=7.4",
27
+ "pytest-cov>=4.1",
28
+ "black>=23.0",
29
+ "mypy>=1.0",
30
+ ]
31
+
32
+ [project.scripts]
33
+ pytransdecoder = "pytransdecoder.cli:cli"
34
+ pyTransdecoder = "pytransdecoder.cli:pipeline_main"
35
+
36
+ [tool.setuptools.packages.find]
37
+ where = ["."]
38
+ include = ["pytransdecoder*"]
39
+
40
+ [tool.setuptools.package-data]
41
+ pytransdecoder = ["presets/*/*"]
42
+
43
+ [tool.black]
44
+ line-length = 100
45
+ target-version = ['py38', 'py39', 'py310', 'py311']
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
49
+ python_files = ["test_*.py"]
50
+ python_classes = ["Test*"]
51
+ python_functions = ["test_*"]
52
+ addopts = "-v --strict-markers"
@@ -0,0 +1,7 @@
1
+ """
2
+ PyTransDecoder - Python port of TransDecoder
3
+
4
+ Identifies candidate protein-coding regions within transcript sequences.
5
+ """
6
+
7
+ __version__ = "0.2.1"