servalcat 0.4.60__cp312-cp312-win_amd64.whl
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.
Potentially problematic release.
This version of servalcat might be problematic. Click here for more details.
- servalcat/__init__.py +10 -0
- servalcat/__main__.py +120 -0
- servalcat/ext.cp312-win_amd64.pyd +0 -0
- servalcat/refine/__init__.py +0 -0
- servalcat/refine/cgsolve.py +100 -0
- servalcat/refine/refine.py +733 -0
- servalcat/refine/refine_geom.py +207 -0
- servalcat/refine/refine_spa.py +327 -0
- servalcat/refine/refine_xtal.py +242 -0
- servalcat/refine/spa.py +132 -0
- servalcat/refine/xtal.py +227 -0
- servalcat/refmac/__init__.py +0 -0
- servalcat/refmac/exte.py +182 -0
- servalcat/refmac/refmac_keywords.py +536 -0
- servalcat/refmac/refmac_wrapper.py +360 -0
- servalcat/spa/__init__.py +0 -0
- servalcat/spa/fofc.py +462 -0
- servalcat/spa/fsc.py +385 -0
- servalcat/spa/localcc.py +188 -0
- servalcat/spa/realspcc_from_var.py +128 -0
- servalcat/spa/run_refmac.py +961 -0
- servalcat/spa/shift_maps.py +293 -0
- servalcat/spa/shiftback.py +137 -0
- servalcat/spa/translate.py +129 -0
- servalcat/utils/__init__.py +35 -0
- servalcat/utils/commands.py +1277 -0
- servalcat/utils/fileio.py +745 -0
- servalcat/utils/generate_operators.py +296 -0
- servalcat/utils/hkl.py +699 -0
- servalcat/utils/logger.py +116 -0
- servalcat/utils/maps.py +340 -0
- servalcat/utils/model.py +774 -0
- servalcat/utils/refmac.py +747 -0
- servalcat/utils/restraints.py +605 -0
- servalcat/utils/symmetry.py +295 -0
- servalcat/xtal/__init__.py +0 -0
- servalcat/xtal/french_wilson.py +250 -0
- servalcat/xtal/run_refmac_small.py +240 -0
- servalcat/xtal/sigmaa.py +1403 -0
- servalcat-0.4.60.dist-info/METADATA +56 -0
- servalcat-0.4.60.dist-info/RECORD +44 -0
- servalcat-0.4.60.dist-info/WHEEL +5 -0
- servalcat-0.4.60.dist-info/entry_points.txt +4 -0
- servalcat-0.4.60.dist-info/licenses/LICENSE +373 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Author: "Keitaro Yamashita, Garib N. Murshudov"
|
|
3
|
+
MRC Laboratory of Molecular Biology
|
|
4
|
+
|
|
5
|
+
This software is released under the
|
|
6
|
+
Mozilla Public License, version 2.0; see LICENSE.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import absolute_import, division, print_function, generators
|
|
9
|
+
import gemmi
|
|
10
|
+
import numpy
|
|
11
|
+
import json
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
import tempfile
|
|
15
|
+
import subprocess
|
|
16
|
+
import argparse
|
|
17
|
+
from collections import OrderedDict
|
|
18
|
+
from servalcat.utils import logger
|
|
19
|
+
from servalcat.refmac import refmac_keywords
|
|
20
|
+
from servalcat import utils
|
|
21
|
+
|
|
22
|
+
def add_arguments(parser):
|
|
23
|
+
parser.description = 'Run REFMAC5 with gemmi-prepared restraints'
|
|
24
|
+
parser.add_argument('--exe', default="refmac5", help='refmac5 binary')
|
|
25
|
+
parser.add_argument("--monlib",
|
|
26
|
+
help="Monomer library path. Default: $CLIBD_MON")
|
|
27
|
+
parser.add_argument('--ligand', nargs="*", action="append")
|
|
28
|
+
parser.add_argument("opts", nargs="+",
|
|
29
|
+
help="HKLIN hklin XYZIN xyzin...")
|
|
30
|
+
parser.add_argument('--auto_box_with_padding', type=float, help="Determine box size from model with specified padding")
|
|
31
|
+
parser.add_argument('--no_adjust_hydrogen_distances', action='store_true', help="By default it adjusts hydrogen distances using ideal values. This option is to disable it.")
|
|
32
|
+
parser.add_argument('--keep_original_output', action='store_true', help="with .org extension")
|
|
33
|
+
parser.add_argument("--keep_entities", action='store_true',
|
|
34
|
+
help="Do not override entities")
|
|
35
|
+
parser.add_argument('--prefix', help="output prefix")
|
|
36
|
+
parser.add_argument("-v", "--version", action="version",
|
|
37
|
+
version=logger.versions_str())
|
|
38
|
+
# TODO --cell to override unit cell?
|
|
39
|
+
|
|
40
|
+
# add_arguments()
|
|
41
|
+
|
|
42
|
+
def parse_args(arg_list):
|
|
43
|
+
parser = argparse.ArgumentParser()
|
|
44
|
+
add_arguments(parser)
|
|
45
|
+
return parser.parse_args(arg_list)
|
|
46
|
+
# parse_args()
|
|
47
|
+
|
|
48
|
+
def read_stdin(stdin):
|
|
49
|
+
print("Waiting for input..")
|
|
50
|
+
# these make keywords will be ignored (just passed to refmac): ribo,valu,spec,form,sdmi,segi
|
|
51
|
+
ret = {"make":{}, "ridge":{}, "refi":{}}
|
|
52
|
+
inputs = []
|
|
53
|
+
for l in refmac_keywords.get_lines(stdin):
|
|
54
|
+
if l.split()[0].lower().startswith("end"):
|
|
55
|
+
break
|
|
56
|
+
refmac_keywords.parse_line(l, ret)
|
|
57
|
+
inputs.append(l + "\n")
|
|
58
|
+
|
|
59
|
+
def sorry(s): raise SystemExit("Sorry, '{}' is not supported".format(s))
|
|
60
|
+
if ret["make"].get("hydr") == "f":
|
|
61
|
+
sorry("make hydr full")
|
|
62
|
+
if ret["make"].get("buil") == "y":
|
|
63
|
+
sorry("make build yes")
|
|
64
|
+
return inputs, ret
|
|
65
|
+
# read_stdin()
|
|
66
|
+
|
|
67
|
+
def prepare_crd(st, crdout, ligand, make, monlib_path=None, h_pos="elec",
|
|
68
|
+
no_adjust_hydrogen_distances=False, fix_long_resnames=True):
|
|
69
|
+
assert h_pos in ("elec", "nucl")
|
|
70
|
+
h_change = dict(a=gemmi.HydrogenChange.ReAddButWater,
|
|
71
|
+
y=gemmi.HydrogenChange.NoChange,
|
|
72
|
+
n=gemmi.HydrogenChange.Remove)[make.get("hydr", "a")]
|
|
73
|
+
utils.model.fix_deuterium_residues(st)
|
|
74
|
+
for chain in st[0]:
|
|
75
|
+
if not chain.name:
|
|
76
|
+
chain.name = "X" # Refmac behavior. Empty chain name will cause a problem
|
|
77
|
+
for res in chain:
|
|
78
|
+
if res.is_water():
|
|
79
|
+
res.name = "HOH"
|
|
80
|
+
|
|
81
|
+
# TODO read dictionary from xyzin (priority: user cif -> monlib -> xyzin
|
|
82
|
+
try:
|
|
83
|
+
monlib = utils.restraints.load_monomer_library(st,
|
|
84
|
+
monomer_dir=monlib_path,
|
|
85
|
+
cif_files=ligand,
|
|
86
|
+
stop_for_unknowns=not make.get("newligand"))
|
|
87
|
+
except RuntimeError as e:
|
|
88
|
+
raise SystemExit("Error: {}".format(e))
|
|
89
|
+
|
|
90
|
+
use_cispeps = make.get("cispept", "y") != "y"
|
|
91
|
+
make_link = make.get("link", "n")
|
|
92
|
+
make_ss = make.get("ss", "y")
|
|
93
|
+
only_from = set()
|
|
94
|
+
if make_link == "y":
|
|
95
|
+
# add all links
|
|
96
|
+
add_found = True
|
|
97
|
+
elif make_ss == "y":
|
|
98
|
+
add_found = True
|
|
99
|
+
only_from.add("disulf")
|
|
100
|
+
else:
|
|
101
|
+
add_found = False
|
|
102
|
+
|
|
103
|
+
utils.restraints.find_and_fix_links(st, monlib, add_found=add_found, find_symmetry_related=False, add_only_from=only_from)
|
|
104
|
+
for con in st.connections:
|
|
105
|
+
if con.link_id not in ("?", "", "gap") and con.link_id not in monlib.links:
|
|
106
|
+
logger.writeln(" removing unknown link id ({}). Ad-hoc link will be generated.".format(con.link_id))
|
|
107
|
+
con.link_id = ""
|
|
108
|
+
|
|
109
|
+
refmac_fixes = utils.refmac.FixForRefmac()
|
|
110
|
+
max_seq_num = max([max(res.seqid.num for res in chain) for model in st for chain in model])
|
|
111
|
+
if max_seq_num > 9999:
|
|
112
|
+
logger.writeln("Max residue number ({}) exceeds 9999. Needs workaround.".format(max_seq_num))
|
|
113
|
+
topo = gemmi.prepare_topology(st, monlib, ignore_unknown_links=True)
|
|
114
|
+
refmac_fixes.fix_before_topology(st, topo,
|
|
115
|
+
fix_microheterogeneity=False,
|
|
116
|
+
fix_resimax=True,
|
|
117
|
+
fix_nonpolymer=False)
|
|
118
|
+
|
|
119
|
+
if make.get("hydr") == "a": logger.writeln("(re)generating hydrogen atoms")
|
|
120
|
+
try:
|
|
121
|
+
topo, metal_kws = utils.restraints.prepare_topology(st, monlib, h_change=h_change, ignore_unknown_links=False,
|
|
122
|
+
check_hydrogen=(h_change==gemmi.HydrogenChange.NoChange),
|
|
123
|
+
use_cispeps=use_cispeps)
|
|
124
|
+
except RuntimeError as e:
|
|
125
|
+
raise SystemExit("Error: {}".format(e))
|
|
126
|
+
|
|
127
|
+
if make.get("hydr") != "n" and st[0].has_hydrogen():
|
|
128
|
+
if h_pos == "nucl" and (make.get("hydr") == "a" or not no_adjust_hydrogen_distances):
|
|
129
|
+
resnames = st[0].get_all_residue_names()
|
|
130
|
+
utils.restraints.check_monlib_support_nucleus_distances(monlib, resnames)
|
|
131
|
+
logger.writeln("adjusting hydrogen position to nucleus")
|
|
132
|
+
topo.adjust_hydrogen_distances(gemmi.Restraints.DistanceOf.Nucleus, default_scale=1.1)
|
|
133
|
+
elif h_pos == "elec" and make.get("hydr") == "y" and not no_adjust_hydrogen_distances:
|
|
134
|
+
logger.writeln("adjusting hydrogen position to electron cloud")
|
|
135
|
+
topo.adjust_hydrogen_distances(gemmi.Restraints.DistanceOf.ElectronCloud)
|
|
136
|
+
|
|
137
|
+
if fix_long_resnames: refmac_fixes.fix_long_resnames(st)
|
|
138
|
+
|
|
139
|
+
# for safety
|
|
140
|
+
if "_entry.id" in st.info:
|
|
141
|
+
st.info["_entry.id"] = st.info["_entry.id"].replace(" ", "")
|
|
142
|
+
date_key = "_pdbx_database_status.recvd_initial_deposition_date"
|
|
143
|
+
if date_key in st.info:
|
|
144
|
+
tmp = st.info[date_key]
|
|
145
|
+
if len(tmp) > 5 and tmp[4] == "-":
|
|
146
|
+
if len(tmp) > 8 and tmp[8] != "" and not tmp[5:7].isdigit():
|
|
147
|
+
tmp = "XX"
|
|
148
|
+
elif len(tmp) > 6 and tmp[5] == "-":
|
|
149
|
+
if not tmp[3:5].isdigit():
|
|
150
|
+
tmp = "XX"
|
|
151
|
+
st.info[date_key] = tmp
|
|
152
|
+
# internal chain ID
|
|
153
|
+
for chain in st[0]:
|
|
154
|
+
for res in chain:
|
|
155
|
+
if len(chain.name) < 3:
|
|
156
|
+
# Change Axp (or AAxp) to A_p (or AA_p)
|
|
157
|
+
res.subchain = res.subchain[:-2] + "_" + res.subchain[-1:]
|
|
158
|
+
else:
|
|
159
|
+
# Refmac only expects '_' at 2nd or 3rd position, and can accept up to 4 letters.
|
|
160
|
+
# Using raw chain ID may change alignment result for local NCS restraints,
|
|
161
|
+
# but to avoid this we would need chain ID translation, which is too complicated.
|
|
162
|
+
# This also invalidates _struct_asym, which Refmac does not seem to care
|
|
163
|
+
res.subchain = chain.name
|
|
164
|
+
doc = gemmi.prepare_refmac_crd(st, topo, monlib, h_change)
|
|
165
|
+
doc.write_file(crdout, style=gemmi.cif.Style.NoBlankLines)
|
|
166
|
+
logger.writeln("crd file written: {}".format(crdout))
|
|
167
|
+
return refmac_fixes, [x+"\n" for x in metal_kws]
|
|
168
|
+
# prepare_crd()
|
|
169
|
+
|
|
170
|
+
def get_output_model_names(xyzout):
|
|
171
|
+
# ref: WRITE_ATOMS_REFMAC in oppro_allocate.f
|
|
172
|
+
if xyzout is None: xyzout = "XYZOUT"
|
|
173
|
+
pdb, mmcif = "", ""
|
|
174
|
+
if len(xyzout) > 3:
|
|
175
|
+
if xyzout.lower().endswith("pdb"):
|
|
176
|
+
mmcif = xyzout[:-4] + ".mmcif"
|
|
177
|
+
pdb = xyzout
|
|
178
|
+
else:
|
|
179
|
+
if xyzout.lower().endswith("cif") and len(xyzout) > 5:
|
|
180
|
+
if xyzout.lower().endswith("mmcif"):
|
|
181
|
+
mmcif = xyzout
|
|
182
|
+
pdb = xyzout[:-6] + ".pdb"
|
|
183
|
+
else:
|
|
184
|
+
mmcif = xyzout
|
|
185
|
+
pdb = xyzout[:-4] + ".pdb"
|
|
186
|
+
else:
|
|
187
|
+
mmcif = xyzout + ".mmcif"
|
|
188
|
+
pdb = xyzout
|
|
189
|
+
else:
|
|
190
|
+
mmcif = xyzout + ".mmcif"
|
|
191
|
+
pdb = xyzout
|
|
192
|
+
|
|
193
|
+
return pdb, mmcif
|
|
194
|
+
# get_output_model_names()
|
|
195
|
+
|
|
196
|
+
def modify_output(pdbout, cifout, fixes, hout, cispeps, keep_original_output=False):
|
|
197
|
+
st = utils.fileio.read_structure(cifout)
|
|
198
|
+
st.cispeps = cispeps
|
|
199
|
+
if os.path.exists(pdbout):
|
|
200
|
+
st.raw_remarks = gemmi.read_pdb(pdbout).raw_remarks
|
|
201
|
+
if fixes is not None:
|
|
202
|
+
fixes.modify_back(st)
|
|
203
|
+
for con in st.connections:
|
|
204
|
+
if con.link_id == "disulf":
|
|
205
|
+
con.type = gemmi.ConnectionType.Disulf
|
|
206
|
+
# should we check metals and put MetalC?
|
|
207
|
+
|
|
208
|
+
# fix entity (Refmac seems to make DNA non-polymer; as seen in 1fix)
|
|
209
|
+
utils.model.setup_entities(st, clear=True, overwrite_entity_type=True, force_subchain_names=True)
|
|
210
|
+
for e in st.entities:
|
|
211
|
+
if not e.full_sequence and e.entity_type == gemmi.EntityType.Polymer and e.subchains:
|
|
212
|
+
rspan = st[0].get_subchain(e.subchains[0])
|
|
213
|
+
e.full_sequence = [r.name for r in rspan]
|
|
214
|
+
|
|
215
|
+
suffix = ".org"
|
|
216
|
+
os.rename(cifout, cifout + suffix)
|
|
217
|
+
utils.fileio.write_mmcif(st, cifout, cifout + suffix)
|
|
218
|
+
|
|
219
|
+
if st.has_d_fraction:
|
|
220
|
+
st.store_deuterium_as_fraction(False) # also useful for pdb
|
|
221
|
+
logger.writeln("will write a H/D expanded mmcif file")
|
|
222
|
+
cifout2 = cifout[:cifout.rindex(".")] + "_hd_expand" + cifout[cifout.rindex("."):]
|
|
223
|
+
utils.fileio.write_mmcif(st, cifout2, cifout + suffix)
|
|
224
|
+
|
|
225
|
+
chain_id_len_max = max([len(x) for x in utils.model.all_chain_ids(st)])
|
|
226
|
+
seqnums = [res.seqid.num for chain in st[0] for res in chain]
|
|
227
|
+
if chain_id_len_max > 1 or min(seqnums) <= -1000 or max(seqnums) >= 10000:
|
|
228
|
+
logger.writeln("This structure cannot be saved as an official PDB format. Using hybrid-36. Header part may be inaccurate.")
|
|
229
|
+
if not hout:
|
|
230
|
+
st.remove_hydrogens() # remove hydrogen from pdb, while kept in mmcif
|
|
231
|
+
# Use short name in pdb
|
|
232
|
+
st.shorten_ccd_codes()
|
|
233
|
+
if st.shortened_ccd_codes:
|
|
234
|
+
msg = " ".join("{}->{}".format(o,n) for o,n in st.shortened_ccd_codes)
|
|
235
|
+
logger.writeln("Using shortened residue names in the output pdb file: " + msg)
|
|
236
|
+
os.rename(pdbout, pdbout + suffix)
|
|
237
|
+
utils.fileio.write_pdb(st, pdbout)
|
|
238
|
+
if not keep_original_output:
|
|
239
|
+
os.remove(pdbout + suffix)
|
|
240
|
+
os.remove(cifout + suffix)
|
|
241
|
+
# modify_output()
|
|
242
|
+
|
|
243
|
+
def main(args):
|
|
244
|
+
if len(args.opts) % 2 != 0: raise SystemExit("Invalid number of args")
|
|
245
|
+
args.ligand = sum(args.ligand, []) if args.ligand else []
|
|
246
|
+
|
|
247
|
+
inputs, keywords = read_stdin(sys.stdin) # TODO read psrestin also?
|
|
248
|
+
if not keywords["make"].get("exit"):
|
|
249
|
+
refmac_ver = utils.refmac.check_version(args.exe)
|
|
250
|
+
if not refmac_ver:
|
|
251
|
+
raise SystemExit("Error: Check Refmac installation or use --exe to give the location.")
|
|
252
|
+
if refmac_ver < (5, 8, 404):
|
|
253
|
+
raise SystemExit("Error: this version of Refmac is not supported. Update to 5.8.404 or newer")
|
|
254
|
+
|
|
255
|
+
opts = OrderedDict((args.opts[2*i].lower(), args.opts[2*i+1]) for i in range(len(args.opts)//2))
|
|
256
|
+
xyzin = opts.get("xyzin")
|
|
257
|
+
xyzout = opts.get("xyzout")
|
|
258
|
+
libin = opts.pop("libin", None)
|
|
259
|
+
if libin: args.ligand.append(libin)
|
|
260
|
+
if not args.monlib:
|
|
261
|
+
# if --monlib is given, it has priority.
|
|
262
|
+
args.monlib = opts.pop("clibd_mon", None)
|
|
263
|
+
for k in ("temp1", "scrref"): # scrref has priority
|
|
264
|
+
if k in opts:
|
|
265
|
+
logger.writeln("updating CCP4_SCR from {}={}".format(k, opts[k]))
|
|
266
|
+
os.environ["CCP4_SCR"] = os.path.dirname(opts[k]) # XXX "." may be given, which causes problem (os.path.isdir("") is False)
|
|
267
|
+
utils.refmac.ensure_ccp4scr()
|
|
268
|
+
if args.prefix:
|
|
269
|
+
if "xyzin" in opts and "xyzout" not in opts: opts["xyzout"] = args.prefix + ".pdb"
|
|
270
|
+
if "hklin" in opts and "hklout" not in opts: opts["hklout"] = args.prefix + ".mtz"
|
|
271
|
+
if "tlsin" in opts and "tlsout" not in opts: opts["tlsout"] = args.prefix + ".tls"
|
|
272
|
+
|
|
273
|
+
# TODO what if restin is given or make cr prepared is given?
|
|
274
|
+
# TODO check make pept/link/suga/ss/conn/symm/chain
|
|
275
|
+
|
|
276
|
+
# Process model
|
|
277
|
+
crdout = None
|
|
278
|
+
refmac_fixes = None
|
|
279
|
+
cispeps = []
|
|
280
|
+
if xyzin is not None and keywords["refi"].get("type") != "unre":
|
|
281
|
+
#tmpfd, crdout = tempfile.mkstemp(prefix="gemmi_", suffix=".crd") # TODO use dir=CCP4_SCR
|
|
282
|
+
#os.close(tmpfd)
|
|
283
|
+
st = utils.fileio.read_structure(xyzin)
|
|
284
|
+
if not st.cell.is_crystal():
|
|
285
|
+
if args.auto_box_with_padding is not None:
|
|
286
|
+
st.cell = utils.model.box_from_model(st[0], args.auto_box_with_padding)
|
|
287
|
+
st.spacegroup_hm = "P 1"
|
|
288
|
+
logger.writeln("Box size from the model with padding of {}: {}".format(args.auto_box_with_padding, st.cell.parameters))
|
|
289
|
+
else:
|
|
290
|
+
raise SystemExit("Error: unit cell is not defined in the model.")
|
|
291
|
+
if any(not op.given for op in st.ncs):
|
|
292
|
+
logger.writeln("WARNING: Refmac ignores MTRIX (_struct_ncs_oper) records. Add following instructions if you need:")
|
|
293
|
+
logger.writeln("\n".join(utils.symmetry.ncs_ops_for_refmac(st.ncs))+"\n")
|
|
294
|
+
st.ncs.clear()
|
|
295
|
+
st.setup_cell_images()
|
|
296
|
+
# TODO set st.ncs if ncsc instructions given - but should be done outside of this function?
|
|
297
|
+
if not args.keep_entities:
|
|
298
|
+
utils.model.setup_entities(st, clear=True, force_subchain_names=True, overwrite_entity_type=True)
|
|
299
|
+
xyzout_dir = os.path.dirname(get_output_model_names(opts.get("xyzout"))[0])
|
|
300
|
+
crdout = os.path.join(xyzout_dir,
|
|
301
|
+
"gemmi_{}_{}.crd".format(utils.fileio.splitext(os.path.basename(xyzin))[0], os.getpid()))
|
|
302
|
+
refmac_fixes, metal_kws = prepare_crd(st, crdout, args.ligand, make=keywords["make"], monlib_path=args.monlib,
|
|
303
|
+
h_pos="nucl" if keywords.get("source")=="ne" else "elec",
|
|
304
|
+
no_adjust_hydrogen_distances=args.no_adjust_hydrogen_distances)
|
|
305
|
+
inputs = metal_kws + inputs # add metal exte first; otherwise it may be affected by user-defined inputs
|
|
306
|
+
opts["xyzin"] = crdout
|
|
307
|
+
cispeps = st.cispeps
|
|
308
|
+
|
|
309
|
+
if keywords["make"].get("exit"):
|
|
310
|
+
return
|
|
311
|
+
|
|
312
|
+
# Run Refmac
|
|
313
|
+
cmd = [args.exe] + list(sum(tuple(opts.items()), ()))
|
|
314
|
+
env = os.environ
|
|
315
|
+
logger.writeln("Running REFMAC5..")
|
|
316
|
+
if args.monlib:
|
|
317
|
+
logger.writeln("CLIBD_MON={}".format(args.monlib))
|
|
318
|
+
env["CLIBD_MON"] = os.path.join(args.monlib, "") # should end with /
|
|
319
|
+
logger.writeln(" ".join(cmd))
|
|
320
|
+
p = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE,
|
|
321
|
+
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
|
322
|
+
universal_newlines=True, env=env)
|
|
323
|
+
if crdout: p.stdin.write("make cr prepared\n")
|
|
324
|
+
p.stdin.write("".join(inputs))
|
|
325
|
+
p.stdin.close()
|
|
326
|
+
# prepare conversion for long residue names
|
|
327
|
+
resn_conv = {}
|
|
328
|
+
if refmac_fixes:
|
|
329
|
+
for old, new in refmac_fixes.resn_old_new:
|
|
330
|
+
n = "{:4s}".format(old)
|
|
331
|
+
if len(n) > 4: n += " "
|
|
332
|
+
resn_conv[new] = n
|
|
333
|
+
# print raw output
|
|
334
|
+
for l in iter(p.stdout.readline, ""):
|
|
335
|
+
for tn in resn_conv:
|
|
336
|
+
l = l.replace(tn, resn_conv[tn])
|
|
337
|
+
logger.write(l)
|
|
338
|
+
retcode = p.wait()
|
|
339
|
+
logger.writeln("\nRefmac finished with exit code= {}".format(retcode))
|
|
340
|
+
|
|
341
|
+
if not args.keep_original_output and crdout and os.path.exists(crdout):
|
|
342
|
+
os.remove(crdout)
|
|
343
|
+
|
|
344
|
+
# Modify output
|
|
345
|
+
if xyzin is not None:
|
|
346
|
+
pdbout, cifout = get_output_model_names(opts.get("xyzout"))
|
|
347
|
+
if os.path.exists(cifout):
|
|
348
|
+
modify_output(pdbout, cifout, refmac_fixes, keywords["make"].get("hout"), cispeps, args.keep_original_output)
|
|
349
|
+
# main()
|
|
350
|
+
|
|
351
|
+
def command_line():
|
|
352
|
+
import sys
|
|
353
|
+
args = parse_args(sys.argv[1:])
|
|
354
|
+
if args.prefix:
|
|
355
|
+
logger.set_file(args.prefix + ".log")
|
|
356
|
+
logger.write_header(command="refmacat")
|
|
357
|
+
main(args)
|
|
358
|
+
|
|
359
|
+
if __name__ == "__main__":
|
|
360
|
+
command_line()
|
|
File without changes
|