<commit_before>#!/usr/bin/env python
r"""
Sequence collections and alignments (:mod:`bipy.core.alignment`)
================================================================

.. currentmodule:: bipy.core.alignment

This module provides functionality for working with biological sequence
collections and alignments. These can be composed of generic sequences, 
nucelotide sequences, DNA sequences, and RNA sequences.

Classes
-------

.. autosummary::
   :toctree: generated/

   SequenceCollection
   Alignment

Examples
--------
>>> from bipy.core.alignment import SequenceCollection, Alignment
>>> from bipy.core.sequence import DNA

>>> seqs = [("s1", "ACC--G-GGTA.."), ("s2", "TCC--G-GGCA..")]
>>> a1 = Alignment(seqs, DNA)

>>> from bipy.parse.fasta import MinimalFastaParser
>>> fp = "/Users/caporaso/data/gg_13_8_otus/rep_set/79_otus.fasta"
>>> s1 = SequenceCollection(MinimalFastaParser(open(fp)), DNA)
>>> s1


"""
from __future__ import division

#-----------------------------------------------------------------------------
# Copyright (c) 2013--, bipy development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

import numpy as np

from bipy.core.exception import SequenceCollectionError


class SequenceCollection(object):
    """
    """

    def __init__(self, seqs, validate=False):
       """
       """
       self._data = seqs
       if validate and not self.is_valid():
           raise SequenceCollectionError(
               "Something is wrong, and it's your fault.")

    @classmethod
    def from_fasta_records(cls, fasta_records, seq_constructor,
            validate=False):
        """
        """
        data = []
        for seq_id, seq in fasta_records:
            try:
                identifier, description = seq_id.split(None, 1)
            except ValueError:
                identifier = seq_id.strip()
                description = None
            data.append(seq_constructor(seq, identifier=identifier,
              description=description))
 
        return cls(data, validate=validate)
    
    def __getitem__(self, index):
        """
        """
        return self._data[index]

    def __iter__(self):
        """
        """
        return iter(self._data)

#    def degap(self):
#        """
#        """
#        result = []
#        for 

    def items(self):
        """
        """
        for seq in self:
            yield seq.identifier, seq

    def __len__(self):
        """
        """
        return len(self._data)

    def __repr__(self):
        """The repr method.

        Returns
        -------
        str
            Returns a string representation of the object.

        Notes
        -----

        Examples
        --------

        """
        cn = self.__class__.__name__
        count, center, spread = self.count_center_spread() 
        return "<%s: n=%d; mean +/- std length=%.2f +/- %.2f>" % (cn, count,
                center, spread)

    def _validate_character_set(self):
        """
        """
        for seq in self:
            if not seq.is_valid():
                return False
        return True

    def count_center_spread(self, center_f=np.mean, spread_f=np.std):
        """
        """
        sequence_lengths = self.sequence_lengths()
        return (len(sequence_lengths), center_f(sequence_lengths),
                spread_f(sequence_lengths))

    def is_valid(self):
        """
        """
        return self._validate_character_set()

    def sequence_lengths(self):
        """
        """
        return [len(seq) for seq in self]

    def to_fasta(self):
        """
        """
        return ''.join([seq.to_fasta() for seq in self._data])


class Alignment(SequenceCollection):
    """
    """

    def _validate_lengths(self):
        """
        """
        seq1_length = len(self[0])
        for seq in self:
            if seq1_length != len(seq):
                return False
        return True

    def is_valid(self):
        """
        """
        result = super(Alignment, self).is_valid() or self._validate_lengths()

<commit_msg>improved documentation<commit_after>#!/usr/bin/env python
r"""
Sequence collections and alignments (:mod:`bipy.core.alignment`)
================================================================

.. currentmodule:: bipy.core.alignment

This module provides functionality for working with biological sequence
collections and alignments. These can be composed of generic sequences, 
nucelotide sequences, DNA sequences, and RNA sequences.

Classes
-------

.. autosummary::
   :toctree: generated/

   SequenceCollection
   Alignment

Examples
--------
>>> from bipy.core.alignment import SequenceCollection, Alignment
>>> from bipy.core.sequence import DNA

>>> seqs = [("s1", "ACC--G-GGTA.."), ("s2", "TCC--G-GGCA..")]
>>> a1 = Alignment(seqs, DNA)

>>> from bipy.parse.fasta import MinimalFastaParser
>>> fp = "/Users/caporaso/data/gg_13_8_otus/rep_set/79_otus.fasta"
>>> s1 = SequenceCollection.from_fasta_records(MinimalFastaParser(open(fp)), DNA)
>>> s1


"""
from __future__ import division

#-----------------------------------------------------------------------------
# Copyright (c) 2013--, bipy development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

import numpy as np

from bipy.core.exception import SequenceCollectionError


class SequenceCollection(object):
    """
    """

    def __init__(self, seqs, validate=False):
       """
       """
       self._data = seqs
       if validate and not self.is_valid():
           raise SequenceCollectionError(
               "Something is wrong, and it's your fault.")

    @classmethod
    def from_fasta_records(cls, fasta_records, seq_constructor,
            validate=False):
        """
        """
        data = []
        for seq_id, seq in fasta_records:
            try:
                identifier, description = seq_id.split(None, 1)
            except ValueError:
                identifier = seq_id.strip()
                description = None
            data.append(seq_constructor(seq, identifier=identifier,
              description=description))
 
        return cls(data, validate=validate)
    
    def __getitem__(self, index):
        """
        """
        return self._data[index]

    def __iter__(self):
        """
        """
        return iter(self._data)

#    def degap(self):
#        """
#        """
#        result = []
#        for 

    def items(self):
        """
        """
        for seq in self:
            yield seq.identifier, seq

    def __len__(self):
        """
        """
        return len(self._data)

    def __repr__(self):
        """The repr method.

        Returns
        -------
        str
            Returns a string representation of the object.

        Notes
        -----

        Examples
        --------

        """
        cn = self.__class__.__name__
        count, center, spread = self.count_center_spread() 
        return "<%s: n=%d; mean +/- std length=%.2f +/- %.2f>" % (cn, count,
                center, spread)

    def _validate_character_set(self):
        """
        """
        for seq in self:
            if not seq.is_valid():
                return False
        return True

    def count_center_spread(self, center_f=np.mean, spread_f=np.std):
        """
        """
        sequence_lengths = self.sequence_lengths()
        return (len(sequence_lengths), center_f(sequence_lengths),
                spread_f(sequence_lengths))

    def is_valid(self):
        """
        """
        return self._validate_character_set()

    def sequence_lengths(self):
        """
        """
        return [len(seq) for seq in self]

    def to_fasta(self):
        """
        """
        return ''.join([seq.to_fasta() for seq in self._data])


class Alignment(SequenceCollection):
    """
    """

    def _validate_lengths(self):
        """
        """
        seq1_length = len(self[0])
        for seq in self:
            if seq1_length != len(seq):
                return False
        return True

    def is_valid(self):
        """
        """
        result = super(Alignment, self).is_valid() or self._validate_lengths()


{'fraction_non_alphanumeric': 0.16944967074317968, 'fraction_numerical': 0.004703668861712135, 'mean_word_length': 1.824642975755563, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3704827', 'n_tokens_mistral': 2421, 'n_tokens_neox': 2270, 'n_words': 573}