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.
Files changed (45) hide show
  1. servalcat/__init__.py +10 -0
  2. servalcat/__main__.py +120 -0
  3. servalcat/ext.cpython-314t-x86_64-linux-gnu.so +0 -0
  4. servalcat/refine/__init__.py +0 -0
  5. servalcat/refine/cgsolve.py +100 -0
  6. servalcat/refine/refine.py +1162 -0
  7. servalcat/refine/refine_geom.py +245 -0
  8. servalcat/refine/refine_spa.py +400 -0
  9. servalcat/refine/refine_xtal.py +339 -0
  10. servalcat/refine/spa.py +151 -0
  11. servalcat/refine/xtal.py +312 -0
  12. servalcat/refmac/__init__.py +0 -0
  13. servalcat/refmac/exte.py +191 -0
  14. servalcat/refmac/refmac_keywords.py +660 -0
  15. servalcat/refmac/refmac_wrapper.py +423 -0
  16. servalcat/spa/__init__.py +0 -0
  17. servalcat/spa/fofc.py +488 -0
  18. servalcat/spa/fsc.py +391 -0
  19. servalcat/spa/localcc.py +197 -0
  20. servalcat/spa/realspcc_from_var.py +128 -0
  21. servalcat/spa/run_refmac.py +979 -0
  22. servalcat/spa/shift_maps.py +293 -0
  23. servalcat/spa/shiftback.py +137 -0
  24. servalcat/spa/translate.py +129 -0
  25. servalcat/utils/__init__.py +35 -0
  26. servalcat/utils/commands.py +1629 -0
  27. servalcat/utils/fileio.py +836 -0
  28. servalcat/utils/generate_operators.py +296 -0
  29. servalcat/utils/hkl.py +811 -0
  30. servalcat/utils/logger.py +140 -0
  31. servalcat/utils/maps.py +345 -0
  32. servalcat/utils/model.py +933 -0
  33. servalcat/utils/refmac.py +759 -0
  34. servalcat/utils/restraints.py +888 -0
  35. servalcat/utils/symmetry.py +298 -0
  36. servalcat/xtal/__init__.py +0 -0
  37. servalcat/xtal/french_wilson.py +262 -0
  38. servalcat/xtal/run_refmac_small.py +240 -0
  39. servalcat/xtal/sigmaa.py +1954 -0
  40. servalcat/xtal/twin.py +316 -0
  41. servalcat-0.4.131.dist-info/METADATA +60 -0
  42. servalcat-0.4.131.dist-info/RECORD +45 -0
  43. servalcat-0.4.131.dist-info/WHEEL +6 -0
  44. servalcat-0.4.131.dist-info/entry_points.txt +4 -0
  45. 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
+