pyfasta

fast, memory-efficient, pythonic (and command-line) access to fasta sequence files

https://github.com/brentp/pyfasta

Science Score: 10.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
    1 of 4 committers (25.0%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (11.0%) to scientific vocabulary

Keywords from Contributors

bioinformatics
Last synced: 11 months ago · JSON representation

Repository

fast, memory-efficient, pythonic (and command-line) access to fasta sequence files

Basic Info
Statistics
  • Stars: 87
  • Watchers: 5
  • Forks: 26
  • Open Issues: 6
  • Releases: 0
Archived
Created about 16 years ago · Last pushed over 8 years ago
Metadata Files
Readme Changelog

README.rst

==================================================
pyfasta: pythonic access to fasta sequence files.
==================================================

**NOTE** : unless you have specific reason to use pyfasta, I suggest to use `pyfaidx `_ 


:Author: Brent Pedersen (brentp)
:Email: bpederse@gmail.com
:License: MIT



.. contents ::

Implementation
==============

Requires Python >= 2.6. Stores a flattened version of the fasta file without
spaces or headers and uses either a mmap of numpy binary format or fseek/fread so the
*sequence data is never read into memory*. Saves a pickle (.gdx) of the start, stop 
(for fseek/mmap) locations of each header in the fasta file for internal use.

Usage
=====
::
  
    >>> from pyfasta import Fasta

    >>> f = Fasta('tests/data/three_chrs.fasta')
    >>> sorted(f.keys())
    ['chr1', 'chr2', 'chr3']

    >>> f['chr1']
    NpyFastaRecord(0..80)



Slicing
-------
::

    # get full the sequence:
    >>> a = str(f['chr1'])
    >>> b = f['chr1'][:]
    >>> a == b
    True

    >>> f['chr1'][:10]
    'ACTGACTGAC'

    # get the 1st basepair in every codon (it's python yo)
    >>> f['chr1'][::3]
    'AGTCAGTCAGTCAGTCAGTCAGTCAGT'

    # can query by a 'feature' dictionary (note this is one based coordinates)
    >>> f.sequence({'chr': 'chr1', 'start': 2, 'stop': 9})
    'CTGACTGA'

    # same as:
    >>> f['chr1'][1:9]
    'CTGACTGA'

    # use python, zero based coords
    >>> f.sequence({'chr': 'chr1', 'start': 2, 'stop': 9}, one_based=False)
    'TGACTGA'

    # with reverse complement (automatic for - strand)
    >>> f.sequence({'chr': 'chr1', 'start': 2, 'stop': 9, 'strand': '-'})
    'TCAGTCAG'

Key Function
------------
Sometimes your fasta will have a long header like: "AT1G51370.2 | Symbols:  | F-box family protein | chr1:19045615-19046748 FORWARD" when you only want to key off: "AT1G51370.2". In this case, specify the key_fn argument to the constructor:

::

    >>> fkey = Fasta('tests/data/key.fasta', key_fn=lambda key: key.split()[0])
    >>> sorted(fkey.keys())
    ['a', 'b', 'c']

Numpy
=====

The default is to use a memmaped numpy array as the backend. In which case it's possible to
get back an array directly...
::

    >>> f['chr1'].as_string = False
    >>> f['chr1'][:10] # doctest: +NORMALIZE_WHITESPACE
    memmap(['A', 'C', 'T', 'G', 'A', 'C', 'T', 'G', 'A', 'C'], dtype='|S1')

    >>> import numpy as np
    >>> a = np.array(f['chr2'])
    >>> a.shape[0] == len(f['chr2'])
    True

    >>> a[10:14] # doctest: +NORMALIZE_WHITESPACE
    array(['A', 'A', 'A', 'A'], dtype='|S1')

mask a sub-sequence
::

    >>> a[11:13] = np.array('N', dtype='S1')
    >>> a[10:14].tostring()
    'ANNA'


Backends (Record class)
=======================
It's also possible to specify another record class as the underlying work-horse
for slicing and reading. Currently, there's just the default: 

  * NpyFastaRecord which uses numpy memmap
  * FastaRecord, which uses using fseek/fread
  * MemoryRecord which reads everything into memory and must reparse the original
    fasta every time.
  * TCRecord which is identical to NpyFastaRecord except that it saves the index
    in a TokyoCabinet hash database, for cases when there are enough records that
    loading the entire index from a pickle into memory is unwise. (NOTE: that the
    sequence is not loaded into memory in either case).

It's possible to specify the class used with the `record_class` kwarg to the `Fasta`
constructor:
::

    >>> from pyfasta import FastaRecord # default is NpyFastaRecord
    >>> f = Fasta('tests/data/three_chrs.fasta', record_class=FastaRecord)
    >>> f['chr1']
    FastaRecord('tests/data/three_chrs.fasta.flat', 0..80)

other than the repr, it should behave exactly like the Npy record class backend

it's possible to create your own using a sub-class of FastaRecord. see the source 
in pyfasta/records.py for details.

Flattening
==========
In order to efficiently access the sequence content, pyfasta saves a separate, flattened file with all newlines and headers removed from the sequence. In the case of large fasta files, one may not wish to save 2 copies of a 5GG+ file. In that case, it's possible to flatten the file "inplace", keeping all the headers, and retaining the validity of the fasta file -- with the only change being that the new-lines are removed from each sequence. This can be specified via `flatten_inplace` = True
::
    
    >>> import os
    >>> os.unlink('tests/data/three_chrs.fasta.gdx') # cleanup non-inplace idx
    >>> f = Fasta('tests/data/three_chrs.fasta', flatten_inplace=True)
    >>> f['chr1']  # note the difference in the output from above.
    NpyFastaRecord(6..86)

    # sequence from is same as when requested from non-flat file above.
    >>> f['chr1'][1:9]
    'CTGACTGA'

    # the flattened file is kept as a place holder without the sequence data.
    >>> open('tests/data/three_chrs.fasta.flat').read()
    '@flattened@'


Command Line Interface
======================
there's also a command line interface to manipulate / view fasta files.
the `pyfasta` executable is installed via setuptools, running it will show
help text.

split a fasta file into 6 new files of relatively even size:

  $ pyfasta **split** -n 6 original.fasta

split the fasta file into one new file per header with "%(seqid)s" being filled into each filename.:
  
  $ pyfasta **split** --header "%(seqid)s.fasta" original.fasta

create 1 new fasta file with the sequence split into 10K-mers:

  $ pyfasta **split** -n 1 -k 10000 original.fasta

2 new fasta files with the sequence split into 10K-mers with 2K overlap:

  $ pyfasta **split** -n 2 -k 10000 -o 2000 original.fasta


show some info about the file (and show gc content):

  $ pyfasta **info** --gc test/data/three_chrs.fasta


**extract** sequence from the file. use the header flag to make
a new fasta file. the args are a list of sequences to extract.

  $ pyfasta **extract** --header --fasta test/data/three_chrs.fasta seqa seqb seqc

**extract** sequence from a file using a file containing the headers *not* wanted in the new file:

  $ pyfasta extract --header --fasta input.fasta --exclude --file seqids_to_exclude.txt

**extract** sequence from a fasta file with complex keys where we only want to lookup based on the part before the space.

  $ pyfasta extract --header --fasta input.with.keys.fasta --space --file seqids.txt

**flatten** a file inplace, for faster later use by pyfasta, and without creating another copy. (`Flattening`_)

  $ pyfasta flatten input.fasta 

cleanup 
=======
(though for real use these will remain for faster access)
::

    >>> os.unlink('tests/data/three_chrs.fasta.gdx')
    >>> os.unlink('tests/data/three_chrs.fasta.flat')

Testing
=======
there is currently > 99% test coverage for the 2 modules and all included 
record classes. to run the tests:
::

  $ python setup.py nosetests

Owner

  • Name: Brent Pedersen
  • Login: brentp
  • Kind: user
  • Location: Oregon, USA

Doing genomics

GitHub Events

Total
  • Watch event: 1
Last Year
  • Watch event: 1

Committers

Last synced: over 2 years ago

All Time
  • Total Commits: 49
  • Total Committers: 4
  • Avg Commits per committer: 12.25
  • Development Distribution Score (DDS): 0.551
Past Year
  • Commits: 0
  • Committers: 0
  • Avg Commits per committer: 0.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
brentp b****e@g****m 22
Matthew Ruffalo m****o@c****u 21
James Casbon j****n@p****m 3
James Boocock s****1@g****m 3
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 12 months ago

All Time
  • Total issues: 14
  • Total pull requests: 9
  • Average time to close issues: 13 days
  • Average time to close pull requests: about 10 hours
  • Total issue authors: 13
  • Total pull request authors: 4
  • Average comments per issue: 2.57
  • Average comments per pull request: 2.22
  • Merged pull requests: 8
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • brentp (2)
  • darked89 (1)
  • ian1roberts (1)
  • deannachurch (1)
  • vejnar (1)
  • tanghaibao (1)
  • osallou (1)
  • quacksawbones (1)
  • rmzelle (1)
  • ialbert (1)
  • jamescasbon (1)
  • mruffalo (1)
  • jdidion (1)
Pull Request Authors
  • mruffalo (5)
  • theboocock (2)
  • doctormo (1)
  • jamescasbon (1)
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • pypi 1,455 last-month
  • Total docker downloads: 93,745
  • Total dependent packages: 4
  • Total dependent repositories: 57
  • Total versions: 27
  • Total maintainers: 1
pypi.org: pyfasta

fast, memory-efficient, pythonic (and command-line) access to fasta sequence files

  • Versions: 27
  • Dependent Packages: 4
  • Dependent Repositories: 57
  • Downloads: 1,455 Last month
  • Docker Downloads: 93,745
Rankings
Docker downloads count: 1.0%
Dependent packages count: 1.8%
Dependent repos count: 2.0%
Average: 4.1%
Downloads: 4.8%
Stargazers count: 7.6%
Forks count: 7.7%
Maintainers (1)
Last synced: 12 months ago

Dependencies

setup.py pypi
  • Extra *