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

Source Code for Package Bio.Pathway

  1  # Copyright 2001 by Tarjei Mikkelsen.  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  """BioPython Pathway module. 
  7   
  8  Bio.Pathway is a lightweight class library designed to support the following tasks: 
  9   
 10   - Data interchange and preprocessing between pathway databases and analysis software.  
 11   - Quick prototyping of pathway analysis algorithms 
 12   
 13  The basic object in the Bio.Pathway model is Interaction, which represents an arbitrary 
 14  interaction between any number of biochemical species. 
 15   
 16  Network objects are used to represent the connectivity between species in pathways 
 17  and reaction networks. 
 18   
 19  For applications where it is not neccessary to explicitly represent network connectivity, 
 20  the specialized classes Reaction and System should be used in place of Interacton and 
 21  Network. 
 22   
 23  The Bio.Pathway classes, especially Interaction, are intentionally 
 24  desgined to be very flexible. Their intended use are as wrappers around database 
 25  specific records, such as BIND objects. The value-added in this module is a 
 26  framework for representing collections of reactions in a way that supports 
 27  graph theoretic and numeric analysis. 
 28   
 29  Note: This module should be regarded as a prototype only. API changes are likely. 
 30        Comments and feature requests are most welcome. 
 31  """ 
 32   
 33   
 34  from Bio.Pathway.Rep.HashSet import * 
 35  from Bio.Pathway.Rep.MultiGraph import * 
 36   
 37   
38 -class Reaction:
39 """Abstraction for a biochemical transformation. 40 41 This class represents a (potentially reversible) biochemical 42 transformation of the type: 43 44 a S1 + b S2 + ... --> c P1 + d P2 + ... 45 46 where 47 - a, b, c, d ... are positive numeric stochiometric coefficients, 48 - S1, S2, ... are substrates 49 - P1, P2, ... are products 50 51 A Reaction should be viewed as the net result of one or more individual 52 reaction steps, where each step is potentially facilitated by a different 53 catalyst. Support for 'Reaction algebra' will be added at some point in 54 the future. 55 56 Attributes: 57 58 reactants -- map of involved species to their stochiometric coefficients: 59 reactants[S] = stochiometric constant for S 60 catalysts -- list of tuples of catalysts required for this reaction 61 reversible -- true iff reaction is reversible 62 data -- reference to arbitrary additional data 63 64 Invariants: 65 66 for all S in reactants: reactants[S] != 0 67 for all C in catalysts: catalysts[C] != 0 68 69 """ 70
71 - def __init__(self, reactants = {}, catalysts = [], 72 reversible = 0, data = None):
73 """Initializes a new Reaction object.""" 74 # enforce invariants on reactants: 75 self.reactants = reactants.copy() 76 # loop over original, edit the copy 77 for r, value in reactants.iteritems(): 78 if value == 0: 79 del self.reactants[r] 80 self.catalysts = HashSet(catalysts).list() 81 self.data = data 82 self.reversible = reversible
83
84 - def __eq__(self, r):
85 """Returns true iff self is equal to r.""" 86 return isinstance(r, Reaction) and \ 87 self.reactants == r.reactants and \ 88 self.catalysts == r.catalysts and \ 89 self.data == r.data and \ 90 self.reversible == r.reversible
91
92 - def __ne__(self, r):
93 """Returns true iff self is not equal to r.""" 94 return not self.__eq__(r)
95
96 - def __hash__(self):
97 """Returns a hashcode for self.""" 98 t = tuple(self.species()) 99 return hash(t)
100
101 - def __repr__(self):
102 """Returns a debugging string representation of self.""" 103 return "Reaction(" + \ 104 ",".join(map(repr,[self.reactants, 105 self.catalysts, 106 self.data, 107 self.reversible])) + ")"
108
109 - def __str__(self):
110 """Returns a string representation of self.""" 111 substrates = "" 112 products = "" 113 all_species = sorted(self.reactants) 114 for species in all_species: 115 stoch = self.reactants[species] 116 if stoch < 0: 117 # species is a substrate: 118 if substrates != "": 119 substrates = substrates + " + " 120 if stoch != -1: 121 substrates = substrates + str(abs(stoch)) + " " 122 substrates = substrates + str(species) 123 elif stoch > 0: 124 # species is a product: 125 if products != "": 126 products = products + " + " 127 if stoch != 1: 128 products = products + str(stoch) + " " 129 products = products + str(species) 130 else: 131 raise AttributeError("Invalid 0 coefficient in Reaction.reactants") 132 if self.reversible: 133 return substrates + " <=> " + products 134 else: 135 return substrates + " --> " + products
136
137 - def reverse(self):
138 """Returns a new Reaction that is the reverse of self.""" 139 reactants = {} 140 for r in self.reactants: 141 reactants[r] = - self.reactants[r] 142 return Reaction(reactants, self.catalysts, 143 self.reversible, self.data)
144
145 - def species(self):
146 """Returns a list of all Species involved in self.""" 147 return self.reactants.keys()
148 149
150 -class System:
151 """Abstraction for a collection of reactions. 152 153 This class is used in the Bio.Pathway framework to represent an arbitrary 154 collection of reactions without explicitly defined links. 155 156 Attributes: 157 158 None 159 """ 160
161 - def __init__(self, reactions = []):
162 """Initializes a new System object.""" 163 self.__reactions = HashSet(reactions)
164
165 - def __repr__(self):
166 """Returns a debugging string representation of self.""" 167 return "System(" + ",".join(map(repr,self.__reactions.list())) + ")"
168
169 - def __str__(self):
170 """Returns a string representation of self.""" 171 return "System of " + str(len(self.__reactions)) + \ 172 " reactions involving " + str(len(self.species())) + \ 173 " species"
174
175 - def add_reaction(self, reaction):
176 """Adds reaction to self.""" 177 self.__reactions.add(reaction)
178
179 - def remove_reaction(self, reaction):
180 """Removes reaction from self.""" 181 self.__reactions.remove(reaction)
182
183 - def reactions(self):
184 """Returns a list of the reactions in this system.""" 185 return self.__reactions.list()
186
187 - def species(self):
188 """Returns a list of the species in this system.""" 189 s = HashSet(reduce(lambda s,x: s + x, 190 [x.species() for x in self.reactions()], [])) 191 return s.list()
192
193 - def stochiometry(self):
194 """Computes the stoichiometry matrix for self. 195 196 Returns (species, reactions, stoch) where 197 198 species = ordered list of species in this system 199 reactions = ordered list of reactions in this system 200 stoch = 2D array where stoch[i][j] is coef of the 201 jth species in the ith reaction, as defined 202 by species and reactions above 203 """ 204 # Note: This an inefficient and ugly temporary implementation. 205 # To be practical, stochiometric matrices should probably 206 # be implemented by sparse matrices, which would require 207 # NumPy dependencies. 208 # 209 # PS: We should implement automatic checking for NumPy here. 210 species = self.species() 211 reactions = self.reactions() 212 stoch = [] * len(reactions) 213 for i in range(len(reactions)): 214 stoch[i] = 0 * len(species) 215 for s in reactions[i].species(): 216 stoch[species.index(s)] = reactions[i].reactants[s] 217 return (species, reactions, stoch)
218 219
220 -class Interaction:
221 """An arbitrary interaction between any number of species. 222 223 This class definition is inteded solely as a minimal wrapper interface that should 224 be implemented and extended by more specific abstractions. 225 226 Attributes: 227 228 data -- reference to arbitrary additional data 229 """ 230
231 - def __init_(self, data):
232 self.data = data
233
234 - def __hash__(self):
235 """Returns a hashcode for self.""" 236 return hash(self.data)
237
238 - def __repr__(self):
239 """Returns a debugging string representation of self.""" 240 return "Interaction(" + repr(self.data) + ")"
241
242 - def __str__(self):
243 """Returns a string representation of self.""" 244 return "<" + str(self.data) + ">"
245 246
247 -class Network:
248 """A set of species that are explicitly linked by interactions. 249 250 The network is a directed multigraph with labeled edges. The nodes in the graph 251 are the biochemical species involved. The edges represent an interaction between 252 two species, and the edge label is a reference to the associated Interaction 253 object. 254 255 Attributes: 256 257 None 258 259 """ 260
261 - def __init__(self, species = []):
262 """Initializes a new Network object.""" 263 self.__graph = MultiGraph(species)
264
265 - def __repr__(self):
266 """Returns a debugging string representation of this network.""" 267 return "<Network: __graph: " + repr(self.__graph) + ">"
268
269 - def __str__(self):
270 """Returns a string representation of this network.""" 271 return "Network of " + str(len(self.species())) + " species and " + \ 272 str(len(self.interactions())) + " interactions."
273
274 - def add_species(self, species):
275 """Adds species to this network.""" 276 self.__graph.add_node(species)
277
278 - def add_interaction(self, source, sink, interaction):
279 """Adds interaction to this network.""" 280 self.__graph.add_edge(source, sink, interaction)
281
282 - def source(self, species):
283 """Returns list of unique sources for species.""" 284 return self.__graph.parents(species)
285
286 - def source_interactions(self, species):
287 """Returns list of (source, interaction) pairs for species.""" 288 return self.__graph.parent_edges(species)
289
290 - def sink(self, species):
291 """Returns list of unique sinks for species.""" 292 return self.__graph.children(species)
293
294 - def sink_interactions(self, species):
295 """Returns list of (sink, interaction) pairs for species.""" 296 return self.__graph.child_edges(species)
297
298 - def species(self):
299 """Returns list of the species in this network.""" 300 return self.__graph.nodes()
301
302 - def interactions(self):
303 """Returns list of the unique interactions in this network.""" 304 return self.__graph.labels()
305