Gene prediction¶
FunFlux predicts the protein-coding and tRNA genes of each sample with funannotate predict 1.8.17, on the soft-masked genome from repeat masking. Tiberius, a gene finder that is not trained on your genome, runs first and adds its gene models to the evidence. Two checks run before the prediction, so that a wrong AUGUSTUS model or an expired GeneMark-ES key stops the run early instead of hours into it. Read this page to choose the AUGUSTUS model of each sample, to decide whether GeneMark-ES and Tiberius run, and to interpret the gene models and their files.
---
config:
themeVariables:
fontSize: 14px
flowchart:
nodeSpacing: 35
rankSpacing: 35
---
flowchart TD
MASK([contigs_mask.fasta<br/>repeats in lowercase]) -.->|"only with GeneMark-ES on"| GM[GeneMark-ES licence check<br/>genemark_check]
MASK --> TIB[Tiberius<br/>on by default]
TIB --> TGFF([tiberius.evm.gff3])
TAB([annotation table<br/>species, proteins,<br/>AUGUSTUS model]) --> AUG[AUGUSTUS model check<br/>augustus_model_check<br/>named model in the database?]
GM -.-> FP[funannotate predict]
TGFF --> FP
MASK --> FP
AUG --> FP
TAB --> FP
FP --> OUT([funannotate/predict_results/<br/>gene models, proteins,<br/>GenBank file])
OUT --> FA[functional annotation]
One rule, funannotate_prediction, makes the gene models with funannotate predict. The other rules
prepare its evidence or check its settings:
| Rule, as the console and the log files name it | What it does |
|---|---|
augustus_model_check |
checks the AUGUSTUS model of column 4 of the annotation parameter table, files.annotation_params (The AUGUSTUS model) |
genemark_check |
runs GeneMark-ES on a slice of the genome to catch an expired licence key (GeneMark-ES and the licence check) |
tiberius_model, tiberius_prediction, tiberius_gff3 |
download the Tiberius model, predict genes, convert them for funannotate (Tiberius) |
funannotate_prediction |
runs funannotate predict on 04.annotation/{sample}/contigs_mask.fasta, one sample at a time, with all resources.threads |
The output folder of funannotate predict, 04.annotation/{sample}/funannotate/, feeds every step
of the functional annotation.
Terms used on this page
| soft-masking | writing repeats in lower case, so that gene finders can treat them differently without losing the sequence |
| annotation parameter table | the tab-separated file named by files.annotation_params, one row per sample: name, species, a protein FASTA of related fungi and, optionally, an AUGUSTUS model |
| funannotate database | the frozen snapshot of funannotate's data, such as Swiss-Prot, Pfam, the BUSCO set and stored AUGUSTUS models, downloaded once from Zenodo into directories.funannotate_db |
| stored AUGUSTUS model | the AUGUSTUS parameters trained earlier for one species, kept in trained_species/ of the funannotate database; named in column 4, they are used as they are |
| BUSCO set | the BUSCO genes funannotate looks for to train SNAP, GlimmerHMM and, without a stored AUGUSTUS model, AUGUSTUS: dikarya (dikarya_odb9) unless parameters.prediction.busco_db names another |
| EVidenceModeler | the program inside funannotate predict that builds one consensus gene per locus from the gene finders and protein alignments, weighting each source's votes |
| ab initio | said of a gene finder that predicts genes from the DNA sequence with a trained model, such as AUGUSTUS or SNAP; EVidenceModeler counts Tiberius apart |
| licence key | the file ~/.gm_key that GeneMark-ES needs; it expires one year after download, and an expired key stops the run at genemark_check, before gene prediction |
Evidence¶
funannotate predict builds the gene models from the evidence below. The annotation table chooses the proteins and the AUGUSTUS model of each sample, and the configuration chooses the rest for every sample.
| Evidence | Where it comes from | Set by |
|---|---|---|
the genome, repeats in lowercase, contigs named scaffold_N |
repeat masking | parameters.masking_method |
| proteins of related fungi | column 3 of the annotation table | files.annotation_params |
UniProtKB/Swiss-Prot 2026_03 (uniprot_sprot.fasta, 575,748 proteins) |
the funannotate database | directories.funannotate_db |
| a stored AUGUSTUS model, if any (see The AUGUSTUS model) | column 4 of the annotation table: one of the models the funannotate database holds; empty or - trains AUGUSTUS on this genome |
files.annotation_params, parameters.prediction.augustus_optimize |
| a BUSCO set, to find conserved genes on which SNAP and GlimmerHMM (and AUGUSTUS, when column 4 is empty) are trained | the funannotate database: dikarya (BUSCO dikarya_odb9, 1,312 genes) is the only set it comes with |
parameters.prediction.busco_db |
| GeneMark-ES, optional and licensed | the user's installation | directories.genemark_dir, parameters.genemark.mode |
| Tiberius's gene models, on by default | Tiberius | parameters.tiberius.mode |
dikarya, the only BUSCO set the funannotate database comes with, suits fungi of the Dikarya. For
a fungus outside the Dikarya, add another BUSCO set, such as fungi, to the funannotate database
first and set prediction.busco_db to its name. When the database is on disk and the named set is
not in it, the run stops before any job starts, with
[FunFlux] parameters.prediction.busco_db: '<name>' is not in the funannotate database at '<db>'. Add it with FunFlux's funannotate conda environment activated ('Other BUSCO sets for gene prediction' in the documentation shows how to find it): funannotate setup -i busco -b <name> -d <db> -w.
Other BUSCO sets for gene prediction shows how to find
and activate that environment.
The command¶
Rule funannotate_prediction runs this command for each sample, shown here with a stored AUGUSTUS
model in column 4 and Tiberius on:
funannotate predict -i contigs_mask.fasta -o 04.annotation/{sample}/funannotate \
-s "<species>" --name {sample} --strain {sample} \
--augustus_species <augustus_species> \
--other_gff 04.annotation/{sample}/tiberius/tiberius.evm.gff3:1 --busco_db dikarya \
--protein_evidence <proteins> /path/to/funannotate_db/uniprot_sprot.fasta \
--cpus {threads}
The annotation table and the Tiberius setting change the command. Column 4 decides whether a
stored AUGUSTUS model is used or AUGUSTUS is trained on the genome, and tiberius.mode decides
whether Tiberius's gene models are part of the evidence:
| Setting | Effect on the command |
|---|---|
| column 4 of the annotation table names a stored AUGUSTUS model | --augustus_species <augustus_species>, as above |
| column 4 empty | --augustus_species is left out; --optimize_augustus takes its place when parameters.prediction.augustus_optimize is true |
parameters.tiberius.mode: on (the default) |
--other_gff <file>:1 hands funannotate Tiberius's gene models with weight 1 |
parameters.tiberius.mode: off |
--other_gff is left out |
Before the command, the rule sets FUNANNOTATE_DB, cuts PATH down to the funannotate
environment plus /usr/bin:/bin, and clears GENEMARK_PATH unless GeneMark-ES is enabled. A
GeneMark-ES installed elsewhere on the computer is therefore never used by accident.
What funannotate predict does¶
funannotate predict turns the evidence into gene models in the following steps:
| Step | Tools |
|---|---|
| align the protein evidence to the genome | DIAMOND 2.2.4, then Exonerate 2.4.0 |
| self-train on the genome and predict (when enabled) | GeneMark-ES |
| find conserved genes for training | BUSCO, with prediction.busco_db |
| predict with the stored AUGUSTUS model of column 4, or, with column 4 empty, train on the BUSCO models first | AUGUSTUS 3.5.0 |
| train on the BUSCO models and predict | SNAP 2017_03_01, GlimmerHMM 3.0.4 |
| combine into one consensus | EVidenceModeler 1.1.1 |
| drop models shorter than 50 amino acids or spanning a gap; the repeat filter drops models that lie for at least 90 % in a masked (lowercase) repeat or whose protein matches a transposable element | funannotate |
| find tRNA genes | tRNAscan-SE 2.0.13 |
EVidenceModeler builds one consensus gene per locus from all of this. Every source votes for the
exons, introns and gene ends it predicts or supports, each vote multiplied by the weight of the
source, and the gene structure with the highest total wins. A weight is a relative trust, so only
the ratios between weights matter. funannotate writes the sources, with the kind and the weight it
gives each, to predict_misc/weights.evm.txt:
| Source in EVidenceModeler | Evidence | Kind | Weight |
|---|---|---|---|
Augustus |
AUGUSTUS models | ab initio (ABINITIO_PREDICTION) |
1 |
HiQ |
AUGUSTUS models with more than 90 % of their exons supported by the protein alignments; they count here instead of under Augustus |
other (OTHER_PREDICTION) |
2 |
snap, GlimmerHMM |
SNAP and GlimmerHMM models | ab initio (ABINITIO_PREDICTION) |
1 each |
GeneMark |
GeneMark-ES models, when GeneMark-ES is on | ab initio (ABINITIO_PREDICTION) |
1 |
other_pred1 |
Tiberius models, when Tiberius is on (fixed in FunFlux) | other (OTHER_PREDICTION) |
1 |
exonerate |
the protein alignments | protein (PROTEIN) |
1 |
AUGUSTUS models that the proteins support therefore count double, and every other source counts
once. The ab initio sources also score the stretches between genes. HiQ and other_pred1 count
only for the exons and introns they predict, not for the stretches between genes.
The log lists where the training of each predictor came from:
| Word in the log | Meaning |
|---|---|
pretrained |
column 4 named a stored AUGUSTUS model of the database, which AUGUSTUS uses as it is |
busco |
trained on this genome's BUSCO models: SNAP and GlimmerHMM always, AUGUSTUS when column 4 is empty |
selftraining |
GeneMark-ES trained itself on the genome |
A name that is not in the database would also make funannotate train AUGUSTUS, without a word. FunFlux stops on such a name instead, as The AUGUSTUS model explains.
The GFF3 numbers genes and tRNA genes together, so its gene count is the protein-coding genes plus the tRNA genes.
The annotation parameter table¶
The annotation parameter table and the sample name fill in the parts of the command that differ between samples:
| From | Option of funannotate predict |
Effect |
|---|---|---|
| column 2 | -s |
the species |
| column 3 | --protein_evidence |
the protein evidence, beside Swiss-Prot |
| column 4, if it names a model | --augustus_species |
the stored AUGUSTUS model |
| the sample name | --name |
the locus-tag prefix: genes are numbered SAMPLE1_000001, SAMPLE1_000002, ..., their transcripts SAMPLE1_000001-T1 |
| the sample name | --strain |
adds the sample name to the file stem |
The funannotate database comes with 166 stored AUGUSTUS models, and
ls /path/to/funannotate_db/trained_species/ lists them. Fungal models among them include
aspergillus_fumigatus, aspergillus_nidulans, botrytis_cinerea, fusarium,
fusarium_graminearum, magnaporthe_grisea and neurospora_crassa.
NCBI accepts a locus-tag prefix of 3 to 12 letters or digits that starts with a letter, and FunFlux prints a NOTE for a sample name that does not fit. Such a sample runs, but its gene IDs cannot be submitted to GenBank as they are.
The AUGUSTUS model¶
Column 4 of the annotation table decides which parameters AUGUSTUS runs with. The choice matters because AUGUSTUS models with strong evidence (more than 90 % of their exons supported) carry weight 2 in EVidenceModeler. That is the highest weight of any gene finder here, and every other model counts 1.
| Column 4 | What AUGUSTUS does | The log says |
|---|---|---|
empty, -, or no fourth column (the default) |
is trained on this genome's BUSCO models with etraining, AUGUSTUS's training program (a few seconds) |
augustus busco |
a stored AUGUSTUS model, such as fusarium_graminearum |
uses that species' parameters from <funannotate_db>/trained_species/ as they are; it is not trained on this genome |
augustus pretrained |
empty, with prediction.augustus_optimize: true |
the same, then optimize_augustus.pl tunes the model's meta-parameters by 8-fold cross-validation, and AUGUSTUS is trained again (details below) |
augustus busco |
The default, an empty column 4, trains AUGUSTUS on the genome itself and needs no choice. Name a stored AUGUSTUS model instead when you know one that suits the genome, typically one of the same species or genus, or when the genome yields too few BUSCO models for training (below). The choice changes a large share of the final gene models, so FunFlux records it for every sample.
Training AUGUSTUS on fewer than 200 BUSCO models stops the prediction late
Training needs at least 200 BUSCO models (funannotate's --min_training_models, which FunFlux
does not change). With fewer, funannotate stops after the protein alignment and the BUSCO
search, well into the prediction, with
Not enough gene models <N> to train Augustus (200 required), exiting. The dikarya set has
1,312 BUSCO genes, but a fragmented assembly, or a fungus outside the Dikarya with the fungi
set (290 genes), can give fewer than 200. Name a stored AUGUSTUS model for such a genome.
With prediction.augustus_optimize: true, optimize_augustus.pl tunes the model's
meta-parameters, the settings the quick training keeps fixed, such as the width of the windows
around splice sites in which AUGUSTUS learns sequence patterns. It tunes them by 8-fold
cross-validation. The test genes, the tenth of the BUSCO models funannotate sets aside for
testing, are cut into 8 parts, and each part is predicted by a model trained without it. AUGUSTUS
is then trained again. This takes about a quarter of an hour for a 40 Mb genome and uses at
most 8 CPUs.
With column 4 empty, funannotate first looks for a stored AUGUSTUS model under the name it gives a
newly trained one, <genus>_<species>_<sample> in lower case (beauveria_bassiana_arsef3097).
Such a model exists only if someone added an earlier result to the database with
funannotate species, as funannotate's last message suggests. If it exists, funannotate uses it
as it is instead of training, and FunFlux says so in a NOTE and in the record described below.
Rule augustus_model_check runs right after the funannotate database is ready, long before the
gene prediction. It stops the run on a name the database does not hold and gives the closest names
it does hold, also in logs/augustus_model_check_{sample}.log. It writes the choice to
04.annotation/{sample}/augustus_model.txt, which the gene prediction copies to the top of its
log. When the database is already on disk, the same check runs before any job starts, so a dry
run shows the error too. Every dry run prints one line with the choice for each sample, for
example:
| Column 4 | Dry-run line |
|---|---|
| empty | AUGUSTUS: ARSEF3097 is trained on its BUSCO genes. |
| a stored AUGUSTUS model | AUGUSTUS: ARSEF3097 uses the stored model fusarium_graminearum. |
| either, before the database is downloaded | the line ends in (checked once the database is unpacked) |
GeneMark-ES and the licence check¶
GeneMark-ES is optional and needs a licence. Two configuration keys decide whether it runs:
directories.genemark_dir |
parameters.genemark.mode |
GeneMark-ES |
|---|---|---|
names an installation (the folder with gmes_petap.pl) |
auto, the default; a mode left empty (mode: or mode: "") also means auto, as for the other mode keys |
used |
| empty | any | not used |
| any | off |
not used |
When it is not used, funannotate runs without it, and the dry run prints
GeneMark-ES: off (funannotate runs its no-GeneMark branch). FunFlux v2 was tested with
GeneMark-ES, and with mode: off on one public genome
(Validation on public genomes). See
Licensed and external tools for the installation and the
key.
The licence key, ~/.gm_key of the user who runs Snakemake, expires one year after download, and
the date of the key file does not tell when. gmes_petap.pl only checks that the file exists, so
an expired key would show only when funannotate predict reaches GeneMark-ES, well into the run,
with Your license period has ended. With GeneMark-ES on, rule genemark_check therefore runs
GeneMark-ES on the first 200,000 bytes of contigs_mask.fasta before the prediction. This check
takes about a minute. It stops the run when the licence or the installation fails, and writes its
result to 04.annotation/{sample}/genemark_check.txt. The command, its outcomes and its messages
are on
The licence check before gene prediction.
Tiberius¶
Tiberius (Gabriel et al. 2024) finds genes with a deep neural network
joined to a hidden Markov model. A hidden Markov model is the kind of model AUGUSTUS and
GeneMark-ES use for the order of exons, introns and the DNA between genes. Unlike them, Tiberius
is not trained on your genome. It uses
one model, fungi, that its authors trained on many fungal genomes. It needs no licence and no
evidence, and it runs whether or not GeneMark-ES does. With both on, both count in
EVidenceModeler.
Tiberius is on by default and needs no setting. Three configuration keys control it:
| Setting | Default | Meaning |
|---|---|---|
parameters.tiberius.mode |
on |
off leaves Tiberius out; the funannotate predict command is then the one without --other_gff |
links.tiberius_model_link |
the fungi model on the Tiberius authors' server |
where the model is downloaded from; required while Tiberius is on |
parameters.tiberius.model_sha256 |
the checksum of the model file of 8 February 2026 | the SHA-256 the downloaded file must have |
Tiberius runs in three rules, from the download of its model to the file funannotate reads:
| Rule | Runs | What it does | Writes |
|---|---|---|---|
tiberius_model |
once per output folder | downloads the model archive (about 30 MB), checks its SHA-256 checksum and unpacks it | 00.resources/tiberius/model/ |
tiberius_prediction |
per sample | runs Tiberius 1.1.8 (bioconda; its own conda environment with the CPU build of TensorFlow 2.17) on contigs_mask.fasta, so that the scaffold names are the ones funannotate predict uses |
04.annotation/{sample}/tiberius/tiberius.gtf |
tiberius_gff3 |
per sample | converts that GTF with EVidenceModeler's own converter (augustus_GTF_to_EVM_GFF3.pl) into the file funannotate predict gets with --other_gff |
04.annotation/{sample}/tiberius/tiberius.evm.gff3 |
The fungi model was trained without repeat masking, the kind of model the Tiberius authors
recommend as the safer default, so Tiberius runs with --no_softmasking. Tiberius therefore reads
lowercase and uppercase letters alike, and contigs_mask.fasta gives it the same input as the
unmasked genome. After EVidenceModeler, funannotate's repeat filter removes the gene models that
fall in repeats, whatever gene finder they came from
(What funannotate predict does). Tiberius also gets
--seq_len 100080, the model's own length for the pieces the genome is cut into, which Tiberius
1.1.8 does not take from the model.
The model's address carries no version number, so the authors can replace the file at the same
address. A file that does not match the checksum stops the run with a message instead of quietly
changing the gene models. To accept a new model, check it, compute its checksum with
sha256sum <archive> and put that into parameters.tiberius.model_sha256, as described under
Tiberius model.
For a fungal genome of about 40 Mb, Tiberius needs:
| Resource | Need |
|---|---|
| memory | about 16 GB. On a single computer Snakemake does not reserve this memory, so switch Tiberius off on a computer with less free memory. On a cluster the job asks for resources.ram_gb, which must then be at least 16 GB |
| CPU | all of resources.threads; roughly half an hour on 24 to 32 threads |
| graphics card | not used: Tiberius runs on the CPU |
The weight of Tiberius in EVidenceModeler is fixed at 1, the weight of the other gene finders, and other values have not been tested.
The logs are logs/tiberius_model.log, logs/tiberius_prediction_{sample}.log and
logs/tiberius_gff3_{sample}.log.
Run time¶
For each sample, the two prediction steps run one after the other:
| Step | Run time for a fungal genome |
|---|---|
| Tiberius, before funannotate predict | about half an hour for a 40 Mb genome |
| funannotate predict | usually an hour or more |
Run-to-run variation¶
funannotate predict does not give the same gene models twice from the same masked genome and settings. The differences are small, but they change the gene counts and the counts of the functional annotation. Run-to-run differences explains which steps differ, and why.
Compare two runs by coordinates, not by gene IDs
Gene IDs are numbered along the scaffolds, so one model gained or lost renumbers every gene after it. Match the gene models of two runs by scaffold, strand and CDS intervals instead.
Outputs¶
funannotate predict writes its results into 04.annotation/{sample}/funannotate/. In the paths
below, <stem> is <Genus_species>_{sample}, for example Fusarium_graminearum_SAMPLE1:
Path in funannotate/ |
Content |
|---|---|
predict_results/<stem>.gff3 |
gene models: genes, mRNAs, exons, CDS, tRNAs |
predict_results/<stem>.gbk |
the genome with the gene models, GenBank format; the input of antiSMASH |
predict_results/<stem>.proteins.fa |
the predicted proteins; the input of InterProScan, eggNOG-mapper and SignalP 6 |
predict_results/<stem>.cds-transcripts.fa, .mrna-transcripts.fa |
coding sequences, transcripts |
predict_results/<stem>.scaffolds.fa, .tbl, .stats.json |
the genome, the feature table, counts |
predict_results/<stem>.discrepency.report.txt, .error.summary.txt, .validation.txt |
the checks of tbl2asn 25.7 |
predict_results/<model>.parameters.json |
the AUGUSTUS parameters used: named after the stored AUGUSTUS model, or <genus>_<species>_<sample> in lower case for a model trained on this genome (beauveria_bassiana_arsef3097.parameters.json) |
predict_misc/ |
working files: alignments, the models of each predictor, EVidenceModeler |
logfiles/ |
funannotate's own logs, funannotate-predict.log among them |
With Tiberius on, 04.annotation/{sample}/tiberius/ holds tiberius.gtf, Tiberius's gene
models, and tiberius.evm.gff3, the same models as funannotate hands them to EVidenceModeler.
The functional annotation adds annotate_results/ and
annotate_misc/ to the same folder, and annotate_results/ holds the final files.
The rule log is logs/funannotate_prediction_{sample}.log. Like every log, it holds the latest
attempt only.
Re-running the prediction deletes the annotation
Snakemake treats funannotate/ as one output and deletes it before funannotate_prediction
runs again. funannotate/ holds both the prediction and the final annotation. Whenever the
prediction runs again, for example after a change in the annotation table, the annotation is
therefore deleted and every annotation step runs again, with slightly different gene models.
Copy annotate_results/ elsewhere first if you need to keep it.