hydrogen_bondifier 0.0.2
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.
- data/.gitignore +3 -0
- data/History +9 -0
- data/LICENSE +23 -0
- data/README.rdoc +67 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/bin/hydrogen_bondifier.rb +159 -0
- data/lib/hydrogen_bondifier/utils.rb +39 -0
- data/lib/pymol/connections.rb +55 -0
- data/lib/pymol/hydrogen_bonds.rb +157 -0
- data/lib/pymol/orientation.rb +23 -0
- data/lib/pymol/surface.rb +35 -0
- data/lib/pymol.rb +93 -0
- data/reference/all_connections.py +24 -0
- data/reference/campbell_find_hb.py +18 -0
- data/reference/list_hbonds.py +47 -0
- data/reference/test_pymol.rb +125 -0
- data/spec/pymol/connections_spec.rb +25 -0
- data/spec/pymol/hydrogen_bonds_spec.rb +38 -0
- data/spec/pymol/surface_spec.rb +47 -0
- data/spec/pymol_spec.rb +41 -0
- data/spec/scripts/confirm_angle_and_h_dist.rb +126 -0
- data/spec/scripts/confirm_distances.rb +83 -0
- data/spec/scripts/mins.rb +9 -0
- data/spec/scripts/obj_ranges.rb +22 -0
- data/spec/scripts/pdb_ranges.rb +30 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/testfiles/1YQS.pdb +6655 -0
- data/spec/testfiles/1YQS_h_added.pdb +7924 -0
- data/spec/testfiles/2ERK_Hbond.out +302 -0
- data/spec/testfiles/2pERK2_HBOND.out +303 -0
- data/spec/testfiles/2pERK2_Hadded.pdb +5767 -0
- data/spec/testfiles/2pERK2_dis-surf.txt +330 -0
- data/spec/testfiles/little.pdb +210 -0
- data/validation/jtp_vs_insight_angles.png +0 -0
- data/validation/jtp_vs_insight_distances.png +0 -0
- data/validation/jtp_vs_insight_surface_distances.png +0 -0
- data/validation/jtp_vs_insight_surface_distances_aa_geometric.png +0 -0
- data/validation/jtp_vs_insight_surface_distances_center_of_grav.png +0 -0
- data/validation/jtp_vs_insight_surface_distances_closest_atom.png +0 -0
- metadata +113 -0
data/lib/pymol.rb
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
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
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
from pymol import cmd
|
|
3
|
+
|
|
4
|
+
def all_connections(selection):
|
|
5
|
+
"""
|
|
6
|
+
USAGE
|
|
7
|
+
|
|
8
|
+
all_connections selection
|
|
9
|
+
|
|
10
|
+
returns lines: "CONNECTION: id id"
|
|
11
|
+
"""
|
|
12
|
+
stored.xs = []
|
|
13
|
+
cmd.iterate(selection, 'stored.xs.append( index )')
|
|
14
|
+
#outit = open("all_connections.output.tmp", 'w')
|
|
15
|
+
for i in stored.xs:
|
|
16
|
+
selName = "neighbor%s" % i
|
|
17
|
+
ids = cmd.select(selName, ("%s and neighbor id %s" % (selection, i)))
|
|
18
|
+
base = "CONNECTION: %s - " % i
|
|
19
|
+
to_print = base + "%s"
|
|
20
|
+
print_string = 'print "' + to_print + '" % index'
|
|
21
|
+
cmd.iterate(selName, print_string )
|
|
22
|
+
|
|
23
|
+
cmd.extend("all_connections", all_connections)
|
|
24
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
# http://www.mail-archive.com/pymol-users@lists.sourceforge.net/msg06211.html
|
|
3
|
+
|
|
4
|
+
from pymol import cmd
|
|
5
|
+
|
|
6
|
+
def print_hb(selection):
|
|
7
|
+
hb = cmd.find_pairs("((byres "+selection+") and n;n)","((byres "+selection+") and n;o)",mode=1,cutoff=3.7,angle=55)
|
|
8
|
+
|
|
9
|
+
pair1_list = []
|
|
10
|
+
pair2_list = []
|
|
11
|
+
dist_list = []
|
|
12
|
+
for pairs in hb:
|
|
13
|
+
cmd.iterate("%s and ID %s" % (pairs[0][0],pairs[0][1]), 'print "%s/%3s`%s/%s " % (chain,resn,resi,name),')
|
|
14
|
+
cmd.iterate("%s and ID %s" % (pairs[1][0],pairs[1][1]), 'print "%s/%3s`%s/%s " % (chain,resn,resi,name),')
|
|
15
|
+
print "%.2f" % cmd.dist("%s and ID %s" % (pairs[0][0],pairs[0][1]),"%s and ID %s" % (pairs[1][0],pairs[1][1]))
|
|
16
|
+
|
|
17
|
+
cmd.extend("print_hb",print_hb)
|
|
18
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
# list_hb <selection>, cutoff=3.2 (default)
|
|
3
|
+
|
|
4
|
+
# exclude waters first:
|
|
5
|
+
# list_hb 1xnb &! r. hoh, cutoff=3.2
|
|
6
|
+
|
|
7
|
+
# from: ./pymol/trunk/pymol/layer3/Selector.c
|
|
8
|
+
#
|
|
9
|
+
# if(mode == 1) {
|
|
10
|
+
# angle_cutoff = (float) cos(PI * h_angle / 180.8);
|
|
11
|
+
# }
|
|
12
|
+
# ## cos(PI * 55 / 180.8) => 0.577 # just converts to radians and takes the cosine
|
|
13
|
+
# ## so, they take the cosine of the angle as the "angle_cutoff"
|
|
14
|
+
|
|
15
|
+
# if(mode == 1) { /* coarse hydrogen bonding assessment */
|
|
16
|
+
# ## so, mode 1 is hydrogen bonding finding.
|
|
17
|
+
# flag = false;
|
|
18
|
+
# if(ObjectMoleculeGetAvgHBondVector(obj1, at1, state1, v1, NULL) > 0.3)
|
|
19
|
+
# if(dot_product3f(v1, dir) < -angle_cutoff)
|
|
20
|
+
# flag = true;
|
|
21
|
+
# if(ObjectMoleculeGetAvgHBondVector(obj2, at2, state2, v2, NULL) > 0.3)
|
|
22
|
+
# if(dot_product3f(v2, dir) > angle_cutoff)
|
|
23
|
+
# flag = true;
|
|
24
|
+
|
|
25
|
+
from pymol import cmd
|
|
26
|
+
|
|
27
|
+
def list_hb(selection,cutoff=3.2,angle=55,hb_list_name='hbonds'):
|
|
28
|
+
"""
|
|
29
|
+
USAGE
|
|
30
|
+
|
|
31
|
+
list_hb selection, [cutoff (default=3.2)], [angle (default=55)], [hb_list_name]
|
|
32
|
+
|
|
33
|
+
e.g.
|
|
34
|
+
list_hb 1abc & c. a &! r. hoh, cutoff=3.2, hb_list_name=abc-hbonds
|
|
35
|
+
"""
|
|
36
|
+
cutoff=float(cutoff)
|
|
37
|
+
angle=float(angle)
|
|
38
|
+
hb = cmd.find_pairs("((byres "+selection+") and n;n)","((byres "+selection+") and n;o)",mode=1,cutoff=cutoff,angle=angle)
|
|
39
|
+
# sort the list for easier reading
|
|
40
|
+
hb.sort(lambda x,y:(cmp(x[0][1],y[0][1])))
|
|
41
|
+
|
|
42
|
+
for pairs in hb:
|
|
43
|
+
for ind in [0,1]:
|
|
44
|
+
cmd.iterate("%s and index %s" % (pairs[ind][0],pairs[ind][1]), 'print "%s/%3s`%s/%s/%s " % (chain,resn,resi,name,index),')
|
|
45
|
+
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]))
|
|
46
|
+
|
|
47
|
+
cmd.extend("list_hb",list_hb)
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
|
|
2
|
+
require 'open3'
|
|
3
|
+
|
|
4
|
+
cmd = 'pymol -cq -p'
|
|
5
|
+
|
|
6
|
+
#output = IO.popen("pymol -cq -p", 'w+') do |pipe|
|
|
7
|
+
#reader = Thread.new { pipe.to_a }
|
|
8
|
+
|
|
9
|
+
#pipe.puts "load 2pERK2_Hadded.pdb, mymodel"
|
|
10
|
+
#pipe.puts "run all_connections.py"
|
|
11
|
+
## this command will generate a whole bunch of output to stdout
|
|
12
|
+
#pipe.puts "all_connections mymodel"
|
|
13
|
+
|
|
14
|
+
#pipe.close_write
|
|
15
|
+
#reader.value
|
|
16
|
+
#end
|
|
17
|
+
|
|
18
|
+
#p output
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
my_string = ""
|
|
22
|
+
Open3.popen3("pymol -cq -p") do |si, so, se|
|
|
23
|
+
si.puts "load 2pERK2_Hadded.pdb, mymodel\n"
|
|
24
|
+
si.puts "run all_connections.py\n"
|
|
25
|
+
si.puts "all_connections mymodel\n"
|
|
26
|
+
|
|
27
|
+
# await input for 0.5 seconds, will return nil and
|
|
28
|
+
# break the loop if there is nothing to read from so after 0.5s
|
|
29
|
+
while ready = IO.select([so], nil, nil, 0.5)
|
|
30
|
+
# ready.first == so # in this case
|
|
31
|
+
|
|
32
|
+
# read until the current pipe buffer is empty
|
|
33
|
+
begin
|
|
34
|
+
my_string << so.read_nonblock(4096)
|
|
35
|
+
rescue Errno::EAGAIN
|
|
36
|
+
break
|
|
37
|
+
end while true
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
p my_string
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
#IO.popen("pymol -cq -p", 'w+') do |pipe|
|
|
45
|
+
#pipe.puts "load 2pERK2_Hadded.pdb, mymodel\n"
|
|
46
|
+
#pipe.puts "run all_connections.py"
|
|
47
|
+
#pipe.puts "all_connections mymodel"
|
|
48
|
+
#pipe.puts "quit"
|
|
49
|
+
|
|
50
|
+
#IO.select([pipe]) # you shouldn't need to uncomment this...
|
|
51
|
+
|
|
52
|
+
#output = pipe.read
|
|
53
|
+
#end
|
|
54
|
+
#p output
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
#my_string = ""
|
|
58
|
+
#Open3.popen3(cmd) do |si, so, se|
|
|
59
|
+
#si.puts "run all_connections.py\n"
|
|
60
|
+
#si.puts "load 2pERK2_Hadded.pdb, mdl\n"
|
|
61
|
+
##si.puts "show surface, mdl\n"
|
|
62
|
+
#si.puts "all_connections mdl\n"
|
|
63
|
+
#si.puts "print \"DONE\""
|
|
64
|
+
#stringsz = -1
|
|
65
|
+
|
|
66
|
+
#forstdout = Thread.new do
|
|
67
|
+
#Thread.current['lines'] = ""
|
|
68
|
+
#loop do
|
|
69
|
+
#Thread.current['lines'] << so.read(2024)
|
|
70
|
+
#end
|
|
71
|
+
#end
|
|
72
|
+
#past_size = -1
|
|
73
|
+
#loop do
|
|
74
|
+
#sleep(0.7)
|
|
75
|
+
#csize = forstdout['lines'].size
|
|
76
|
+
#break if csize == past_size
|
|
77
|
+
#past_size = csize
|
|
78
|
+
#end
|
|
79
|
+
#my_string = forstdout['lines']
|
|
80
|
+
#forstdout.kill
|
|
81
|
+
#si.close
|
|
82
|
+
#end
|
|
83
|
+
#p my_string.size
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
=begin
|
|
89
|
+
IO.popen(cmd, 'w') do |pipe|
|
|
90
|
+
pipe.puts "run all_connections.py\n"
|
|
91
|
+
pipe.puts "load 2pERK2_Hadded.pdb, mdl\n"
|
|
92
|
+
#pipe.puts "show surface, mdl\n"
|
|
93
|
+
pipe.puts "all_connections mdl\n"
|
|
94
|
+
pipe.puts "quit\n"
|
|
95
|
+
can_do = pipe.fsync
|
|
96
|
+
puts can_do
|
|
97
|
+
pipe.close_write
|
|
98
|
+
puts pipe.read
|
|
99
|
+
end
|
|
100
|
+
=end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
=begin
|
|
105
|
+
|
|
106
|
+
cmd = 'pymol -cq -p'
|
|
107
|
+
|
|
108
|
+
my_string = ""
|
|
109
|
+
Open3.popen3(cmd) do |si, so, se|
|
|
110
|
+
si.puts "run all_connections.py\n"
|
|
111
|
+
si.puts "load 2pERK2_Hadded.pdb, mdl\n"
|
|
112
|
+
si.puts "all_connections mdl\n"
|
|
113
|
+
loop do
|
|
114
|
+
if File.exist?("all_connections.output.tmp")
|
|
115
|
+
break
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
si.close
|
|
119
|
+
end
|
|
120
|
+
p my_string.size
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
=end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'pymol/connections'
|
|
5
|
+
|
|
6
|
+
describe 'pymol connections' do
|
|
7
|
+
|
|
8
|
+
before do
|
|
9
|
+
@file = 'little.pdb'
|
|
10
|
+
origfile = TESTFILES + '/' + @file
|
|
11
|
+
FileUtils.copy origfile, @file
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
after do
|
|
15
|
+
File.unlink @file if File.exist?(@file)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'finds all connections in the molecule' do
|
|
19
|
+
id_pairs = Pymol::Connections.from_pdb(@file)
|
|
20
|
+
id_pairs[0,2].enums [[1, 2], [1, 6]]
|
|
21
|
+
id_pairs[-2,2].enums [[204, 209], [205, 206]]
|
|
22
|
+
id_pairs.size.is 210
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'pymol/hydrogen_bonds'
|
|
5
|
+
|
|
6
|
+
describe 'pymol hydrogen bonds' do
|
|
7
|
+
|
|
8
|
+
before do
|
|
9
|
+
@file = 'little.pdb'
|
|
10
|
+
origfile = TESTFILES + '/' + @file
|
|
11
|
+
FileUtils.copy origfile, @file
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
after do
|
|
15
|
+
File.unlink @file if File.exist?(@file)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'finds hydrogen bonds' do
|
|
19
|
+
triplets = Pymol::HydrogenBonds.from_pdb(@file)
|
|
20
|
+
|
|
21
|
+
answers_but_atoms_as_ids = [[75, 82, 125, 2.70110007356142, 2.87, 1.9000997342245],
|
|
22
|
+
[122, 131, 78, 2.65823167164358, 2.94, 1.98408492761777],
|
|
23
|
+
[155, 166, 46, 2.77786431401053, 2.89, 1.90544535476618],
|
|
24
|
+
[187, 194, 158, 2.19624439858352, 2.86, 2.13271728084151]]
|
|
25
|
+
|
|
26
|
+
triplets.zip(answers_but_atoms_as_ids) do |row1, row2|
|
|
27
|
+
row1[0,3] = row1[0,3].map(&:serial)
|
|
28
|
+
row1.zip(row2) do |v1, v2|
|
|
29
|
+
if v1.is_a? Integer
|
|
30
|
+
v1.is v2
|
|
31
|
+
else
|
|
32
|
+
v1.should.be.close v2, 0.00001
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'pymol/surface'
|
|
5
|
+
|
|
6
|
+
class Object
|
|
7
|
+
def enums_close(other, delta)
|
|
8
|
+
self_ar = []
|
|
9
|
+
self.each do |v|
|
|
10
|
+
self_ar << v
|
|
11
|
+
end
|
|
12
|
+
other_ar = []
|
|
13
|
+
other.each do |v|
|
|
14
|
+
other_ar << v
|
|
15
|
+
end
|
|
16
|
+
self_ar.zip(other_ar) do |a,b|
|
|
17
|
+
if a.is_a? Enumerable
|
|
18
|
+
a.enums_close b, delta
|
|
19
|
+
else
|
|
20
|
+
a.should.be.close b, delta
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe 'pymol surface' do
|
|
27
|
+
|
|
28
|
+
before do
|
|
29
|
+
@file = 'little.pdb'
|
|
30
|
+
origfile = TESTFILES + '/' + @file
|
|
31
|
+
FileUtils.copy origfile, @file
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
after do
|
|
35
|
+
File.unlink @file if File.exist?(@file)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'finds surface coordinates' do
|
|
39
|
+
coords = Pymol::Surface.from_pdb(@file)
|
|
40
|
+
first_two = [[9.083281, 60.507313, 9.422514], [9.540758, 60.98122, 9.483328]]
|
|
41
|
+
last_two = [[7.323, 47.034184, 6.684179], [5.81, 47.229004, 6.411]]
|
|
42
|
+
coords[0,2].enums_close first_two, 0.0001
|
|
43
|
+
coords[-2,2].enums_close last_two, 0.0001
|
|
44
|
+
coords.size.is 9684
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
data/spec/pymol_spec.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'pymol'
|
|
5
|
+
|
|
6
|
+
describe 'pymol running basic tests' do
|
|
7
|
+
|
|
8
|
+
before do
|
|
9
|
+
@file = 'little.pdb'
|
|
10
|
+
origfile = TESTFILES + '/' + @file
|
|
11
|
+
FileUtils.copy origfile, @file
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
after do
|
|
15
|
+
File.unlink @file if File.exist?(@file)
|
|
16
|
+
File.unlink @file if File.exist?(@file)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'can run commands and wait for a file to be written' do
|
|
20
|
+
newfile = @file.sub(/\.pdb/i, ".HADDED.pdb")
|
|
21
|
+
reply = Pymol.run do |p|
|
|
22
|
+
p.cmd "load #{@file}, mdl"
|
|
23
|
+
p.cmd "h_add"
|
|
24
|
+
p.cmd "save #{newfile}"
|
|
25
|
+
end
|
|
26
|
+
ok File.exist?(newfile)
|
|
27
|
+
fs = File.size(newfile)
|
|
28
|
+
ok ((fs == 17014) or (fs == 16805)) # linux / windows filesizes
|
|
29
|
+
File.unlink(newfile) if File.exist?(newfile)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'can run commands and wait for stdout output' do
|
|
33
|
+
reply = Pymol.run do |p|
|
|
34
|
+
p.cmd "load #{@file}, mdl"
|
|
35
|
+
p.cmd "select mysel, mdl and elem o"
|
|
36
|
+
p.cmd 'iterate mysel, print "GRAB: %s" % index'
|
|
37
|
+
end
|
|
38
|
+
reply.split("\n").select {|line| line =~ /^GRAB: / }.size.is 20
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require 'gnuplot'
|
|
2
|
+
|
|
3
|
+
require 'runarray/more'
|
|
4
|
+
require 'narray'
|
|
5
|
+
require 'rsruby'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class NArray
|
|
9
|
+
include Runarray::More
|
|
10
|
+
alias_method :avg, :mean
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if ARGV.size != 2
|
|
14
|
+
puts "usage: #{File.basename(__FILE__)} <file>_hbonds.csv <file>_HBOND.out"
|
|
15
|
+
exit
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
(mine, theirs) = ARGV
|
|
19
|
+
|
|
20
|
+
lines = IO.readlines(mine)
|
|
21
|
+
lines.shift
|
|
22
|
+
|
|
23
|
+
my_angle_dist_by_res_and_name = {}
|
|
24
|
+
lines.each do |line|
|
|
25
|
+
pieces = line.split(',')
|
|
26
|
+
key = [pieces[5], pieces[3], pieces[8], pieces[9]]
|
|
27
|
+
my_angle_dist_by_res_and_name[key] = [pieces[10].to_f, pieces[12].to_f]
|
|
28
|
+
end
|
|
29
|
+
# ["22", "HE", "42", "OD1"] == ["22", "HE", "42", "OD1"]
|
|
30
|
+
#["43", "1HD2", "24", "OG1"]
|
|
31
|
+
#
|
|
32
|
+
#["48", "1HH1", "25", "O"]
|
|
33
|
+
#["48", "2HH2", "25", "O"]
|
|
34
|
+
#["48", "2HH2", "39", "OG"]
|
|
35
|
+
#
|
|
36
|
+
#["48", "HH21", "39", "OG"]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
lines = []
|
|
41
|
+
get_lines = false
|
|
42
|
+
IO.foreach(theirs) do |line|
|
|
43
|
+
if get_lines
|
|
44
|
+
lines << line
|
|
45
|
+
end
|
|
46
|
+
if line =~ /^Donor/
|
|
47
|
+
get_lines = true
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
puts "*******************************************"
|
|
52
|
+
puts "SECOND"
|
|
53
|
+
puts "*******************************************"
|
|
54
|
+
|
|
55
|
+
res_to_vals = {}
|
|
56
|
+
lines.each do |v|
|
|
57
|
+
pieces = v.chomp.split(/\s+/)
|
|
58
|
+
key = pieces[0].split(':')[1,2].push(*(pieces[1].split(':')[1,2]))
|
|
59
|
+
key[1] = key[1].sub(/^HN/,'H').sub(/^(\w+\d?)(\d)$/) {|md| $2 + $1 }
|
|
60
|
+
res_to_vals[key] = [pieces[3].to_f, pieces[2].to_f]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
a_x = []
|
|
64
|
+
a_y = []
|
|
65
|
+
d_x = []
|
|
66
|
+
d_y = []
|
|
67
|
+
my_angle_dist_by_res_and_name.each do |id, angle_dist|
|
|
68
|
+
(angle, dist) = angle_dist
|
|
69
|
+
(o_angle, o_dist) = res_to_vals[id]
|
|
70
|
+
if o_angle && o_dist
|
|
71
|
+
a_x << angle
|
|
72
|
+
a_y << o_angle
|
|
73
|
+
d_x << dist
|
|
74
|
+
d_y << o_dist
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
puts "EXAMINE"
|
|
78
|
+
p a_x
|
|
79
|
+
p a_y
|
|
80
|
+
|
|
81
|
+
intersection = a_x.size
|
|
82
|
+
my_hbond_count = my_angle_dist_by_res_and_name.size
|
|
83
|
+
their_hbond_count = res_to_vals.size
|
|
84
|
+
|
|
85
|
+
a_rsi = NArray.to_na(a_x).rsq_slope_intercept(NArray.to_na(a_y)).map {|v| "%0.2f" % v }
|
|
86
|
+
d_rsi = NArray.to_na(d_x).rsq_slope_intercept(NArray.to_na(d_y)).map {|v| "%0.2f" % v }
|
|
87
|
+
|
|
88
|
+
set_analysis = [[:jtp, my_hbond_count], [:insight, their_hbond_count], [:intersection, intersection]]
|
|
89
|
+
title_string = set_analysis.map {|pair| pair.join('=')}.join(', ')
|
|
90
|
+
|
|
91
|
+
Gnuplot.open do |gp|
|
|
92
|
+
Gnuplot::Plot.new(gp) do |plot|
|
|
93
|
+
plot.terminal "png"
|
|
94
|
+
plot.output "jtp_vs_insight_angles.png"
|
|
95
|
+
plot.title "2pERK2_Hadded.pdb - #{title_string}"
|
|
96
|
+
plot.xlabel "[JTP] donor, H, acceptor angle (degrees)"
|
|
97
|
+
plot.ylabel "[Insight] angle (degrees)"
|
|
98
|
+
|
|
99
|
+
plot.data << Gnuplot::DataSet.new( [a_x, a_y] ) do |ds|
|
|
100
|
+
ds.title = "RSQ=#{a_rsi[0]} SLOPE=#{a_rsi[1]} INT=#{a_rsi[2]}"
|
|
101
|
+
end
|
|
102
|
+
plot.data << Gnuplot::DataSet.new( [[118,180], [118,180]] ) do |ds|
|
|
103
|
+
ds.with = "lines"
|
|
104
|
+
ds.title = "perfect"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
Gnuplot.open do |gp|
|
|
110
|
+
Gnuplot::Plot.new(gp) do |plot|
|
|
111
|
+
plot.terminal "png"
|
|
112
|
+
plot.output "jtp_vs_insight_distances.png"
|
|
113
|
+
plot.title "2pERK2_Hadded.pdb - #{title_string}"
|
|
114
|
+
plot.xlabel "[JTP] distance (Angstrom)"
|
|
115
|
+
plot.ylabel "[Insight] distance (Angstrom)"
|
|
116
|
+
|
|
117
|
+
plot.data << Gnuplot::DataSet.new( [d_x, d_y] ) do |ds|
|
|
118
|
+
ds.title = "RSQ=#{d_rsi[0]} SLOPE=#{d_rsi[1]} INT=#{d_rsi[2]}"
|
|
119
|
+
end
|
|
120
|
+
plot.data << Gnuplot::DataSet.new( [[1,3], [1,3]] ) do |ds|
|
|
121
|
+
ds.with = "lines"
|
|
122
|
+
ds.title = "perfect"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/ruby -s
|
|
2
|
+
|
|
3
|
+
require 'rsruby'
|
|
4
|
+
require 'narray'
|
|
5
|
+
require 'runarray/more'
|
|
6
|
+
require 'gnuplot'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class NArray
|
|
11
|
+
include Runarray::More
|
|
12
|
+
alias_method :avg, :mean
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def pairs_from_their_format(file)
|
|
16
|
+
their_pairs = IO.readlines(file).map do |line|
|
|
17
|
+
pieces = line.chomp.split(/\s+/)
|
|
18
|
+
[pieces.first[3..-1].to_i, pieces.last.to_f]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if ARGV.size != 3
|
|
23
|
+
puts "[-s] theirs mine <from_what>"
|
|
24
|
+
exit
|
|
25
|
+
end
|
|
26
|
+
(theirs, mine, keywords) = ARGV
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if $s # mine is same format as theirs!
|
|
30
|
+
(their_pairs, my_pairs) = [theirs, mine].map {|f| pairs_from_their_format f }
|
|
31
|
+
their_index = []
|
|
32
|
+
their_pairs.each do |res, dist|
|
|
33
|
+
their_index[res] = dist
|
|
34
|
+
end
|
|
35
|
+
else
|
|
36
|
+
their_pairs = pairs_from_their_format(theirs)
|
|
37
|
+
|
|
38
|
+
lines = IO.readlines(mine)
|
|
39
|
+
lines.shift
|
|
40
|
+
|
|
41
|
+
my_pairs = lines.map do |line|
|
|
42
|
+
pieces = line.split(',')
|
|
43
|
+
[pieces[4].to_i, pieces[12].to_f]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
x = [] ; y = []
|
|
48
|
+
my_pairs.each do |i, dist|
|
|
49
|
+
if their_index[i]
|
|
50
|
+
x << dist
|
|
51
|
+
y << their_index[i]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
intersection = x.size
|
|
56
|
+
my_hbond_count = my_pairs.size
|
|
57
|
+
their_hbond_count = their_index.size
|
|
58
|
+
|
|
59
|
+
set_analysis = [[:jtp, my_hbond_count], [:insight, their_hbond_count], [:intersection, intersection]]
|
|
60
|
+
title_string = set_analysis.map {|pair| pair.join('=')}.join(', ')
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
(rsq, slope, inter) = NArray.to_na(x).rsq_slope_intercept(NArray.to_na(y)).map {|v| "%0.2f" % v }
|
|
64
|
+
|
|
65
|
+
Gnuplot.open do |gp|
|
|
66
|
+
Gnuplot::Plot.new(gp) do |plot|
|
|
67
|
+
plot.terminal "png"
|
|
68
|
+
plot.output "jtp_vs_insight_surface_distances_#{keywords.gsub(/\s+/,'_')}.png"
|
|
69
|
+
plot.title "2pERK2_Hadded.pdb - #{title_string}"
|
|
70
|
+
plot.xlabel "[JTP] distance from #{keywords} to surface (Angstrom)"
|
|
71
|
+
plot.ylabel "[Insight] distance from residue to surface (Angstrom)"
|
|
72
|
+
plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds|
|
|
73
|
+
ds.title = "RSQ=#{rsq} SLOPE=#{slope} INT=#{inter}"
|
|
74
|
+
end
|
|
75
|
+
plot.data << Gnuplot::DataSet.new( [[1,7], [1,7]] ) do |ds|
|
|
76
|
+
ds.with = "lines"
|
|
77
|
+
ds.title = "perfect"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|