File: jligand.py

package info (click to toggle)
coot 1.1.18%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 219,964 kB
  • sloc: cpp: 495,934; python: 35,043; ansic: 26,143; lisp: 22,768; sh: 13,186; makefile: 2,746; awk: 441; xml: 245; csh: 14
file content (224 lines) | stat: -rw-r--r-- 8,881 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
import numbers
# Coot and JLigand communicate via "secret" files.
# 
# Coot send to jligand the comp-ids it wants joined in *to-jligand-secret-file-name*.
#
# JLigand sends Coot a file that contains filenames for the link and
# new dictionary/restraints.
#
global to_jligand_secret_file_name
to_jligand_secret_file_name = ".coot-to-jligand-8lcs"
global from_jligand_secret_link_file_name
from_jligand_secret_link_file_name = ".jligand-to-coot-link"

# Define an environment variable for the place where jligand.jar
# resides in a canonical distribution
# Can be everywhere on windows? (maybe not in new ccp4!?) its in CCP4_BIN
#
setup_ccp4()
jligand_home_env = os.getenv("JLIGAND_HOME")
jligand_home = jligand_home_env if jligand_home_env else "."

global java_command
java_command = "java"

jligand_name = "JLigand.jar"
jligand_jar = os.path.join(os.path.normpath(jligand_home), jligand_name)
# Not yet as the old version uses different files...
if not os.path.isfile(jligand_jar):
    # lets try CCP4_BIN and JLigand.jar
    ccp4_bin = os.getenv("CCP4_BIN")
    if not ccp4_bin:
       ccp4_bin = os.getenv("CBIN")
    if ccp4_bin:
        jligand_jar = os.path.join(os.path.normpath(ccp4_bin), jligand_name)
jligand_args = ["-jar", jligand_jar, "-coot"] # for coot-enable jligand

# jligand internal parameter
global imol_jligand_link
imol_jligand_link = False

def jligand_code_file_maybe(comp_id, port):

    def jligand_standard_amino_acid_qm(comp_id):
        aa_ls = ["ALA", "ARG", "ASN", "ASP", "CYS", "GLN",
                 "GLU", "GLY", "HIS", "ILE", "LEU", "LYS", "MET",
                 "PHE", "PRO", "SER", "THR", "TRP", "TYR", "VAL"]
        return comp_id in aa_ls

    # if code was read from a cif file then write a line to port like
    # "CODE TLC FILE file.cif" (with a newline).
    #
    if not jligand_standard_amino_acid_qm(comp_id):
        cif_file = coot.cif_file_for_comp_id_py(comp_id)
        if (len(cif_file) > 0):
            port.write("CODE " + comp_id + " " + \
                       "FILE " + os.path.normpath(cif_file))
            port.write("\n")

def write_file_for_jligand(res_spec_1, resname_1, res_spec_2, resname_2):

    refmac_version = refmac.get_refmac_version()
    refmac_new_enough = (refmac_version[0] >= 5 and 
                         refmac_version[1] > 6)       # newer than 5.6
    fin = open(to_jligand_secret_file_name, 'w')
    int_time = time.time()
    #print "res_spec_1:", res_spec_1
    #print "res_spec_2:", res_spec_2
    chain_id_1 = coot_utils.res_spec_to_chain_id(res_spec_1)
    chain_id_2 = coot_utils.res_spec_to_chain_id(res_spec_2)

    fin.write("CODE " + resname_1 + " " + chain_id_1 + " " + \
              str(coot_utils.res_spec_to_res_no(res_spec_1)))
    fin.write("\n")
    if refmac_new_enough:
        jligand_code_file_maybe(resname_1, fin)
    fin.write("CODE " + resname_2 + " " + chain_id_2 + " " + \
              str(coot_utils.res_spec_to_res_no(res_spec_2)))
    fin.write("\n")
    if refmac_new_enough:
        jligand_code_file_maybe(resname_2, fin)
    fin.write("TIME " + str(int_time) + "\n")
    fin.close()

def click2res_spec(click):
    return [click[2],
            click[3],
            click[4]]

# every fraction of a second look to see if
# from_jligand_secret_link_file_name has been updated.  If so, then
# run the handle_read_from_jligand_file function.
#
def start_jligand_listener():

    global from_jligand_secret_link_file_name
    global startup_mtime
    
    # BL says: why do we use the link file and not the other one??
    startup_mtime = prodrg_import.get_file_latest_time(from_jligand_secret_link_file_name)
    
    def jligand_timeout_func():

        import operator
        global startup_mtime
    
        now_time = prodrg_import.get_file_latest_time(from_jligand_secret_link_file_name)
        if isinstance(now_time, numbers.Number):
            if not isinstance(startup_mtime, numbers.Number):
                startup_mtime = now_time
                # print "just set startup-mtime to (first)", startup_mtime
                handle_read_from_jligand_file()
            else:
                if (now_time > startup_mtime):
                    startup_mtime = now_time
                    # print "just set startup-mtime to", startup_mtime
                    handle_read_from_jligand_file()
        return True # we never expire...

    gobject.timeout_add(700, with_jligand.jligand_timeout_func)


def handle_read_from_jligand_file():

    global imol_jligand_link
    global from_jligand_secret_link_file_name
    
    def bond_length(pos_1, pos_2):
        def square(x):
            return x*x
        def sub(x, y):
            return x-y

        import math
        ret = math.sqrt(sum(map(square, list(map(sub, pos_1, pos_2)))))
        return ret

    def bond_length_from_atoms(atom_1, atom_2):
        if not isinstance(atom_1, list):
            print("   WARNING:: bond_length_from_atoms: atom_1 not a list:", atom_1)
            return
        elif not isinstance(atom_2, list):
                  print("   WARNING:: bond_length_from_atoms: atom_2 not a list:", atom_2)
                  return
        else:
            return bond_length(atom_1[2],
                               atom_2[2])

    def get_dist(atom_spec_1, atom_spec_2):
        atom_1 = coot_utils.get_atom(*([imol_jligand_link] + atom_spec_1))
        atom_2 = coot_utils.get_atom(*([imol_jligand_link] + atom_spec_2))
        if not (isinstance(atom_1, list) and
                isinstance(atom_2, list)):
            return False
        else:
            return bond_length_from_atoms(atom_1, atom_2)

    if os.path.isfile(from_jligand_secret_link_file_name):
        # this file consists of 2 lines:
        # the first is a file name that contains the cif dictionary for the cif
        # the second is a LINK link that should be added to the PDB file.
        #
        fin = open(from_jligand_secret_link_file_name, 'r')
        lines = fin.read().splitlines()  # remove the newlines
        fin.close()
        if not lines:
            print("BL WARNING:: empty file", from_jligand_secret_link_file_name)
        else:
            cif_dictionary = lines[0]
            # was it the READY marker or a cif file name?
            if (cif_dictionary == "READY"):
                print("JLigand is ready")
                # maybe I need to set something here? (that
                # from now a modification of .jligand-to-coot
                # is means that we should read it?)
            if os.path.isfile(cif_dictionary):
                coot.read_cif_dictionary(cif_dictionary)
                link_line = lines[1]
                print("Now handle this link line", link_line)
                if (len(link_line) > 72):
                    atom_name_1 = link_line[12:16]
                    atom_name_2 = link_line[42:46]
                    chain_id_1  = link_line[21:22] # 1 char, FIXME in future
                    chain_id_2  = link_line[51:52]
                    res_no_1_str = link_line[22:26]
                    res_no_2_str = link_line[52:56]
                    res_no_1 = int(res_no_1_str)
                    res_no_2 = int(res_no_2_str)
                    ins_code_1 = ""  # too lazy to look these up for now.
                    ins_code_2 = ""
                    alt_conf_1 = ""  # ditto.
                    alt_conf_2 = ""
                    link_type = link_line[72]

                    print("we parsed these: ")
                    print("       atom_name_1", atom_name_1)
                    print("       atom_name_2", atom_name_2)
                    print("        chain_id_1", chain_id_1)
                    print("        chain_id_2", chain_id_2)
                    print("      res_no_1_str", res_no_1_str)
                    print("      res_no_2_str", res_no_2_str)
                    print("         link_type", link_type)

                    # check res_no_1/2 as number? Shoudl be earlier as
                    # converted to int now... use try...
                    if (coot_utils.valid_model_molecule_qm(imol_jligand_link)):
                        res_spec_1 = [chain_id_1, res_no_1, ins_code_1]
                        res_spec_2 = [chain_id_2, res_no_2, ins_code_2]
                        atom_spec_1 = res_spec_1 + [atom_name_1, alt_conf_1]
                        atom_spec_2 = res_spec_2 + [atom_name_2, alt_conf_2]
                        dist = get_dist(atom_spec_1, atom_spec_2)
                        if not dist:
                            print("bad dist %s from %s %s" %(dist, atom_spec_1, atom_spec_2))
                        else:
                            coot.make_link(imol_jligand_link, atom_spec_1,
                                      atom_spec_2, link_type, dist)