Skip to content

Annotation liftover

swarbred edited this page Feb 17, 2026 · 20 revisions

Hands-on: Annotation liftover

LiftOn is explicitly designed to integrate DNA-based mapping from Liftoff and protein to genome alignment from miniprot

1 Go to the Lifton working directory

cd /home/train/Annotation_workshop/Liftover/Lifton
ls -l Inputs/*/

Here we have the Input files for 9 Reference species (FASTA+GFF)

  • GCA_019202805.1 Arabidopsis_suecica
  • GCA_905216605.1 Arabidopsis_arenosa
  • GCA_964271285.1 Arabidopsis_halleri
  • GCF_000004255.2 Arabidopsis_lyrata
  • GCF_000309985.2 Brassica_rapa
  • GCF_000633955.1 Camelina_sativa
  • GCF_000695525.1 Brassica_oleracea
  • GCF_000801105.2 Raphanus_sativus
  • GCF_020379485.1 Brassica_napus

The files have been prefiltered to contain just a small number of genes that will align to the target region.

Plus the target genome Arabidopsis thaliana (Chr3 FASTA + reference GTF).

2 Choose ONE reference species and run Lifton once

Pick a close species first (recommended: Arabidopsis lyrata GCF_000004255.2) so you get a “good” liftover before trying Brassicas.

2.1 Make an output directory and symlink inputs into it

tag=GCF_000004255.2
mkdir -p "$tag"
cd "$tag"
# Symlink the TARGET genome into this output directory
ln -s ../Inputs/Target/Athaliana_447_TAIR10_Chr3_clean.fa target.fa
# Symlink this REFERENCE (source) species subset FASTA+GFF
ln -s ../Inputs/Reference/${tag}.subset.fna ref.fa
ln -s ../Inputs/Reference/${tag}.subset.gff ref.gff
ls -l

Symlinking creates shortcuts (links) to the actual files. This means each output directory is self-contained, without duplicating large reference files.

2.2 Run LiftOn

This will run Liftoff and miniprot internally, then combine the results.

lifton \
-g ref.gff \
-o ${tag}.lifton.gff3 \
-a 0.9 -s 0.5 \
-t 1 \
-copies -sc 0.95 \
target.fa ref.fa \
> ${tag}.lifton.log 2>&1 &

For full options:

lifton -h

2.3 Explore the LiftOn outputs

Check it finished cleanly:

tail -n 27 ${tag}.lifton.log

How many features were transferred?

Were all features transferred?

Were all the features transferred coding features?

The main output file is ${tag}.lifton.gff3 = LiftOn annotation file

Lifton adds some additional tag=value attributes to the transcript-level annotations (e.g. mRNA/transcript features).

  • protein_identity=<0–1> - protein sequence identity for the lifted transcript (relative to the reference protein).

  • dna_identity=<0–1> - DNA sequence identity for the lifted transcript.

  • status=<Liftoff|miniprot|LiftOn_chaining_algorithm> — which method produced the final model (pure Liftoff, pure miniprot, or LiftOn’s chaining algorithm combining them).

  • mutation=<type[,type...]> - mutation class(es) detected for the protein-coding transcript. Documented types include:

    synonymous, nonsynonymous, inframe_insertion, inframe_deletion, frameshift, stop_codon_gain, stop_codon_loss, start_codon_loss.

Note that in addition to the “final” lifton GFF we have the Liftoff and miniprot output GFFs

  • lifton_output/liftoff/

    liftoff.gff3 and unmapped_features.txt
    This is Liftoff’s “DNA→DNA liftover” result that LiftOn then uses as a backbone for loci and gene placement.

  • lifton_output/miniprot/

    miniprot.gff3
    Protein to genome alignment evidence. Miniprot can emit GFF3 alignments (mRNA/CDS/stop_codon features + attributes) which LiftOn can use to repair/replace problematic CDSs from DNA-based mapping.

File lifton_output/score.txt = tsv file summarizing the LiftOn results

See https://ccb.jhu.edu/lifton/content/output_explanation.html for a description of the full outputs

3 Run LiftOn for ALL 9 reference species

3.1 Go back up to the Lifton directory

cd /home/train/Annotation_workshop/Liftover/Lifton

3.2 Run LiftOn

Run the run_lifton.sh script to run lifton on all 9 species

Inputs/Scripts/run_lifton.sh

Quick check that you produced outputs:

for d in GCA_* GCF_*; do
  test -f "$d/$d.lifton.gff3" && echo "OK  $d" || echo "MISS $d"
done

3.3 Symlink the lifton and liftoff GFF3

Ensure you are in:

cd /home/train/Annotation_workshop/Liftover/Lifton

Symlink the Lifton outputs:

for d in GCA_* GCF_*; do
  ln -sf "$d/$d.lifton.gff3" .
done

Symlink the Liftoff outputs (rename the link!):

for d in GCA_*/ GCF_*/; do
  d=${d%/}   # strip trailing slash
  ln -sf "$d/lifton_output/liftoff/liftoff.gff3" "$d.liftoff.gff3"
done

3.4 Summarise Liftoff + Lifton outputs across all species

Once you’ve run LiftOn for all 9 reference species and symlinked the outputs into:

cd /home/train/Annotation_workshop/Liftover/Lifton

You can run the provided summary script to extract key tags from the GFFs and generate:

  • TSV summaries (one row per species per tool)
  • violin plots showing the distributions of key similarity metrics across lifted models

This is useful because both Liftoff and Lifton add informative attributes to their GFF3 outputs (e.g. Liftoff transcript ORF/QC flags, and Lifton’s identity/mutation/status tags).

Command to run:

Inputs/Scripts/liftover_gff_summary.py \
--mapping Inputs/Reference/id_species_mapping.tsv \
--gene-features gene,pseudogene \
--lifton  GCA_019202805.1.lifton.gff3,GCA_905216605.1.lifton.gff3,GCA_964271285.1.lifton.gff3,GCF_000004255.2.lifton.gff3,GCF_000309985.2.lifton.gff3,GCF_000633955.1.lifton.gff3,GCF_000695525.1.lifton.gff3,GCF_000801105.2.lifton.gff3,GCF_020379485.1.lifton.gff3 \
--liftoff GCA_019202805.1.liftoff.gff3,GCA_905216605.1.liftoff.gff3,GCA_964271285.1.liftoff.gff3,GCF_000004255.2.liftoff.gff3,GCF_000309985.2.liftoff.gff3,GCF_000633955.1.liftoff.gff3,GCF_000695525.1.liftoff.gff3,GCF_000801105.2.liftoff.gff3,GCF_020379485.1.liftoff.gff3

What the options do:

  • mapping: maps an accession-like label (extracted from filename) to a species name for nicer plots.
  • gene-features gene,pseudogene: treats both gene and pseudogene as “gene-level” parents when identifying direct transcript children (important for some reference sets).
  • lifton / liftoff: comma-separated lists of GFF3s to summarise.

The script will generate a TSV output summarising the lifton and liftoff attributes across the species and violin plots showing coverage / sequence identity (liftoff) and protein and DNA identity (lifton).

The TSV files can be examined:

column -t -s $'\t' liftover_summary.lifton.summary.tsv |less -S
column -t -s $'\t' liftover_summary.liftoff.summary.tsv |less -S

(press q to quit less)

How does the identity compare across the species?

How do the Lifton status_* and mutation_* counts compare between the species?

Do we transfer more genes with Lifton or Liftoff?

liftover_summary.liftoff.coverage_sequenceID.violin.by_species.png

liftover_summary liftoff coverage_sequenceID violin by_species

liftover_summary.lifton.protein_dna_identity.violin.by_species.png

liftover_summary lifton protein_dna_identity violin by_species

4.0 Run LiftClean to identify and filter potential issues

Liftoff and LiftOn output GFF files can contain gene models that are not compatible with protein coding models. This includes models with internal stop codons but also features that can cause errors with some downstream tools i.e. models with overlapping exon features within the same transcript or where exons are on +ve and -ve strands within one transcript. Depending on how you intend to utilise the Liftoff/LiftOn outputs you may need to filter the GFF file as a preliminary step.

LiftClean https://github.com/EI-CoreBioinformatics/LiftClean can help identify and remove potentially problematic models

cd /home/train/Annotation_workshop/Liftover/Lifton

The command runs liftclean on the liftoff and lifton GFFs for each species:

mkdir Liftclean; for d in *lifton.gff3; do d=${d%.lifton.gff3}; echo "=== Running $d ==="; liftclean -g Inputs/Target/Athaliana_447_TAIR10_Chr3_clean.fa --lifton_gff ${d}.lifton.gff3 --liftoff_gff ${d}.liftoff.gff3 -p $d -o Liftclean/${d}; done

4.1 Liftclean Outputs

The main Liftclean output is the filtered lifton and liftoff GFFs containing only the transcripts that passed all filtering criteria.

ls -ltr Liftclean/{GCA,GCF}*/{liftoff_*.sorted.retained.gff,lifton_*.sorted.retained.gff}

In addition there is a csv file providing the breakdown of the different categories of warnings found:

ls -ltr Liftclean/{GCA,GCF}*/analysis/mikado_prepare_*/*summary_stats.csv

And the corresponding plot:

ls -ltr Liftclean/{GCA,GCF}*/*Rejected_Transcripts_summary_plot.png 

PNG plot summarising the types of warnings found in the rejected transcripts.

GCF_000004255.2_Rejected_Transcripts_summary_plot.png

GCF_000004255 2_Rejected_Transcripts_summary_plot

To assess warning categories across all the 9 species we can bring them together into a single file.

For Liftoff:

Inputs/Scripts/annosummary_pivot.sh --out_prefix liftclean_liftoff_sumary --summary_glob "*liftoff*summary_stats.csv" --metric_col 2 --value_col 4 Liftclean
column -t -s $'\t' liftclean_liftoff_sumary.summary_wide.tsv |less -S

(q to quit less)

For LiftOn:

Inputs/Scripts/annosummary_pivot.sh --out_prefix liftclean_lifton_sumary --summary_glob "*lifton*summary_stats.csv" --metric_col 2 --value_col 4 Liftclean
column -t -s $'\t' liftclean_lifton_sumary.summary_wide.tsv |less -S

(q to quit less)

How many different “warnings” were present in Liftoff / LiftOn?

Post filtering, which of the 9 species had the highest number of transferred models (check out the * mikado_stats.summary.tsv files that give basic annotation stats for the filtered GFFs)?

Clone this wiki locally