SeqLike - flexible biological sequence objects in Python

Overview

SeqLike - flexible biological sequence objects in Python

Introduction

A single object API that makes working with biological sequences in Python more ergonomic. It'll handle anything like a sequence.

Built around the Biopython SeqRecord class, SeqLikes abstract over the semantics of molecular biology (DNA -> RNA -> AA) and data structures (strings, Seqs, SeqRecords, numerical encodings) to allow manipulation of a biological sequence at the level which is most computationally convenient.

Code samples and examples

Build data-type agnostic functions

def f(seq: SeqLikeType, *args):
	seq = SeqLike(seq, seq_type="nt").to_seqrecord()
	# ...

Streamline conversion to/from ML friendly representations

prediction = model(aaSeqLike('MSKGEELFTG').to_onehot())
new_seq = ntSeqLike(generative_model.sample(), alphabet="-ACGTUN")

Interconvert between AA and NT forms of a sequence

Back-translation is conveniently built-in!

aa is well defined s_nt.aa()[0:3].nt() # ATGTCTAAA, works because SeqLike now has both reps s_nt[:-1].aa() # TypeError, len(s_nt) not a multiple of 3 s_aa = aaSeqLike("MSKGE") s_aa.nt() # AttributeError, aa->nt is undefined w/o codon map s_aa = aaSeqLike(s_aa, codon_map=random_codon_map) s_aa.nt() # now works, backtranslated to e.g. ATGTCTAAAGGTGAA s_aa[:1].nt() # ATG, codon_map is maintained">
s_nt = ntSeqLike("ATGTCTAAAGGTGAA")
s_nt[0:3] # ATG
s_nt.aa()[0:3] # MSK, nt->aa is well defined
s_nt.aa()[0:3].nt() # ATGTCTAAA, works because SeqLike now has both reps
s_nt[:-1].aa() # TypeError, len(s_nt) not a multiple of 3

s_aa = aaSeqLike("MSKGE")
s_aa.nt() # AttributeError, aa->nt is undefined w/o codon map
s_aa = aaSeqLike(s_aa, codon_map=random_codon_map)
s_aa.nt() # now works, backtranslated to e.g. ATGTCTAAAGGTGAA
s_aa[:1].nt() # ATG, codon_map is maintained

Easily plot multiple sequence alignments

seqs = [s for s in SeqIO.parse("file.fasta", "fasta")]
df = pd.DataFrame(
    {
        "names": [s.name for s in seqs],
        "seqs": [aaSeqLike(s) for s in seqs],
    }
)
df["aligned"] = df["seqs"].seq.align()
df["aligned"].seq.plot()

Flexibly build and parse numerical sequence representations

# Assume you have a dataframe with a column of 10 SeqLikes of length 90
df["seqs"].seq.to_onehot().shape # (10, 90, 23), padded if needed

To see more in action, please check out the docs!

Getting Started

pip install seqlike

Authors

Support

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Nasos Dousis

πŸ’»

andrew giessel

πŸ’»

Max Wall

πŸ’» πŸ“–

Eric Ma

πŸ’» πŸ“–

Mihir Metkar

πŸ€” πŸ’»

Marcus Caron

πŸ“–

This project follows the all-contributors specification. Contributions of any kind welcome!

Comments
  • Mutation class #57

    Mutation class #57

    This PR is ready for review.

    In this PR, we add in Mutation and MutationSet classes. The intent is to represent mutations made to a SeqLike. I've taken inspiration from multiple places, but the biggest one has been the discussion on #57.

    The use cases for this Mutation class are primarily two-fold:

    1. Adding them to a SeqLike returns another mutated SeqLike.
    2. Subtracting (diffing) a SeqLike from another yields a MutationSet.

    While working through use case 2, I noticed how it's a bit tricky:

    • adding a Mutation or MutationSet to a SeqLike results in a new SeqLike,
    • but subtracting the new SeqLike from the original SeqLike might not necessarily result in the original MutationSet,
    • yet adding the new MutationSet to the original SeqLike will give back a SeqLike identical to the new SeqLike.

    An example of this phenomena is shown in a new notebook, docs/notebooks/mutations.ipynb. For reviewing purposes, that is probably the go-to notebook for understanding what Mutation and MutationSet classes can do; the rest are implementation details.

    Would love to get feedback on this PR -- especially if there are semantics that I haven't yet thought of.


    TODO list of what's left:

    • [x] FIX TEST: SeqLike classes have two more class methods. Therefore, 77 is correct. Reference here.
    • [x] Add .positions class method, which returns a list of positions to mutate.
    • [x] Switch out magical_parse() for __new__() under Mutation.
    opened by ericmjl 6
  • [BUG] `seq_type` handling during instantiation

    [BUG] `seq_type` handling during instantiation

    I was playing around with the library (it was really nice and great job!) and hit this bug: instantiation like SeqLike('ATCGATC') or SeqLike('ATCGATC', None) will fail. From the doc: 1) seq_like is supposedly optional but is required in the implementation (code) and 2) logic regarding seq_like==None only occurs when sequence is a SeqLike (code) as opposed to a native type and thus seems not very useful? (There's a def determine__type() (code) that I think is intended for the job but it's not used.)

    In addition, some general comments regarding dispatch, feel free to ignore them if they are out of context: def _construct_seqlike share the same signature for alphabet and codon_map, and def determine__type_and_alphabet share same signature for seq_type and sequence. Thus it seems clearer to extract the only signature that varies? E.g. for the latter case we only dispatch functions based on alphabet (or even directly use if alphabet==None: alphabet=determine_alphabet(_type, sequence) rather than dispatching). Current setup for these two functions seems to create duplicate logics and is error prone (types for sequence here should be the same?)

    Again, happy to file a PR for anything specific above.

    opened by pagpires 5
  • noqa in documentation

    noqa in documentation

    Hi team, thanks for creating this tool, it looks really nice!

    Just a question regarding #noqa: DAR201: it's generated in the doc in quite a few places (e.g. https://modernatx.github.io/seqlike/reference/seqlike/#seqlike.SeqLike.SeqLike.deepcopy--noqa-dar101). I've tested that it can successfully be ommited via wrapping with <!-- --> (ref). Curious if the team likes the fix? Happy to submit a MR.

    opened by pagpires 5
  • Adding Damien Farrell as a contributor

    Adding Damien Farrell as a contributor

    As mentioned by @ndousis in an earlier email thread, some of @dmnfarrell's code made it into this library. We would like to acknowledge @dmnfarrell as a contributor in the codebase.

    @dmnfarrell is this something you would be amenable to? I would essentially ask the all-contributors bot to add your contribution in.

    opened by ericmjl 4
  • Prepending a string to a SeqLike

    Prepending a string to a SeqLike

    Prepending a string to SeqLike results unexpectedly in an appended version:

    In [1]: from seqlike import SeqLike
    
    In [2]: "ACTG" + SeqLike("TTTT", "nt", id="test")
    Out[2]: 
    *** NT: SeqRecord(seq=Seq('TTTTACTG'), id='test', name='<unknown name>', description='<unknown description>', dbxrefs=[]) 
    

    This should either (1) result in an error ("cannot prepend a string to a SeqLike"), or (2) yield a new SeqLike with the metadata of the parent SeqLike and the correctly-ordered sequence string ("ACTGTTTT"). If the latter, should this new SeqLike be renumbered?

    opened by ndousis 3
  • Feature/create sequence like

    Feature/create sequence like

    As discussed in #49. The naming here is because we inherit from the collections abstract base class of Sequence. Seqs are coupled to Biopython, Sequences are more generic.

    Needs new tests and some documentation, just want to pause here for general feedback and workflow testing.

    All current tests pass.

    edit for usage:

    In [1]: from seqlike.SequenceLike import SequenceLike
    
    In [2]: s = SequenceLike(["abc", "abc", "qwe", "asd"])
    
    In [3]: s
    Out[3]: ['abc', 'abc', 'qwe', 'asd']
    
    In [4]: s.to_index()
    Out[4]: array([0., 0., 2., 1.])
    
    In [5]: s.to_onehot()
    Out[5]: 
    array([[1., 0., 0.],
           [1., 0., 0.],
           [0., 0., 1.],
           [0., 1., 0.]])
    
    In [6]: s.alphabet
    Out[6]: ['abc', 'asd', 'qwe']
    
    In [9]: s2 = SequenceLike([0, 0, 2, 1], alphabet=["abc", "asd", "qwe"], encoding='index')
    
    In [10]: s2
    Out[10]: array(['abc', 'abc', 'qwe', 'asd'], dtype=object)
    
    
    opened by andrewgiessel 3
  • Dispatch based on SeqLikeType.__args__

    Dispatch based on SeqLikeType.__args__

    Also a quick note: when dispatching for SeqLike, I guess we can use SeqLikeType.__args__ as the type instead of hardcoding a list of potential types, otherwise it's hard to keep them consistent (since I saw there's a plan to include torch.tensor)

    Originally posted by @pagpires in https://github.com/modernatx/seqlike/issues/41#issuecomment-1000942209

    good first issue help wanted 
    opened by ericmjl 3
  • Simplify .aa() interface, return original SeqRecord attributes

    Simplify .aa() interface, return original SeqRecord attributes

    Removed **kwargs from SeqLike aa, and hard-coded arguments in the call to self.translate so as to return original attributes like id and name. This is the behavior I would expect from aa().

    I left the interface to SeqLike translate as is to maintain flexibility.

    Closes #25

    opened by ndousis 3
  • Add missing setup.py deps, add notebook extras, and move test deps to extras

    Add missing setup.py deps, add notebook extras, and move test deps to extras

    I had a couple import errors (see below) when testing this package out that are related to undeclared dependencies in setup.py. Some were in requirements.txt, but not declared in setup.py's install_requires, so I moved them all to setup.py and removed requirements.txt (so this doesn't happen again :crossed_fingers:).

    I also added 2 extras:

    • seqlike[test]: this has the pytest* deps (which I removed from the main install_requires)
    • seqlike[notebook]: adds bokeh, which is (currently) required when using ipython/jupyter (I think there were some refactors to make bokeh a lazy import, but it is still imported eagerly/required in notebooks)

    Here are the errors I saw:

    .../lib/python3.7/site-packages/seqlike/SeqLike.py in <module>
          9 from typing import Callable, Optional, Union
         10
    ---> 11 import lazy_loader as lazy
         12
         13 from Bio.Seq import Seq
    
    ModuleNotFoundError: No module named 'lazy_loader'
    
    .../lib/python3.7/site-packages/seqlike/draw_utils.py in <module>
         19 try:
         20     get_ipython
    ---> 21     from bokeh.io import output_notebook
         22
         23     output_notebook()
    
    ModuleNotFoundError: No module named 'bokeh'
    
    opened by JacobHayes 2
  • add commandline wrapper function for Muscle 3.8 #24

    add commandline wrapper function for Muscle 3.8 #24

    The wrapper function muscle_alignment permits alignment using Muscle 3.8:

    from seqlike.alignment_commands import muscle_alignment
    
    sequences.seq.align(aligner=muscle_alignment, muscle_arg1=something, muscle_arg2=something)
    

    and addresses #24. All tests pass except tests/test_assets.py::test_free_mono_font_exists. Two notes:

    1. the latest version of Muscle is v5.1 and has a different interface than v3.8; MuscleCommandline is compatible with v3.8.
    2. the preserve_order parameter (preserves original sequence order, as aligner may try to group sequences by similarity) may still be buggy.
    opened by ndousis 2
  • Support arbitrary alphabets

    Support arbitrary alphabets

    It'd be nice to support arbitrary alphabets for sequences that are not necessarily string-type. For e.g. we may want to do sequence of codons, or sequence of other entities.

    Doing so would allow us to access the to_onehot() or to_index() capabilities of SeqLike objects without necessarily being bound to BioPython SeqRecord/Seq objects.

    Potential challenges:

    1. We would break the "default to SeqRecords pair" that we assume in SeqLike. A list of codons is neither!
    2. We may need to rearchitect the SeqLike object such that there is a .sequence and .alphabet, which the encoder functions expect (?). .to_*() functions.
    3. We may need a more generic SeqLike object from which our current SeqLikes inherit.

    A good concrete first step here is to create an Abstract Base Class for discussion purposes.

    enhancement high-priority 
    opened by ericmjl 2
  • Objects to represent mutations

    Objects to represent mutations

    I've encountered the situation where we need to represent mutations of a sequence. Having written essentially the same code over and over, I thought it might be good to talk about some of these ideas here.

    I was thinking of something along the lines of two classes: a Mutation and a MutationSet. Defining them as classes allows for certain semantics:

    s = SeqLike('MKAIL')
    mut = Mutation('A', 2, 'C')
    # mut's repr would look like A3C
    mut2 = Mutation('K', 1, 'R')
    

    We may consider 'addition' to be an application of mutations to a reference sequence:

    s2 = s + mut
    # s2 <-- SeqLike('MKCIL')
    
    s2 = s + mut2
    # s2 <-- SeqLike('MRAIL')
    

    Mutations can also be offset by position:

    mut3 = mut - 1
    # mut3 <-- A1C, but would raise an error if wt sequence does not have A at index 1.
    

    If we need to hold multiple mutations together, we might use a MutationSet:

    mutations = MutationSet([mut, mut2])
    # mutations <-- [K1R, A2C] (automatically sorted by position, then by letter)
    s2 = s + mutations
    # s2 <-- SeqLike('MRCIL')
    

    MutationSets could also be offset by position:

    mutations + 1  # would give us [K2R, A3C]
    

    We could also consider subtraction of two SeqLikes to give us the 'diff' as a MutationSet:

    mutset = s2 - s1  # (left is canonically considered the 'wt')
    # mutset <-- [R1K, C2A]
    mutset = s1 - s2 
    # mutset <-- [K1R, A2C]
    

    I'm not sure what other semantics I might have missed here. Any thoughts?

    UPDATE: I changed the position numbers above to reflect Python indexing rules, not canonical indexing. I am sure we could magically handle both, but IMO because SeqLike uses Python indexing rules, Mutations and MutationSets should also use Python indexing rules for positions.

    opened by ericmjl 4
  • Adjusting alignment parameters?

    Adjusting alignment parameters?

    I have a need to adjust alignment parameters; for example, I have encountered something akin to this issue, and the proposed solution from the author of MAFFT is to adjust one of the MAFFT parameters.

    Adjusting alignment parameters via the .seq.align() API might be helpful. A few designs for the user-facing API that I can think of include:

    # default aligner is MAFFT, so we can pass through the command line options via kwargs.
    sequences.seq.align(ep=1.59, op=0.0)
    
    # want to use MUSCLE instead of MAFFT
    from seqlike.AlignCommandLine import MuscleCommandLine as muscle
    sequences.seq.align(aligner=muscle, muscle_arg1=something, muscle_arg2=something)
    
    enhancement low-priority 
    opened by ericmjl 1
  • Add all-contributors bot

    Add all-contributors bot

    We should ensure that all contributions are recognized. Following the all contributors spec, we should use the bot to help recognize contributors of all kinds to the project.

    https://allcontributors.org/

    opened by ericmjl 26
Releases(v1.3.4)
Datamol is a python library to work with molecules

Datamol is a python library to work with molecules. It's a layer built on top of RDKit and aims to be as light as possible.

datamol 276 Dec 19, 2022
A simple computer program made with Python on the brachistochrone curve.

Brachistochrone-curve This is a simple computer program made with Python on the brachistochrone curve. I decided to write it after a physics lesson on

Diego Romeo 1 Dec 16, 2021
Veusz scientific plotting application

Veusz 3.3.1 Veusz is a scientific plotting package. It is designed to produce publication-ready PDF or SVG output. Graphs are built-up by combining pl

Veusz 613 Dec 16, 2022
artisan: visual scope for coffee roasters

Artisan Visual scope for coffee roasters WARNING: pre-release builds may not work. Use at your own risk. Summary Artisan is a software that helps coff

Artisan – Visual Scope for Coffee Roasters 705 Jan 05, 2023
CONCEPT (COsmological N-body CodE in PyThon) is a free and open-source simulation code for cosmological structure formation

CONCEPT (COsmological N-body CodE in PyThon) is a free and open-source simulation code for cosmological structure formation. The code should run on any Linux system, from massively parallel computer

Jeppe Dakin 62 Dec 08, 2022
OPEM (Open Source PEM Fuel Cell Simulation Tool)

Table of contents What is PEM? Overview Installation Usage Executable Library Telegram Bot Try OPEM in Your Browser! MATLAB Issues & Bug Reports Contr

ECSIM 133 Jan 04, 2023
🍊 :bar_chart: :bulb: Orange: Interactive data analysis

Orange Data Mining Orange is a data mining and visualization toolbox for novice and expert alike. To explore data with Orange, one requires no program

Bioinformatics Laboratory 3.9k Jan 05, 2023
CKAN is an open-source DMS (data management system) for powering data hubs and data portals. CKAN makes it easy to publish, share and use data. It powers catalog.data.gov, open.canada.ca/data, data.humdata.org among many other sites.

CKAN: The Open Source Data Portal Software CKAN is the world’s leading open-source data portal platform. CKAN makes it easy to publish, share and work

ckan 3.6k Dec 27, 2022
Discontinuous Galerkin finite element method (DGFEM) for Maxwell Equations

DGFEM Maxwell Equations Discontinuous Galerkin finite element method (DGFEM) for Maxwell Equations. Work in progress. Currently, the 1D Maxwell equati

Rafael de la Fuente 9 Aug 16, 2022
Efficient Python Tricks and Tools for Data Scientists

Why efficient Python? Because using Python more efficiently will make your code more readable and run more efficiently.

Khuyen Tran 944 Dec 28, 2022
A flexible package manager that supports multiple versions, configurations, platforms, and compilers.

Spack Spack is a multi-platform package manager that builds and installs multiple versions and configurations of software. It works on Linux, macOS, a

Spack 3.1k Dec 31, 2022
3D medical imaging reconstruction software

InVesalius InVesalius generates 3D medical imaging reconstructions based on a sequence of 2D DICOM files acquired with CT or MRI equipments. InVesaliu

443 Jan 01, 2023
Algorithms covered in the Bioinformatics Course part of the Cambridge Computer Science Tripos

Bioinformatics This is a repository of all the algorithms covered in the Bioinformatics Course part of the Cambridge Computer Science Tripos Algorithm

16 Jun 30, 2022
ReproZip is a tool that simplifies the process of creating reproducible experiments from command-line executions, a frequently-used common denominator in computational science.

ReproZip ReproZip is a tool aimed at simplifying the process of creating reproducible experiments from command-line executions, a frequently-used comm

267 Jan 01, 2023
An interactive explorer for single-cell transcriptomics data

an interactive explorer for single-cell transcriptomics data cellxgene (pronounced "cell-by-gene") is an interactive data explorer for single-cell tra

Chan Zuckerberg Initiative 424 Dec 15, 2022
collection of interesting Computer Science resources

collection of interesting Computer Science resources

Kirill Bobyrev 137 Dec 22, 2022
Incubator for useful bioinformatics code, primarily in Python and R

Collection of useful code related to biological analysis. Much of this is discussed with examples at Blue collar bioinformatics. All code, images and

Brad Chapman 560 Dec 24, 2022
Float2Binary - A simple python class which finds the binary representation of a floating-point number.

Float2Binary A simple python class which finds the binary representation of a floating-point number. You can find a class in IEEE754.py file with the

Bora Canbula 3 Dec 14, 2021
Book on Julia for Data Science

Book on Julia for Data Science

Julia Data Science 349 Dec 25, 2022
Doing bayesian data analysis - Python/PyMC3 versions of the programs described in Doing bayesian data analysis by John K. Kruschke

Doing_bayesian_data_analysis This repository contains the Python version of the R programs described in the great book Doing bayesian data analysis (f

Osvaldo Martin 851 Dec 27, 2022