GitHub PullRequestReviewCommentEvent at 2014-03-18 04:48:25
Repository: scikit-bio
Actor: ElDeveloper
Payload: {"comment":{"url":"https://api.github.com/repos/biocore/scikit-bio/pulls/comments/10690483","id":10690483,"diff_hunk":"@@ -0,0 +1,1295 @@\n+#!/usr/bin/env python\n+r\"\"\"\n+Sequence collections and alignments (:mod:`skbio.core.alignment`)\n+=================================================================\n+\n+.. currentmodule:: skbio.core.alignment\n+\n+This module provides functionality for working with biological sequence\n+collections and alignments. These can be composed of generic sequences,\n+nucelotide sequences, DNA sequences, and RNA sequences. By default, input is\n+not validated, expect that sequence identifiers must be unique, but all\n+contructor methods take a validate option which checks different features of\n+the input based on `SequenceCollection` type.\n+\n+Classes\n+-------\n+\n+.. autosummary::\n+   :toctree: generated/\n+\n+   SequenceCollection\n+   Alignment\n+\n+Examples\n+--------\n+>>> from StringIO import StringIO\n+>>> from skbio.core.alignment import SequenceCollection, Alignment\n+>>> from skbio.core.sequence import DNA\n+\n+>>> seqs = [DNA(\"ACC--G-GGTA..\", identifier=\"seq1\"),\n+...     DNA(\"TCC--G-GGCA..\", identifier=\"seqs2\")]\n+>>> a1 = Alignment(seqs)\n+>>> a1\n+<Alignment: n=2; mean +/- std length=13.00 +/- 0.00>\n+\n+>>> seqs = [DNA(\"ACCGGG\", identifier=\"seq1\"),\n+...     DNA(\"TCCGGGCA\", identifier=\"seq2\")]\n+>>> s1 = SequenceCollection(seqs)\n+>>> s1\n+<SequenceCollection: n=2; mean +/- std length=7.00 +/- 1.00>\n+\n+>>> from skbio.parse.sequences import parse_fasta\n+>>> fasta_f = StringIO('>seq1\\n'\n+...                    'CGATGTCGATCGATCGATCGATCAG\\n'\n+...                    '>seq2\\n'\n+...                    'CATCGATCGATCGATGCATGCATGCATG\\n')\n+>>> s1 = SequenceCollection.from_fasta_records(parse_fasta(fasta_f), DNA)\n+>>> s1\n+<SequenceCollection: n=2; mean +/- std length=26.50 +/- 1.50>\n+\n+\"\"\"\n+from __future__ import division\n+\n+#-----------------------------------------------------------------------------\n+# Copyright (c) 2013--, scikit-bio development team.\n+#\n+# Distributed under the terms of the Modified BSD License.\n+#\n+# The full license is in the file COPYING.txt, distributed with this software.\n+#-----------------------------------------------------------------------------\n+\n+from collections import Counter, defaultdict\n+\n+import numpy as np\n+\n+from scipy.stats import entropy\n+\n+from skbio.core.exception import SequenceCollectionError\n+from skbio.core.distance import SymmetricDistanceMatrix\n+\n+\n+class SequenceCollection(object):\n+    \"\"\"Class for storing collections of biological sequences.\n+    \"\"\"\n+\n+    @classmethod\n+    def from_fasta_records(cls, fasta_records, seq_constructor,\n+                           validate=False):\n+        r\"\"\"Initialize a `SequenceCollection` object\n+\n+        Parameters\n+        ----------\n+        fasta_records : generator of tuples\n+            The records to load into a new `SequenceCollection` object. These\n+            should be tuples of ``(sequence_identifier, sequence)``.\n+        seq_constructor : skbio.core.sequence.BiologicalSequence\n+        validate : bool, optional\n+            If True, runs the `is_valid` method after construction and raises\n+            `SequenceCollectionError` if ``is_valid == False``.\n+\n+        Results\n+        -------\n+        SequenceCollection (or a derived class)\n+            The new `SequenceCollection` object.\n+\n+        Raises\n+        ------\n+        skbio.core.exception.SequenceCollectionError\n+            If ``validate == True`` and ``is_valid == False``.\n+\n+        See Also\n+        --------\n+        skbio.core.sequence.BiologicalSequence\n+        skbio.core.sequence.NucelotideSequence\n+        skbio.core.sequence.DNASequence\n+        skbio.core.sequence.RNASequence\n+        SequenceCollection\n+        Alignment\n+        skbio.parse.sequences\n+        skbio.parse.sequences.parse_fasta\n+\n+        Examples\n+        --------\n+        >>> from skbio.core.alignment import SequenceCollection\n+        >>> from skbio.parse.sequences import parse_fasta\n+        >>> from StringIO import StringIO\n+        >>> from skbio.core.sequence import DNA\n+        >>> fasta_f = StringIO('>seq1\\nACCGT\\n>seq2\\nAACCGGT\\n')\n+        >>> s1 = SequenceCollection.from_fasta_records(\n+        ...     parse_fasta(fasta_f), DNA)\n+        >>> s1\n+        <SequenceCollection: n=2; mean +/- std length=6.00 +/- 1.00>\n+\n+        >>> records = [('seq1', 'ACCGT'), ('seq2', 'AACCGGT')]\n+        >>> s1 = SequenceCollection.from_fasta_records(records, DNA)\n+        >>> s1\n+        <SequenceCollection: n=2; mean +/- std length=6.00 +/- 1.00>\n+\n+        \"\"\"\n+        data = []\n+        for seq_id, seq in fasta_records:\n+            try:\n+                identifier, description = seq_id.split(None, 1)\n+            except ValueError:\n+                identifier = seq_id.strip()\n+                description = None\n+            data.append(seq_constructor(seq, identifier=identifier,\n+                                        description=description))\n+\n+        return cls(data, validate=validate)\n+\n+    def __init__(self, seqs, validate=False):\n+        r\"\"\"Initialize a `SequenceCollection` object\n+\n+        Parameters\n+        ----------\n+        seqs : list of `skbio.core.sequence.BiologicalSequence` objects\n+            The `skbio.core.sequence.BiologicalSequence` objects to load into\n+            a new `SequenceCollection` object.\n+        validate : bool, optional\n+            If True, runs the `is_valid` method after construction and raises\n+            `SequenceCollectionError` if ``is_valid == False``.\n+\n+        Results\n+        -------\n+        SequenceCollection (or a derived class)\n+            The new `SequenceCollection` object.\n+\n+        Raises\n+        ------\n+        skbio.core.exception.SequenceCollectionError\n+            If ``validate == True`` and ``is_valid == False``.\n+\n+        See Also\n+        --------\n+        skbio.core.sequence.BiologicalSequence\n+        skbio.core.sequence.NucelotideSequence\n+        skbio.core.sequence.DNASequence\n+        skbio.core.sequence.RNASequence\n+        SequenceCollection\n+        Alignment\n+        skbio.parse.sequences\n+        skbio.parse.sequences.parse_fasta\n+\n+        Examples\n+        --------\n+        >>> from skbio.core.alignment import SequenceCollection\n+        >>> from skbio.core.sequence import DNA\n+        >>> sequences = [DNA('ACCGT', identifier=\"seq1\"),\n+        ...              DNA('AACCGGT', identifier=\"seq2\")]\n+        >>> s1 = SequenceCollection(sequences)\n+        >>> s1\n+        <SequenceCollection: n=2; mean +/- std length=6.00 +/- 1.00>\n+\n+        \"\"\"\n+        self._data = seqs\n+        self._identifier_to_index = {}\n+        for i, seq in enumerate(self._data):\n+            identifier = seq.identifier\n+            if identifier in self._identifier_to_index:\n+                raise SequenceCollectionError(\n+                    \"All sequence identifiers must be unique, but \"\n+                    \"identifier %s is present multiple times.\" % identifier)\n+            else:\n+                self._identifier_to_index[seq.identifier] = i\n+\n+        # This is bad because we're making a second pass through the sequence\n+        # collection to validate. We'll want to avoid this, but it's tricky\n+        # because different subclasses will want to define their own is_valid\n+        # methods.\n+        if validate and not self.is_valid():\n+            raise SequenceCollectionError(\n+                \"%s failed to validate.\" % self.__class__.__name__)\n+\n+    def __eq__(self, other):\n+        r\"\"\"The equality operator.\n+\n+        Parameters\n+        ----------\n+        other : `SequenceCollection`\n+            The sequence collection to test for equality against.\n+\n+        Returns\n+        -------\n+        bool\n+            Indicates whether `self` and `other` are equal.\n+\n+        Notes\n+        -----\n+        `SequenceCollection` objects are equal if they are the same type,\n+        contain the same number of sequences, and if each of the\n+        `skbio.core.sequence.BiologicalSequence` objects, in order, are equal.\n+\n+        \"\"\"\n+        if self.__class__ != other.__class__:\n+            return False\n+        elif len(self) != len(other):\n+            return False\n+        else:\n+            for self_seq, other_seq in zip(self, other):\n+                if self_seq != other_seq:\n+                    return False\n+        return True\n+\n+    def __getitem__(self, index):\n+        r\"\"\"The indexing operator.\n+\n+        Parameters\n+        ----------\n+        index : int, str\n+            The position or sequence identifier of the\n+            `skbio.core.sequence.BiologicalSequence` to return from the\n+            `SequenceCollection`.\n+\n+        Returns\n+        -------\n+        str\n+            The `skbio.core.sequence.BiologicalSequence` at the specified\n+            index in the `SequenceCollection`.\n+\n+        Examples\n+        --------\n+        >>> from skbio.core.alignment import SequenceCollection\n+        >>> from skbio.core.sequence import DNA\n+        >>> sequences = [DNA('ACCGT', identifier=\"seq1\"),\n+        ...              DNA('AACCGGT', identifier=\"seq2\")]\n+        >>> s1 = SequenceCollection(sequences)\n+        >>> s1[0]\n+        <DNASequence: ACCGT (length: 5)>\n+        >>> s1[\"seq1\"]\n+        <DNASequence: ACCGT (length: 5)>\n+\n+        \"\"\"\n+        if isinstance(index, str):\n+            return self.get_seq(index)\n+        else:\n+            return self._data[index]\n+\n+    def __iter__(self):\n+        r\"\"\"The iter operator.\n+\n+        Returns\n+        -------\n+        iterator\n+            `skbio.core.sequence.BiologicalSequence` iterator for the\n+            `SequenceCollection`.\n+\n+        \"\"\"\n+        return iter(self._data)\n+\n+    def __len__(self):\n+        r\"\"\"The len operator.\n+\n+        Returns\n+        -------\n+        int\n+            The number of sequences in the `SequenceCollection`.\n+\n+        \"\"\"\n+        return self.sequence_count()\n+\n+    def __ne__(self, other):\n+        r\"\"\"The inequality operator.\n+\n+        Parameters\n+        ----------\n+        other : `SequenceCollection`\n+\n+        Returns\n+        -------\n+        bool\n+            Indicates whether self and other are not equal.\n+\n+        Notes\n+        -----\n+        See `SequenceCollection.__eq__` for a description of what it means for\n+        a pair of `SequenceCollection` objects to be equal.\n+\n+        \"\"\"\n+        return not self.__eq__(other)\n+\n+    def __repr__(self):\n+        r\"\"\"The repr method.\n+\n+        Returns\n+        -------\n+        str\n+            Returns a string representation of the object.\n+\n+        Notes\n+        -----\n+        String representation contains the class name, the number of sequences\n+        in the `SequenceCollection` (n), and the mean and standard deviation\n+        sequence length.\n+\n+        Examples\n+        --------\n+        >>> from skbio.core.alignment import SequenceCollection\n+        >>> from skbio.core.sequence import DNA\n+        >>> sequences = [DNA('ACCGT', identifier=\"seq1\"),\n+        ...              DNA('AACCGGT', identifier=\"seq2\")]\n+        >>> s1 = SequenceCollection(sequences)\n+        >>> print repr(s1)\n+        <SequenceCollection: n=2; mean +/- std length=6.00 +/- 1.00>\n+\n+        \"\"\"\n+        cn = self.__class__.__name__\n+        count, center, spread = self.count_center_spread()\n+        return \"<%s: n=%d; mean +/- std length=%.2f +/- %.2f>\" \\\n+            % (cn, count, center, spread)\n+\n+    def count_center_spread(self, center_f=np.mean, spread_f=np.std):\n+        r\"\"\"Return sequence count, and center and spread of sequence lengths\n+\n+        Parameters\n+        ----------\n+        center_f : function\n+            Should take a list-like object and return a single value\n+            representing the center of the distribution.\n+        spread_f : function\n+            Should take a list-like object and return a single value\n+            representing the spread of the distribution.\n+\n+        Return\n+        ------\n+        tuple\n+            The sequence count, center of length distribution, spread of length\n+            distribution.\n+\n+        Notes\n+        -----\n+        Alternatives for center_f and spread_f could be median and median\n+        absolute deviation.\n+\n+        Examples\n+        --------\n+        >>> from skbio.core.alignment import SequenceCollection\n+        >>> from skbio.core.sequence import DNA\n+        >>> sequences = [DNA('ACCGT', identifier=\"seq1\"),\n+        ...              DNA('AACCGGT', identifier=\"seq2\")]\n+        >>> s1 = SequenceCollection(sequences)\n+        >>> count, center, spread = s1.count_center_spread()\n+        >>> print count\n+        2\n+        >>> print center\n+        6.0\n+        >>> print spread\n+        1.0\n+\n+        \"\"\"\n+        sequence_lengths = self.sequence_lengths()\n+        return (len(sequence_lengths), center_f(sequence_lengths),\n+                spread_f(sequence_lengths))\n+\n+    def degap(self):\n+        r\"\"\"Return a new `SequenceCollection` with all gap characters removed.\n+\n+        Returns\n+        -------\n+        SequenceCollection\n+            A new `SequenceCollection` where\n+            `skbio.core.sequence.BiologicalSequence.degap` has been called on\n+            each sequence.\n+\n+        Examples\n+        --------\n+        >>> from skbio.core.alignment import SequenceCollection\n+        >>> from skbio.core.sequence import DNA\n+        >>> sequences = [DNA('A--CCGT.', identifier=\"seq1\"),\n+        ...              DNA('.AACCG-GT.', identifier=\"seq2\")]\n+        >>> s1 = SequenceCollection(sequences)\n+        >>> s2 = s1.degap()\n+        >>> print s2[0]\n+        ACCGT\n+        >>> print s2[1]\n+        AACCGGT\n+\n+        \"\"\"\n+        result = []\n+        for seq in self:\n+            result.append(seq.degap())\n+        return SequenceCollection(result)\n+\n+    def get_seq(self, identifier):\n+        r\"\"\"Return a sequence from the `SequenceCollection` by its identifier.\n+\n+        Parameters\n+        ----------\n+        identifier, str\n+            The identifier of the sequence to return.\n+\n+        Returns\n+        -------\n+        skbio.core.sequence.BiologicalSequence\n+            The `skbio.core.sequence.BiologicalSequence` with `identifier`.\n+\n+        Raises\n+        ------\n+        KeyError\n+            If `identifier` is not in the `SequenceCollection` object.\n+\n+        Examples\n+        --------\n+        >>> from skbio.core.alignment import SequenceCollection\n+        >>> from skbio.core.sequence import DNA\n+        >>> sequences = [DNA('A--CCGT.', identifier=\"seq1\"),\n+        ...              DNA('.AACCG-GT.', identifier=\"seq2\")]\n+        >>> s1 = SequenceCollection(sequences)\n+        >>> print s1['seq1']\n+        A--CCGT.\n+\n+        \"\"\"\n+        return self[self._identifier_to_index[identifier]]\n+\n+    def identifiers(self):\n+        \"\"\"Returns the `BiologicalSequence` idenitfiers","path":"skbio/core/alignment.py","position":446,"original_position":446,"commit_id":"4d83ab3399eeeb71de246b58bf73892f3f7206cb","original_commit_id":"4d83ab3399eeeb71de246b58bf73892f3f7206cb","user":{"login":"ElDeveloper","id":375307,"avatar_url":"https://avatars.githubusercontent.com/u/375307?","gravatar_id":"5ee33edf9eb551a3756365466dd91075","url":"https://api.github.com/users/ElDeveloper","html_url":"https://github.com/ElDeveloper","followers_url":"https://api.github.com/users/ElDeveloper/followers","following_url":"https://api.github.com/users/ElDeveloper/following{/other_user}","gists_url":"https://api.github.com/users/ElDeveloper/gists{/gist_id}","starred_url":"https://api.github.com/users/ElDeveloper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ElDeveloper/subscriptions","organizations_url":"https://api.github.com/users/ElDeveloper/orgs","repos_url":"https://api.github.com/users/ElDeveloper/repos","events_url":"https://api.github.com/users/ElDeveloper/events{/privacy}","received_events_url":"https://api.github.com/users/ElDeveloper/received_events","type":"User","site_admin":false},"body":"idenitfires -> identifiers.","created_at":"2014-03-18T04:48:25Z","updated_at":"2014-03-18T04:48:25Z","html_url":"https://github.com/biocore/scikit-bio/pull/195#discussion_r10690483","pull_request_url":"https://api.github.com/repos/biocore/scikit-bio/pulls/195","_links":{"self":{"href":"https://api.github.com/repos/biocore/scikit-bio/pulls/comments/10690483"},"html":{"href":"https://github.com/biocore/scikit-bio/pull/195#discussion_r10690483"},"pull_request":{"href":"https://api.github.com/repos/biocore/scikit-bio/pulls/195"}}}}