hydrogen_bondifier 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -6,6 +6,7 @@
6
6
  # see this on hydrogen bond finding in pymol:
7
7
  # http://www.mail-archive.com/pymol-users@lists.sourceforge.net/msg06680.html
8
8
 
9
+
9
10
  require 'yaml'
10
11
  require 'narray'
11
12
  require 'optparse'
@@ -60,13 +61,12 @@ if ARGV.size == 0
60
61
  exit
61
62
  end
62
63
 
63
- files = ARGV.map
64
+ files = ARGV.dup
64
65
  ARGV.clear
65
66
 
66
67
  categories = %w(D_id H_id A_id H_name D_res D_res_id D_name A_res A_res_id A_name angle D_A_dist H_A_dist H_dist_to_surf)
67
68
 
68
69
  files.each do |file|
69
-
70
70
  ####################
71
71
  # need to implement copying of file, etc......
72
72
  ####################
data/spec/pymol_spec.rb CHANGED
@@ -13,7 +13,6 @@ describe 'pymol running basic tests' do
13
13
 
14
14
  after do
15
15
  File.unlink @file if File.exist?(@file)
16
- File.unlink @file if File.exist?(@file)
17
16
  end
18
17
 
19
18
  it 'can run commands and wait for a file to be written' do
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydrogen_bondifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 3
9
+ version: 0.0.3
5
10
  platform: ruby
6
11
  authors:
7
12
  - John T. Prince
@@ -9,19 +14,22 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-02-10 00:00:00 -07:00
17
+ date: 2010-11-30 00:00:00 -07:00
13
18
  default_executable: hydrogen_bondifier.rb
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: spec-more
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
20
25
  requirements:
21
26
  - - ">="
22
27
  - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
23
30
  version: "0"
24
- version:
31
+ type: :development
32
+ version_requirements: *id001
25
33
  description: uses pymol
26
34
  email: jtprince@gmail.com
27
35
  executables:
@@ -32,46 +40,20 @@ extra_rdoc_files:
32
40
  - LICENSE
33
41
  - README.rdoc
34
42
  files:
35
- - .gitignore
36
- - History
43
+ - VERSION
37
44
  - LICENSE
38
45
  - README.rdoc
39
- - Rakefile
40
- - VERSION
41
- - bin/hydrogen_bondifier.rb
42
- - lib/hydrogen_bondifier/utils.rb
43
- - lib/pymol.rb
44
- - lib/pymol/connections.rb
45
- - lib/pymol/hydrogen_bonds.rb
46
- - lib/pymol/orientation.rb
47
- - lib/pymol/surface.rb
48
- - reference/all_connections.py
49
- - reference/campbell_find_hb.py
50
- - reference/list_hbonds.py
51
- - reference/test_pymol.rb
52
- - spec/pymol/connections_spec.rb
53
- - spec/pymol/hydrogen_bonds_spec.rb
54
- - spec/pymol/surface_spec.rb
55
- - spec/pymol_spec.rb
56
- - spec/scripts/confirm_angle_and_h_dist.rb
57
- - spec/scripts/confirm_distances.rb
58
46
  - spec/scripts/mins.rb
47
+ - spec/scripts/confirm_distances.rb
48
+ - spec/scripts/confirm_angle_and_h_dist.rb
59
49
  - spec/scripts/obj_ranges.rb
60
50
  - spec/scripts/pdb_ranges.rb
51
+ - spec/pymol_spec.rb
52
+ - spec/pymol/hydrogen_bonds_spec.rb
53
+ - spec/pymol/connections_spec.rb
54
+ - spec/pymol/surface_spec.rb
61
55
  - spec/spec_helper.rb
62
- - spec/testfiles/1YQS.pdb
63
- - spec/testfiles/1YQS_h_added.pdb
64
- - spec/testfiles/2ERK_Hbond.out
65
- - spec/testfiles/2pERK2_HBOND.out
66
- - spec/testfiles/2pERK2_Hadded.pdb
67
- - spec/testfiles/2pERK2_dis-surf.txt
68
- - spec/testfiles/little.pdb
69
- - validation/jtp_vs_insight_angles.png
70
- - validation/jtp_vs_insight_distances.png
71
- - validation/jtp_vs_insight_surface_distances.png
72
- - validation/jtp_vs_insight_surface_distances_aa_geometric.png
73
- - validation/jtp_vs_insight_surface_distances_center_of_grav.png
74
- - validation/jtp_vs_insight_surface_distances_closest_atom.png
56
+ - bin/hydrogen_bondifier.rb
75
57
  has_rdoc: true
76
58
  homepage: http://jtprince.github.com/hydrogen_bondifier
77
59
  licenses: []
@@ -82,32 +64,36 @@ rdoc_options:
82
64
  require_paths:
83
65
  - lib
84
66
  required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
85
68
  requirements:
86
69
  - - ">="
87
70
  - !ruby/object:Gem::Version
71
+ segments:
72
+ - 0
88
73
  version: "0"
89
- version:
90
74
  required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
91
76
  requirements:
92
77
  - - ">="
93
78
  - !ruby/object:Gem::Version
79
+ segments:
80
+ - 0
94
81
  version: "0"
95
- version:
96
82
  requirements: []
97
83
 
98
84
  rubyforge_project:
99
- rubygems_version: 1.3.5
85
+ rubygems_version: 1.3.7
100
86
  signing_key:
101
87
  specification_version: 3
102
88
  summary: finds hydrogen bonds using pymol
103
89
  test_files:
104
- - spec/scripts/obj_ranges.rb
105
- - spec/scripts/pdb_ranges.rb
106
90
  - spec/scripts/mins.rb
107
- - spec/scripts/confirm_angle_and_h_dist.rb
108
91
  - spec/scripts/confirm_distances.rb
92
+ - spec/scripts/confirm_angle_and_h_dist.rb
93
+ - spec/scripts/obj_ranges.rb
94
+ - spec/scripts/pdb_ranges.rb
109
95
  - spec/pymol_spec.rb
110
- - spec/spec_helper.rb
111
96
  - spec/pymol/hydrogen_bonds_spec.rb
112
97
  - spec/pymol/connections_spec.rb
113
98
  - spec/pymol/surface_spec.rb
99
+ - spec/spec_helper.rb
data/.gitignore DELETED
@@ -1,3 +0,0 @@
1
- .*.swp
2
- *.gemspec
3
- pkg
data/History DELETED
@@ -1,9 +0,0 @@
1
- == 0.0.2 / 2010-02-10
2
-
3
- * switched to system calls using temp files. Note that Tempfiles on windows do not work at least the way I am trying to use them.
4
-
5
- == 0.0.1 / 2009-12
6
-
7
- * using pipes
8
-
9
-
data/Rakefile DELETED
@@ -1,54 +0,0 @@
1
-
2
- require 'rubygems'
3
- require 'rake'
4
- require 'jeweler'
5
- require 'rake/testtask'
6
- # require 'rcov/rcovtask'
7
-
8
- NAME = "hydrogen_bondifier"
9
- WEBSITE_BASE = "website"
10
- WEBSITE_OUTPUT = WEBSITE_BASE + "/output"
11
-
12
- gemspec = Gem::Specification.new do |s|
13
- s.name = NAME
14
- s.authors = ["John T. Prince"]
15
- s.email = "jtprince@gmail.com"
16
- s.homepage = "http://jtprince.github.com/" + NAME
17
- s.summary = "finds hydrogen bonds using pymol"
18
- s.description = "uses pymol"
19
- #s.rubyforge_project = 'mspire'
20
- # s.add_dependency("ms-core", ">= 0.0.2")
21
- # s.add_development_dependency("ms-testdata", ">= 0.18.0")
22
- s.add_development_dependency("spec-more")
23
- s.files << "VERSION"
24
- end
25
-
26
- Jeweler::Tasks.new(gemspec)
27
-
28
- Rake::TestTask.new(:spec) do |spec|
29
- spec.libs << 'lib' << 'spec'
30
- spec.pattern = 'spec/**/*_spec.rb'
31
- spec.verbose = true
32
- end
33
-
34
- #Rcov::RcovTask.new do |spec|
35
- # spec.libs << 'spec'
36
- # spec.pattern = 'spec/**/*_spec.rb'
37
- # spec.verbose = true
38
- #end
39
-
40
- require 'rake/rdoctask'
41
- Rake::RDocTask.new do |rdoc|
42
- base_rdoc_output_dir = WEBSITE_OUTPUT + '/rdoc'
43
- version = File.read('VERSION')
44
- rdoc.rdoc_dir = base_rdoc_output_dir + "/#{version}"
45
- rdoc.title = NAME + ' ' + version
46
- rdoc.rdoc_files.include('README*')
47
- rdoc.rdoc_files.include('lib/**/*.rb')
48
- end
49
-
50
- task :default => :spec
51
-
52
- task :build => :gemspec
53
-
54
- # credit: Rakefile modeled after Jeweler's
@@ -1,39 +0,0 @@
1
- require 'narray'
2
-
3
- module Bio
4
- class PDB
5
- module Utils
6
-
7
- module_function
8
- # calculates the angle between 2 Narray vecs (in radians)
9
- def angle_between_vectors(vec1, vec2)
10
- vec1 = NArray.to_na(vec1.to_a) unless vec1.is_a?(NArray)
11
- vec2 = NArray.to_na(vec2.to_a) unless vec2.is_a?(NArray)
12
- nil_vec = NArray[0.0, 0.0, 0.0]
13
- return nil if (vec1 == nil_vec or vec2 == nil_vec)
14
- (mag_a, mag_b) = [vec1,vec2].map {|vec| Math::sqrt((vec*vec).sum) }
15
- # acos(dotprod / |a||b|)
16
- Bio::PDB::Utils.acos( (vec1 * vec2).sum.to_f / (mag_a * mag_b) )
17
- end
18
-
19
- def angle_from_coords(triplet)
20
- a = triplet.last - triplet[1]
21
- b = triplet.first - triplet[1]
22
- angle_between_vectors(a,b)
23
- end
24
-
25
- # other is 3 parallel NArray objects with the x, y and z coordinates
26
- # or a triplet like coord
27
- def distance_to_many(coord, other)
28
- # distance may be another narray or an array of vecs
29
- sq_diffs = []
30
- (0...(coord.size)).each do |i|
31
- pos = coord[i]
32
- oth = other[i]
33
- sq_diffs << (oth - pos)**2
34
- end
35
- NMath.sqrt(sq_diffs.inject {|sum, vec| sum + vec })
36
- end
37
- end
38
- end
39
- end
data/lib/pymol.rb DELETED
@@ -1,93 +0,0 @@
1
- require 'tempfile'
2
-
3
-
4
- class Pymol
5
-
6
- TMP_PYTHON_SCRIPT_FILENAME = "python_script_for_pymol"
7
- TMP_PYMOL_SCRIPT_FILENAME = "pymol_script"
8
- TMP_PYMOL_REPLY_FILENAME = "pymol_reply"
9
-
10
- PYMOL_SCRIPT_POSTFIX = '.pml' # <- very freaking important
11
- PYTHON_SCRIPT_POSTFIX = '.py' # <- very freaking important
12
-
13
- attr_accessor :cmds
14
-
15
- def self.run(opt={}, &block)
16
- self.new.run(opt, &block)
17
- end
18
-
19
- def initialize
20
- @cmds = []
21
- end
22
-
23
- def cmd(string)
24
- @cmds << string
25
- end
26
-
27
- def tmp_file(base, postfix)
28
- [base, $$, Time.now.to_f].join('-') << postfix
29
- end
30
-
31
- # you can add your path to pymol to this array if you need to
32
- # or with a commandline flag
33
- PYMOL_EXE_TO_TRY = ['PyMOL.exe', 'pymol']
34
-
35
- ####################################################
36
- # determine if we have pymol and how to execute it
37
- ####################################################
38
- PYMOL_EXE_TO_TRY.unshift(ENV['PYMOL_EXE']) if ENV['PYMOL_EXE']
39
- to_use = false
40
- PYMOL_EXE_TO_TRY.each do |name|
41
- begin
42
- _cmd = "#{name} -cq"
43
- if system(_cmd)
44
- to_use = _cmd
45
- break
46
- end
47
- rescue
48
- end
49
- end
50
-
51
- if to_use
52
- PYMOL_QUIET = to_use
53
- puts "pymol executable looks good: '#{PYMOL_QUIET}'" if $VERBOSE
54
- else
55
- abort "pymol not installed or can't find path, specify with --path-to-pymol" if !to_use
56
- end
57
-
58
- def run(opt={}, &block)
59
- puts( "[working in pymol]: " + opt[:msg] + " ...") if (opt[:msg] && $VERBOSE)
60
-
61
- block.call(self)
62
-
63
- cmds_to_run = self.cmds.map
64
-
65
- tmpfiles = []
66
- if script = opt[:script]
67
- script_tmpfn = tmp_file TMP_PYTHON_SCRIPT_FILENAME, PYTHON_SCRIPT_POSTFIX
68
- File.open(script_tmpfn, 'w') {|out| out.print script }
69
- tmpfiles << script_tmpfn
70
- cmds_to_run.unshift( "run #{script_tmpfn}" )
71
- end
72
-
73
- to_run = cmds_to_run.map {|v| v + "\n" }.join
74
-
75
- pymol_tmpfn = tmp_file TMP_PYMOL_SCRIPT_FILENAME, PYMOL_SCRIPT_POSTFIX
76
- File.open(pymol_tmpfn, 'w') {|out| out.print to_run }
77
- tmpfiles << pymol_tmpfn
78
-
79
- # much more suave to open a pipe, but python does not play well with pipes
80
- # and this is *MUCH* more compatible with windows
81
- pymol_reply_tmpfn = tmp_file TMP_PYMOL_REPLY_FILENAME, '.pmolreply'
82
- tmpfiles << pymol_reply_tmpfn
83
- system_cmd = "#{PYMOL_QUIET} #{pymol_tmpfn} > #{pymol_reply_tmpfn}"
84
- system system_cmd
85
-
86
- reply = IO.read(pymol_reply_tmpfn)
87
-
88
- tmpfiles.each {|tmpf| File.unlink tmpf }
89
- self.cmds.clear
90
- reply
91
- end
92
-
93
- end
@@ -1,55 +0,0 @@
1
- require 'pymol'
2
-
3
- class Pymol
4
- module Connections
5
- module Script
6
- module_function
7
-
8
- def all_connections_script
9
- %Q{
10
- from pymol import cmd
11
-
12
- def all_connections(selection):
13
- """
14
- USAGE
15
-
16
- all_connections selection
17
-
18
- returns lines: "CONNECTION: id - id"
19
- """
20
- stored.xs = []
21
- cmd.iterate(selection, 'stored.xs.append( index )')
22
- for i in stored.xs:
23
- selName = "neighbor%s" % i
24
- ids = cmd.select(selName, ("%s and neighbor id %s" % (selection, i)))
25
- base = "CONNECTION: %s - " % i
26
- to_print = base + "%s"
27
- print_string = 'print "' + to_print + '" % index'
28
- cmd.iterate(selName, print_string )
29
-
30
- cmd.extend("all_connections", all_connections)
31
- }
32
- end
33
-
34
- # returns an array of all pairs of atom IDs with no redundancy
35
- def all_connections_parser(reply_from_all_connections, flag=/^CONNECTION: /)
36
- pairs = reply_from_all_connections.split("\n").select {|v| v =~ flag }.map do |line|
37
- line.split(':').last.split(' - ').map {|v| v.to_i }.sort
38
- end
39
- pairs.uniq
40
- end
41
-
42
- end
43
-
44
- module_function
45
-
46
- # returns all connections as pairs of ID's (all uniq)
47
- def from_pdb(pdb)
48
- reply = Pymol.run(:msg => 'getting all atom connections', :script => Pymol::Connections::Script.all_connections_script) do |pm|
49
- pm.cmd "load #{pdb}, mymodel"
50
- pm.cmd "all_connections mymodel"
51
- end
52
- Pymol::Connections::Script.all_connections_parser(reply)
53
- end
54
- end
55
- end
@@ -1,157 +0,0 @@
1
- require 'pymol'
2
- require 'pymol/connections'
3
-
4
- require 'bio/db/pdb'
5
- require 'hydrogen_bondifier/utils'
6
-
7
- class Pymol
8
- EXCLUDE_WATER_FILTER = " &! resn hoh"
9
- module HydrogenBonds
10
-
11
- DEFAULT_FIND_PAIRS_OPTS = {:max_dist => 3.2, :max_angle => 60, :exclude_water => true }
12
- DEFAULT_H_BOND_OPTS = {
13
- :select_donor => "and (elem n,o and (neighbor hydro))",
14
- :select_acceptor => "and (elem o or (elem n and not (neighbor hydro)))",
15
- }
16
-
17
- module_function
18
-
19
- def pdb_with_hydrogens(pdb_filename, newname=nil)
20
- pfile = pdb_filename
21
- newname = pfile.chomp(File.extname(pfile)) + "_plus_h.pdb" unless newname
22
- Pymol.run(:msg => 'creating pdb with hydrogens') do |pm|
23
- pm.cmd "load #{pfile}, mymodel"
24
- pm.cmd "h_add"
25
- pm.cmd "save #{newname}"
26
- end
27
- newname
28
- end
29
-
30
- # returns [id1, id2, distance] for each atom
31
- def find_pairs(file, sel1, sel2, opt={})
32
- opt = DEFAULT_FIND_PAIRS_OPTS.merge( opt )
33
- exclude_water_command = opt[:exclude_water] ? EXCLUDE_WATER_FILTER : ""
34
- hbond_script = Pymol::HydrogenBonds.list_hb_script(sel1, sel2)
35
- reply = Pymol.run(:msg => "getting hydrogen bonds", :script => hbond_script) do |pm|
36
- pm.cmd "load #{file}, mymodel"
37
- pm.cmd "list_hb mymodel#{exclude_water_command}, cutoff=#{opt[:max_dist]}, angle=#{opt[:max_angle]}"
38
- end
39
- Pymol::HydrogenBonds.list_hb_parser(reply)
40
- end
41
-
42
-
43
- # returns [donor, hydrogen, acceptor, angle, don_to_acc_dist, h_to_acc_dist]
44
- # The first three are Bio::PDB::Record::ATOM structs.
45
- # respects DEFAULT_FIND_PAIRS_OPTS and DEFAULT_H_BOND_OPTS
46
- # expects that hydrogen bonds are already specified in the PDB file
47
- # returns an array triplet atom IDs [donor, hydrogen, acceptor]
48
- # :connections can be passed in (an array of arrays of all unique pairwise
49
- # connections [by ID])
50
- def from_pdb(file, opt={})
51
- opt = DEFAULT_H_BOND_OPTS.merge(opt)
52
-
53
- pairs = find_pairs(file, opt[:select_donor], opt[:select_acceptor], opt)
54
-
55
- connection_pairs = Pymol::Connections.from_pdb(file)
56
- connection_index = Hash.new {|h,k| h[k] = [] }
57
- connection_pairs.each do |pair|
58
- connection_index[pair.first] << pair.last
59
- connection_index[pair.last] << pair.first
60
- end
61
-
62
- # make an index of the atoms
63
- pdb = Bio::PDB.new(IO.read(file))
64
- pdb.extend(Bio::PDB::AtomFinder)
65
- atom_index = []
66
- pdb.each_atom do |atom|
67
- atom_index[atom.serial] = atom
68
- end
69
-
70
- max_angle = opt[:max_angle] || DEFAULT_FIND_PAIRS_OPTS[:max_angle]
71
- cutoff_in_degress = max_angle
72
-
73
- hbonds = []
74
- puts "calculating angles and distances" if $VERBOSE
75
- pairs.each do |don_id, acc_id, don_to_acc_dist|
76
- donor = atom_index[don_id]
77
- acceptor = atom_index[acc_id]
78
- next if (acceptor.element == 'H' or donor.element == 'H') # check for sloppy queries
79
- acceptor_xyz = acceptor.xyz
80
- donor_xyz = donor.xyz
81
- connection_index[don_id].each do |id|
82
- hydrogen = atom_index[id]
83
- next if hydrogen.element != 'H'
84
-
85
- #puts "ACCEPT ID: "
86
- #puts acc_id
87
- #p acceptor_xyz
88
- #puts "HYDRO ID: "
89
- #p id
90
- #p hydrogen.xyz
91
-
92
- angle = Bio::PDB::Utils.angle_from_coords([donor_xyz, hydrogen.xyz, acceptor_xyz])
93
- h_to_acc_dist = Bio::PDB::Utils.distance(hydrogen.xyz, acceptor_xyz)
94
-
95
- #puts "DISTANCES: "
96
- #p don_to_acc_dist
97
- #p h_to_acc_dist
98
- # abort 'here'
99
-
100
- # I'm not sure why the angle cutoff is not being respected, but we
101
- # can enforce it right here since we want the angles anyway
102
- if (180.0 - Bio::PDB::Utils.rad2deg(angle)) <= cutoff_in_degress
103
- hbonds << [donor, hydrogen, acceptor, angle, don_to_acc_dist, h_to_acc_dist]
104
- end
105
- end
106
- end
107
- hbonds
108
- end
109
-
110
- def list_hb_script(select1, select2)
111
- %Q{
112
- # modified by JTP from here:
113
- # Dr. Robert L. Campbell
114
- # http://pldserver1.biochem.queensu.ca/~rlc/work/pymol/
115
- # find_pairs is an undocumented method but mode==1 is hydrogen bond finding
116
-
117
- from pymol import cmd
118
-
119
- def list_hb(selection,cutoff=3.2,angle=55,hb_list_name='hbonds'):
120
- """
121
- USAGE
122
-
123
- list_hb selection, [cutoff (default=3.2)], [angle (default=55)], [hb_list_name]
124
-
125
- e.g.
126
- list_hb 1abc & c. a &! r. hoh, cutoff=3.2, hb_list_name=abc-hbonds
127
- """
128
- cutoff=float(cutoff)
129
- angle=float(angle)
130
- hb = cmd.find_pairs("((byres "+selection+") #{select1})","((byres "+selection+") #{select2})",mode=1,cutoff=cutoff,angle=angle)
131
- # sort the list for easier reading
132
- hb.sort(lambda x,y:(cmp(x[0][1],y[0][1])))
133
-
134
- for pairs in hb:
135
- print "PAIR:",
136
- for ind in [0,1]:
137
- cmd.iterate("%s and index %s" % (pairs[ind][0],pairs[ind][1]), 'print "%s/%3s`%s/%s/%s " % (chain,resn,resi,name,index),')
138
- print "%.2f" % cmd.distance(hb_list_name,"%s and index %s" % (pairs[0][0],pairs[0][1]),"%s and index %s" % (pairs[1][0],pairs[1][1]))
139
-
140
- cmd.extend("list_hb",list_hb)
141
- }
142
- end
143
-
144
- # takes output of hb_script and returns an array of triplets [id1, id2, distance]
145
- def list_hb_parser(pymol_hb_script_reply, flag=/^PAIR: /)
146
- # grab each line of output with specified header, then remove the header
147
- hbond_lines = pymol_hb_script_reply.split("\n").select {|line| line =~ flag }.map {|line| line.sub(flag,'') }
148
-
149
- ids_and_distances = hbond_lines.map do |line|
150
- # A/THR`325/N/2478 A/ALA`323/O/2468 3.05
151
- (first, second, dist) = line.split(/\s+/)
152
- (id1, id2) = [first, second].map {|v| v.split('/').last.to_i }
153
- [id1, id2, dist.to_f]
154
- end
155
- end
156
- end
157
- end