bio 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,14 @@
1
1
  #
2
- # bio/db/pdb/residue.rb - residue class for PDB
2
+ # = bio/db/pdb/residue.rb - residue class for PDB
3
3
  #
4
- # Copyright (C) 2004 Alex Gutteridge <alexg@ebi.ac.uk>
4
+ # Copyright:: Copyright (C) 2004, 2006
5
+ # Alex Gutteridge <alexg@ebi.ac.uk>
6
+ # Naohisa Goto <ng@bioruby.org>
7
+ # License:: LGPL
5
8
  #
9
+ # $Id: residue.rb,v 1.10 2006/01/20 13:54:08 ngoto Exp $
10
+ #
11
+ #--
6
12
  # This library is free software; you can redistribute it and/or
7
13
  # modify it under the terms of the GNU Lesser General Public
8
14
  # License as published by the Free Software Foundation; either
@@ -16,8 +22,12 @@
16
22
  # You should have received a copy of the GNU Lesser General Public
17
23
  # License along with this library; if not, write to the Free Software
18
24
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
+ #++
26
+ #
27
+ # = Bio::PDB::Residue
28
+ #
29
+ # = Bio::PDB::Heterogen
19
30
  #
20
- # $Id: residue.rb,v 1.4 2005/12/18 17:34:47 ngoto Exp $
21
31
 
22
32
  require 'bio/db/pdb'
23
33
 
@@ -25,81 +35,103 @@ module Bio
25
35
 
26
36
  class PDB
27
37
 
28
- #Residue class - id is a composite of resSeq and iCode
38
+ # Bio::PDB::Residue is a class to store a residue.
39
+ # The object would contain some atoms (Bio::PDB::Record::ATOM objects).
40
+ #
29
41
  class Residue
30
42
 
31
43
  include Utils
32
44
  include AtomFinder
45
+
33
46
  include Enumerable
34
47
  include Comparable
35
-
36
- attr_reader :resName, :resSeq, :iCode, :id, :chain, :hetatm
37
- attr_writer :resName, :chain, :hetatm
38
-
48
+
49
+ # Creates residue id from an ATOM (or HETATM) object.
50
+ def self.get_residue_id_from_atom(atom)
51
+ "#{atom.resSeq}#{atom.iCode.strip}".strip
52
+ end
53
+
54
+ # Creates a new Residue object.
39
55
  def initialize(resName = nil, resSeq = nil, iCode = nil,
40
- chain = nil, hetatm = false)
56
+ chain = nil)
41
57
 
42
58
  @resName = resName
43
59
  @resSeq = resSeq
44
60
  @iCode = iCode
45
61
 
46
- @hetatm = hetatm
47
-
48
- #Residue id is required because resSeq doesn't uniquely identify
49
- #a residue. ID is constructed from resSeq and iCode and is appended
50
- #to 'LIGAND' if the residue is a HETATM
51
- if (!@resSeq and !@iCode)
52
- @id = nil
53
- else
54
- @id = "#{@resSeq}#{@iCode.strip}"
55
- if @hetatm
56
- @id = 'LIGAND' + @id
57
- end
58
- end
59
-
60
62
  @chain = chain
61
-
62
- @atoms = Array.new
63
-
63
+ @atoms = []
64
+
65
+ update_residue_id
64
66
  end
65
-
67
+
68
+ # atoms in this residue. (Array)
69
+ attr_reader :atoms
70
+
71
+ # the chain to which this residue belongs
72
+ attr_accessor :chain
73
+
74
+ # resName (residue name)
75
+ attr_accessor :resName
76
+
77
+ # residue id (String or nil).
78
+ # The id is a composite of resSeq and iCode.
79
+ attr_reader :residue_id
80
+
81
+ # Now, Residue#id is an alias of residue_id.
82
+ alias id residue_id
83
+
66
84
  #Keyed access to atoms based on element e.g. ["CA"]
67
85
  def [](key)
68
86
  atom = @atoms.find{ |atom| key == atom.element }
69
87
  end
70
-
71
- #Need to define these to make sure id is correctly updated
88
+
89
+ # Updates residue id. This is a private method.
90
+ # Need to call this method to make sure id is correctly updated.
91
+ def update_residue_id
92
+ if !@resSeq and !@iCode
93
+ @residue_id = nil
94
+ else
95
+ @residue_id = "#{@resSeq}#{@iCode.to_s.strip}".strip
96
+ end
97
+ end
98
+ private :update_residue_id
99
+
100
+ # resSeq
101
+ attr_reader :resSeq
102
+
103
+ # resSeq=()
72
104
  def resSeq=(resSeq)
73
105
  @resSeq = resSeq.to_i
74
- @id = "#{@resSeq}#{@iCode.strip}"
75
- if @hetatm
76
- @id = 'LIGAND' + @id
77
- end
106
+ update_residue_id
107
+ @resSeq
78
108
  end
79
-
109
+
110
+ # iCode
111
+ attr_reader :iCode
112
+
113
+ # iCode=()
80
114
  def iCode=(iCode)
81
115
  @iCode = iCode
82
- @id = "#{@resSeq}#{@iCode.strip}"
83
- if @hetatm
84
- @id = 'LIGAND' + @id
85
- end
116
+ update_residue_id
117
+ @iCode
86
118
  end
87
119
 
88
- #Adds an atom to this residue
120
+ # Adds an atom to this residue
89
121
  def addAtom(atom)
90
122
  raise "Expecting ATOM or HETATM" unless atom.is_a? Bio::PDB::Record::ATOM
91
123
  @atoms.push(atom)
92
124
  self
93
125
  end
94
126
 
95
- #Iterator over the atoms
127
+ # Iterator over the atoms
96
128
  def each
97
129
  @atoms.each{ |atom| yield atom }
98
130
  end
99
- #Alias to override AtomFinder#each_atom
131
+ # Alias to override AtomFinder#each_atom
100
132
  alias each_atom each
101
133
 
102
- #Sorts based on resSeq and iCode if need be
134
+ # Sorts based on resSeq and iCode if need be
103
135
  def <=>(other)
104
136
  if @resSeq != other.resSeq
105
137
  return @resSeq <=> other.resSeq
@@ -108,15 +140,47 @@ module Bio
108
140
  end
109
141
  end
110
142
 
111
- #Stringifies each atom
143
+ # Stringifies each atom
112
144
  def to_s
113
- string = ""
114
- @atoms.each{ |atom| string << atom.to_s << "\n" }
115
- return string
145
+ @atoms.join('')
116
146
  end
117
-
118
- end
119
147
 
120
- end
148
+ # Always returns false.
149
+ #
150
+ # If the residue is HETATM, returns true.
151
+ # Otherwise, returns false.
152
+ def hetatm
153
+ false
154
+ end
155
+ end #class Residue
156
+
157
+ # Bio::PDB::Heterogen is a class to store a heterogen.
158
+ # It inherits Bio::PDB::Residue and most of the methods are the same.
159
+ #
160
+ # The object would contain some HETATMs
161
+ # (Bio::PDB::Record::HETATM objects).
162
+ class Heterogen < Residue
163
+
164
+ include HetatmFinder
165
+
166
+ # Always returns true.
167
+ #
168
+ # If the residue is HETATM, returns true.
169
+ # Otherwise, returns false.
170
+ def hetatm
171
+ true
172
+ end
173
+
174
+ # Alias to override HetatmFinder#each_hetatm
175
+ alias each_hetatm each
176
+
177
+ # Alias needed for HeterogenFinder.
178
+ alias hetatms atoms
179
+
180
+ # Alias to avoid confusion
181
+ alias heterogen_id residue_id
182
+ end #class Heterogen
183
+
184
+ end #class PDB
121
185
 
122
- end
186
+ end #module Bio
@@ -1,9 +1,14 @@
1
1
  #
2
- # bio/db/pdb/utils.rb - Utility modules for PDB
2
+ # = bio/db/pdb/utils.rb - Utility modules for PDB
3
3
  #
4
- # Copyright (C) 2004 Alex Gutteridge <alexg@ebi.ac.uk>
5
- # Copyright (C) 2004 GOTO Naohisa <ngoto@gen-info.osaka-u.ac.jp>
4
+ # Copyright:: Copyright (C) 2004, 2006
5
+ # Alex Gutteridge <alexg@ebi.ac.uk>
6
+ # Naohisa Goto <ng@bioruby.org>
7
+ # License:: LGPL
6
8
  #
9
+ # $Id: utils.rb,v 1.5 2006/01/08 12:59:04 ngoto Exp $
10
+ #
11
+ #--
7
12
  # This library is free software; you can redistribute it and/or
8
13
  # modify it under the terms of the GNU Lesser General Public
9
14
  # License as published by the Free Software Foundation; either
@@ -17,36 +22,69 @@
17
22
  # You should have received a copy of the GNU Lesser General Public
18
23
  # License along with this library; if not, write to the Free Software
19
24
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
+ #++
26
+ #
27
+ # = Bio::PDB::Utils
28
+ #
29
+ # Bio::PDB::Utils
30
+ #
31
+ # = Bio::PDB::ModelFinder
32
+ #
33
+ # Bio::PDB::ModelFinder
34
+ #
35
+ # = Bio::PDB::ChainFinder
36
+ #
37
+ # Bio::PDB::ChainFinder
38
+ #
39
+ # = Bio::PDB::ResidueFinder
40
+ #
41
+ # Bio::PDB::ResidueFinder
42
+ #
43
+ # = Bio::PDB::AtomFinder
44
+ #
45
+ # Bio::PDB::AtomFinder
46
+ #
47
+ # = Bio::PDB::HeterogenFinder
48
+ #
49
+ # Bio::PDB::HeterogenFinder
50
+ #
51
+ # = Bio::PDB::HetatmFinder
52
+ #
53
+ # Bio::PDB::HetatmFinder
20
54
  #
21
- # $Id: utils.rb,v 1.2 2005/09/08 01:22:11 k Exp $
22
55
 
23
56
  require 'matrix'
24
57
  require 'bio/db/pdb'
25
58
 
26
59
  module Bio; class PDB
27
60
 
61
+ # Utility methods for PDB data.
62
+ # The methods in this mixin should be applicalbe to all PDB objects.
63
+ #
64
+ # Bio::PDB::Utils is included by Bio::PDB, Bio::PDB::Model,
65
+ # Bio::PDB::Chain, Bio::PDB::Residue, and Bio::PDB::Heterogen classes.
28
66
  module Utils
29
- #The methods in this mixin should be applicalbe to all PDB objects
30
67
 
31
- #Returns the coordinates of the geometric centre (average co-ord)
32
- #of any AtomFinder (or .atoms) implementing object
33
- def geometricCentre()
34
-
68
+ # Returns the coordinates of the geometric centre (average co-ord)
69
+ # of any AtomFinder (or .atoms) implementing object
70
+ #
71
+ # If you want to get the geometric centre of hetatms,
72
+ # call geometricCentre(:each_hetatm).
73
+ def geometricCentre(method = :each_atom)
35
74
  x = y = z = count = 0
36
75
 
37
- self.each_atom{ |atom|
76
+ self.__send__(method) do |atom|
38
77
  x += atom.x
39
78
  y += atom.y
40
79
  z += atom.z
41
80
  count += 1
42
- }
43
-
44
- x = x / count
45
- y = y / count
46
- z = z / count
81
+ end
47
82
 
83
+ x = (x / count)
84
+ y = (y / count)
85
+ z = (z / count)
86
+
48
87
  Coordinate[x,y,z]
49
-
50
88
  end
51
89
 
52
90
  #Returns the coords of the centre of gravity for any
@@ -63,8 +101,8 @@ module Bio; class PDB
63
101
  'P' => 31
64
102
  }
65
103
 
104
+ # calculates centre of gravitiy
66
105
  def centreOfGravity()
67
-
68
106
  x = y = z = total = 0
69
107
 
70
108
  self.each_atom{ |atom|
@@ -81,19 +119,23 @@ module Bio; class PDB
81
119
  z = z / total
82
120
 
83
121
  Coordinate[x,y,z]
84
-
85
122
  end
86
123
 
124
+ #--
87
125
  #Perhaps distance and dihedral would be better off as class methods?
88
126
  #(rather) than instance methods
89
- def self.distance(coord1,coord2)
90
- coord1 = to_xyz(coord1)
91
- coord2 = to_xyz(coord2)
127
+ #++
128
+
129
+ # Calculates distance between _coord1_ and _coord2_.
130
+ def distance(coord1, coord2)
131
+ coord1 = convert_to_xyz(coord1)
132
+ coord2 = convert_to_xyz(coord2)
92
133
  (coord1 - coord2).r
93
134
  end
135
+ module_function :distance
94
136
 
95
- def self.dihedral_angle(coord1,coord2,coord3,coord4)
96
-
137
+ # Calculates dihedral angle.
138
+ def dihedral_angle(coord1, coord2, coord3, coord4)
97
139
  (a1,b1,c1,d) = calculatePlane(coord1,coord2,coord3)
98
140
  (a2,b2,c2) = calculatePlane(coord2,coord3,coord4)
99
141
 
@@ -105,9 +147,10 @@ module Bio; class PDB
105
147
  torsion
106
148
  end
107
149
  end
150
+ module_function :dihedral_angle
108
151
 
109
- #Implicit conversion into Vector or Bio::PDB::Coordinate
110
- def self.to_xyz(obj)
152
+ # Implicit conversion into Vector or Bio::PDB::Coordinate
153
+ def convert_to_xyz(obj)
111
154
  unless obj.is_a?(Vector)
112
155
  begin
113
156
  obj = obj.xyz
@@ -117,18 +160,32 @@ module Bio; class PDB
117
160
  end
118
161
  obj
119
162
  end
163
+ module_function :convert_to_xyz
164
+
165
+ # (Deprecated) alias of convert_to_xyz(obj)
166
+ def self.to_xyz(obj)
167
+ convert_to_xyz(obj)
168
+ end
120
169
 
170
+ #--
121
171
  #Methods required for the dihedral angle calculations
122
172
  #perhaps these should go in some separate Math module
123
- def self.rad2deg(r)
173
+ #++
174
+
175
+ # radian to degree
176
+ def rad2deg(r)
124
177
  (r/Math::PI)*180
125
178
  end
126
-
127
- def self.acos(x)
179
+ module_function :rad2deg
180
+
181
+ # acos
182
+ def acos(x)
128
183
  Math.atan2(Math.sqrt(1 - x**2),x)
129
184
  end
130
-
131
- def self.calculatePlane(coord1,coord2,coord3)
185
+ module_function :acos
186
+
187
+ # calculates plane
188
+ def calculatePlane(coord1, coord2, coord3)
132
189
  a = coord1.y * (coord2.z - coord3.z) +
133
190
  coord2.y * (coord3.z - coord1.z) +
134
191
  coord3.y * (coord1.z - coord2.z)
@@ -146,13 +203,16 @@ module Bio; class PDB
146
203
  )
147
204
 
148
205
  return [a,b,c,d]
149
-
150
206
  end
207
+ module_function :calculatePlane
151
208
 
152
- #Every class in the heirarchy implements finder, this takes
153
- #a class which determines which type of object to find, the associated
154
- #block is then run in classic .find style
155
- def finder(findtype,&block)
209
+ # Every class in the heirarchy implements finder, this takes
210
+ # a class which determines which type of object to find, the associated
211
+ # block is then run in classic .find style.
212
+ #
213
+ # The method might be deprecated.
214
+ # You'd better using find_XXX directly.
215
+ def finder(findtype, &block) #:yields: obj
156
216
  if findtype == Bio::PDB::Atom
157
217
  return self.find_atom(&block)
158
218
  elsif findtype == Bio::PDB::Residue
@@ -166,69 +226,190 @@ module Bio; class PDB
166
226
  end
167
227
  end
168
228
  end #module Utils
169
-
229
+
230
+ #--
170
231
  #The *Finder modules implement a find_* method which returns
171
232
  #an array of anything for which the block evals true
172
233
  #(suppose Enumerable#find_all method).
173
234
  #The each_* style methods act as classic iterators.
235
+ #++
236
+
237
+ # methods to access models
238
+ #
239
+ # XXX#each_model must be defined.
240
+ #
241
+ # Bio::PDB::ModelFinder is included by Bio::PDB::PDB.
242
+ #
174
243
  module ModelFinder
175
- def find_model()
244
+ # returns an array containing all chains for which given block
245
+ # is not +false+ (similar to Enumerable#find_all).
246
+ def find_model
176
247
  array = []
177
- self.each_model{ |model|
248
+ self.each_model do |model|
178
249
  array.push(model) if yield(model)
179
- }
250
+ end
180
251
  return array
181
252
  end
182
- end
253
+ end #module ModelFinder
183
254
 
255
+ #--
184
256
  #The heirarchical nature of the objects allow us to re-use the
185
257
  #methods from the previous level - e.g. A PDB object can use the .models
186
258
  #method defined in ModuleFinder to iterate through the models to find the
187
259
  #chains
260
+ #++
261
+
262
+ # methods to access chains
263
+ #
264
+ # XXX#each_model must be defined.
265
+ #
266
+ # Bio::PDB::ChainFinder is included by Bio::PDB::PDB and Bio::PDB::Model.
267
+ #
188
268
  module ChainFinder
189
- def find_chain()
269
+
270
+ # returns an array containing all chains for which given block
271
+ # is not +false+ (similar to Enumerable#find_all).
272
+ def find_chain
190
273
  array = []
191
- self.each_chain{ |chain|
274
+ self.each_chain do |chain|
192
275
  array.push(chain) if yield(chain)
193
- }
276
+ end
194
277
  return array
195
278
  end
196
- def each_chain()
197
- self.each_model{ |model|
198
- model.each{ |chain| yield chain }
199
- }
279
+
280
+ # iterates over each chain
281
+ def each_chain(&x) #:yields: chain
282
+ self.each_model { |model| model.each(&x) }
200
283
  end
201
- end
284
+
285
+ # returns all chains
286
+ def chains
287
+ array = []
288
+ self.each_model { |model| array.concat(model.chains) }
289
+ return array
290
+ end
291
+ end #module ChainFinder
202
292
 
293
+ # methods to access residues
294
+ #
295
+ # XXX#each_chain must be defined.
296
+ #
297
+ # Bio::PDB::ResidueFinder is included by Bio::PDB::PDB, Bio::PDB::Model,
298
+ # and Bio::PDB::Chain.
299
+ #
203
300
  module ResidueFinder
204
- def find_residue()
301
+
302
+ # returns an array containing all residues for which given block
303
+ # is not +false+ (similar to Enumerable#find_all).
304
+ def find_residue
205
305
  array = []
206
- self.each_residue{ |residue|
306
+ self.each_residue do |residue|
207
307
  array.push(residue) if yield(residue)
208
- }
308
+ end
209
309
  return array
210
310
  end
211
- def each_residue()
212
- self.each_chain{ |chain|
213
- chain.each{ |residue| yield residue }
214
- }
311
+
312
+ # iterates over each residue
313
+ def each_residue(&x) #:yields: residue
314
+ self.each_chain { |chain| chain.each(&x) }
315
+ end
316
+
317
+ # returns all residues
318
+ def residues
319
+ array = []
320
+ self.each_chain { |chain| array.concat(chain.residues) }
321
+ return array
215
322
  end
216
- end
323
+ end #module ResidueFinder
217
324
 
325
+ # methods to access atoms
326
+ #
327
+ # XXX#each_residue must be defined.
218
328
  module AtomFinder
219
- def find_atom()
329
+ # returns an array containing all atoms for which given block
330
+ # is not +false+ (similar to Enumerable#find_all).
331
+ def find_atom
220
332
  array = []
221
- self.each_atom{ |atom|
333
+ self.each_atom do |atom|
222
334
  array.push(atom) if yield(atom)
223
- }
335
+ end
224
336
  return array
225
337
  end
226
- def each_atom()
227
- self.each_residue{ |residue|
228
- residue.each{ |atom| yield atom }
229
- }
338
+
339
+ # iterates over each atom
340
+ def each_atom(&x) #:yields: atom
341
+ self.each_residue { |residue| residue.each(&x) }
342
+ end
343
+
344
+ # returns all atoms
345
+ def atoms
346
+ array = []
347
+ self.each_residue { |residue| array.concat(residue.atoms) }
348
+ return array
349
+ end
350
+ end #module AtomFinder
351
+
352
+ # methods to access HETATMs
353
+ #
354
+ # XXX#each_heterogen must be defined.
355
+ #
356
+ # Bio::PDB::HetatmFinder is included by Bio::PDB::PDB, Bio::PDB::Model,
357
+ # Bio::PDB::Chain, and Bio::PDB::Heterogen.
358
+ #
359
+ module HetatmFinder
360
+ # returns an array containing all HETATMs for which given block
361
+ # is not +false+ (similar to Enumerable#find_all).
362
+ def find_hetatm
363
+ array = []
364
+ self.each_hetatm do |hetatm|
365
+ array.push(hetatm) if yield(hetatm)
366
+ end
367
+ return array
368
+ end
369
+
370
+ # iterates over each HETATM
371
+ def each_hetatm(&x) #:yields: hetatm
372
+ self.each_heterogen { |heterogen| heterogen.each(&x) }
373
+ end
374
+
375
+ # returns all HETATMs
376
+ def hetatms
377
+ array = []
378
+ self.each_heterogen { |heterogen| array.concat(heterogen.hetatms) }
379
+ return array
380
+ end
381
+ end #module HetatmFinder
382
+
383
+ # methods to access heterogens (compounds or ligands)
384
+ #
385
+ # XXX#each_chain must be defined.
386
+ #
387
+ # Bio::PDB::HeterogenFinder is included by Bio::PDB::PDB, Bio::PDB::Model,
388
+ # and Bio::PDB::Chain.
389
+ #
390
+ module HeterogenFinder
391
+ # returns an array containing all heterogens for which given block
392
+ # is not +false+ (similar to Enumerable#find_all).
393
+ def find_heterogen
394
+ array = []
395
+ self.each_heterogen do |heterogen|
396
+ array.push(heterogen) if yield(heterogen)
397
+ end
398
+ return array
399
+ end
400
+
401
+ # iterates over each heterogens
402
+ def each_heterogen(&x) #:yields: heterogen
403
+ self.each_chain { |chain| chain.each_heterogen(&x) }
404
+ end
405
+
406
+ # returns all heterogens
407
+ def heterogens
408
+ array = []
409
+ self.each_chain { |chain| array.concat(chain.heterogens) }
410
+ return array
230
411
  end
231
- end
412
+ end #module HeterogenFinder
232
413
 
233
414
  end; end #module Bio; class PDB
234
415