modelcraft 4.0.2__tar.gz → 5.0.0__tar.gz

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 (93) hide show
  1. {modelcraft-4.0.2/modelcraft.egg-info → modelcraft-5.0.0}/PKG-INFO +1 -1
  2. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/__init__.py +1 -1
  3. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/arguments.py +50 -29
  4. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/servalcat.py +9 -10
  5. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/modelcraftem.py +48 -27
  6. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccpem/test_em.py +10 -7
  7. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccpem/test_servalcat.py +6 -4
  8. {modelcraft-4.0.2 → modelcraft-5.0.0/modelcraft.egg-info}/PKG-INFO +1 -1
  9. {modelcraft-4.0.2 → modelcraft-5.0.0}/setup.py +1 -1
  10. {modelcraft-4.0.2 → modelcraft-5.0.0}/LICENSE +0 -0
  11. {modelcraft-4.0.2 → modelcraft-5.0.0}/MANIFEST.in +0 -0
  12. {modelcraft-4.0.2 → modelcraft-5.0.0}/README.md +0 -0
  13. {modelcraft-4.0.2 → modelcraft-5.0.0}/docs/css/custom.css +0 -0
  14. {modelcraft-4.0.2 → modelcraft-5.0.0}/docs/css/milligram.min.css +0 -0
  15. {modelcraft-4.0.2 → modelcraft-5.0.0}/docs/css/normalize.min.css +0 -0
  16. {modelcraft-4.0.2 → modelcraft-5.0.0}/docs/img/modelcraft.png +0 -0
  17. {modelcraft-4.0.2 → modelcraft-5.0.0}/docs/index.html +0 -0
  18. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/__main__.py +0 -0
  19. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/cell.py +0 -0
  20. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/combine.py +0 -0
  21. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/contents.py +0 -0
  22. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/coot/prune.py +0 -0
  23. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/coot/sidechains.py +0 -0
  24. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/environ.py +0 -0
  25. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/geometry.py +0 -0
  26. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/job.py +0 -0
  27. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/__init__.py +0 -0
  28. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/acedrg.py +0 -0
  29. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/acorn.py +0 -0
  30. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/buccaneer.py +0 -0
  31. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/comit.py +0 -0
  32. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/coot.py +0 -0
  33. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/ctruncate.py +0 -0
  34. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/emda.py +0 -0
  35. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/findwaters.py +0 -0
  36. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/freerflag.py +0 -0
  37. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/libg.py +0 -0
  38. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/molrep.py +0 -0
  39. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/nautilus.py +0 -0
  40. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/parrot.py +0 -0
  41. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/phasematch.py +0 -0
  42. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/refmac.py +0 -0
  43. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/jobs/sheetbend.py +0 -0
  44. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/maps.py +0 -0
  45. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/modelcraftxray.py +0 -0
  46. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/monlib.py +0 -0
  47. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/pipeline.py +0 -0
  48. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/reflections.py +0 -0
  49. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/scripts/__init__.py +0 -0
  50. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/scripts/contents.py +0 -0
  51. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/scripts/copies.py +0 -0
  52. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/scripts/modelcraft.py +0 -0
  53. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/solvent.py +0 -0
  54. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/structure.py +0 -0
  55. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/__init__.py +0 -0
  56. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/__init__.py +0 -0
  57. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_acedrg.py +0 -0
  58. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_arguments.py +0 -0
  59. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_buccaneer.py +0 -0
  60. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_cell.py +0 -0
  61. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_comit.py +0 -0
  62. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_contents.py +0 -0
  63. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_coot.py +0 -0
  64. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_copies.py +0 -0
  65. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_ctruncate.py +0 -0
  66. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_findwaters.py +0 -0
  67. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_freerflag.py +0 -0
  68. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_geometry.py +0 -0
  69. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_libg.py +0 -0
  70. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_molrep.py +0 -0
  71. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_monlib.py +0 -0
  72. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_nautilus.py +0 -0
  73. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_parrot.py +0 -0
  74. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_phasematch.py +0 -0
  75. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_reflections.py +0 -0
  76. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_refmac.py +0 -0
  77. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_sheetbend.py +0 -0
  78. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_solvent.py +0 -0
  79. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_structure.py +0 -0
  80. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccp4/test_xray.py +0 -0
  81. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccpem/__init__.py +0 -0
  82. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccpem/test_emda.py +0 -0
  83. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/ccpem/test_refmac.py +0 -0
  84. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/unittests/__init__.py +0 -0
  85. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/unittests/test_contents.py +0 -0
  86. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/tests/unittests/test_reflections.py +0 -0
  87. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft/utils.py +0 -0
  88. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft.egg-info/SOURCES.txt +0 -0
  89. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft.egg-info/dependency_links.txt +0 -0
  90. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft.egg-info/entry_points.txt +0 -0
  91. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft.egg-info/requires.txt +0 -0
  92. {modelcraft-4.0.2 → modelcraft-5.0.0}/modelcraft.egg-info/top_level.txt +0 -0
  93. {modelcraft-4.0.2 → modelcraft-5.0.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modelcraft
3
- Version: 4.0.2
3
+ Version: 5.0.0
4
4
  Summary: Automated model building pipeline for X-ray crystallography
5
5
  Home-page: https://github.com/paulsbond/modelcraft
6
6
  Author: Paul Bond
@@ -1,4 +1,4 @@
1
- __version__ = "4.0.2"
1
+ __version__ = "5.0.0"
2
2
 
3
3
  from .cell import max_distortion as max_cell_distortion
4
4
  from .cell import remove_scale
@@ -241,25 +241,27 @@ _GROUP.add_argument(
241
241
 
242
242
  _EM = _SUB_PARSERS.add_parser("em", parents=[_PARENT], formatter_class=_FORMATTER)
243
243
  _GROUP = _EM.add_argument_group("required arguments (em)")
244
- _GROUP.add_argument(
245
- "--map",
246
- required=True,
247
- nargs="+",
244
+ _MAP = _GROUP.add_mutually_exclusive_group(required=True)
245
+ _MAP.add_argument(
246
+ "--half-maps",
247
+ nargs=2,
248
248
  metavar="X",
249
249
  help=(
250
- "Either two half-maps or a single map in MRC format. "
251
- "Input maps will be trimmed using Servalcat. "
252
- "If two half-maps are provided then Servalcat will be used to calculate "
250
+ "Unsharpened, unweighted half-maps in MRC format for use in refinement. "
251
+ "This option is preferred over providing a single map. "
252
+ "If the --build-map argument is not provided "
253
+ "then Servalcat will be used to calculate "
253
254
  "a normalised expected (NE) map for model building."
254
255
  ),
255
256
  )
256
- _GROUP.add_argument(
257
- "--mask",
257
+ _MAP.add_argument(
258
+ "--single-map",
258
259
  metavar="X",
259
260
  help=(
260
- "Mask with the same grid size and dimensions as the input map(s). "
261
- "Servalcat will use this mask when trimming the maps. "
262
- "If a mask is not provided then EMDA mapmask will be used to create one."
261
+ "A single unsharpened, unweighted map in MRC format for use in refinement. "
262
+ "Only use this option if you do not have two half-maps available. "
263
+ "If the --build-map argument is not provided "
264
+ "then this map will also be used for model building. "
263
265
  ),
264
266
  )
265
267
  _GROUP.add_argument(
@@ -267,19 +269,33 @@ _GROUP.add_argument(
267
269
  type=float,
268
270
  required=True,
269
271
  metavar="X",
270
- help="High resolution limit in Angstroms",
272
+ help=(
273
+ "Best resolution (high resolution limit) in Angstroms. "
274
+ "Using a higher resolution (a smaller number) reduces the grid spacing, "
275
+ "which may give better results at the cost of slower calculations."
276
+ ),
271
277
  )
278
+ _GROUP = _EM.add_argument_group("optional arguments (em)")
272
279
  _GROUP.add_argument(
273
- "--blur",
274
- default=0.0,
275
- type=float,
280
+ "--build-map",
281
+ metavar="X",
282
+ help=(
283
+ "Optimally-sharpened map (e.g. from LocScale) for use in model building. "
284
+ "If this is not provided then a normalised expected (NE) map "
285
+ "will be calculated from the two half-maps. "
286
+ "If half-maps were not provided then the single map will be used."
287
+ ),
288
+ )
289
+ _GROUP.add_argument(
290
+ "--mask",
276
291
  metavar="X",
277
292
  help=(
278
- "B-factor for global blurring or sharpening of the input map "
279
- "(positive values for blurring and negative values for sharpening). "
280
- "This value is only used if a single input map is provided. "
281
- "If two half-maps are provided then local blurring and sharpening "
282
- "is performed in the calculation of the normalised expected (NE) map."
293
+ "Mask for trimming the input maps in MRC format, "
294
+ "with the same grid size and dimensions as the input maps. "
295
+ "Having a box size that is too large will lead to worse building results, "
296
+ "slow down the programs, and make the FSC calculation less accurate. "
297
+ "If this argument is set to 'auto' "
298
+ "then EMDA mapmask will be used to create a mask."
283
299
  ),
284
300
  )
285
301
 
@@ -303,25 +319,30 @@ def _basic_check(args: argparse.Namespace):
303
319
  _PARSER.error(f"--threads must be between 1 and {(os.cpu_count() or 1)}")
304
320
  if args.mode == "em" and args.resolution <= 0:
305
321
  _PARSER.error("--resolution must be greater than 0")
306
- if args.mode == "em" and len(args.map) > 2:
307
- _PARSER.error("--map only takes two half-maps or a single map")
308
- if args.mode == "em" and len(args.map) == 2 and args.blur != 0.0:
309
- _PARSER.error("--blur can only be used with a single map and not two half-maps")
310
322
 
311
323
 
312
324
  def _check_paths(args: argparse.Namespace):
313
- for arg in ("contents", "data", "map", "mask", "model", "restraints"):
325
+ for arg in (
326
+ "build_map",
327
+ "contents",
328
+ "data",
329
+ "half_maps",
330
+ "mask",
331
+ "model",
332
+ "restraints",
333
+ "single_map",
334
+ ):
314
335
  if hasattr(args, arg):
315
336
  attr = getattr(args, arg)
316
- if isinstance(attr, str):
337
+ if isinstance(attr, str) and attr != "auto":
317
338
  if not os.path.exists(attr):
318
- _PARSER.error("File not found: %s" % attr)
339
+ _PARSER.error(f"File not found: {attr}")
319
340
  attr = os.path.abspath(attr)
320
341
  setattr(args, arg, attr)
321
342
  if isinstance(attr, list):
322
343
  for i, path in enumerate(attr):
323
344
  if not os.path.exists(path):
324
- _PARSER.error("File not found: %s" % path)
345
+ _PARSER.error(f"File not found: {path}")
325
346
  attr[i] = os.path.abspath(path)
326
347
 
327
348
 
@@ -49,12 +49,12 @@ class ServalcatNemap(Job):
49
49
  @dataclasses.dataclass
50
50
  class ServalcatTrimResult:
51
51
  mask: gemmi.Ccp4Map
52
- maps: list
52
+ maps: dict
53
53
  seconds: float
54
54
 
55
55
 
56
56
  class ServalcatTrim(Job):
57
- def __init__(self, mask: gemmi.Ccp4Map, maps: list):
57
+ def __init__(self, mask: gemmi.Ccp4Map, maps: dict):
58
58
  super().__init__("servalcat")
59
59
  self.mask = mask
60
60
  self.maps = maps
@@ -64,21 +64,20 @@ class ServalcatTrim(Job):
64
64
  self.mask.write_ccp4_map(self._path("mask.ccp4"))
65
65
  self._args += ["--mask", "mask.ccp4"]
66
66
  self._args.append("--maps")
67
- for i, map_ in enumerate(self.maps):
68
- map_.write_ccp4_map(self._path(f"map{i}.ccp4"))
69
- self._args.append(f"map{i}.ccp4")
67
+ for name, ccp4_map in self.maps.items():
68
+ ccp4_map.write_ccp4_map(self._path(f"{name}.ccp4"))
69
+ self._args.append(f"{name}.ccp4")
70
70
  self._args.append("--noncubic")
71
71
  self._args.append("--noncentered")
72
72
  self._args.append("--no_shift")
73
73
 
74
74
  def _result(self) -> ServalcatTrimResult:
75
- self._check_files_exist("mask_trimmed.mrc", "map0_trimmed.mrc")
75
+ self._check_files_exist("mask_trimmed.mrc")
76
76
  return ServalcatTrimResult(
77
77
  mask=read_map(self._path("mask_trimmed.mrc")),
78
- maps=[
79
- read_map(self._path(f"map{i}_trimmed.mrc"))
80
- for i in range(len(self.maps))
81
- ],
78
+ maps={
79
+ name: read_map(self._path(f"{name}_trimmed.mrc")) for name in self.maps
80
+ },
82
81
  seconds=self._seconds,
83
82
  )
84
83
 
@@ -25,12 +25,17 @@ class ModelCraftEm(Pipeline):
25
25
  self.report["version"] = __version__
26
26
  self.report["args"] = raw_args
27
27
  self.report["cycles"] = []
28
+ self.maps = {}
29
+ self.fmean = None
30
+ self.phases = None
28
31
 
29
32
  def run(self):
30
33
  print(f"# ModelCraft {__version__}", flush=True)
31
34
  os.makedirs(self.args.directory, exist_ok=self.args.overwrite_directory)
32
35
  self.start_time = time.time()
33
- self._process_input_maps()
36
+ self._read_input_maps()
37
+ self._trim_input_maps()
38
+ self._calculate_fmean_and_phases()
34
39
  structure = self.args.model
35
40
  best_fsc = None
36
41
  cycles_without_improvement = 0
@@ -58,36 +63,52 @@ class ModelCraftEm(Pipeline):
58
63
  break
59
64
  self.terminate("Normal")
60
65
 
61
- def _process_input_maps(self):
62
- maps = [read_map(path) for path in self.args.map]
63
- if self.args.mask is not None:
64
- mask = read_map(self.args.mask)
66
+ def _read_input_maps(self):
67
+ if self.args.half_maps:
68
+ self.maps["half_map1"] = read_map(self.args.half_maps[0])
69
+ self.maps["half_map2"] = read_map(self.args.half_maps[1])
65
70
  else:
66
- mask = EmdaMapMask(maps[0]).run(self).mask
67
- trimmed = ServalcatTrim(mask, maps).run(self)
68
- self.args.map = trimmed.maps
69
- if len(maps) == 2:
71
+ self.maps["single_map"] = read_map(self.args.single_map)
72
+ if self.args.build_map:
73
+ self.maps["build_map"] = read_map(self.args.build_map)
74
+
75
+ def _trim_input_maps(self):
76
+ if self.args.mask:
77
+ if self.args.mask == "auto":
78
+ map_for_mask = self.maps.get("half_map1", self.maps.get("single_map"))
79
+ mask = EmdaMapMask(map_for_mask).run(self).mask
80
+ else:
81
+ mask = read_map(self.args.mask)
82
+ trimmed = ServalcatTrim(mask, self.maps).run(self)
83
+ self.maps.update(trimmed.maps)
84
+
85
+ def _calculate_fmean_and_phases(self):
86
+ if self.args.build_map:
87
+ refmac = RefmacMapToMtz(
88
+ density=self.maps["build_map"],
89
+ resolution=self.args.resolution,
90
+ ).run(self)
91
+ fphi = refmac.fphi
92
+ elif self.args.half_maps:
70
93
  nemap = ServalcatNemap(
71
- halfmap1=trimmed.maps[0],
72
- halfmap2=trimmed.maps[1],
94
+ halfmap1=self.maps["half_map1"],
95
+ halfmap2=self.maps["half_map2"],
73
96
  resolution=self.args.resolution,
74
- mask=trimmed.mask,
75
97
  ).run(self)
76
- self.args.fphi = nemap.fphi
98
+ fphi = nemap.fphi
77
99
  else:
78
100
  refmac = RefmacMapToMtz(
79
- density=trimmed.maps[0],
101
+ density=self.maps["single_map"],
80
102
  resolution=self.args.resolution,
81
- blur=self.args.blur,
82
103
  ).run(self)
83
- self.args.fphi = refmac.fphi
84
- self.args.fmean, self.args.phases = convert_to_fsigf_and_phifom(self.args.fphi)
104
+ fphi = refmac.fphi
105
+ self.fmean, self.phases = convert_to_fsigf_and_phifom(fphi)
85
106
 
86
107
  def buccaneer(self, structure: gemmi.Structure) -> gemmi.Structure:
87
108
  result = Buccaneer(
88
109
  contents=self.args.contents,
89
- fsigf=self.args.fmean,
90
- phases=self.args.phases,
110
+ fsigf=self.fmean,
111
+ phases=self.phases,
91
112
  input_structure=structure,
92
113
  mr_structure=self.args.model,
93
114
  cycles=5,
@@ -99,8 +120,8 @@ class ModelCraftEm(Pipeline):
99
120
  def nautilus(self, structure: gemmi.Structure) -> gemmi.Structure:
100
121
  result = Nautilus(
101
122
  contents=self.args.contents,
102
- fsigf=self.args.fmean,
103
- phases=self.args.phases,
123
+ fsigf=self.fmean,
124
+ phases=self.phases,
104
125
  structure=structure,
105
126
  ).run(self)
106
127
  return result.structure
@@ -111,9 +132,9 @@ class ModelCraftEm(Pipeline):
111
132
  result = ServalcatRefine(
112
133
  structure=structure,
113
134
  resolution=self.args.resolution,
114
- halfmap1=self.args.map[0] if len(self.args.map) == 2 else None,
115
- halfmap2=self.args.map[1] if len(self.args.map) == 2 else None,
116
- density=self.args.map[0] if len(self.args.map) == 1 else None,
135
+ halfmap1=self.maps.get("half_map1"),
136
+ halfmap2=self.maps.get("half_map2"),
137
+ density=self.maps.get("single_map"),
117
138
  ligand=self.args.restraints,
118
139
  ).run(self)
119
140
  return result.structure
@@ -122,8 +143,8 @@ class ModelCraftEm(Pipeline):
122
143
  result = ServalcatFsc(
123
144
  structure=structure,
124
145
  resolution=self.args.resolution,
125
- halfmap1=self.args.map[0] if len(self.args.map) == 2 else None,
126
- halfmap2=self.args.map[1] if len(self.args.map) == 2 else None,
127
- density=self.args.map[0] if len(self.args.map) == 1 else None,
146
+ halfmap1=self.maps.get("half_map1"),
147
+ halfmap2=self.maps.get("half_map2"),
148
+ density=self.maps.get("single_map"),
128
149
  ).run(self)
129
150
  return result.fsc
@@ -14,17 +14,18 @@ from . import (
14
14
 
15
15
 
16
16
  @in_temp_directory
17
- def test_3488_model():
17
+ def test_3488_single_map():
18
18
  args = ["em"]
19
19
  args += ["--contents", sequence_path()]
20
- args += ["--map", density_path()]
20
+ args += ["--single-map", density_path()]
21
21
  args += ["--resolution", "3.2"]
22
- args += ["--blur", "10"]
23
22
  args += ["--cycles", "1"]
24
23
  args += ["--model", structure_path()]
24
+ args += ["--mask", "auto"]
25
25
  with pytest.raises(SystemExit):
26
26
  main(args)
27
- with open(os.path.join("modelcraft", "modelcraft.json")) as report_file:
27
+ report_path = os.path.join("modelcraft", "modelcraft.json")
28
+ with open(report_path, encoding="utf-8") as report_file:
28
29
  report = json.load(report_file)
29
30
  assert report["seconds"]["total"] > 0
30
31
  assert report["final"]["fsc"] > 0.6
@@ -32,16 +33,18 @@ def test_3488_model():
32
33
 
33
34
 
34
35
  @in_temp_directory
35
- def test_3488_halfmaps():
36
+ def test_3488_half_maps():
36
37
  args = ["em"]
37
38
  args += ["--contents", sequence_path()]
38
- args += ["--map", halfmap1_path(), halfmap2_path()]
39
+ args += ["--half-maps", halfmap1_path(), halfmap2_path()]
40
+ args += ["--build-map", density_path()]
39
41
  args += ["--mask", mask_path()]
40
42
  args += ["--resolution", "3.2"]
41
43
  args += ["--cycles", "1"]
42
44
  with pytest.raises(SystemExit):
43
45
  main(args)
44
- with open(os.path.join("modelcraft", "modelcraft.json")) as report_file:
46
+ report_path = os.path.join("modelcraft", "modelcraft.json")
47
+ with open(report_path, encoding="utf-8") as report_file:
45
48
  report = json.load(report_file)
46
49
  assert report["seconds"]["total"] > 0
47
50
  assert report["termination_reason"] == "Normal"
@@ -17,11 +17,13 @@ def test_servalcat_nemap():
17
17
 
18
18
 
19
19
  def test_servalcat_trim():
20
- halfmap1 = read_map(halfmap1_path())
21
- halfmap2 = read_map(halfmap2_path())
22
- density = read_map(density_path())
20
+ maps = {
21
+ "halfmap1": read_map(halfmap1_path()),
22
+ "halfmap2": read_map(halfmap2_path()),
23
+ "density": read_map(density_path()),
24
+ }
23
25
  mask = read_map(mask_path())
24
- trimmed = ServalcatTrim(mask, [density, halfmap1, halfmap2]).run()
26
+ trimmed = ServalcatTrim(mask, maps).run()
25
27
  assert len(trimmed.maps) == 3
26
28
 
27
29
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modelcraft
3
- Version: 4.0.2
3
+ Version: 5.0.0
4
4
  Summary: Automated model building pipeline for X-ray crystallography
5
5
  Home-page: https://github.com/paulsbond/modelcraft
6
6
  Author: Paul Bond
@@ -5,7 +5,7 @@ with open("README.md", "r") as f:
5
5
 
6
6
  setuptools.setup(
7
7
  name="modelcraft",
8
- version="4.0.2",
8
+ version="5.0.0",
9
9
  author="Paul Bond",
10
10
  author_email="paul.bond@york.ac.uk",
11
11
  description="Automated model building pipeline for X-ray crystallography",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes