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.

@@ -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 = "EXPERIMENTAL program to refine cryo-EM SPA structures"
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: add riding hydrogen atoms, yes: use hydrogen atoms if present, no: remove hydrogen atoms in input. "
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 (e.g. expanded model is used with --pg) test')
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 NCS consistency test')
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 in B (default: %(default)f)")
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
- parser.add_argument('--adp', choices=["fix", "iso", "aniso"], default="iso")
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('--refine_h', action="store_true", help="Refine hydrogen (default: restraints only)")
108
- parser.add_argument("--source", choices=["electron", "xray", "neutron"], default="electron")
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
- try:
142
- monlib = utils.restraints.load_monomer_library(st, monomer_dir=args.monlib, cif_files=args.ligand,
143
- stop_for_unknowns=True, params=params)
144
- except RuntimeError as e:
145
- raise SystemExit("Error: {}".format(e))
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, add_found=args.find_links)
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
- mask = utils.fileio.read_ccp4_map(args.mask)[0] if args.mask else None
259
- fscavg_text = calc_fsc(st_expanded, args.output_prefix, maps,
260
- args.resolution, mask=mask, mask_radius=args.mask_radius if not args.no_mask else None,
261
- soft_edge=args.mask_soft_edge,
262
- b_before_mask=args.b_before_mask,
263
- no_sharpen_before_mask=args.no_sharpen_before_mask,
264
- make_hydrogen="yes", # no change needed in the model
265
- monlib=monlib,
266
- blur=args.blur,
267
- d_min_fsc=args.fsc_resolution,
268
- cross_validation=args.cross_validation,
269
- cross_validation_method=args.cross_validation_method
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,
@@ -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 = "EXPERIMENTAL program to refine crystallographic structures"
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("WARNING: in unrestrained refinement hydrogen atoms are not generated.")
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=True, params=params)
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
- utils.model.setup_entities(st, clear=True, force_subchain_names=True, overwrite_entity_type=True)
166
- utils.restraints.find_and_fix_links(st, monlib, add_found=args.find_links)
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 is_int:
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 is_int:
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.d_min = hkldata.d_min_max()[0]
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.d_min - 1e-6,
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
- return {"bin_stats": stats, "summary": {"FSCaverage": fsca, "-LL": self.calc_target()}}
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.d_min / 3) # TODO need more work
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]