pyfaidx

repository·master·Indexed 19 days ago

https://github.com/mdshw5/pyfaidx

A Python library for efficient random access to FASTA subsequences using Samtools-compatible indexing. It provides the Fasta and Faidx classes for sequence retrieval, slicing, and in-place modification via MutableFastaRecord. Key features include reverse complementing, GC content calculation, consensus sequence generation from VCF files via FastaVariant, and a faidx CLI tool for masking sequences. Supports 0-based slicing and provides utilities for parsing UCSC and BED region strings.

Tokens
7K
Snippets
20
Records
26
Agent score
66%

What's inside pyfaidx

  1. Overview of pyfaidx

    master

    pyfaidx is a Python module designed for fast random access to subsequences in FASTA files. It implements pure Python classes for indexing, retrieval, and in-place modification of FASTA files using a .fai index format that is compatible with Samtools' faidx function.

    Key features include:

    • Fast Random Access: Uses a small flat index file (.fai) to load minimal amounts of data into memory.
    • API Compatibility: Compatible with the pygr seqdb module.
    • CLI Tool: Includes a faidx command-line script for complex FASTA file manipulation without writing code.
  2. Install pyfaidx

    master

    You can install pyfaidx via PyPI using pip. The package is tested on Linux and macOS using Python 3.7+.

    To install for the current user (if you do not have root access):

    pip install pyfaidx

    Alternatively, you can download a release and install from the source directory:

    pip install .

    Note for Python 2 users: If you are using Python 2.6 or 2.7, you must use version v0.7.2 or earlier.

  3. Basic usage of the Fasta class

    master

    The Fasta class allows you to interact with FASTA files like a dictionary. You can access sequences by their names, slice them using Python's standard 0-based slicing, and retrieve various attributes from the resulting Sequence objects.

    Key behaviors:

    • Dictionary-like access: Use genes['name'] to get a sequence.
    • Slicing: Slicing coordinates are 0-based, consistent with Python strings.
    • Attributes: A sliced sequence object provides .seq (the string), .name (the sequence name), .start (1-based start), .end (0-based end), and .fancy_name (a formatted string like name:start-end).
    • Coordinate System: By default, .start is 1-based and .end is 0-based. You can change this to 0-based for both by passing one_based_attributes=False to the Fasta constructor.
    from pyfaidx import Fasta
    
    # Load the fasta file
    genes = Fasta('tests/data/genes.fasta')
    
    # Access a sequence and slice it (0-based slicing)
    seq_slice = genes['NM_001282543.1'][200:230]
    
    print(seq_slice.seq)      # 'CTCGTTCCGCGCCCGCCATGGAACCGGATG'
    print(seq_slice.name)     # 'NM_001282543.1'
    print(seq_slice.start)    # 201 (1-based)
    print(seq_slice.end)      # 230 (0-based)
    print(seq_slice.fancy_name) # 'NM_001282543.1:201-230'
  4. Modify FASTA files in-place using mutable=True

    master

    By default, Fasta objects are read-only. To modify the contents of your FASTA file in-place, pass mutable=True to the constructor. This returns MutableFastaRecord objects.

    Warning: Any changes made to a sequence via assignment will be written to the file immediately and permanently.

    from pyfaidx import Fasta
    
    # Enable in-place modification
    genes = Fasta('tests/data/genes.fasta', mutable=True)
    
    # Replace a segment with a new string of the same length
    genes['NM_001282543.1'][:10] = 'NNNNNNNNNN'
  5. Access FASTA files from remote filesystems via fsspec

    master

    You can access FASTA files stored on remote filesystems (like S3) by passing an fsspec file object to the Fasta constructor (new in v0.7.0).

    import fsspec
    from pyfaidx import Fasta
    
    # Open a file from S3 using fsspec
    of = fsspec.open("s3://broad-references/hg19/v0/Homo_sapiens_assembly19.fasta", anon=True)
    
    # Pass the file object to Fasta
    genes = Fasta(of)
  6. Configure PATH for the faidx CLI script

    master

    If you install pyfaidx using the --user flag, you must manually add the local bin directory to your $PATH to use the faidx command-line script.

    • Linux: Add /home/$USER/.local/bin to your $PATH.
    • macOS: Add /Users/$USER/Library/Python/{python version}/bin to your $PATH.
  7. Use read-ahead buffering for fast sequential access

    master

    To improve performance during sequential access (e.g., reading through a chromosome), you can use a read-ahead buffer by setting the read_ahead parameter in the Fasta constructor. This can reduce runtime by up to 1/2 for sequential accesses to buffered regions.

    from pyfaidx import Fasta
    
    # Initialize with a read-ahead buffer (e.g., 10,000 bases)
    genes = Fasta('tests/data/genes.fasta', read_ahead=10000)
    
    # Sequential access is now faster
    for i in range(0, 100000, 100):
        print(genes['NM_001282543.1'][i:i+100])
  8. How Faidx handles duplicate sequence names

    master

    When reading a FASTA file, if multiple entries result in the same key (after applying key_function), the duplicate_action parameter determines the behavior:

    • "stop": Raises a ValueError.
    • "first": Keeps only the first occurrence.
    • "last": Keeps only the last occurrence.
    • "longest": Keeps the sequence with the greatest length.
    • "shortest": Keeps the sequence with the smallest length.
    • "drop": Drops the duplicate key entirely.
  9. Customize indexing with key_function, split_char, and filt_function

    master

    When initializing Fasta, you can customize how sequences are indexed and accessed:

    • key_function: A callable used to transform the original FASTA header into the dictionary key used for access.
    • split_char: A character used to split names. This generates additional entries in the index for each part of the split name.
    • duplicate_action: Determines what to do if key_function or split_char creates duplicate keys. Options include "first", "longest" (new in v0.4.9), or "stop" (default).
    • filt_function: (New in v0.3.8) A callable that takes a name and returns True or False. Only names returning True are included in the index.
    from pyfaidx import Fasta
    
    # Using a custom key function
    genes = Fasta('tests/data/genes.fasta', key_function=lambda x: x.split('.')[0])
    
    # Splitting names and handling duplicates
    genes = Fasta('tests/data/genes.fasta', split_char="|", duplicate_action="longest")
    
    # Filtering the index
    genes = Fasta('tests/data/genes.fasta', filt_function=lambda x: x[0] == 'N')
  10. How FastaRecord and MutableFastaRecord work

    master

    A FastaRecord represents a single contig/chromosome from a FASTA file. It behaves like a sequence container:

    • Slicing: Supports __getitem__ with integers or slices. Slices return a Sequence object (or a string if as_raw=True was set in the parent Fasta object).
    • Iteration: __iter__ provides a line-based generator that respects the original file's line lengths.
    • Properties:
      • len(record): Returns the total length of the contig.
      • record.long_name: Returns the full defline (description) from the FASTA header.
      • record.unpadded_len: Returns the length of the contig excluding leading/trailing 'N' padding.
      • record.variant_sites: (Only for FastaVariant) Returns a tuple of SNP positions.

    MutableFastaRecord inherits from FastaRecord and adds __setitem__ support to allow in-place modification of the underlying file.

  11. Mask FASTA sequences via CLI

    master

    You can modify an existing FASTA file in-place using the faidx CLI to mask sequences.

    Masking Options:

    • --mask-with-default-seq: Replaces sequence content with the character provided in --default-seq (e.g., -s N).
    • --mask-by-case: Converts the sequence to lowercase.

    Note: Masking requires the FASTA file to be opened in mutable mode (handled internally by the CLI).

    # Mask regions in a BED file with 'N'
    faidx input.fasta --bed regions.bed --mask-with-default-seq -s N
    
    # Convert the entire file to lowercase
    faidx input.fasta --mask-by-case
  12. Perform DNA operations: complement and reverse complement

    master

    You can perform standard DNA operations on Sequence objects using .complement, .reverse, or the unary negation operator - for the reverse complement.

    from pyfaidx import Fasta
    
    genes = Fasta('tests/data/genes.fasta')
    segment = genes['NM_001282543.1'][200:230]
    
    # Complement
    print(segment.complement)
    
    # Reverse
    print(segment.reverse)
    
    # Reverse complement (using unary minus)
    print(-segment)