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 necessary 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  designed 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  from functools import reduce 
 34   
 35  from Bio.Pathway.Rep.MultiGraph import * 
 36   
 37   
38 -class Reaction(object):
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 -- dict of involved species to their stochiometric coefficients: 59 reactants[S] = stochiometric constant for S 60 - catalysts -- list/tuple 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=None, catalysts=(), 72 reversible=0, data=None):
73 """Initializes a new Reaction object.""" 74 # enforce invariants on reactants: 75 if reactants is None: 76 self.reactants = {} 77 else: 78 self.reactants = reactants.copy() 79 # loop over original, edit the copy 80 for r, value in reactants.items(): 81 if value == 0: 82 del self.reactants[r] 83 self.catalysts = sorted(set(catalysts)) 84 self.data = data 85 self.reversible = reversible
86
87 - def __eq__(self, r):
88 """Returns true iff self is equal to r.""" 89 return isinstance(r, Reaction) and \ 90 self.reactants == r.reactants and \ 91 self.catalysts == r.catalysts and \ 92 self.data == r.data and \ 93 self.reversible == r.reversible
94
95 - def __ne__(self, r):
96 """Returns true iff self is not equal to r.""" 97 return not self.__eq__(r)
98
99 - def __hash__(self):
100 """Returns a hashcode for self.""" 101 t = tuple(self.species()) 102 return hash(t)
103
104 - def __repr__(self):
105 """Returns a debugging string representation of self.""" 106 return "Reaction(" + \ 107 ",".join(map(repr, [self.reactants, 108 self.catalysts, 109 self.data, 110 self.reversible])) + ")"
111
112 - def __str__(self):
113 """Returns a string representation of self.""" 114 substrates = "" 115 products = "" 116 all_species = sorted(self.reactants) 117 for species in all_species: 118 stoch = self.reactants[species] 119 if stoch < 0: 120 # species is a substrate: 121 if substrates != "": 122 substrates = substrates + " + " 123 if stoch != -1: 124 substrates = substrates + str(abs(stoch)) + " " 125 substrates = substrates + str(species) 126 elif stoch > 0: 127 # species is a product: 128 if products != "": 129 products = products + " + " 130 if stoch != 1: 131 products = products + str(stoch) + " " 132 products = products + str(species) 133 else: 134 raise AttributeError("Invalid 0 coefficient in Reaction.reactants") 135 if self.reversible: 136 return substrates + " <=> " + products 137 else: 138 return substrates + " --> " + products
139
140 - def reverse(self):
141 """Returns a new Reaction that is the reverse of self.""" 142 reactants = {} 143 for r in self.reactants: 144 reactants[r] = - self.reactants[r] 145 return Reaction(reactants, self.catalysts, 146 self.reversible, self.data)
147
148 - def species(self):
149 """Returns a list of all Species involved in self.""" 150 return list(self.reactants)
151 152
153 -class System(object):
154 """Abstraction for a collection of reactions. 155 156 This class is used in the Bio.Pathway framework to represent an arbitrary 157 collection of reactions without explicitly defined links. 158 159 Attributes: 160 161 None 162 """ 163
164 - def __init__(self, reactions=()):
165 """Initializes a new System object.""" 166 self.__reactions = set(reactions)
167
168 - def __repr__(self):
169 """Returns a debugging string representation of self.""" 170 return "System(" + ",".join(map(repr, self.__reactions)) + ")"
171
172 - def __str__(self):
173 """Returns a string representation of self.""" 174 return "System of " + str(len(self.__reactions)) + \ 175 " reactions involving " + str(len(self.species())) + \ 176 " species"
177
178 - def add_reaction(self, reaction):
179 """Adds reaction to self.""" 180 self.__reactions.add(reaction)
181
182 - def remove_reaction(self, reaction):
183 """Removes reaction from self.""" 184 self.__reactions.remove(reaction)
185
186 - def reactions(self):
187 """Returns a list of the reactions in this system. 188 189 Note the order is arbitrary! 190 """ 191 # TODO - Define __lt__ so that Reactions can be sorted on Python? 192 return list(self.__reactions)
193
194 - def species(self):
195 """Returns a list of the species in this system.""" 196 return sorted(set(reduce(lambda s, x: s + x, 197 [x.species() for x in self.reactions()], [])))
198
199 - def stochiometry(self):
200 """Computes the stoichiometry matrix for self. 201 202 Returns (species, reactions, stoch) where 203 204 - species = ordered list of species in this system 205 - reactions = ordered list of reactions in this system 206 - stoch = 2D array where stoch[i][j] is coef of the 207 jth species in the ith reaction, as defined 208 by species and reactions above 209 """ 210 # Note: This an inefficient and ugly temporary implementation. 211 # To be practical, stochiometric matrices should probably 212 # be implemented by sparse matrices, which would require 213 # NumPy dependencies. 214 # 215 # PS: We should implement automatic checking for NumPy here. 216 species = self.species() 217 reactions = self.reactions() 218 stoch = [] * len(reactions) 219 for i in range(len(reactions)): 220 stoch[i] = 0 * len(species) 221 for s in reactions[i].species(): 222 stoch[species.index(s)] = reactions[i].reactants[s] 223 return (species, reactions, stoch)
224 225
226 -class Interaction(object):
227 """An arbitrary interaction between any number of species. 228 229 This class definition is intended solely as a minimal wrapper interface that should 230 be implemented and extended by more specific abstractions. 231 232 Attributes: 233 234 - data -- reference to arbitrary additional data 235 """ 236
237 - def __init_(self, data):
238 self.data = data
239
240 - def __hash__(self):
241 """Returns a hashcode for self.""" 242 return hash(self.data)
243
244 - def __repr__(self):
245 """Returns a debugging string representation of self.""" 246 return "Interaction(" + repr(self.data) + ")"
247
248 - def __str__(self):
249 """Returns a string representation of self.""" 250 return "<" + str(self.data) + ">"
251 252
253 -class Network(object):
254 """A set of species that are explicitly linked by interactions. 255 256 The network is a directed multigraph with labeled edges. The nodes in the graph 257 are the biochemical species involved. The edges represent an interaction between 258 two species, and the edge label is a reference to the associated Interaction 259 object. 260 261 Attributes: 262 263 None 264 """ 265
266 - def __init__(self, species=()):
267 """Initializes a new Network object.""" 268 self.__graph = MultiGraph(species)
269
270 - def __repr__(self):
271 """Returns a debugging string representation of this network.""" 272 return "<Network: __graph: " + repr(self.__graph) + ">"
273
274 - def __str__(self):
275 """Returns a string representation of this network.""" 276 return "Network of " + str(len(self.species())) + " species and " + \ 277 str(len(self.interactions())) + " interactions."
278
279 - def add_species(self, species):
280 """Adds species to this network.""" 281 self.__graph.add_node(species)
282
283 - def add_interaction(self, source, sink, interaction):
284 """Adds interaction to this network.""" 285 self.__graph.add_edge(source, sink, interaction)
286
287 - def source(self, species):
288 """Returns list of unique sources for species.""" 289 return self.__graph.parents(species)
290
291 - def source_interactions(self, species):
292 """Returns list of (source, interaction) pairs for species.""" 293 return self.__graph.parent_edges(species)
294
295 - def sink(self, species):
296 """Returns list of unique sinks for species.""" 297 return self.__graph.children(species)
298
299 - def sink_interactions(self, species):
300 """Returns list of (sink, interaction) pairs for species.""" 301 return self.__graph.child_edges(species)
302
303 - def species(self):
304 """Returns list of the species in this network.""" 305 return self.__graph.nodes()
306
307 - def interactions(self):
308 """Returns list of the unique interactions in this network.""" 309 return self.__graph.labels()
310