lib/bio/db/pdb/pdb.rb in bio-1.0.0 vs lib/bio/db/pdb/pdb.rb in bio-1.1.0
- old
+ new
@@ -2,30 +2,14 @@
# = bio/db/pdb/pdb.rb - PDB database class for PDB file format
#
# Copyright:: Copyright (C) 2003-2006
# GOTO Naohisa <ngoto@gen-info.osaka-u.ac.jp>
# Alex Gutteridge <alexg@ebi.ac.uk>
-# License:: LGPL
+# License:: The Ruby License
#
-# $Id: pdb.rb,v 1.15 2006/02/20 13:00:43 ngoto Exp $
+# $Id: pdb.rb,v 1.23 2007/07/10 10:44:46 ngoto Exp $
#
-#--
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#++
-#
# = About Bio::PDB
#
# Please refer document of Bio::PDB class.
#
# = References
@@ -133,11 +117,11 @@
end
}
m
end
def self.new(str)
- String.new(str)
+ String.new(str.to_s)
end
end
module Pdb_Real
def self.[](fmt)
@@ -352,11 +336,11 @@
#
# Normally, it is automatically called and you don't explicitly
# need to call it .
#
def do_parse
- return self if @parsed
+ return self if @parsed or !@str
str = @str
each_symbol do |key, klass, ranges|
#If we only have one range then pull that out
#and store it in the hash
if ranges.size <= 1 then
@@ -988,35 +972,83 @@
def <=>(other)
return serial <=> other.serial
end
def do_parse
- return self if @parsed
+ return self if @parsed or !@str
self.serial = @str[6..10].to_i
- self.name = @str[12..15]
+ self.name = @str[12..15].strip
self.altLoc = @str[16..16]
- self.resName = @str[17..19].rstrip
+ self.resName = @str[17..19].strip
self.chainID = @str[21..21]
self.resSeq = @str[22..25].to_i
- self.iCode = @str[26..26]
+ self.iCode = @str[26..26].strip
self.x = @str[30..37].to_f
self.y = @str[38..45].to_f
self.z = @str[46..53].to_f
self.occupancy = @str[54..59].to_f
self.tempFactor = @str[60..65].to_f
- self.segID = @str[72..75]
- self.element = @str[76..77]
- self.charge = @str[78..79]
+ self.segID = @str[72..75].to_s.rstrip
+ self.element = @str[76..77].to_s.lstrip
+ self.charge = @str[78..79].to_s.strip
@parsed = true
self
end
+ def justify_atomname
+ atomname = self.name.to_s
+ return atomname[0, 4] if atomname.length >= 4
+ case atomname.length
+ when 0
+ return ' '
+ when 1
+ return ' ' + atomname + ' '
+ when 2
+ if /\A[0-9]/ =~ atomname then
+ return sprintf('%-4s', atomname)
+ elsif /[0-9]\z/ =~ atomname then
+ return sprintf(' %-3s', atomname)
+ end
+ when 3
+ if /\A[0-9]/ =~ atomname then
+ return sprintf('%-4s', atomname)
+ end
+ end
+ # ambiguous case for two- or three-letter name
+ elem = self.element.to_s.strip
+ if elem.size > 0 and i = atomname.index(elem) then
+ if i == 0 and elem.size == 1 then
+ return sprintf(' %-3s', atomname)
+ else
+ return sprintf('%-4s', atomname)
+ end
+ end
+ if self.kind_of?(HETATM) then
+ if /\A(B[^AEHIKR]|C[^ADEFLMORSU]|F[^EMR]|H[^EFGOS]|I[^NR]|K[^R]|N[^ABDEIOP]|O[^S]|P[^ABDMORTU]|S[^BCEGIMNR]|V|W|Y[^B])/ =~
+ atomname then
+ return sprintf(' %-3s', atomname)
+ else
+ return sprintf('%-4s', atomname)
+ end
+ else # ATOM
+ if /\A[CHONSP]/ =~ atomname then
+ return sprintf(' %-3s', atomname)
+ else
+ return sprintf('%-4s', atomname)
+ end
+ end
+ # could not be reached here
+ raise 'bug!'
+ end
+ private :justify_atomname
+
def to_s
+ atomname = justify_atomname
sprintf("%-6s%5d %-4s%-1s%3s %-1s%4d%-1s %8.3f%8.3f%8.3f%6.2f%6.2f %-4s%2s%-2s\n",
self.record_name,
self.serial,
- self.name,
+ atomname,
self.altLoc,
self.resName,
self.chainID,
self.resSeq,
self.iCode,
@@ -1501,10 +1533,11 @@
f.residue = ligand
ligand.addAtom(f)
when 'MODEL'
c_atom = nil
+ cChain = nil
if cModel.model_serial or cModel.chains.size > 0 then
self.addModel(cModel)
end
cModel = Model.new(f.serial)
@@ -1639,11 +1672,11 @@
# Example:
# p pdb.record('HETATM')
# p pdb.record['HETATM']
#
def record(name = nil)
- name ? @hash[name] : @hash
+ name ? (@hash[name] || []) : @hash
end
#--
# PDB original methods
#Returns a hash of the REMARK records based on the remarkNum
@@ -1802,40 +1835,46 @@
self.record('KEYWDS').collect { |f| f.keywds }.flatten
end
# Classification in "HEADER".
def classification
- self.record('HEADER').first.classification
+ f = self.record('HEADER').first
+ f ? f.classification : nil
end
# Get authors in "AUTHOR".
def authors
- self.record('AUTHOR').first.authorList
+ self.record('AUTHOR').collect { |f| f.authorList }.flatten
end
#--
# Bio::DB methods
#++
# PDB identifier written in "HEADER". (e.g. 1A00)
def entry_id
- @id = self.record('HEADER').first.idCode unless @id
+ unless @id
+ f = self.record('HEADER').first
+ @id = f ? f.idCode : nil
+ end
@id
end
# Same as <tt>Bio::PDB#entry_id</tt>.
def accession
self.entry_id
end
# Title of this entry in "TITLE".
def definition
- self.record('TITLE').first.title
+ f = self.record('TITLE').first
+ f ? f.title : nil
end
# Current modification number in "REVDAT".
def version
- self.record('REVDAT').first.modNum
+ f = self.record('REVDAT').first
+ f ? f.modNum : nil
end
end #class PDB
end #module Bio