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