Repository navigation
Text before the first '>' header becomes an extra transcript with predicted ORFs #213
Description
What happens. If a transcript FASTA file has any text before its first > header line, TransDecoder.LongOrfs (6.0.0, and current master) treats that text as an extra transcript, named after the first word of the text, and predicts ORFs on it. There is no warning. The text also changes base_freqs.dat, which TransDecoder.Predict uses for scoring.
Reproduction. Three RefSeq mRNAs (NM_000546.6 TP53, NM_002046.7 GAPDH, NM_000207.3 INS), with and without a 1,437-byte block of ; comment lines in front, e.g. ;This file holds three RefSeq mRNA sequences that were downloaded…:
cat comment_block.txt mrna.fa > mrna.commented.fa
TransDecoder.LongOrfs -t mrna.fa
TransDecoder.LongOrfs -t mrna.commented.fa
| 6.0.0 | mrna.fa |
mrna.commented.fa |
|---|---|---|
ORFs in longest_orfs.pep |
10 | 16 (6 on a "transcript" named ;This) |
base_freqs.dat A / C / G / T |
1903 / 2359 / 2359 / 1903 | 2040 / 2418 / 2418 / 2040 |
The real transcripts' ORFs are unchanged. Current master behaves the same way: 22 ORFs without the comment block, 28 with it, 6 of them on the comment text.
Cause. Fasta_reader::next() reads with $/ = "\n>", so the first chunk is everything before the first header. It is only skipped when it contains no word characters, which covers leading whitespace but not text.
Possible fix. On the first read only, skip a chunk that doesn't start with > but ends right before a header. This also covers the existing leading-whitespace case:
--- a/PerlLib/Fasta_reader.pm
+++ b/PerlLib/Fasta_reader.pm
@@ -42,6 +42,14 @@ sub next {
$/="\n>";
my $filehandle = $self->{fileHandle};
my $next_text_input = <$filehandle>;
+
+ unless ($self->{_read_first_record}) {
+ $self->{_read_first_record} = 1;
+ ## skip any text before the first '>' header line (e.g. ';' comment lines)
+ if (defined($next_text_input) && $next_text_input !~ /^>/ && $next_text_input =~ /\n>$/) {
+ $next_text_input = <$filehandle>;
+ }
+ }
if (defined($next_text_input) && $next_text_input !~ /\w/) {With this change on master, longest_orfs.pep, .cds, .gff3 and base_freqs.dat are byte-identical with and without the comment block, for the three mRNAs and for a small synthetic file. In __testing, make gives the same result with and without the change (the single_best target currently differs from its expected file on master either way).
The same Fasta_reader.pm (with an identical next()) is in Trinity's PerlLib, so the fix may apply there too.
I'm happy to open a pull request if that would help.
Context. We found this while testing tools with the FAIR Header Reference genome (FHR) metadata standard, which stores provenance as ; comment lines before the first record (https://doi.org/10.1093/bib/bbae122). But any file with text before the first header is affected.
This report was prepared with an AI coding assistant (Claude Code) and checked by me.
Activity
brianjohnhaas commentedon Oct 20, 2026
adamjohnwright commentedon Oct 20, 2026
Thank you @brianjohnhaas, much appreciated! In case it's useful, the same
Fasta_reader.pmis in Trinity's PerlLib.brianjohnhaas commentedon Oct 20, 2026