servalcat 0.4.72__cp38-cp38-macosx_11_0_arm64.whl → 0.4.99__cp38-cp38-macosx_11_0_arm64.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 +2 -2
- servalcat/ext.cpython-38-darwin.so +0 -0
- servalcat/refine/refine.py +152 -67
- servalcat/refine/refine_geom.py +32 -13
- servalcat/refine/refine_spa.py +70 -40
- servalcat/refine/refine_xtal.py +45 -13
- servalcat/refine/spa.py +15 -4
- servalcat/refine/xtal.py +147 -98
- servalcat/refmac/exte.py +7 -5
- servalcat/refmac/refmac_keywords.py +11 -9
- servalcat/refmac/refmac_wrapper.py +87 -60
- servalcat/spa/fofc.py +20 -3
- servalcat/spa/fsc.py +11 -11
- servalcat/spa/run_refmac.py +27 -12
- servalcat/spa/translate.py +2 -2
- servalcat/utils/commands.py +154 -4
- servalcat/utils/fileio.py +20 -10
- servalcat/utils/hkl.py +43 -29
- servalcat/utils/logger.py +25 -1
- servalcat/utils/maps.py +2 -2
- servalcat/utils/model.py +23 -10
- servalcat/utils/refmac.py +20 -1
- servalcat/utils/restraints.py +34 -25
- servalcat/utils/symmetry.py +5 -5
- servalcat/xtal/french_wilson.py +39 -31
- servalcat/xtal/sigmaa.py +382 -152
- servalcat/xtal/twin.py +121 -0
- {servalcat-0.4.72.dist-info → servalcat-0.4.99.dist-info}/METADATA +4 -4
- servalcat-0.4.99.dist-info/RECORD +45 -0
- {servalcat-0.4.72.dist-info → servalcat-0.4.99.dist-info}/WHEEL +1 -1
- servalcat-0.4.72.dist-info/RECORD +0 -44
- {servalcat-0.4.72.dist-info → servalcat-0.4.99.dist-info}/entry_points.txt +0 -0
- {servalcat-0.4.72.dist-info → servalcat-0.4.99.dist-info}/licenses/LICENSE +0 -0
servalcat/refine/refine_spa.py
CHANGED
|
@@ -14,12 +14,12 @@ from servalcat import utils
|
|
|
14
14
|
from servalcat.spa.run_refmac import check_args, process_input, calc_fsc, calc_fofc
|
|
15
15
|
from servalcat.spa import fofc
|
|
16
16
|
from servalcat.refine import spa
|
|
17
|
-
from servalcat.refine.refine import Geom, Refine
|
|
17
|
+
from servalcat.refine.refine import Geom, Refine, update_meta, print_h_options
|
|
18
18
|
from servalcat.refmac import refmac_keywords
|
|
19
19
|
b_to_u = utils.model.b_to_u
|
|
20
20
|
|
|
21
21
|
def add_arguments(parser):
|
|
22
|
-
parser.description = "
|
|
22
|
+
parser.description = "program to refine cryo-EM SPA structures"
|
|
23
23
|
group = parser.add_mutually_exclusive_group(required=True)
|
|
24
24
|
group.add_argument("--halfmaps", nargs=2, help="Input half map files")
|
|
25
25
|
group.add_argument("--map", help="Use this only if you really do not have half maps.")
|
|
@@ -53,8 +53,10 @@ def add_arguments(parser):
|
|
|
53
53
|
help="Monomer library path. Default: $CLIBD_MON")
|
|
54
54
|
parser.add_argument('--ligand', nargs="*", action="append",
|
|
55
55
|
help="restraint dictionary cif file(s)")
|
|
56
|
+
parser.add_argument('--newligand_continue', action='store_true',
|
|
57
|
+
help="Make ad-hoc restraints for unknown ligands (not recommended)")
|
|
56
58
|
parser.add_argument('--hydrogen', default="all", choices=["all", "yes", "no"],
|
|
57
|
-
help="all:
|
|
59
|
+
help="all: (re)generate hydrogen atoms, yes: use hydrogen atoms if present, no: remove hydrogen atoms in input. "
|
|
58
60
|
"Default: %(default)s")
|
|
59
61
|
parser.add_argument('--hout', action='store_true', help="write hydrogen atoms in the output model")
|
|
60
62
|
parser.add_argument('--jellybody', action='store_true',
|
|
@@ -65,15 +67,15 @@ def add_arguments(parser):
|
|
|
65
67
|
parser.add_argument('--jellyonly', action='store_true',
|
|
66
68
|
help="Jelly body only (experimental, may not be useful)")
|
|
67
69
|
utils.symmetry.add_symmetry_args(parser) # add --pg etc
|
|
68
|
-
parser.add_argument('--contacting_only', action="store_true", help="Filter out non-contacting NCS")
|
|
69
|
-
parser.add_argument('--ignore_symmetry',
|
|
70
|
+
parser.add_argument('--contacting_only', action="store_true", help="Filter out non-contacting strict NCS copies")
|
|
71
|
+
parser.add_argument('--ignore_symmetry', action='store_true',
|
|
70
72
|
help='Ignore symmetry information (MTRIX/_struct_ncs_oper) in the model file')
|
|
71
73
|
parser.add_argument('--find_links', action='store_true',
|
|
72
74
|
help='Automatically add links')
|
|
73
75
|
parser.add_argument('--no_check_ncs_overlaps', action='store_true',
|
|
74
|
-
help='Disable model overlap
|
|
76
|
+
help='Disable model overlap test due to strict NCS')
|
|
75
77
|
parser.add_argument('--no_check_ncs_map', action='store_true',
|
|
76
|
-
help='Disable map
|
|
78
|
+
help='Disable map symmetry test due to strict NCS')
|
|
77
79
|
parser.add_argument('--no_check_mask_with_model', action='store_true',
|
|
78
80
|
help='Disable mask test using model')
|
|
79
81
|
parser.add_argument('--keywords', nargs='+', action="append",
|
|
@@ -81,7 +83,7 @@ def add_arguments(parser):
|
|
|
81
83
|
parser.add_argument('--keyword_file', nargs='+', action="append",
|
|
82
84
|
help="refmac keyword file(s)")
|
|
83
85
|
parser.add_argument('--randomize', type=float, default=0,
|
|
84
|
-
help='Shake coordinates with specified rmsd')
|
|
86
|
+
help='Shake coordinates with the specified rmsd value')
|
|
85
87
|
parser.add_argument('--ncycle', type=int, default=10,
|
|
86
88
|
help="number of CG cycles (default: %(default)d)")
|
|
87
89
|
parser.add_argument('--weight', type=float,
|
|
@@ -91,21 +93,26 @@ def add_arguments(parser):
|
|
|
91
93
|
parser.add_argument('--target_bond_rmsz_range', nargs=2, type=float, default=[0.5, 1.],
|
|
92
94
|
help='Bond rmsz range for weight adjustment (default: %(default)s)')
|
|
93
95
|
parser.add_argument('--adpr_weight', type=float, default=1.,
|
|
94
|
-
help="ADP restraint weight
|
|
96
|
+
help="ADP restraint weight (default: %(default)f)")
|
|
97
|
+
parser.add_argument('--occr_weight', type=float, default=1.,
|
|
98
|
+
help="Occupancy restraint weight (default: %(default)f)")
|
|
95
99
|
parser.add_argument('--ncsr', action='store_true',
|
|
96
100
|
help='Use local NCS restraints')
|
|
97
101
|
parser.add_argument('--bfactor', type=float,
|
|
98
|
-
help="reset all atomic B values to specified value")
|
|
99
|
-
parser.add_argument('--fix_xyz', action="store_true"
|
|
100
|
-
|
|
102
|
+
help="reset all atomic B values to the specified value")
|
|
103
|
+
parser.add_argument('--fix_xyz', action="store_true",
|
|
104
|
+
help="Fix atomic coordinates")
|
|
105
|
+
parser.add_argument('--adp', choices=["fix", "iso", "aniso"], default="iso",
|
|
106
|
+
help="ADP parameterization")
|
|
101
107
|
parser.add_argument('--refine_all_occ', action="store_true")
|
|
102
108
|
parser.add_argument('--max_dist_for_adp_restraint', type=float, default=4.)
|
|
103
109
|
parser.add_argument('--adp_restraint_power', type=float)
|
|
104
110
|
parser.add_argument('--adp_restraint_exp_fac', type=float)
|
|
105
111
|
parser.add_argument('--adp_restraint_no_long_range', action='store_true')
|
|
106
112
|
parser.add_argument('--adp_restraint_mode', choices=["diff", "kldiv"], default="diff")
|
|
107
|
-
parser.add_argument('--
|
|
108
|
-
parser.add_argument(
|
|
113
|
+
parser.add_argument('--unrestrained', action='store_true', help="No positional restraints")
|
|
114
|
+
parser.add_argument('--refine_h', action="store_true", help="Refine hydrogen against data (default: only restraints apply)")
|
|
115
|
+
parser.add_argument("-s", "--source", choices=["electron", "xray", "neutron"], default="electron")
|
|
109
116
|
parser.add_argument('-o','--output_prefix', default="refined")
|
|
110
117
|
parser.add_argument('--cross_validation', action='store_true',
|
|
111
118
|
help='Run cross validation. Only "throughout" mode is available (no "shake" mode)')
|
|
@@ -138,11 +145,23 @@ def main(args):
|
|
|
138
145
|
params["write_trajectory"] = args.write_trajectory
|
|
139
146
|
|
|
140
147
|
st = utils.fileio.read_structure(args.model)
|
|
141
|
-
|
|
142
|
-
monlib =
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
148
|
+
if args.unrestrained:
|
|
149
|
+
monlib = gemmi.MonLib()
|
|
150
|
+
topo = None
|
|
151
|
+
if args.hydrogen == "all":
|
|
152
|
+
logger.writeln("\nWARNING: in unrestrained refinement hydrogen atoms are not generated.\n")
|
|
153
|
+
args.hydrogen = "yes"
|
|
154
|
+
elif args.hydrogen == "no":
|
|
155
|
+
st.remove_hydrogens()
|
|
156
|
+
for i, cra in enumerate(st[0].all()):
|
|
157
|
+
cra.atom.serial = i + 1
|
|
158
|
+
else:
|
|
159
|
+
try:
|
|
160
|
+
monlib = utils.restraints.load_monomer_library(st, monomer_dir=args.monlib, cif_files=args.ligand,
|
|
161
|
+
stop_for_unknowns=not args.newligand_continue,
|
|
162
|
+
params=params)
|
|
163
|
+
except RuntimeError as e:
|
|
164
|
+
raise SystemExit("Error: {}".format(e))
|
|
146
165
|
if not args.keep_entities:
|
|
147
166
|
utils.model.setup_entities(st, clear=True, force_subchain_names=True, overwrite_entity_type=True)
|
|
148
167
|
if not args.keep_charges:
|
|
@@ -161,7 +180,8 @@ def main(args):
|
|
|
161
180
|
st.spacegroup_hm = hkldata.sg.xhm()
|
|
162
181
|
st.setup_cell_images()
|
|
163
182
|
info = {}
|
|
164
|
-
utils.restraints.find_and_fix_links(st, monlib,
|
|
183
|
+
utils.restraints.find_and_fix_links(st, monlib, find_metal_links=args.find_links,
|
|
184
|
+
add_found=args.find_links)
|
|
165
185
|
else:
|
|
166
186
|
if args.halfmaps:
|
|
167
187
|
maps = utils.fileio.read_halfmaps(args.halfmaps, pixel_size=args.pixel_size)
|
|
@@ -180,6 +200,8 @@ def main(args):
|
|
|
180
200
|
except RuntimeError as e:
|
|
181
201
|
raise SystemExit("Error: {}".format(e))
|
|
182
202
|
|
|
203
|
+
print_h_options(h_change, st[0].has_hydrogen(), args.refine_h, args.hout, geom_only=False)
|
|
204
|
+
|
|
183
205
|
# initialize ADP
|
|
184
206
|
utils.model.reset_adp(st[0], args.bfactor, args.adp)
|
|
185
207
|
|
|
@@ -208,8 +230,8 @@ def main(args):
|
|
|
208
230
|
ncslist = utils.restraints.prepare_ncs_restraints(st)
|
|
209
231
|
else:
|
|
210
232
|
ncslist = False
|
|
211
|
-
geom = Geom(st, topo, monlib, shake_rms=args.randomize, adpr_w=args.adpr_weight,
|
|
212
|
-
params=params, unrestrained=args.jellyonly,
|
|
233
|
+
geom = Geom(st, topo, monlib, shake_rms=args.randomize, adpr_w=args.adpr_weight, occr_w=args.occr_weight,
|
|
234
|
+
params=params, unrestrained=args.unrestrained or args.jellyonly,
|
|
213
235
|
ncslist=ncslist)
|
|
214
236
|
ll = spa.LL_SPA(hkldata, st, monlib,
|
|
215
237
|
lab_obs="F_map1" if args.cross_validation else "FP",
|
|
@@ -218,6 +240,7 @@ def main(args):
|
|
|
218
240
|
refine_xyz=not args.fix_xyz,
|
|
219
241
|
adp_mode=dict(fix=0, iso=1, aniso=2)[args.adp],
|
|
220
242
|
refine_h=args.refine_h,
|
|
243
|
+
unrestrained=args.unrestrained,
|
|
221
244
|
params=params,
|
|
222
245
|
refine_occ=args.refine_all_occ)
|
|
223
246
|
|
|
@@ -241,12 +264,8 @@ def main(args):
|
|
|
241
264
|
refiner.st.cell = maps[0][0].unit_cell
|
|
242
265
|
refiner.st.setup_cell_images()
|
|
243
266
|
|
|
244
|
-
refiner.st.name = args.output_prefix
|
|
245
|
-
utils.fileio.write_model(refiner.st, args.output_prefix, pdb=True, cif=True, hout=args.hout)
|
|
246
267
|
if params["write_trajectory"]:
|
|
247
268
|
utils.fileio.write_model(refiner.st_traj, args.output_prefix + "_traj", cif=True)
|
|
248
|
-
if args.hklin:
|
|
249
|
-
return
|
|
250
269
|
|
|
251
270
|
# Expand sym here
|
|
252
271
|
st_expanded = refiner.st.clone()
|
|
@@ -255,20 +274,28 @@ def main(args):
|
|
|
255
274
|
utils.fileio.write_model(st_expanded, args.output_prefix+"_expanded", pdb=True, cif=True, hout=args.hout)
|
|
256
275
|
|
|
257
276
|
# Calc FSC
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
277
|
+
if args.hklin: # cannot update a mask
|
|
278
|
+
stats_for_meta = stats[-1]
|
|
279
|
+
else:
|
|
280
|
+
mask = utils.fileio.read_ccp4_map(args.mask)[0] if args.mask else None
|
|
281
|
+
fscavg_text, stats2 = calc_fsc(st_expanded, args.output_prefix, maps,
|
|
282
|
+
args.resolution, mask=mask, mask_radius=args.mask_radius if not args.no_mask else None,
|
|
283
|
+
soft_edge=args.mask_soft_edge,
|
|
284
|
+
b_before_mask=args.b_before_mask,
|
|
285
|
+
no_sharpen_before_mask=args.no_sharpen_before_mask,
|
|
286
|
+
make_hydrogen="yes", # no change needed in the model
|
|
287
|
+
monlib=monlib,
|
|
288
|
+
blur=args.blur,
|
|
289
|
+
d_min_fsc=args.fsc_resolution,
|
|
290
|
+
cross_validation=args.cross_validation,
|
|
291
|
+
cross_validation_method=args.cross_validation_method
|
|
292
|
+
)
|
|
293
|
+
stats_for_meta = {"geom": stats[-1]["geom"], "data": stats2}
|
|
294
|
+
update_meta(refiner.st, stats_for_meta, ll)
|
|
295
|
+
refiner.st.name = args.output_prefix
|
|
296
|
+
utils.fileio.write_model(refiner.st, args.output_prefix, pdb=True, cif=True, hout=args.hout)
|
|
297
|
+
if args.hklin:
|
|
298
|
+
return
|
|
272
299
|
# Calc Fo-Fc (and updated) maps
|
|
273
300
|
diffmap_prefix = "{}_diffmap".format(args.output_prefix)
|
|
274
301
|
calc_fofc(refiner.st, st_expanded, maps, monlib, ".mmcif", args, diffmap_prefix=diffmap_prefix)
|
|
@@ -316,6 +343,9 @@ Weight used: {final_weight:.3e}
|
|
|
316
343
|
Open refined model and {diffmap_prefix}.mtz with COOT:
|
|
317
344
|
coot --script {prefix}_coot.py
|
|
318
345
|
|
|
346
|
+
Open refined model, map and difference map with ChimeraX/ISOLDE:
|
|
347
|
+
chimerax {prefix}_chimerax.cxc
|
|
348
|
+
|
|
319
349
|
{map_peaks_msg}
|
|
320
350
|
=============================================================================
|
|
321
351
|
""".format(rmsbond=rmsbond,
|
servalcat/refine/refine_xtal.py
CHANGED
|
@@ -8,19 +8,21 @@ Mozilla Public License, version 2.0; see LICENSE.
|
|
|
8
8
|
from __future__ import absolute_import, division, print_function, generators
|
|
9
9
|
import gemmi
|
|
10
10
|
import numpy
|
|
11
|
+
import pandas
|
|
11
12
|
import os
|
|
12
13
|
import shutil
|
|
13
14
|
import argparse
|
|
14
15
|
from servalcat.utils import logger
|
|
15
16
|
from servalcat import utils
|
|
16
|
-
from servalcat.xtal.sigmaa import decide_mtz_labels, process_input, calculate_maps, calculate_maps_int
|
|
17
|
+
from servalcat.xtal.sigmaa import decide_mtz_labels, process_input, calculate_maps, calculate_maps_int, calculate_maps_twin
|
|
17
18
|
from servalcat.refine.xtal import LL_Xtal
|
|
18
|
-
from servalcat.refine.refine import Geom, Refine
|
|
19
|
+
from servalcat.refine.refine import Geom, Refine, update_meta, print_h_options
|
|
19
20
|
from servalcat.refmac import refmac_keywords
|
|
21
|
+
from servalcat import ext
|
|
20
22
|
b_to_u = utils.model.b_to_u
|
|
21
23
|
|
|
22
24
|
def add_arguments(parser):
|
|
23
|
-
parser.description = "
|
|
25
|
+
parser.description = "program to refine crystallographic structures"
|
|
24
26
|
parser.add_argument("--hklin", required=True)
|
|
25
27
|
parser.add_argument("-d", '--d_min', type=float)
|
|
26
28
|
parser.add_argument('--d_max', type=float)
|
|
@@ -35,6 +37,8 @@ def add_arguments(parser):
|
|
|
35
37
|
help="Monomer library path. Default: $CLIBD_MON")
|
|
36
38
|
parser.add_argument('--ligand', nargs="*", action="append",
|
|
37
39
|
help="restraint dictionary cif file(s)")
|
|
40
|
+
parser.add_argument('--newligand_continue', action='store_true',
|
|
41
|
+
help="Make ad-hoc restraints for unknown ligands (not recommended)")
|
|
38
42
|
parser.add_argument('--hydrogen', default="all", choices=["all", "yes", "no"],
|
|
39
43
|
help="all: add riding hydrogen atoms, yes: use hydrogen atoms if present, no: remove hydrogen atoms in input. "
|
|
40
44
|
"Default: %(default)s")
|
|
@@ -60,10 +64,14 @@ def add_arguments(parser):
|
|
|
60
64
|
help="refinement weight (default: auto)")
|
|
61
65
|
parser.add_argument('--no_weight_adjust', action='store_true',
|
|
62
66
|
help='Do not adjust weight during refinement')
|
|
67
|
+
parser.add_argument('--target_bond_rmsz_range', nargs=2, type=float, default=[0.5, 1.],
|
|
68
|
+
help='Bond rmsz range for weight adjustment (default: %(default)s)')
|
|
63
69
|
parser.add_argument('--ncsr', action='store_true',
|
|
64
70
|
help='Use local NCS restraints')
|
|
65
71
|
parser.add_argument('--adpr_weight', type=float, default=1.,
|
|
66
72
|
help="ADP restraint weight (default: %(default)f)")
|
|
73
|
+
parser.add_argument('--occr_weight', type=float, default=1.,
|
|
74
|
+
help="Occupancy restraint weight (default: %(default)f)")
|
|
67
75
|
parser.add_argument('--bfactor', type=float,
|
|
68
76
|
help="reset all atomic B values to specified value")
|
|
69
77
|
parser.add_argument('--fix_xyz', action="store_true")
|
|
@@ -76,6 +84,7 @@ def add_arguments(parser):
|
|
|
76
84
|
parser.add_argument('--adp_restraint_mode', choices=["diff", "kldiv"], default="kldiv")
|
|
77
85
|
parser.add_argument('--unrestrained', action='store_true', help="No positional restraints")
|
|
78
86
|
parser.add_argument('--refine_h', action="store_true", help="Refine hydrogen (default: restraints only)")
|
|
87
|
+
parser.add_argument('--twin', action="store_true", help="Turn on twin refinement")
|
|
79
88
|
parser.add_argument("-s", "--source", choices=["electron", "xray", "neutron"], required=True)
|
|
80
89
|
parser.add_argument('--no_solvent', action='store_true',
|
|
81
90
|
help="Do not consider bulk solvent contribution")
|
|
@@ -83,9 +92,14 @@ def add_arguments(parser):
|
|
|
83
92
|
help="Use work reflections in ML parameter estimates")
|
|
84
93
|
parser.add_argument('--keep_charges', action='store_true',
|
|
85
94
|
help="Use scattering factor for charged atoms. Use it with care.")
|
|
95
|
+
parser.add_argument("--keep_entities", action='store_true',
|
|
96
|
+
help="Do not override entities")
|
|
97
|
+
parser.add_argument('--allow_unusual_occupancies', action="store_true", help="Allow negative or more than one occupancies")
|
|
86
98
|
parser.add_argument('-o','--output_prefix')
|
|
87
99
|
parser.add_argument("--write_trajectory", action='store_true',
|
|
88
100
|
help="Write all output from cycles")
|
|
101
|
+
parser.add_argument("--vonmises", action='store_true',
|
|
102
|
+
help="Experimental: von Mises type restraint for angles")
|
|
89
103
|
# add_arguments()
|
|
90
104
|
|
|
91
105
|
def parse_args(arg_list):
|
|
@@ -140,7 +154,8 @@ def main(args):
|
|
|
140
154
|
n_per_bin=n_per_bin,
|
|
141
155
|
use=use_in_est,
|
|
142
156
|
max_bins=30,
|
|
143
|
-
keep_charges=args.keep_charges
|
|
157
|
+
keep_charges=args.keep_charges,
|
|
158
|
+
allow_unusual_occupancies=args.allow_unusual_occupancies)
|
|
144
159
|
except RuntimeError as e:
|
|
145
160
|
raise SystemExit("Error: {}".format(e))
|
|
146
161
|
|
|
@@ -150,20 +165,25 @@ def main(args):
|
|
|
150
165
|
if args.unrestrained:
|
|
151
166
|
monlib = gemmi.MonLib()
|
|
152
167
|
topo = None
|
|
168
|
+
h_change = gemmi.HydrogenChange.NoChange
|
|
153
169
|
if args.hydrogen == "all":
|
|
154
|
-
logger.writeln("
|
|
170
|
+
logger.writeln("\nWARNING: in unrestrained refinement hydrogen atoms are not generated.\n")
|
|
155
171
|
elif args.hydrogen == "no":
|
|
156
172
|
st.remove_hydrogens()
|
|
173
|
+
h_change = gemmi.HydrogenChange.Remove
|
|
157
174
|
for i, cra in enumerate(st[0].all()):
|
|
158
175
|
cra.atom.serial = i + 1
|
|
159
176
|
else:
|
|
160
177
|
try:
|
|
161
178
|
monlib = utils.restraints.load_monomer_library(st, monomer_dir=args.monlib, cif_files=args.ligand,
|
|
162
|
-
stop_for_unknowns=
|
|
179
|
+
stop_for_unknowns=not args.newligand_continue,
|
|
180
|
+
params=params)
|
|
163
181
|
except RuntimeError as e:
|
|
164
182
|
raise SystemExit("Error: {}".format(e))
|
|
165
|
-
|
|
166
|
-
|
|
183
|
+
if not args.keep_entities:
|
|
184
|
+
utils.model.setup_entities(st, clear=True, force_subchain_names=True, overwrite_entity_type=True)
|
|
185
|
+
utils.restraints.find_and_fix_links(st, monlib, find_metal_links=args.find_links,
|
|
186
|
+
add_found=args.find_links)
|
|
167
187
|
h_change = {"all":gemmi.HydrogenChange.ReAddKnown,
|
|
168
188
|
"yes":gemmi.HydrogenChange.NoChange,
|
|
169
189
|
"no":gemmi.HydrogenChange.Remove}[args.hydrogen]
|
|
@@ -174,6 +194,8 @@ def main(args):
|
|
|
174
194
|
except RuntimeError as e:
|
|
175
195
|
raise SystemExit("Error: {}".format(e))
|
|
176
196
|
|
|
197
|
+
print_h_options(h_change, st[0].has_hydrogen(), args.refine_h, args.hout, geom_only=False)
|
|
198
|
+
|
|
177
199
|
# initialize ADP
|
|
178
200
|
utils.model.reset_adp(st[0], args.bfactor, args.adp)
|
|
179
201
|
|
|
@@ -188,9 +210,10 @@ def main(args):
|
|
|
188
210
|
ncslist = utils.restraints.prepare_ncs_restraints(st)
|
|
189
211
|
else:
|
|
190
212
|
ncslist = False
|
|
191
|
-
geom = Geom(st, topo, monlib, shake_rms=args.randomize, adpr_w=args.adpr_weight, params=params,
|
|
213
|
+
geom = Geom(st, topo, monlib, shake_rms=args.randomize, adpr_w=args.adpr_weight, occr_w=args.occr_weight, params=params,
|
|
192
214
|
unrestrained=args.unrestrained or args.jellyonly, use_nucleus=(args.source=="neutron"),
|
|
193
215
|
ncslist=ncslist)
|
|
216
|
+
geom.geom.angle_von_mises = args.vonmises
|
|
194
217
|
geom.geom.adpr_max_dist = args.max_dist_for_adp_restraint
|
|
195
218
|
if args.adp_restraint_power is not None: geom.geom.adpr_d_power = args.adp_restraint_power
|
|
196
219
|
if args.adp_restraint_exp_fac is not None: geom.geom.adpr_exp_fac = args.adp_restraint_exp_fac
|
|
@@ -201,7 +224,8 @@ def main(args):
|
|
|
201
224
|
if args.jellyonly: geom.geom.ridge_exclude_short_dist = False
|
|
202
225
|
|
|
203
226
|
ll = LL_Xtal(hkldata, centric_and_selections, args.free, st, monlib, source=args.source,
|
|
204
|
-
use_solvent=not args.no_solvent, use_in_est=use_in_est, use_in_target=use_in_target
|
|
227
|
+
use_solvent=not args.no_solvent, use_in_est=use_in_est, use_in_target=use_in_target,
|
|
228
|
+
twin=args.twin)
|
|
205
229
|
refiner = Refine(st, geom, ll=ll,
|
|
206
230
|
refine_xyz=not args.fix_xyz,
|
|
207
231
|
adp_mode=dict(fix=0, iso=1, aniso=2)[args.adp],
|
|
@@ -212,13 +236,19 @@ def main(args):
|
|
|
212
236
|
|
|
213
237
|
stats = refiner.run_cycles(args.ncycle, weight=args.weight,
|
|
214
238
|
weight_adjust=not args.no_weight_adjust,
|
|
239
|
+
weight_adjust_bond_rmsz_range=args.target_bond_rmsz_range,
|
|
215
240
|
stats_json_out=args.output_prefix + "_stats.json")
|
|
241
|
+
update_meta(st, stats[-1], ll)
|
|
216
242
|
refiner.st.name = args.output_prefix
|
|
217
243
|
utils.fileio.write_model(refiner.st, args.output_prefix, pdb=True, cif=True, hout=args.hout)
|
|
218
244
|
if params["write_trajectory"]:
|
|
219
245
|
utils.fileio.write_model(refiner.st_traj, args.output_prefix + "_traj", cif=True)
|
|
220
246
|
|
|
221
|
-
if
|
|
247
|
+
if ll.twin_data:
|
|
248
|
+
# replace hkldata
|
|
249
|
+
hkldata = calculate_maps_twin(ll.hkldata, ll.b_aniso, ll.fc_labs, ll.D_labs, ll.twin_data,
|
|
250
|
+
centric_and_selections, use=use_in_target)
|
|
251
|
+
elif is_int:
|
|
222
252
|
calculate_maps_int(ll.hkldata, ll.b_aniso, ll.fc_labs, ll.D_labs, centric_and_selections,
|
|
223
253
|
use=use_in_target)
|
|
224
254
|
else:
|
|
@@ -226,7 +256,9 @@ def main(args):
|
|
|
226
256
|
use=use_in_target)
|
|
227
257
|
|
|
228
258
|
# Write mtz file
|
|
229
|
-
if
|
|
259
|
+
if ll.twin_data:
|
|
260
|
+
labs = ["F_est", "F_exp", "FOM"]
|
|
261
|
+
elif is_int:
|
|
230
262
|
labs = ["I", "SIGI", "FOM"]
|
|
231
263
|
else:
|
|
232
264
|
labs = ["FP", "SIGFP", "FOM"]
|
|
@@ -239,7 +271,7 @@ def main(args):
|
|
|
239
271
|
labs.append("FREE")
|
|
240
272
|
labs += ll.D_labs + ["S"] # for debugging, for now
|
|
241
273
|
mtz_out = args.output_prefix+".mtz"
|
|
242
|
-
hkldata.write_mtz(mtz_out, labs=labs, types={"FOM": "W", "FP":"F", "SIGFP":"Q", "I":"J", "SIGI":"Q"})
|
|
274
|
+
hkldata.write_mtz(mtz_out, labs=labs, types={"FOM": "W", "FP":"F", "SIGFP":"Q", "I":"J", "SIGI":"Q", "F_est": "F", "F_exp": "F"})
|
|
243
275
|
|
|
244
276
|
# main()
|
|
245
277
|
|
servalcat/refine/spa.py
CHANGED
|
@@ -38,8 +38,14 @@ class LL_SPA:
|
|
|
38
38
|
self.lab_obs = lab_obs
|
|
39
39
|
self.st = st
|
|
40
40
|
self.monlib = monlib
|
|
41
|
-
self.
|
|
41
|
+
self.d_min_max = hkldata.d_min_max()
|
|
42
42
|
self.ll = None
|
|
43
|
+
self.b_aniso = None
|
|
44
|
+
|
|
45
|
+
def refine_id(self):
|
|
46
|
+
if self.source == "electron":
|
|
47
|
+
return "ELECTRON MICROSCOPY"
|
|
48
|
+
return "NON-EM SPA" # does not happen, I guess
|
|
43
49
|
|
|
44
50
|
def update_ml_params(self):
|
|
45
51
|
# FIXME make sure D > 0
|
|
@@ -52,12 +58,15 @@ class LL_SPA:
|
|
|
52
58
|
else:
|
|
53
59
|
st = self.st
|
|
54
60
|
|
|
55
|
-
self.hkldata.df["FC"] = utils.model.calc_fc_fft(st, self.
|
|
61
|
+
self.hkldata.df["FC"] = utils.model.calc_fc_fft(st, self.d_min_max[0] - 1e-6,
|
|
56
62
|
monlib=self.monlib,
|
|
57
63
|
source=self.source,
|
|
58
64
|
mott_bethe=self.mott_bethe,
|
|
59
65
|
miller_array=self.hkldata.miller_array())
|
|
60
66
|
|
|
67
|
+
def prepare_target(self):
|
|
68
|
+
pass
|
|
69
|
+
|
|
61
70
|
def overall_scale(self, min_b=0.5):
|
|
62
71
|
k, b = self.hkldata.scale_k_and_b(lab_ref=self.lab_obs, lab_scaled="FC")
|
|
63
72
|
min_b_iso = self.st[0].calculate_b_aniso_range()[0] # actually min of aniso too
|
|
@@ -89,15 +98,17 @@ class LL_SPA:
|
|
|
89
98
|
stats = fsc.calc_fsc_all(self.hkldata, labs_fc=["FC"], lab_f=self.lab_obs)
|
|
90
99
|
fsca = fsc.fsc_average(stats.ncoeffs, stats.fsc_FC_full)
|
|
91
100
|
logger.writeln("FSCaverage = {:.4f}".format(fsca))
|
|
101
|
+
ret = {"summary": {"FSCaverage": fsca, "-LL": self.calc_target()}}
|
|
92
102
|
# XXX in fsc object, _full is misleading - it's not full in cross validation mode
|
|
93
103
|
if "D" in self.hkldata.binned_df and "S" in self.hkldata.binned_df:
|
|
94
104
|
stats[["D", "S"]] = self.hkldata.binned_df[["D", "S"]]
|
|
95
|
-
|
|
105
|
+
ret["bin_stats"] = stats
|
|
106
|
+
return ret
|
|
96
107
|
|
|
97
108
|
def calc_grad(self, atom_pos, refine_xyz, adp_mode, refine_occ, refine_h, specs):
|
|
98
109
|
dll_dab = numpy.empty_like(self.hkldata.df[self.lab_obs])
|
|
99
110
|
d2ll_dab2 = numpy.zeros(len(self.hkldata.df.index))
|
|
100
|
-
blur = utils.model.determine_blur_for_dencalc(self.st, self.
|
|
111
|
+
blur = utils.model.determine_blur_for_dencalc(self.st, self.d_min_max[0] / 3) # TODO need more work
|
|
101
112
|
logger.writeln("blur for deriv= {:.2f}".format(blur))
|
|
102
113
|
for i_bin, idxes in self.hkldata.binned():
|
|
103
114
|
D = self.hkldata.binned_df.D[i_bin]
|