Package: pyrodigal
🔥 PyrodigalCython bindings and Python interface toProdigal, an ORF
finder for genomes and metagenomes.Now with SIMD!🗺️ OverviewPyrodigal is a Python module that provides bindings to Prodigal usingCython. It directly interacts with the Prodigal
internals, which has the following advantages:single dependency: Pyrodigal is distributed as a Python package, so you
can add it as a dependency to your project, and stop worrying about the
Prodigal binary being present on the end-user machine.no intermediate files: Everything happens in memory, in a Python object
you fully control, so you don't have to invoke the Prodigal CLI using a
sub-process and temporary files. Sequences can be passed directly as
strings or bytes, which avoids the overhead of formatting your input to
FASTA for Prodigal.better memory usage: Pyrodigal uses more compact data structures compared
to the original Prodigal implementation, allowing to save memory to store
the same information. A heuristic is used to estimate the number of nodes
to allocate based on the sequence GC% in order to minimize reallocations.better performance: Pyrodigal usesSIMDinstructions to compute which
dynamic programming nodes can be ignored when scoring connections. This can
save from a third to half the runtime depending on the sequence. TheBenchmarkspage of the documentation contains comprehensive comparisons. See theJOSS paperfor details about how this is achieved.same results: Pyrodigal is tested to make sure it produces
exactly the same results as Prodigalv2.6.3+31b300a.This was verified
extensively byJulian Hahnfeldand can be
checked with hiscomparison repository.📋 FeaturesThe library now features everything from the original Prodigal CLI:run mode selection: Choose betweensinglemode, using a training
sequence to count nucleotide hexamers, ormetagenomicmode, using
pre-trained data from different organisms (prodigal -p).region masking: Prevent genes from being predicted across regions
containing unknown nucleotides  (prodigal -m).closed ends: Genes will be identified as running over edges if they
are larger than a certain size, but this can be disabled (prodigal -c).training configuration: During the training process, a custom
translation table can be given (prodigal -g), and the Shine-Dalgarno motif
search can be forcefully bypassed (prodigal -n)output files: Output files can be written in a format mostly
compatible with the Prodigal binary, including the protein translations
in FASTA format (prodigal -a), the gene sequences in FASTA format
(prodigal -d), or the potential gene scores in tabular format
(prodigal -s).training data persistence: Getting training data from a sequence and
using it for other sequences is supported; in addition, a training data
file can be saved and loaded transparently (prodigal -t).In addition, thenewfeatures are available:custom gene size threshold: While Prodigal uses a minimum gene size
of 90 nucleotides (60 if on edge), Pyrodigal allows to customize this
threshold, allowing for smaller ORFs to be identified if needed.custom metagenomic models: Sincev3.0.0, you can use your own
metagenomic models to run Pyrodigal inmeta-mode.Check for instancepyrodigal-gv, which
provides additional models for giant viruses and gut phages.🐏 MemoryPyrodigal makes several changes compared to the original Prodigal binary
regarding memory management:Sequences are stored as raw bytes instead of compressed bitmaps. This means
that the sequence itself takes 3/8th more space, but since the memory used
for storing the sequence is often negligible compared to the memory used to
store dynamic programming nodes, this is an acceptable trade-off for better
performance when extracting said nodes.Node fields use smaller data types to fit into 128 bytes, compared to the
176 bytes of the original Prodigal data structure.Node arrays are pre-allocated based on the sequence GC% to extrapolate the
probability to find a start or stop codon.Genes are stored in a more compact data structure than in Prodigal (which
reserves a buffer to store string data), saving around 1KiB per gene.🧶 Thread-safetypyrodigal.GeneFinderinstances are thread-safe. In addition, thefind_genesmethod is re-entrant. This means you can train anGeneFinderinstance once, and then use a pool to process sequences in parallel:importmultiprocessing.poolimportpyrodigalgene_finder=pyrodigal.GeneFinder()gene_finder.train(training_sequence)withmultiprocessing.pool.ThreadPool()aspool:predictions=pool.map(orf_finder.find_genes,sequences)🔧 InstallingPyrodigal can be installed directly fromPyPI,
which hosts some pre-built wheels for the x86-64 architecture (Linux/MacOS/Windows)
and the Aarch64 architecture (Linux/MacOS), as well as the code required to compile
from source with Cython:$pipinstallpyrodigalOtherwise, Pyrodigal is also available as aBiocondapackage:$condainstall-cbiocondapyrodigalCheck theinstallpageof the documentation for other ways to install Pyrodigal on your machine.💡 ExampleLet's load a sequence from aGenBankfile, use anGeneFinderto find all the genes it contains, and print the proteins in two-line FASTA
format.🔬BiopythonTo use theGeneFinderin single mode (corresponding toprodigal -p single, the default operation mode of Prodigal),
you must explicitly call thetrainmethod
with the sequence you want to use for training before trying to find genes,
or you will get aRuntimeError:importBio.SeqIOimportpyrodigalrecord=Bio.SeqIO.read("sequence.gbk","genbank")orf_finder=pyrodigal.GeneFinder()orf_finder.train(bytes(record.seq))genes=orf_finder.find_genes(bytes(record.seq))However, inmetamode (corresponding toprodigal -p meta), you can find genes directly:importBio.SeqIOimportpyrodigalrecord=Bio.SeqIO.read("sequence.gbk","genbank")orf_finder=pyrodigal.GeneFinder(meta=True)fori,predinenumerate(orf_finder.find_genes(bytes(record.seq))):print(f">{record.id}_{i+1}")print(pred.translate())On older versions of Biopython (before 1.79) you will need to userecord.seq.encode()instead ofbytes(record.seq).🧪Scikit-bioimportskbio.ioimportpyrodigalseq=next(skbio.io.read("sequence.gbk","genbank"))orf_finder=pyrodigal.GeneFinder(meta=True)fori,predinenumerate(orf_finder.find_genes(seq.values.view('B'))):print(f">{record.id}_{i+1}")print(pred.translate())We need to use theviewmethod to get the sequence viewable by Cython as an array ofunsigned char.🔖 CitationPyrodigal is scientific software, with apublished paperin theJournal of Open-Source Software. Please
cite bothPyrodigalandProdigalif you are using it in
an academic work, for instance as:Pyrodigal (Larralde, 2022), a Python library binding to Prodigal (Hyattet al., 2010).Detailed references are available on thePublications pageof theonline documentation.💭 Feedback⚠️ Issue TrackerFound a bug ? Have an enhancement request ? Head over to theGitHub issue
trackerif you need to report
or ask something. If you are filing in on a bug, please include as much
information as you can about the issue, and try to recreate the same bug
in a simple, easily reproducible situation.🏗️ ContributingContributions are more than welcome! SeeCONTRIBUTING.mdfor more details.📋 ChangelogThis project adheres toSemantic Versioningand provides achangelogin theKeep a Changelogformat.⚖️ LicenseThis library is provided under theGNU General Public License v3.0.
The Prodigal code was written byDoug Hyattand is distributed under the
terms of the GPLv3 as well. Seevendor/Prodigal/LICENSEfor more information.This project is in no way not affiliated, sponsored, or otherwise endorsed
by theoriginal Prodigal authors. It was developed
byMartin Larraldeduring his PhD project
at theEuropean Molecular Biology Laboratoryin
theZeller team.