Package Bio :: Package MetaTool
[hide private]
[frames] | no frames]

Source Code for Package Bio.MetaTool

  1  # Copyright 2001 by Katharine Lindner.  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  """Parser for output from MetaTool 3.5 (DEPRECATED). 
  6   
  7  MetaTool is a program which defines metabolic routes within networks. 
  8  This parser does not support the current version, MetaTool 5.0. 
  9   
 10  http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed& 
 11  list_uids=10222413&dopt=Abstract 
 12  """ 
 13   
 14  import warnings 
 15  warnings.warn("Bio.MetalTool was deprecated, as it only supported the obsolete" 
 16                +"MetaTool 3.5 output.") 
 17   
 18  # standard library 
 19  import string 
 20   
 21  import numpy.oldnumeric.matrix as Matrix 
 22   
 23  # XML from python 2.0 
 24  from xml.sax import handler 
 25   
 26  # Martel 
 27  import Martel 
 28  from Martel import RecordReader 
 29   
 30  from Bio.ParserSupport import EventGenerator 
 31  from Bio import File 
 32  import metatool_format 
 33  import Record 
 34   
35 -class Iterator:
36 """Iterator interface to move over a file of MetaTool entries one at a time. 37 """
38 - def __init__(self, handle, parser = None):
39 """Initialize the iterator. 40 41 Arguments: 42 o handle - A handle with Kabat entries to iterate through. 43 o parser - An optional parser to pass the entries through before 44 returning them. If None, then the raw entry will be returned. 45 """ 46 self._reader = RecordReader.StartsWith(handle, "METATOOL") 47 # self._reader = RecordReader.EndsWith(handle, "RECEND|\n") 48 self._parser = parser
49
50 - def next(self):
51 """Return the next MetaTool record from the handle. 52 53 Will return None if we ran out of records. 54 """ 55 data = self._reader.next() 56 57 if self._parser is not None: 58 if data: 59 return self._parser.parse(File.StringHandle(data)) 60 61 return data
62
63 - def __iter__(self):
64 return iter(self.next, None)
65
66 -class _RecordConsumer:
67 """Create a MetaTool Record object from scanner generated information. 68 """
69 - def __init__(self):
70 self.data = Record.Record() 71 self.data.internal_metabolites = [] 72 self.data.external_metabolites = []
73
74 - def input_file_name( self, content ):
75 self.data.input_file_name = content[ 0 ]
76
77 - def input_file_tag( self, content ):
78 self.state = "input_file_state"
79
80 - def metabolite_count_tag( self, content ):
81 self.state = "metabolite_count_state"
82
83 - def reaction_count_tag( self, content ):
84 self.state = "reaction_count_state"
85
86 - def matrix_row( self, matrix_rows ):
87 for matrix_row in matrix_rows: 88 elements = matrix_row.split() 89 vector = [] 90 for element in elements: 91 vector.append( int( element ) ) 92 self._vectors.append( vector )
93
94 - def unbalanced_metabolite( self, content ):
95 for metabolite in content: 96 self.data.unbalanced_metabolites.append( metabolite )
97
98 - def branch_metabolite( self, content ):
99 for metabolite in content: 100 items = metabolite.split() 101 name = items[ 0 ] 102 consumed = int( items[ 1 ] ) 103 built = int( items[ 2 ] ) 104 vector = items[ 4 ].replace( 'r', '0' ) 105 106 vector = vector.replace( 'i', '1' ) 107 vector = list( vector ) 108 map( int, vector ) 109 entry = Record.MetaboliteRole( name, consumed, built, vector ) 110 self.data.branch_metabolites.append( entry )
111
112 - def non_branch_metabolite( self, content ):
113 for metabolite in content: 114 items = metabolite.split() 115 name = items[ 0 ] 116 consumed = int( items[ 1 ] ) 117 built = int( items[ 2 ] ) 118 vector = items[ 4 ].replace( 'r', '0' ) 119 vector = vector.replace( 'i', '1' ) 120 vector = list( vector ) 121 entry = Record.MetaboliteRole( name, consumed, built, vector ) 122 self.data.non_branch_metabolites.append( entry )
123
124 - def stoichiometric_tag( self, content ):
125 self.state = "stoichiometry_state" 126 self._vectors = [] 127 self._enzymes = [] 128 self._reactions = []
129
130 - def kernel_tag( self, kernel_tag ):
131 self.state = "kernel_state" 132 self._vectors = [] 133 self._enzymes = [] 134 self._reactions = []
135
136 - def subsets_tag( self, content ):
137 self.state = "subsets_state" 138 self._vectors = [] 139 self._enzymes = [] 140 self._reactions = []
141
142 - def reduced_system_tag( self, content ):
143 self.state = "reduced_system_state" 144 self._vectors = [] 145 self._enzymes = [] 146 self._reactions = []
147
148 - def convex_basis_tag( self, content ):
149 self.state = "convex_basis_state" 150 self._vectors = [] 151 self._enzymes = [] 152 self._reactions = []
153
154 - def conservation_relations_tag( self, content ):
155 self.state = "conservation_relations_state" 156 self._vectors = [] 157 self._enzymes = [] 158 self._reactions = []
159
160 - def elementary_modes_tag( self, content ):
161 self.state = "elementary_modes_state" 162 self._vectors = [] 163 self._enzymes = [] 164 self._reactions = []
165
166 - def metabolite_line( self, content ):
167 self.data.external_metabolites = [] 168 self.data.internal_metabolites = [] 169 for metabolite in content: 170 items = metabolite.split() 171 entry = Record.Metabolite( int( items[ 0 ] ), items[ 2 ] ) 172 173 if( items[ 1 ] == "external" ): 174 self.data.external_metabolites.append( entry ) 175 else: 176 self.data.internal_metabolites.append( entry )
177 178
179 - def num_int_metabolites( self, content ):
180 num_int_metabolites = content[ 0 ] 181 self.data.num_int_metabolites = int( num_int_metabolites )
182
183 - def num_reactions( self, content ):
184 num_reactions = content[ 0 ] 185 self.data.num_reactions = int( num_reactions )
186
187 - def irreversible_vector( self, content ):
188 self._irreversible_vector = content[ 0 ].split()
189
190 - def reaction( self, reactions ):
191 for reaction in reactions: 192 items = reaction.split() 193 item = string.join( items[ 1: ] ) 194 self._reactions.append(item)
195
196 - def enzyme( self, enzymes ):
197 for enzyme in enzymes: 198 items = enzyme.split() 199 item = string.join( items[ 1: ] ) 200 self._enzymes.append(item)
201
202 - def sum_is_constant_line( self, lines ):
203 for line in lines: 204 items = line.split( ':') 205 items = items[ 1 ].split( '=' ) 206 self.data.sum_is_constant_lines.append( items[ 0 ] )
207
208 - def num_rows( self, num_rows ):
209 pass
210
211 - def num_cols( self, num_cols ):
212 pass
213
214 - def metabolite_roles( self, content ):
215 for metabolite_role in content: 216 cols = metabolite_role.split()
217
218 - def end_stochiometric( self, content ):
219 if( self._vectors != [] ): 220 self.data.stochiometric.matrix = Matrix.Matrix( self._vectors ) 221 self.data.stochiometric.enzymes = [] 222 for enzyme in self._enzymes: 223 self.data.stochiometric.enzymes.append( enzyme ) 224 self.data.stochiometric.enzymes = [] 225 for reaction in self._reactions: 226 self.data.stochiometric.reactions.append( reaction ) 227 for col in self._irreversible_vector: 228 self.data.stochiometric.irreversible_vector.append( col )
229
230 - def end_kernel( self, content ):
231 if( self._vectors != [] ): 232 self.data.kernel.matrix = Matrix.Matrix( self._vectors ) 233 self.data.kernel.enzymes = [] 234 for enzyme in self._enzymes: 235 self.data.kernel.enzymes.append( enzyme ) 236 for reaction in self._reactions: 237 self.data.kernel.reactions.append( reaction )
238
239 - def end_subsets( self, content ):
240 if( self._vectors != [] ): 241 self.data.subsets.matrix = Matrix.Matrix( self._vectors ) 242 self.data.subsets.enzymes = [] 243 for enzyme in self._enzymes: 244 self.data.subsets.enzymes.append( enzyme ) 245 for reaction in self._reactions: 246 self.data.subsets.reactions.append( reaction )
247 248
249 - def end_reduced_system( self, content ):
250 if( self._vectors != [] ): 251 self.data.reduced_system.matrix = Matrix.Matrix( self._vectors[:14] ) 252 self.data.reduced_system.enzymes = [] 253 for enzyme in self._enzymes: 254 self.data.reduced_system.enzymes.append( enzyme ) 255 for reaction in self._reactions: 256 self.data.reduced_system.reactions.append( reaction ) 257 for col in self._irreversible_vector: 258 self.data.reduced_system.irreversible_vector.append( col )
259 260
261 - def end_convex_basis( self, content ):
262 if( self._vectors != [] ): 263 self.data.convex_basis.matrix = Matrix.Matrix( self._vectors ) 264 self.data.convex_basis.enzymes = [] 265 for enzyme in self._enzymes: 266 self.data.convex_basis.enzymes.append( enzyme ) 267 for reaction in self._reactions: 268 self.data.convex_basis.reactions.append( reaction )
269
270 - def end_conservation_relations( self, content ):
271 if( self._vectors != [] ): 272 self.data.conservation_relations.matrix = Matrix.Matrix( self._vectors ) 273 self.data.conservation_relations.enzymes = [] 274 for enzyme in self._enzymes: 275 self.data.conservation_relations.enzymes.append( enzyme ) 276 for reaction in self._reactions: 277 self.data.conservation_relations.reactions.append( reaction )
278 279
280 - def end_elementary_modes( self, content ):
281 if( self._vectors != [] ): 282 self.data.elementary_modes.matrix = Matrix.Matrix( self._vectors ) 283 self.data.elementary_modes.enzymes = [] 284 for enzyme in self._enzymes: 285 self.data.elementary_modes.enzymes.append( enzyme ) 286 for reaction in self._reactions: 287 self.data.elementary_modes.reactions.append( reaction )
288
289 -class _Scanner:
290 """Start up Martel to do the scanning of the file. 291 292 This initialzes the Martel based parser and connects it to a handler 293 that will generate events for a Feature Consumer. 294 """
295 - def __init__(self, debug = 0):
296 """Initialize the scanner by setting up our caches. 297 298 Creating the parser takes a long time, so we want to cache it 299 to reduce parsing time. 300 301 Arguments: 302 o debug - The level of debugging that the parser should 303 display. Level 0 is no debugging, Level 2 displays the most 304 debugging info (but is much slower). See Martel documentation 305 for more info on this. 306 """ 307 # a listing of all tags we are interested in scanning for 308 # in the MartelParser 309 self.interest_tags = [ "input_file_name", "num_int_metabolites", \ 310 "num_reactions", "metabolite_line", "unbalanced_metabolite", \ 311 "num_rows", "num_cols", "irreversible_vector", \ 312 "branch_metabolite", "non_branch_metabolite", \ 313 "stoichiometric_tag", "kernel_tag", "subsets_tag", \ 314 "reduced_system_tag", "convex_basis_tag", \ 315 "conservation_relations_tag", "elementary_modes_tag", \ 316 "reaction", "enzyme", "matrix_row", "sum_is_constant_line", \ 317 "end_stochiometric", "end_kernel", "end_subsets", \ 318 "end_reduced_system", "end_convex_basis", \ 319 "end_conservation_relations", "end_elementary_modes" ] 320 321 # make a parser that returns only the tags we are interested in 322 expression = Martel.select_names( metatool_format.metatool_record, 323 self.interest_tags) 324 self._parser = expression.make_parser(debug_level = debug)
325
326 - def feed(self, handle, consumer):
327 """Feeed a set of data into the scanner. 328 329 Arguments: 330 o handle - A handle with the information to parse. 331 o consumer - The consumer that should be informed of events. 332 """ 333 self._parser.setContentHandler(EventGenerator(consumer, 334 self.interest_tags )) 335 # _strip_and_combine )) 336 self._parser.setErrorHandler(handler.ErrorHandler()) 337 338 self._parser.parseFile(handle)
339
340 -class RecordParser:
341 """Parse MetaTool files into Record objects 342 """
343 - def __init__(self, debug_level = 0):
344 """Initialize the parser. 345 346 Arguments: 347 o debug_level - An optional argument that species the amount of 348 debugging information Martel should spit out. By default we have 349 no debugging info (the fastest way to do things), but if you want 350 you can set this as high as two and see exactly where a parse fails. 351 """ 352 self._scanner = _Scanner(debug_level)
353
354 - def parse(self, handle):
355 """Parse the specified handle into a MetaTool record. 356 """ 357 self._consumer = _RecordConsumer() 358 self._scanner.feed(handle, self._consumer) 359 return self._consumer.data
360
361 -def _strip_and_combine(line_list):
362 """Combine multiple lines of content separated by spaces. 363 364 This function is used by the EventGenerator callback function to 365 combine multiple lines of information. The lines are first 366 stripped to remove whitepsace, and then combined so they are separated 367 by a space. This is a simple minded way to combine lines, but should 368 work for most cases. 369 """ 370 # first strip out extra whitespace 371 stripped_line_list = map(string.strip, line_list) 372 373 # now combine everything with spaces 374 return string.join(stripped_line_list)
375