bio 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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