Package Bio :: Package PopGen :: Package FDist
[hide private]
[frames] | no frames]

Source Code for Package Bio.PopGen.FDist

  1  # Copyright 2007 by Tiago Antao <tiagoantao@gmail.com>.  All rights reserved. 
  2  # This code is part of the Biopython distribution and governed by its 
  3  # license.  Please see the LICENSE file that should have been included 
  4  # as part of this package. 
  5   
  6   
  7  """ 
  8  This module provides code to work with FDist. 
  9   
 10  See http://www.rubic.rdg.ac.uk/~mab/software.html . 
 11   
 12  Classes: 
 13  Record           Holds FDist data. 
 14  RecordParser     Parses a FDist record (file) into a Record object. 
 15   
 16  _Scanner         Scans a FDist record. 
 17  _RecordConsumer  Consumes FDist data to a Record object. 
 18   
 19   
 20  """ 
 21  from types import * 
 22   
 23   
 24  from Bio import File 
 25  from Bio.ParserSupport import * 
 26   
 27   
 28   
29 -class Record:
30 """Holds information from a FDist record. 31 32 Members: 33 data_org Data organization (0 pops by rows, 1 alleles by rows). 34 The Record will behave as if data was 0 (converting if needed) 35 36 num_pops Number of populations 37 38 num_loci Number of loci 39 40 loci_data Loci data 41 42 loci_data is a list, where each element represents a locus. Each element 43 is a tuple, the first element is the number of alleles, the second 44 element a list. Each element of the list is the count of each allele 45 per population. 46 47 """
48 - def __init__(self):
49 self.data_org = 0 50 self.num_pops = 0 51 self.num_loci = 0 52 self.loci_data = []
53
54 - def __str__(self):
55 rep = ['0\n'] #We only export in 0 format, even if originally was 1 56 rep.append(str(self.num_pops) + '\n') 57 rep.append(str(self.num_loci) + '\n') 58 rep.append('\n') 59 for locus_data in self.loci_data: 60 num_alleles, pops_data = locus_data 61 rep.append(str(num_alleles) + '\n') 62 for pop_data in pops_data: 63 for allele_count in pop_data: 64 rep.append(str(allele_count) + ' ') 65 rep.append('\n') 66 rep.append('\n') 67 return "".join(rep)
68 69
70 -class RecordParser(AbstractParser):
71 """Parses FDist data into a Record object. 72 73 """
74 - def __init__(self):
75 self._scanner = _Scanner() 76 self._consumer = _RecordConsumer()
77
78 - def parse(self, handle):
79 self._scanner.feed(handle, self._consumer) 80 return self._consumer.data
81
82 -class _Scanner:
83 """Scans a FDist record. 84 85 There is only one record per file. 86 87 """ 88
89 - def feed(self, handle, consumer):
90 """feed(self, handle, consumer) 91 92 Feed in a FDist unit record for scanning. handle is a file-like 93 object that contains a FDist record. consumer is a 94 Consumer object that will receive events as the report is scanned. 95 96 """ 97 98 consumer.start_record() 99 self.num_pops = None 100 self.num_loci = None 101 self.loci_data = [] 102 103 data_org = int(handle.readline().rstrip()) 104 consumer.data_org(data_org) 105 num_pops = int(handle.readline().rstrip()) 106 consumer.num_pops(num_pops) 107 num_loci = int(handle.readline().rstrip()) 108 consumer.num_loci(num_loci) 109 for i in range(num_loci): 110 handle.readline() 111 num_alleles = int(handle.readline().rstrip()) 112 pops_data = [] 113 if data_org==0: 114 for j in range(num_pops): 115 line_comp = handle.readline().rstrip().split(' ') 116 pop_dist = map(lambda x: int(x), line_comp) 117 pops_data.append(pop_dist) 118 else: 119 raise NotImplementedError('1/alleles by rows not implemented') 120 consumer.new_locus(num_alleles, pops_data) 121 consumer.end_record()
122
123 -class _RecordConsumer(AbstractConsumer):
124 """Consumer that converts a FDist record to a Record object. 125 126 Members: 127 data Record with FDist data. 128 129 """
130 - def __init__(self):
131 self.data = None
132
133 - def start_record(self):
134 self.data = Record()
135
136 - def end_record(self):
137 pass
138
139 - def data_org(self, data_org):
140 self.data.data_org = data_org
141
142 - def num_pops(self, num_pops):
143 self.data.num_pops = num_pops
144
145 - def num_loci(self, num_loci):
146 self.data.num_loci = num_loci
147
148 - def new_locus(self, num_alleles, pop_data):
149 self.data.loci_data.append((num_alleles, pop_data))
150