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,423 @@
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 sys
14
+ import tempfile
15
+ import subprocess
16
+ import argparse
17
+ from collections import OrderedDict
18
+ import servalcat # for version
19
+ from servalcat.utils import logger
20
+ from servalcat.refmac import refmac_keywords
21
+ from servalcat import utils
22
+
23
+ def add_arguments(parser):
24
+ parser.description = 'Run REFMAC5 with gemmi-prepared restraints'
25
+ parser.add_argument('--exe', default="refmac5", help='refmac5 binary')
26
+ parser.add_argument("--monlib",
27
+ help="Monomer library path. Default: $CLIBD_MON")
28
+ parser.add_argument('--ligand', nargs="*", action="append")
29
+ parser.add_argument("opts", nargs="+",
30
+ help="HKLIN hklin XYZIN xyzin...")
31
+ parser.add_argument('--auto_box_with_padding', type=float, help="Determine box size from model with specified padding")
32
+ parser.add_argument('--no_adjust_hydrogen_distances', action='store_true', help="By default it adjusts hydrogen distances using ideal values. This option is to disable it.")
33
+ parser.add_argument('--keep_original_output', action='store_true', help="with .org extension")
34
+ parser.add_argument("--keep_entities", action='store_true',
35
+ help="Do not override entities")
36
+ parser.add_argument("--tls_addu", action='store_true',
37
+ help="Write prefix_addu.mmcif where TLS contribution is added to aniso U. Don't use this with 'tlso addu' keyword.")
38
+ parser.add_argument('--prefix', help="output prefix")
39
+ parser.add_argument("-v", "--version", action="version",
40
+ version=logger.versions_str())
41
+ # TODO --cell to override unit cell?
42
+
43
+ # add_arguments()
44
+
45
+ def parse_args(arg_list):
46
+ parser = argparse.ArgumentParser()
47
+ add_arguments(parser)
48
+ return parser.parse_args(arg_list)
49
+ # parse_args()
50
+
51
+ def read_stdin(stdin):
52
+ print("Waiting for input..")
53
+ # these make keywords will be ignored (just passed to refmac): ribo,valu,spec,form,sdmi,segi
54
+ ret = {"make":{}, "ridge":{}, "refi":{}}
55
+ inputs = []
56
+ for l in refmac_keywords.get_lines(stdin):
57
+ refmac_keywords.parse_line(l, ret, raise_unknown=False)
58
+ inputs.append(l + "\n")
59
+
60
+ def sorry(s): raise SystemExit("Sorry, '{}' is not supported".format(s))
61
+ if ret["make"].get("hydr") == "f":
62
+ sorry("make hydr full")
63
+ if ret["make"].get("buil") == "y":
64
+ sorry("make build yes")
65
+ return inputs, ret
66
+ # read_stdin()
67
+
68
+ def prepare_crd(st, crdout, ligand, make, monlib_path=None, h_pos="elec",
69
+ no_adjust_hydrogen_distances=False, fix_long_resnames=True,
70
+ keep_entities=False, unre=False):
71
+ assert h_pos in ("elec", "nucl")
72
+ h_change = dict(a=gemmi.HydrogenChange.ReAddButWater,
73
+ y=gemmi.HydrogenChange.NoChange,
74
+ n=gemmi.HydrogenChange.Remove)[make.get("hydr", "a")]
75
+ utils.model.fix_deuterium_residues(st)
76
+ for chain in st[0]:
77
+ if not chain.name:
78
+ chain.name = "X" # Refmac behavior. Empty chain name will cause a problem
79
+ for res in chain:
80
+ if res.is_water():
81
+ res.name = "HOH"
82
+ for at in res:
83
+ if at.occ > 1: # XXX should I check special positions?
84
+ at.occ = 1.
85
+
86
+ refmac_fixes = utils.refmac.FixForRefmac()
87
+ if keep_entities:
88
+ refmac_fixes.store_res_labels(st)
89
+ else:
90
+ utils.model.setup_entities(st, clear=True, force_subchain_names=True, overwrite_entity_type=True)
91
+
92
+ if unre:
93
+ logger.writeln("Monomer library will not be loaded due to unrestrained refinement request")
94
+ monlib = gemmi.MonLib()
95
+ else:
96
+ # TODO read dictionary from xyzin (priority: user cif -> monlib -> xyzin
97
+ try:
98
+ monlib = utils.restraints.load_monomer_library(st,
99
+ monomer_dir=monlib_path,
100
+ cif_files=ligand,
101
+ stop_for_unknowns=not make.get("newligand"))
102
+ except RuntimeError as e:
103
+ raise SystemExit("Error: {}".format(e))
104
+
105
+ use_cispeps = make.get("cispept", "y") != "y"
106
+ make_link = make.get("link", "n")
107
+ make_ss = make.get("ss", "y")
108
+ only_from = set()
109
+ if make_link == "y":
110
+ # add all links
111
+ add_found = True
112
+ elif make_ss == "y":
113
+ add_found = True
114
+ only_from.add("disulf")
115
+ else:
116
+ add_found = False
117
+
118
+ utils.restraints.fix_elements_in_model(monlib, st)
119
+ utils.restraints.find_and_fix_links(st, monlib, add_found=add_found,
120
+ find_metal_links=(make_link == "y"),
121
+ find_symmetry_related=False, add_only_from=only_from)
122
+ for con in st.connections:
123
+ if con.link_id not in ("?", "", "gap") and con.link_id not in monlib.links:
124
+ logger.writeln(" removing unknown link id ({}). Ad-hoc link will be generated.".format(con.link_id))
125
+ con.link_id = ""
126
+
127
+ max_seq_num = max([max(res.seqid.num for res in chain) for model in st for chain in model])
128
+ if max_seq_num > 9999:
129
+ logger.writeln("Max residue number ({}) exceeds 9999. Needs workaround.".format(max_seq_num))
130
+ topo = gemmi.prepare_topology(st, monlib, warnings=logger.silent(), ignore_unknown_links=True)
131
+ refmac_fixes.fix_before_topology(st, topo,
132
+ fix_microheterogeneity=False,
133
+ fix_resimax=True,
134
+ fix_nonpolymer=False)
135
+
136
+ if unre:
137
+ # Refmac5 does not seem to do anything to hydrogen when unre regardless of "make hydr"
138
+ topo = gemmi.prepare_topology(st, monlib, warnings=logger.silent(), ignore_unknown_links=True)
139
+ metal_kws = []
140
+ else:
141
+ if make.get("hydr") == "a": logger.writeln("(re)generating hydrogen atoms")
142
+ try:
143
+ topo, metal_kws = utils.restraints.prepare_topology(st, monlib, h_change=h_change, ignore_unknown_links=False,
144
+ check_hydrogen=(h_change==gemmi.HydrogenChange.NoChange),
145
+ use_cispeps=use_cispeps)
146
+ except RuntimeError as e:
147
+ raise SystemExit("Error: {}".format(e))
148
+
149
+ if make.get("hydr") != "n" and st[0].has_hydrogen():
150
+ if h_pos == "nucl" and (make.get("hydr") == "a" or not no_adjust_hydrogen_distances):
151
+ resnames = st[0].get_all_residue_names()
152
+ utils.restraints.check_monlib_support_nucleus_distances(monlib, resnames)
153
+ logger.writeln("adjusting hydrogen position to nucleus")
154
+ topo.adjust_hydrogen_distances(gemmi.Restraints.DistanceOf.Nucleus, default_scale=1.1)
155
+ elif h_pos == "elec" and make.get("hydr") == "y" and not no_adjust_hydrogen_distances:
156
+ logger.writeln("adjusting hydrogen position to electron cloud")
157
+ topo.adjust_hydrogen_distances(gemmi.Restraints.DistanceOf.ElectronCloud)
158
+
159
+ if fix_long_resnames: refmac_fixes.fix_long_resnames(st)
160
+
161
+ # remove "given" ncs matrices
162
+ # TODO write them back to the output files
163
+ st.ncs = gemmi.NcsOpList(x for x in st.ncs if not x.given)
164
+
165
+ # for safety
166
+ if "_entry.id" in st.info:
167
+ st.info["_entry.id"] = st.info["_entry.id"].replace(" ", "")
168
+ date_key = "_pdbx_database_status.recvd_initial_deposition_date"
169
+ if date_key in st.info:
170
+ tmp = st.info[date_key]
171
+ if len(tmp) > 5 and tmp[4] == "-":
172
+ if len(tmp) > 8 and tmp[8] != "" and not tmp[5:7].isdigit():
173
+ tmp = "XX"
174
+ elif len(tmp) > 6 and tmp[5] == "-":
175
+ if not tmp[3:5].isdigit():
176
+ tmp = "XX"
177
+ st.info[date_key] = tmp
178
+ # internal chain ID
179
+ for chain in st[0]:
180
+ for res in chain:
181
+ if len(chain.name) < 3:
182
+ # Change Axp (or AAxp) to A_p (or AA_p)
183
+ res.subchain = chain.name + "_" + res.subchain[len(chain.name)+1:]
184
+ else:
185
+ # Refmac only expects '_' at 2nd or 3rd position, and can accept up to 4 letters.
186
+ # Using raw chain ID may change alignment result for local NCS restraints,
187
+ # but to avoid this we would need chain ID translation, which is too complicated.
188
+ # This also invalidates _struct_asym, which Refmac does not seem to care
189
+ res.subchain = chain.name
190
+ # change st.name if needed
191
+ block_names = utils.restraints.dictionary_block_names(monlib, topo)
192
+ for i in range(1000):
193
+ if st.name.lower() in block_names:
194
+ st.name = st.name + str(i)
195
+ doc = gemmi.prepare_refmac_crd(st, topo, monlib, h_change)
196
+ doc.write_file(crdout, options=gemmi.cif.Style.NoBlankLines)
197
+ logger.writeln("crd file written: {}".format(crdout))
198
+ return refmac_fixes, [x+"\n" for x in metal_kws]
199
+ # prepare_crd()
200
+
201
+ def get_output_model_names(xyzout):
202
+ # ref: WRITE_ATOMS_REFMAC in oppro_allocate.f
203
+ if xyzout is None: xyzout = "XYZOUT"
204
+ pdb, mmcif = "", ""
205
+ if len(xyzout) > 3:
206
+ if xyzout.lower().endswith("pdb"):
207
+ mmcif = xyzout[:-4] + ".mmcif"
208
+ pdb = xyzout
209
+ else:
210
+ if xyzout.lower().endswith("cif") and len(xyzout) > 5:
211
+ if xyzout.lower().endswith("mmcif"):
212
+ mmcif = xyzout
213
+ pdb = xyzout[:-6] + ".pdb"
214
+ else:
215
+ mmcif = xyzout
216
+ pdb = xyzout[:-4] + ".pdb"
217
+ else:
218
+ mmcif = xyzout + ".mmcif"
219
+ pdb = xyzout
220
+ else:
221
+ mmcif = xyzout + ".mmcif"
222
+ pdb = xyzout
223
+
224
+ return pdb, mmcif
225
+ # get_output_model_names()
226
+
227
+ def modify_output(pdbout, cifout, fixes, hout, cispeps, software_items, modres, keep_original_output=False, tls_addu=False):
228
+ st = utils.fileio.read_structure(cifout)
229
+ st.cispeps = cispeps
230
+ if os.path.exists(pdbout):
231
+ st_pdb = gemmi.read_pdb(pdbout)
232
+ st.raw_remarks = st_pdb.raw_remarks
233
+ # Refmac only writes NCS matrices to pdb
234
+ st.ncs = st_pdb.ncs
235
+ if "_struct_ncs_oper.id" in st_pdb.info: # to write identity operator
236
+ st.info["_struct_ncs_oper.id"] = st_pdb.info["_struct_ncs_oper.id"]
237
+ if fixes is not None:
238
+ fixes.modify_back(st)
239
+ for con in st.connections:
240
+ if con.link_id == "disulf":
241
+ con.type = gemmi.ConnectionType.Disulf
242
+ # should we check metals and put MetalC?
243
+
244
+ # fix entity (Refmac seems to make DNA non-polymer; as seen in 1fix)
245
+ if not fixes or not fixes.res_labels:
246
+ utils.model.setup_entities(st, clear=True, overwrite_entity_type=True, force_subchain_names=True,
247
+ fix_sequences=True)
248
+
249
+ # assuming refmac won't write MODRES
250
+ st.mod_residues = modres
251
+
252
+ # add servalcat version
253
+ if len(st.meta.software) > 0 and st.meta.software[-1].name == "refmac":
254
+ st.meta.software[-1].version += f" (refmacat {servalcat.__version__})"
255
+ st.meta.software = software_items + st.meta.software
256
+
257
+ suffix = ".org"
258
+ os.rename(cifout, cifout + suffix)
259
+ utils.fileio.write_mmcif(st, cifout, cifout + suffix)
260
+
261
+ if tls_addu:
262
+ doc_ref = gemmi.cif.read(cifout + suffix)
263
+ tls_groups = {int(x.id): x for x in st.meta.refinement[0].tls_groups}
264
+ tls_details = doc_ref[0].find_value("_ccp4_refine_tls.details")
265
+ if tls_groups and gemmi.cif.as_string(tls_details) == "U values: residual only":
266
+ st2 = st.clone()
267
+ for cra in st2[0].all():
268
+ tlsgr = tls_groups.get(cra.atom.tls_group_id)
269
+ if cra.atom.tls_group_id > 0 and tlsgr is not None:
270
+ if not cra.atom.aniso.nonzero():
271
+ u = cra.atom.b_iso * utils.model.b_to_u
272
+ cra.atom.aniso = gemmi.SMat33f(u, u, u, 0, 0, 0)
273
+ u_from_tls = gemmi.calculate_u_from_tls(tlsgr, cra.atom.pos)
274
+ cra.atom.aniso += gemmi.SMat33f(*u_from_tls.elements_pdb())
275
+ cra.atom.b_iso = cra.atom.aniso.trace() / 3. * utils.model.u_to_b
276
+ cifout2 = cifout[:cifout.rindex(".")] + "_addu" + cifout[cifout.rindex("."):]
277
+ doc_ref[0].set_pair("_ccp4_refine_tls.details", gemmi.cif.quote("U values: with tls added"))
278
+ utils.fileio.write_mmcif(st2, cifout2, cif_ref_doc=doc_ref)
279
+ else:
280
+ if not tls_groups:
281
+ msg = "TLS group definition not found in the model"
282
+ else:
283
+ msg = "TLS already applied to the U values"
284
+ logger.writeln(f"Error: --tls_addu requested, but {msg}.")
285
+
286
+ if st.has_d_fraction:
287
+ st.store_deuterium_as_fraction(False) # also useful for pdb
288
+ logger.writeln("will write a H/D expanded mmcif file")
289
+ cifout2 = cifout[:cifout.rindex(".")] + "_hd_expand" + cifout[cifout.rindex("."):]
290
+ utils.fileio.write_mmcif(st, cifout2, cifout + suffix)
291
+
292
+ chain_id_len_max = max([len(x) for x in utils.model.all_chain_ids(st)])
293
+ seqnums = [res.seqid.num for chain in st[0] for res in chain]
294
+ if chain_id_len_max > 1 or min(seqnums) <= -1000 or max(seqnums) >= 10000:
295
+ logger.writeln("This structure cannot be saved as an official PDB format. Using hybrid-36. Header part may be inaccurate.")
296
+ if not hout:
297
+ st.remove_hydrogens() # remove hydrogen from pdb, while kept in mmcif
298
+ os.rename(pdbout, pdbout + suffix)
299
+ utils.fileio.write_pdb(st, pdbout)
300
+ if not keep_original_output:
301
+ os.remove(pdbout + suffix)
302
+ os.remove(cifout + suffix)
303
+ # modify_output()
304
+
305
+ def main(args):
306
+ if len(args.opts) % 2 != 0: raise SystemExit("Invalid number of args")
307
+ args.ligand = sum(args.ligand, []) if args.ligand else []
308
+
309
+ inputs, keywords = read_stdin(sys.stdin) # TODO read psrestin also?
310
+ if not keywords["make"].get("exit"):
311
+ refmac_ver = utils.refmac.check_version(args.exe)
312
+ if not refmac_ver:
313
+ raise SystemExit("Error: Check Refmac installation or use --exe to give the location.")
314
+ if refmac_ver < (5, 8, 404):
315
+ raise SystemExit("Error: this version of Refmac is not supported. Update to 5.8.404 or newer")
316
+
317
+ opts = OrderedDict((args.opts[2*i].lower(), args.opts[2*i+1]) for i in range(len(args.opts)//2))
318
+ xyzin = opts.get("xyzin")
319
+ xyzout = opts.get("xyzout")
320
+ libin = opts.pop("libin", None)
321
+ if libin: args.ligand.append(libin)
322
+ if not args.monlib:
323
+ # if --monlib is given, it has priority.
324
+ args.monlib = opts.pop("clibd_mon", None)
325
+ for k in ("temp1", "scrref"): # scrref has priority
326
+ if k in opts:
327
+ logger.writeln("updating CCP4_SCR from {}={}".format(k, opts[k]))
328
+ os.environ["CCP4_SCR"] = os.path.dirname(opts[k]) # XXX "." may be given, which causes problem (os.path.isdir("") is False)
329
+ utils.refmac.ensure_ccp4scr()
330
+ if args.prefix:
331
+ if "xyzin" in opts and "xyzout" not in opts: opts["xyzout"] = args.prefix + ".pdb"
332
+ if "hklin" in opts and "hklout" not in opts: opts["hklout"] = args.prefix + ".mtz"
333
+ if "tlsin" in opts and "tlsout" not in opts: opts["tlsout"] = args.prefix + ".tls"
334
+
335
+ # TODO what if restin is given or make cr prepared is given?
336
+ # TODO check make pept/link/suga/ss/conn/symm/chain
337
+
338
+ if "hklin" in opts: # for history
339
+ software_items = utils.fileio.software_items_from_mtz(opts["hklin"])
340
+ else:
341
+ software_items = []
342
+
343
+ # Process model
344
+ crdout = None
345
+ refmac_fixes = None
346
+ cispeps = []
347
+ unre = keywords["refi"].get("type") == "unre"
348
+ if xyzin is not None:
349
+ #tmpfd, crdout = tempfile.mkstemp(prefix="gemmi_", suffix=".crd") # TODO use dir=CCP4_SCR
350
+ #os.close(tmpfd)
351
+ st = utils.fileio.read_structure(xyzin)
352
+ if not st.cell.is_crystal() and not unre:
353
+ if args.auto_box_with_padding is not None:
354
+ st.cell = utils.model.box_from_model(st[0], args.auto_box_with_padding)
355
+ st.spacegroup_hm = "P 1"
356
+ logger.writeln("Box size from the model with padding of {}: {}".format(args.auto_box_with_padding, st.cell.parameters))
357
+ else:
358
+ raise SystemExit("Error: unit cell is not defined in the model.")
359
+ xyzout_dir = os.path.dirname(get_output_model_names(opts.get("xyzout"))[0])
360
+ crdout = os.path.join(xyzout_dir,
361
+ "gemmi_{}_{}.crd".format(utils.fileio.splitext(os.path.basename(xyzin))[0], os.getpid()))
362
+ refmac_fixes, metal_kws = prepare_crd(st, crdout, args.ligand, make=keywords["make"], monlib_path=args.monlib,
363
+ h_pos="nucl" if keywords.get("source")=="ne" else "elec",
364
+ no_adjust_hydrogen_distances=args.no_adjust_hydrogen_distances,
365
+ keep_entities=args.keep_entities,
366
+ unre=unre)
367
+ inputs = metal_kws + inputs # add metal exte first; otherwise it may be affected by user-defined inputs
368
+ opts["xyzin"] = crdout
369
+ cispeps = st.cispeps
370
+
371
+ if keywords["make"].get("exit"):
372
+ return
373
+
374
+ # Run Refmac
375
+ cmd = [args.exe] + list(sum(tuple(opts.items()), ()))
376
+ env = os.environ
377
+ logger.writeln("Running REFMAC5..")
378
+ if args.monlib:
379
+ logger.writeln("CLIBD_MON={}".format(args.monlib))
380
+ env["CLIBD_MON"] = os.path.join(args.monlib, "") # should end with /
381
+ logger.writeln(" ".join(cmd))
382
+ p = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE,
383
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
384
+ universal_newlines=True, env=env)
385
+ if crdout: p.stdin.write("make cr prepared\n")
386
+ p.stdin.write("".join(inputs))
387
+ p.stdin.close()
388
+ # prepare conversion for long residue names
389
+ resn_conv = {}
390
+ if refmac_fixes:
391
+ for old, new in refmac_fixes.resn_old_new:
392
+ n = "{:4s}".format(old)
393
+ if len(n) > 4: n += " "
394
+ resn_conv[new] = n
395
+ # print raw output
396
+ for l in iter(p.stdout.readline, ""):
397
+ for tn in resn_conv:
398
+ l = l.replace(tn, resn_conv[tn])
399
+ logger.write(l)
400
+ retcode = p.wait()
401
+ logger.writeln("\nRefmac finished with exit code= {}".format(retcode))
402
+
403
+ if not args.keep_original_output and crdout and os.path.exists(crdout):
404
+ os.remove(crdout)
405
+
406
+ # Modify output
407
+ if xyzin is not None:
408
+ pdbout, cifout = get_output_model_names(opts.get("xyzout"))
409
+ if os.path.exists(cifout):
410
+ modify_output(pdbout, cifout, refmac_fixes, keywords["make"].get("hout"), cispeps,
411
+ software_items, st.mod_residues, args.keep_original_output, args.tls_addu)
412
+ # main()
413
+
414
+ def command_line():
415
+ import sys
416
+ args = parse_args(sys.argv[1:])
417
+ if args.prefix:
418
+ logger.set_file(args.prefix + ".log")
419
+ logger.write_header(command="refmacat")
420
+ main(args)
421
+
422
+ if __name__ == "__main__":
423
+ command_line()
File without changes