Source code for pylogeny.model

''' Phylogenetic tree scoring models; intended to be coupled with the use of 
pytbeaglehon (BEAGLE) high-performance library. '''

# Date:   Jun 9 2014
# Author: Alex Safatli
# E-mail: safatli@cs.dal.ca

# High-Performance Numeric Computation Library (pandas)

import pandas as P

# pytbeaglehon coupling

pytbeaglehonEnabled = True
try:
    import pytbeaglehon.disc_state_cont_time_model as BEAGLEModels
    from pytbeaglehon.disc_char_type import DNAType, AAType
    from pytbeaglehon.tests.util import TreeForTesting as BEAGLETree
except: pytbeaglehonEnabled = False

# Exception Handling

[docs]class PhyloModelError(Exception):
[docs] def __init__(self,v): self.value = v
def __str__(self): return repr(self.value) # Model a biological sequence as a discrete state model.
[docs]class DiscreteStateModel(object): ''' Initialize a discrete state model for phylogenetic data. State frequencies and character time are determined from the given alignment object. '''
[docs] def __init__(self,alignment): self.alignment = alignment self.charType = None self.stateList = None self.seqMatrix = None self.rawFreqMap = None self.rawFreqs = None self.stateFreqs = None self._totalFreq = 0.0 if pytbeaglehonEnabled: self._determineCharType() self._transformAlignmentToMatrix() self._determineStateFreqs() # Internals
def _determineCharType(self): ''' PRIVATE: Determine the character type intrinsic to the biological sequence alignment given to the instance. ''' a = self.alignment if (a.getDim() == 4): self.charType = DNAType() elif (a.getDim() >= 20 and a.getDim() <= 21): self.charType = AAType() else: raise PhyloModelError( 'Unrecognizable character type in alignment.') def _transformAlignmentToMatrix(self): ''' PRIVATE: Transform instance alignment to a matrix of states as integers. ''' lioflists = [] strList = map(str.upper,self.alignment.toStrList()) translate = self.charType.to_indices for l in strList: lioflists.append(translate(l)) self.stateList = lioflists self.seqMatrix = P.DataFrame(lioflists) def _determineStateFreqs(self): ''' PRIVATE: Compute the state frequencies for all states if character type is DNA. Otherwise, leave undefined. ''' if self.charType.get_num_states() != 4: return # DNAType? self.rawFreqMap = {} # Get all frequencies from the sequence matrix dataframe. freqS = self.seqMatrix.stack().value_counts() # Get all present states that are found in the dataframe. present = freqS.keys() # Get all possible states. states = self.charType.get_states() # Enumerate over all possible states. for state in states: i = self.charType.to_indices([state])[0] if i in present: self.rawFreqMap[state] = freqS.get(i) else: self.rawFreqMap[state] = 0 self.rawFreqs = self.rawFreqMap.items() # Flatten. # Calculate actual state frequencies. total = float(sum([i[1] for i in self.rawFreqs])) self._totalFreq = total self.stateFreqs = map(lambda x:x[1]/total,self.rawFreqs) # Accessors
[docs] def getAlignment(self): return self.alignment
[docs] def getAlignmentAsStateList(self): return self.stateList
[docs] def getSequenceMatrix(self): return self.seqMatrix
[docs] def getCharType(self): return self.charType
[docs] def getStateFreqs(self): return self.stateFreqs
[docs] def getRawStateFreqs(self): return self.rawFreqs
[docs] def getRawStateFreqsAsList(self): return self.getRawStateFreqs()
[docs] def getRawStateFreqsAsDict(self): return self.rawFreqMap
[docs] def getFrequencyOfState(self,i): if self.rawFreqMap: if i in self.rawFreqMap: return self.rawFreqMap[i]/self._totalFreq
[docs] def getRawFrequencyOfState(self,i): if self.rawFreqMap: if i in self.rawFreqMap: return self.rawFreqMap[i]