servalcat 0.4.131__cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.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.
- servalcat/__init__.py +10 -0
- servalcat/__main__.py +120 -0
- servalcat/ext.cpython-314t-x86_64-linux-gnu.so +0 -0
- servalcat/refine/__init__.py +0 -0
- servalcat/refine/cgsolve.py +100 -0
- servalcat/refine/refine.py +1162 -0
- servalcat/refine/refine_geom.py +245 -0
- servalcat/refine/refine_spa.py +400 -0
- servalcat/refine/refine_xtal.py +339 -0
- servalcat/refine/spa.py +151 -0
- servalcat/refine/xtal.py +312 -0
- servalcat/refmac/__init__.py +0 -0
- servalcat/refmac/exte.py +191 -0
- servalcat/refmac/refmac_keywords.py +660 -0
- servalcat/refmac/refmac_wrapper.py +423 -0
- servalcat/spa/__init__.py +0 -0
- servalcat/spa/fofc.py +488 -0
- servalcat/spa/fsc.py +391 -0
- servalcat/spa/localcc.py +197 -0
- servalcat/spa/realspcc_from_var.py +128 -0
- servalcat/spa/run_refmac.py +979 -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 +1629 -0
- servalcat/utils/fileio.py +836 -0
- servalcat/utils/generate_operators.py +296 -0
- servalcat/utils/hkl.py +811 -0
- servalcat/utils/logger.py +140 -0
- servalcat/utils/maps.py +345 -0
- servalcat/utils/model.py +933 -0
- servalcat/utils/refmac.py +759 -0
- servalcat/utils/restraints.py +888 -0
- servalcat/utils/symmetry.py +298 -0
- servalcat/xtal/__init__.py +0 -0
- servalcat/xtal/french_wilson.py +262 -0
- servalcat/xtal/run_refmac_small.py +240 -0
- servalcat/xtal/sigmaa.py +1954 -0
- servalcat/xtal/twin.py +316 -0
- servalcat-0.4.131.dist-info/METADATA +60 -0
- servalcat-0.4.131.dist-info/RECORD +45 -0
- servalcat-0.4.131.dist-info/WHEEL +6 -0
- servalcat-0.4.131.dist-info/entry_points.txt +4 -0
- servalcat-0.4.131.dist-info/licenses/LICENSE +373 -0
|
@@ -0,0 +1,240 @@
|
|
|
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 argparse
|
|
14
|
+
from servalcat.utils import logger
|
|
15
|
+
from servalcat import utils
|
|
16
|
+
|
|
17
|
+
def add_arguments(parser):
|
|
18
|
+
parser.description = 'Run REFMAC5 for small molecule crystallography'
|
|
19
|
+
parser.add_argument('--exe', default="refmac5", help='refmac5 binary')
|
|
20
|
+
parser.add_argument('--cif', help="cif file containing model and data")
|
|
21
|
+
parser.add_argument('--sg', help="Space group")
|
|
22
|
+
parser.add_argument('--model',
|
|
23
|
+
help='Input atomic model file')
|
|
24
|
+
parser.add_argument('--hklin',
|
|
25
|
+
help='Input reflection file')
|
|
26
|
+
parser.add_argument('--hklin_labs', nargs='+',
|
|
27
|
+
help='column names to be used')
|
|
28
|
+
parser.add_argument('--blur', type=float,
|
|
29
|
+
help='Apply B-factor blurring to --hklin')
|
|
30
|
+
parser.add_argument('--resolution',
|
|
31
|
+
type=float,
|
|
32
|
+
help='')
|
|
33
|
+
parser.add_argument('--ligand', nargs="*", action="append",
|
|
34
|
+
help="restraint dictionary cif file(s)")
|
|
35
|
+
parser.add_argument('--ncycle', type=int, default=10)
|
|
36
|
+
#parser.add_argument('--jellybody', action='store_true')
|
|
37
|
+
#parser.add_argument('--jellybody_params', nargs=2, type=float,
|
|
38
|
+
# metavar=("sigma", "dmax"), default=[0.01, 4.2])
|
|
39
|
+
parser.add_argument('--hydrogen', default="all", choices=["all", "yes", "no"],
|
|
40
|
+
help="all: add riding hydrogen atoms, yes: use hydrogen atoms if present, no: remove hydrogen atoms in input")
|
|
41
|
+
parser.add_argument('--no_hout', action='store_true', help="do not write hydrogen atoms in the output model")
|
|
42
|
+
|
|
43
|
+
group = parser.add_mutually_exclusive_group()
|
|
44
|
+
group.add_argument('--weight_auto_scale', type=float,
|
|
45
|
+
help="'weight auto' scale value. automatically determined from resolution and mask/box volume ratio if unspecified")
|
|
46
|
+
group.add_argument('--weight_matrix', type=float,
|
|
47
|
+
help="weight matrix value")
|
|
48
|
+
parser.add_argument('--invert', action='store_true', help="invert handednes")
|
|
49
|
+
parser.add_argument('--bref', choices=["aniso","iso","iso_then_aniso"], default="aniso")
|
|
50
|
+
parser.add_argument('--unrestrained', action='store_true')
|
|
51
|
+
parser.add_argument('--bulk_solvent', action='store_true')
|
|
52
|
+
parser.add_argument('-s', '--source', choices=["electron", "xray", "neutron"], default="electron") #FIXME
|
|
53
|
+
parser.add_argument('--keywords', nargs='+', action="append",
|
|
54
|
+
help="refmac keyword(s)")
|
|
55
|
+
parser.add_argument('--keyword_file', nargs='+', action="append",
|
|
56
|
+
help="refmac keyword file(s)")
|
|
57
|
+
parser.add_argument('--external_restraints_json')
|
|
58
|
+
parser.add_argument('--show_refmac_log', action='store_true')
|
|
59
|
+
parser.add_argument('--output_prefix', default="refined",
|
|
60
|
+
help='output file name prefix')
|
|
61
|
+
parser.add_argument("--monlib",
|
|
62
|
+
help="Monomer library path. Default: $CLIBD_MON")
|
|
63
|
+
# add_arguments()
|
|
64
|
+
|
|
65
|
+
def parse_args(arg_list):
|
|
66
|
+
parser = argparse.ArgumentParser()
|
|
67
|
+
add_arguments(parser)
|
|
68
|
+
return parser.parse_args(arg_list)
|
|
69
|
+
# parse_args()
|
|
70
|
+
|
|
71
|
+
def make_invert_tr(sg, cell):
|
|
72
|
+
ops = sg.operations()
|
|
73
|
+
coh = sg.change_of_hand_op()
|
|
74
|
+
ops.change_basis_forward(sg.change_of_hand_op())
|
|
75
|
+
new_sg = gemmi.find_spacegroup_by_ops(ops)
|
|
76
|
+
tr = cell.op_as_transform(coh)
|
|
77
|
+
return new_sg, tr
|
|
78
|
+
# make_invert_tr()
|
|
79
|
+
|
|
80
|
+
def merge_anomalous(mtz):
|
|
81
|
+
dlabs = utils.hkl.mtz_find_data_columns(mtz)
|
|
82
|
+
if dlabs["J"] or dlabs["F"]:
|
|
83
|
+
return # no need to merge
|
|
84
|
+
if not dlabs["K"] and not dlabs["G"]:
|
|
85
|
+
return # nothing can be done
|
|
86
|
+
data = mtz.array.copy()
|
|
87
|
+
for typ in ("K", "G"):
|
|
88
|
+
if dlabs[typ] and len(dlabs[typ][0]) == 4:
|
|
89
|
+
idxes = [mtz.column_with_label(x).idx for x in dlabs[typ][0]]
|
|
90
|
+
mean = numpy.nanmean(mtz.array[:,[idxes[0],idxes[2]]], axis=1)
|
|
91
|
+
sig_mean = numpy.sqrt(numpy.nanmean(mtz.array[:,[idxes[1],idxes[3]]]**2, axis=1))
|
|
92
|
+
data = numpy.hstack([data, mean.reshape(-1,1), sig_mean.reshape(-1,1)])
|
|
93
|
+
if typ == "K":
|
|
94
|
+
mtz.add_column("IMEAN", "J")
|
|
95
|
+
mtz.add_column("SIGIMEAN", "Q")
|
|
96
|
+
else:
|
|
97
|
+
mtz.add_column("FP", "F")
|
|
98
|
+
mtz.add_column("SIGFP", "Q")
|
|
99
|
+
mtz.set_data(data)
|
|
100
|
+
# merge_anomalous()
|
|
101
|
+
|
|
102
|
+
def main(args):
|
|
103
|
+
if not args.cif and not (args.model and args.hklin):
|
|
104
|
+
raise SystemExit("Give [--model and --hklin] or --cif")
|
|
105
|
+
|
|
106
|
+
if args.sg:
|
|
107
|
+
try:
|
|
108
|
+
sg_user = gemmi.SpaceGroup(args.sg)
|
|
109
|
+
logger.writeln("User-specified space group: {}".format(sg_user.xhm()))
|
|
110
|
+
except ValueError:
|
|
111
|
+
raise SystemExit("Error: Unknown space group '{}'".format(args.sg))
|
|
112
|
+
else:
|
|
113
|
+
sg_user = None
|
|
114
|
+
|
|
115
|
+
if args.cif:
|
|
116
|
+
mtz, ss, info = utils.fileio.read_smcif_shelx(args.cif)
|
|
117
|
+
st = utils.model.cx_to_mx(ss)
|
|
118
|
+
else:
|
|
119
|
+
st = utils.fileio.read_structure(args.model)
|
|
120
|
+
if utils.fileio.is_mmhkl_file(args.hklin): # TODO may be unmerged mtz
|
|
121
|
+
mtz = utils.fileio.read_mmhkl(args.hklin)
|
|
122
|
+
elif args.hklin.endswith(".hkl"):
|
|
123
|
+
mtz = utils.fileio.read_smcif_hkl(args.hklin, st.cell, st.find_spacegroup())
|
|
124
|
+
else:
|
|
125
|
+
raise SystemExit("Error: unsupported hkl file: {}".format(args.hklin))
|
|
126
|
+
|
|
127
|
+
mtz_in = "input.mtz" # always write this file as an input for Refmac
|
|
128
|
+
sg_st = st.find_spacegroup()
|
|
129
|
+
if not mtz.cell.approx(st.cell, 1e-3):
|
|
130
|
+
logger.writeln(" Warning: unit cell mismatch!")
|
|
131
|
+
if sg_user:
|
|
132
|
+
if not mtz.cell.is_compatible_with_spacegroup(sg_user):
|
|
133
|
+
raise SystemExit("Error: Specified space group {} is incompatible with the unit cell parameters {}".format(sg_user.xhm(),
|
|
134
|
+
mtz.cell.parameters))
|
|
135
|
+
mtz.spacegroup = sg_user
|
|
136
|
+
logger.writeln(" Writing {} as space group {}".format(mtz_in, sg_user.xhm()))
|
|
137
|
+
elif mtz.spacegroup != sg_st:
|
|
138
|
+
if st.cell.is_crystal() and sg_st and sg_st.laue_str() != mtz.spacegroup.laue_str():
|
|
139
|
+
raise RuntimeError("Crystal symmetry mismatch between model and data")
|
|
140
|
+
logger.writeln(" Warning: space group mismatch between model and mtz")
|
|
141
|
+
if sg_st and sg_st.laue_str() == mtz.spacegroup.laue_str():
|
|
142
|
+
logger.writeln(" using space group from model")
|
|
143
|
+
mtz.spacegroup = sg_st
|
|
144
|
+
else:
|
|
145
|
+
logger.writeln(" using space group from mtz")
|
|
146
|
+
|
|
147
|
+
if args.hklin_labs:
|
|
148
|
+
try: mtz = utils.hkl.mtz_selected(mtz, args.hklin_labs)
|
|
149
|
+
except RuntimeError as e:
|
|
150
|
+
raise SystemExit("Error: {}".format(e))
|
|
151
|
+
if args.blur is not None: utils.hkl.blur_mtz(mtz, args.blur)
|
|
152
|
+
merge_anomalous(mtz)
|
|
153
|
+
mtz.write_to_file(mtz_in)
|
|
154
|
+
st.cell = mtz.cell
|
|
155
|
+
st.spacegroup_hm = mtz.spacegroup.xhm()
|
|
156
|
+
|
|
157
|
+
if args.invert:
|
|
158
|
+
logger.writeln("Inversion of structure is requested.")
|
|
159
|
+
old_sg = st.find_spacegroup()
|
|
160
|
+
new_sg, tr = make_invert_tr(old_sg, st.cell)
|
|
161
|
+
logger.writeln(" new space group = {} (no. {})".format(new_sg.xhm(), new_sg.number))
|
|
162
|
+
st[0].transform_pos_and_adp(tr)
|
|
163
|
+
if old_sg != new_sg:
|
|
164
|
+
st.spacegroup_hm = new_sg.xhm()
|
|
165
|
+
# overwrite mtz
|
|
166
|
+
mtz = gemmi.read_mtz_file(mtz_in)
|
|
167
|
+
mtz.spacegroup = new_sg
|
|
168
|
+
mtz.write_to_file(mtz_in)
|
|
169
|
+
|
|
170
|
+
if args.keyword_file:
|
|
171
|
+
args.keyword_file = sum(args.keyword_file, [])
|
|
172
|
+
for f in args.keyword_file:
|
|
173
|
+
logger.writeln("Keyword file: {}".format(f))
|
|
174
|
+
assert os.path.exists(f)
|
|
175
|
+
else:
|
|
176
|
+
args.keyword_file = []
|
|
177
|
+
|
|
178
|
+
if args.keywords:
|
|
179
|
+
args.keywords = sum(args.keywords, [])
|
|
180
|
+
else:
|
|
181
|
+
args.keywords = []
|
|
182
|
+
|
|
183
|
+
for m in st:
|
|
184
|
+
for chain in m:
|
|
185
|
+
# Fix if they are blank TODO if more than one chain/residue?
|
|
186
|
+
if chain.name == "": chain.name = "A"
|
|
187
|
+
for res in chain:
|
|
188
|
+
if res.name == "": res.name = "00"
|
|
189
|
+
|
|
190
|
+
# FIXME in some cases mtz space group should be modified.
|
|
191
|
+
utils.fileio.write_model(st, prefix="input", pdb=True, cif=True)
|
|
192
|
+
|
|
193
|
+
if args.ligand: args.ligand = sum(args.ligand, [])
|
|
194
|
+
|
|
195
|
+
prefix = "refined"
|
|
196
|
+
if args.bref == "aniso":
|
|
197
|
+
args.keywords.append("refi bref aniso")
|
|
198
|
+
elif args.bref == "iso_then_aniso":
|
|
199
|
+
prefix = "refined_1_iso"
|
|
200
|
+
|
|
201
|
+
if args.unrestrained:
|
|
202
|
+
args.keywords.append("refi type unre")
|
|
203
|
+
args.no_hout = False
|
|
204
|
+
else:
|
|
205
|
+
monlib = utils.restraints.load_monomer_library(st, monomer_dir=args.monlib, cif_files=args.ligand,
|
|
206
|
+
stop_for_unknowns=False)
|
|
207
|
+
|
|
208
|
+
# no bulk solvent by default
|
|
209
|
+
if not args.bulk_solvent:
|
|
210
|
+
args.keywords.append("solvent no")
|
|
211
|
+
|
|
212
|
+
# Run Refmac
|
|
213
|
+
refmac = utils.refmac.Refmac(prefix=prefix, global_mode="cx",
|
|
214
|
+
exe=args.exe,
|
|
215
|
+
source=args.source,
|
|
216
|
+
monlib_path=args.monlib,
|
|
217
|
+
xyzin="input.mmcif",
|
|
218
|
+
hklin=mtz_in,
|
|
219
|
+
ncycle=args.ncycle,
|
|
220
|
+
weight_matrix=args.weight_matrix,
|
|
221
|
+
weight_auto_scale=args.weight_auto_scale,
|
|
222
|
+
hydrogen=args.hydrogen,
|
|
223
|
+
hout=not args.no_hout,
|
|
224
|
+
resolution=args.resolution,
|
|
225
|
+
keyword_files=args.keyword_file,
|
|
226
|
+
keywords=args.keywords)
|
|
227
|
+
refmac.set_libin(args.ligand)
|
|
228
|
+
refmac_summary = refmac.run_refmac()
|
|
229
|
+
|
|
230
|
+
if args.bref == "iso_then_aniso":
|
|
231
|
+
refmac2 = refmac.copy(xyzin=prefix+".mmcif",
|
|
232
|
+
prefix="refined_2_aniso")
|
|
233
|
+
refmac2.keywords.append("refi bref aniso")
|
|
234
|
+
refmac_summary = refmac2.run_refmac()
|
|
235
|
+
|
|
236
|
+
if __name__ == "__main__":
|
|
237
|
+
import sys
|
|
238
|
+
args = parse_args(sys.argv[1:])
|
|
239
|
+
main(args)
|
|
240
|
+
|