pytme 0.2.0__cp311-cp311-macosx_14_0_arm64.whl → 0.2.1__cp311-cp311-macosx_14_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.
- {pytme-0.2.0.data → pytme-0.2.1.data}/scripts/match_template.py +183 -69
- {pytme-0.2.0.data → pytme-0.2.1.data}/scripts/postprocess.py +107 -49
- {pytme-0.2.0.data → pytme-0.2.1.data}/scripts/preprocessor_gui.py +4 -1
- {pytme-0.2.0.dist-info → pytme-0.2.1.dist-info}/METADATA +1 -1
- pytme-0.2.1.dist-info/RECORD +73 -0
- scripts/extract_candidates.py +117 -85
- scripts/match_template.py +183 -69
- scripts/match_template_filters.py +193 -71
- scripts/postprocess.py +107 -49
- scripts/preprocessor_gui.py +4 -1
- scripts/refine_matches.py +364 -160
- tme/__version__.py +1 -1
- tme/analyzer.py +259 -117
- tme/backends/__init__.py +1 -0
- tme/backends/cupy_backend.py +20 -13
- tme/backends/jax_backend.py +218 -0
- tme/backends/matching_backend.py +25 -10
- tme/backends/mlx_backend.py +13 -9
- tme/backends/npfftw_backend.py +20 -8
- tme/backends/pytorch_backend.py +20 -9
- tme/density.py +79 -60
- tme/extensions.cpython-311-darwin.so +0 -0
- tme/matching_data.py +85 -61
- tme/matching_exhaustive.py +222 -129
- tme/matching_optimization.py +117 -76
- tme/orientations.py +175 -55
- tme/preprocessing/_utils.py +17 -5
- tme/preprocessing/composable_filter.py +2 -1
- tme/preprocessing/compose.py +1 -2
- tme/preprocessing/frequency_filters.py +97 -41
- tme/preprocessing/tilt_series.py +137 -87
- tme/preprocessor.py +3 -0
- tme/structure.py +4 -1
- pytme-0.2.0.dist-info/RECORD +0 -72
- {pytme-0.2.0.data → pytme-0.2.1.data}/scripts/estimate_ram_usage.py +0 -0
- {pytme-0.2.0.data → pytme-0.2.1.data}/scripts/preprocess.py +0 -0
- {pytme-0.2.0.dist-info → pytme-0.2.1.dist-info}/LICENSE +0 -0
- {pytme-0.2.0.dist-info → pytme-0.2.1.dist-info}/WHEEL +0 -0
- {pytme-0.2.0.dist-info → pytme-0.2.1.dist-info}/entry_points.txt +0 -0
- {pytme-0.2.0.dist-info → pytme-0.2.1.dist-info}/top_level.txt +0 -0
scripts/refine_matches.py
CHANGED
@@ -1,52 +1,121 @@
|
|
1
1
|
#!python3
|
2
|
-
"""
|
2
|
+
""" Iterative template matching parameter tuning.
|
3
3
|
|
4
|
-
Copyright (c)
|
4
|
+
Copyright (c) 2024 European Molecular Biology Laboratory
|
5
5
|
|
6
6
|
Author: Valentin Maurer <valentin.maurer@embl-hamburg.de>
|
7
7
|
"""
|
8
8
|
import argparse
|
9
|
-
|
9
|
+
import subprocess
|
10
|
+
from sys import exit
|
11
|
+
from shutil import copyfile
|
12
|
+
from typing import Tuple, List, Dict
|
10
13
|
|
11
14
|
import numpy as np
|
12
|
-
from
|
13
|
-
|
14
|
-
from tme
|
15
|
-
from tme import
|
16
|
-
from tme.
|
17
|
-
|
18
|
-
from tme.matching_utils import (
|
19
|
-
load_pickle,
|
20
|
-
get_rotation_matrices,
|
21
|
-
compute_parallelization_schedule,
|
22
|
-
)
|
23
|
-
from tme.matching_exhaustive import scan_subsets, MATCHING_EXHAUSTIVE_REGISTER
|
24
|
-
|
25
|
-
from postprocess import Orientations
|
26
|
-
from match_template import load_and_validate_mask
|
15
|
+
from scipy import optimize
|
16
|
+
|
17
|
+
from tme import Orientations, Density
|
18
|
+
from tme.matching_utils import generate_tempfile_name, load_pickle
|
19
|
+
from tme.matching_exhaustive import MATCHING_EXHAUSTIVE_REGISTER
|
20
|
+
|
27
21
|
|
28
22
|
def parse_args():
|
29
23
|
parser = argparse.ArgumentParser(
|
30
|
-
description="Refine
|
24
|
+
description="Refine template matching candidates using deep matching.",
|
31
25
|
)
|
32
|
-
parser.
|
33
|
-
|
26
|
+
io_group = parser.add_argument_group("Input / Output")
|
27
|
+
io_group.add_argument(
|
28
|
+
"--orientations",
|
34
29
|
required=True,
|
35
30
|
type=str,
|
36
|
-
help="Path to
|
31
|
+
help="Path to an orientations file in a supported format. See "
|
32
|
+
"https://kosinskilab.github.io/pyTME/reference/api/tme.orientations.Orientations.from_file.html"
|
33
|
+
" for available options."
|
37
34
|
)
|
38
|
-
|
39
|
-
"--
|
35
|
+
io_group.add_argument(
|
36
|
+
"--output_prefix",
|
40
37
|
required=True,
|
41
38
|
type=str,
|
42
|
-
help="Path to
|
39
|
+
help="Path to write output to."
|
40
|
+
)
|
41
|
+
io_group.add_argument(
|
42
|
+
"--iterations",
|
43
|
+
required=False,
|
44
|
+
default=0,
|
45
|
+
type=int,
|
46
|
+
help="Number of refinement iterations to perform.",
|
47
|
+
)
|
48
|
+
io_group.add_argument(
|
49
|
+
"--verbose",
|
50
|
+
action="store_true",
|
51
|
+
default=False,
|
52
|
+
help="More verbose and more files written to disk.",
|
53
|
+
)
|
54
|
+
matching_group = parser.add_argument_group("Template Matching")
|
55
|
+
matching_group.add_argument(
|
56
|
+
"--input_file",
|
57
|
+
required=False,
|
58
|
+
type=str,
|
59
|
+
help="Path to the output of match_template.py.",
|
60
|
+
)
|
61
|
+
matching_group.add_argument(
|
62
|
+
"-m",
|
63
|
+
"--target",
|
64
|
+
dest="target",
|
65
|
+
type=str,
|
66
|
+
required=False,
|
67
|
+
help="Path to a target in CCP4/MRC, EM, H5 or another format supported by "
|
68
|
+
"tme.density.Density.from_file "
|
69
|
+
"https://kosinskilab.github.io/pyTME/reference/api/tme.density.Density.from_file.html",
|
43
70
|
)
|
44
|
-
|
45
|
-
"--
|
71
|
+
matching_group.add_argument(
|
72
|
+
"--target_mask",
|
73
|
+
dest="target_mask",
|
74
|
+
type=str,
|
75
|
+
required=False,
|
76
|
+
help="Path to a mask for the target in a supported format (see target).",
|
77
|
+
)
|
78
|
+
matching_group.add_argument(
|
79
|
+
"-i",
|
80
|
+
"--template",
|
81
|
+
dest="template",
|
82
|
+
type=str,
|
83
|
+
required=False,
|
84
|
+
help="Path to a template in PDB/MMCIF or other supported formats (see target).",
|
85
|
+
)
|
86
|
+
matching_group.add_argument(
|
87
|
+
"--template_mask",
|
88
|
+
dest="template_mask",
|
89
|
+
type=str,
|
90
|
+
required=False,
|
91
|
+
help="Path to a mask for the template in a supported format (see target).",
|
92
|
+
)
|
93
|
+
matching_group.add_argument(
|
94
|
+
"--invert_target_contrast",
|
95
|
+
dest="invert_target_contrast",
|
96
|
+
action="store_true",
|
97
|
+
default=False,
|
98
|
+
help="Invert the target's contrast and rescale linearly between zero and one. "
|
99
|
+
"This option is intended for targets where templates to-be-matched have "
|
100
|
+
"negative values, e.g. tomograms.",
|
101
|
+
)
|
102
|
+
matching_group.add_argument(
|
103
|
+
"--angular_sampling",
|
104
|
+
dest="angular_sampling",
|
46
105
|
required=True,
|
47
|
-
|
106
|
+
default=None,
|
107
|
+
help="Angular sampling rate using optimized rotational sets."
|
108
|
+
"A lower number yields more rotations. Values >= 180 sample only the identity.",
|
109
|
+
)
|
110
|
+
matching_group.add_argument(
|
111
|
+
"-s",
|
112
|
+
dest="score",
|
113
|
+
type=str,
|
114
|
+
default="FLCSphericalMask",
|
115
|
+
choices=list(MATCHING_EXHAUSTIVE_REGISTER.keys()),
|
116
|
+
help="Template matching scoring function.",
|
48
117
|
)
|
49
|
-
|
118
|
+
matching_group.add_argument(
|
50
119
|
"-n",
|
51
120
|
dest="cores",
|
52
121
|
required=False,
|
@@ -54,165 +123,300 @@ def parse_args():
|
|
54
123
|
default=4,
|
55
124
|
help="Number of cores used for template matching.",
|
56
125
|
)
|
126
|
+
matching_group.add_argument(
|
127
|
+
"--use_gpu",
|
128
|
+
dest="use_gpu",
|
129
|
+
action="store_true",
|
130
|
+
default=False,
|
131
|
+
help="Whether to perform computations on the GPU.",
|
132
|
+
)
|
133
|
+
matching_group.add_argument(
|
134
|
+
"--no_centering",
|
135
|
+
dest="no_centering",
|
136
|
+
action="store_true",
|
137
|
+
help="Assumes the template is already centered and omits centering.",
|
138
|
+
)
|
139
|
+
matching_group.add_argument(
|
140
|
+
"--no_edge_padding",
|
141
|
+
dest="no_edge_padding",
|
142
|
+
action="store_true",
|
143
|
+
default=False,
|
144
|
+
help="Whether to not pad the edges of the target. Can be set if the target"
|
145
|
+
" has a well defined bounding box, e.g. a masked reconstruction.",
|
146
|
+
)
|
147
|
+
matching_group.add_argument(
|
148
|
+
"--no_fourier_padding",
|
149
|
+
dest="no_fourier_padding",
|
150
|
+
action="store_true",
|
151
|
+
default=False,
|
152
|
+
help="Whether input arrays should not be zero-padded to full convolution shape "
|
153
|
+
"for numerical stability. When working with very large targets, e.g. tomograms, "
|
154
|
+
"it is safe to use this flag and benefit from the performance gain.",
|
155
|
+
)
|
156
|
+
|
157
|
+
peak_group = parser.add_argument_group("Peak Calling")
|
158
|
+
peak_group.add_argument(
|
159
|
+
"--number_of_peaks",
|
160
|
+
type=int,
|
161
|
+
default=100,
|
162
|
+
required=False,
|
163
|
+
help="Upper limit of peaks to call, subject to filtering parameters. Default 1000. "
|
164
|
+
"If minimum_score is provided all peaks scoring higher will be reported.",
|
165
|
+
)
|
166
|
+
extraction_group = parser.add_argument_group("Extraction")
|
167
|
+
extraction_group.add_argument(
|
168
|
+
"--keep_out_of_box",
|
169
|
+
action="store_true",
|
170
|
+
required=False,
|
171
|
+
help="Whether to keep orientations that fall outside the box. If the "
|
172
|
+
"orientations are sensible, it is safe to pass this flag.",
|
173
|
+
)
|
174
|
+
|
175
|
+
optimization_group = parser.add_argument_group("Optimization")
|
176
|
+
optimization_group.add_argument(
|
177
|
+
"--lowpass",
|
178
|
+
dest="lowpass",
|
179
|
+
action="store_true",
|
180
|
+
default=False,
|
181
|
+
help="Optimize template matching lowpass filter cutoff.",
|
182
|
+
)
|
183
|
+
optimization_group.add_argument(
|
184
|
+
"--highpass",
|
185
|
+
dest="highpass",
|
186
|
+
action="store_true",
|
187
|
+
default=False,
|
188
|
+
help="Optimize template matching highpass filter cutoff.",
|
189
|
+
)
|
57
190
|
|
58
191
|
args = parser.parse_args()
|
59
192
|
|
193
|
+
data_present = args.target is not None and args.template is not None
|
194
|
+
if args.input_file is None and not data_present:
|
195
|
+
raise ValueError(
|
196
|
+
"Either --input_file or --target and --template need to be specified."
|
197
|
+
)
|
198
|
+
elif args.input_file is not None and data_present:
|
199
|
+
raise ValueError(
|
200
|
+
"Please specific either --input_file or --target and --template."
|
201
|
+
)
|
202
|
+
|
60
203
|
return args
|
61
204
|
|
62
205
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
206
|
+
def argdict_to_command(input_args: Dict, executable: str) -> List:
|
207
|
+
ret = []
|
208
|
+
for key, value in input_args.items():
|
209
|
+
if value is None:
|
210
|
+
continue
|
211
|
+
elif isinstance(value, bool):
|
212
|
+
if value:
|
213
|
+
ret.append(key)
|
214
|
+
else:
|
215
|
+
ret.extend([key, value])
|
216
|
+
|
217
|
+
ret = [str(x) for x in ret]
|
218
|
+
ret.insert(0, executable)
|
219
|
+
return " ".join(ret)
|
220
|
+
|
221
|
+
|
222
|
+
def create_stacking_argdict(args) -> Dict:
|
223
|
+
arg_dict = {
|
224
|
+
"--input_file": args.input_file,
|
225
|
+
"--orientations": args.orientations,
|
226
|
+
"--output_file": args.candidate_stack_path,
|
227
|
+
"--keep_out_of_box": args.keep_out_of_box,
|
228
|
+
}
|
229
|
+
return arg_dict
|
230
|
+
|
231
|
+
|
232
|
+
def create_matching_argdict(args) -> Dict:
|
233
|
+
arg_dict = {
|
234
|
+
"--target": args.target,
|
235
|
+
"--template": args.template,
|
236
|
+
"--template_mask": args.template_mask,
|
237
|
+
"--target_mask": args.target_mask,
|
238
|
+
"-o": args.match_template_path,
|
239
|
+
"-a": args.angular_sampling,
|
240
|
+
"-s": args.score,
|
241
|
+
"--no_fourier_padding": True,
|
242
|
+
"--no_edge_padding": True,
|
243
|
+
"--no_centering": args.no_centering,
|
244
|
+
"-n": args.cores,
|
245
|
+
"--invert_target_contrast": args.invert_target_contrast,
|
246
|
+
"--use_gpu": args.use_gpu,
|
247
|
+
}
|
248
|
+
return arg_dict
|
249
|
+
|
250
|
+
|
251
|
+
def create_postprocessing_argdict(args) -> Dict:
|
252
|
+
arg_dict = {
|
253
|
+
"--input_file": args.match_template_path,
|
254
|
+
"--target_mask": args.target_mask,
|
255
|
+
"--output_prefix": args.new_orientations_path,
|
256
|
+
"--peak_caller": "PeakCallerMaximumFilter",
|
257
|
+
"--number_of_peaks": args.number_of_peaks,
|
258
|
+
"--output_format": "orientations",
|
259
|
+
"--mask_edges" : True,
|
260
|
+
}
|
261
|
+
return arg_dict
|
262
|
+
|
263
|
+
def update_orientations(old, new, args):
|
264
|
+
stack_shape = Density.from_file(
|
265
|
+
args.candidate_stack_path, use_memmap = True
|
266
|
+
).shape
|
267
|
+
|
268
|
+
stack_center = np.add(
|
269
|
+
np.divide(stack_shape, 2).astype(int),
|
270
|
+
np.mod(stack_shape, 2)
|
271
|
+
)
|
69
272
|
|
70
|
-
|
273
|
+
print(old.translations[new.translations[:, 0].astype(int)])
|
274
|
+
print(new.translations[:, 1:], stack_center, stack_shape)
|
71
275
|
|
276
|
+
new.translations[:, 1:] = np.add(
|
277
|
+
old.translations[new.translations[:, 0].astype(int)],
|
278
|
+
np.subtract(new.translations, stack_center)[:, 1:]
|
279
|
+
)
|
280
|
+
print(new.translations)
|
281
|
+
# The effect of --align_orientations should be handled herer
|
282
|
+
return new
|
72
283
|
|
73
|
-
def main():
|
74
|
-
args = parse_args()
|
75
|
-
meta = load_pickle(args.input_file)[-1]
|
76
|
-
target_origin, _, sampling_rate, cli_args = meta
|
77
284
|
|
78
|
-
orientations = Orientations.from_file(
|
79
|
-
filename=args.orientations, file_format="text"
|
80
|
-
)
|
81
285
|
|
82
|
-
template = load_template(cli_args.template, sampling_rate)
|
83
|
-
template_mask = load_and_validate_mask(
|
84
|
-
mask_target=template, mask_path=cli_args.template_mask
|
85
|
-
)
|
86
286
|
|
87
|
-
|
88
|
-
|
287
|
+
class DeepMatcher:
|
288
|
+
def __init__(self, args):
|
289
|
+
self.orientations = Orientations.from_file(args.orientations)
|
89
290
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
enclosing_box = template.minimum_enclosing_box(
|
94
|
-
0, use_geometric_center=False
|
95
|
-
)
|
96
|
-
template_mask.adjust_box(enclosing_box)
|
291
|
+
match_template_args = create_matching_argdict(args)
|
292
|
+
match_template_args["--target"] = args.candidate_stack_path
|
293
|
+
self.match_template_args = match_template_args
|
97
294
|
|
98
|
-
|
99
|
-
|
295
|
+
self.filter_parameters = {}
|
296
|
+
if args.lowpass:
|
297
|
+
self.filter_parameters["--lowpass"] = 0
|
298
|
+
if args.highpass:
|
299
|
+
self.filter_parameters["--highpass"] = 200
|
100
300
|
|
101
|
-
|
102
|
-
|
103
|
-
np.subtract(template.origin, template_mask.origin), template.sampling_rate
|
104
|
-
)
|
105
|
-
translation = np.add(translation, origin_translation)
|
301
|
+
self.postprocess_args = create_postprocessing_argdict(args)
|
302
|
+
self.postprocess_args["--number_of_peaks"] = 1
|
106
303
|
|
107
|
-
template_mask = template_mask.rigid_transform(
|
108
|
-
rotation_matrix=np.eye(template_mask.data.ndim),
|
109
|
-
translation=-translation,
|
110
|
-
order=1,
|
111
|
-
)
|
112
|
-
template_mask.origin = template.origin.copy()
|
113
304
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
observation_starts = np.subtract(peaks, half_shape)
|
118
|
-
observation_stops = np.add(peaks, half_shape) + np.mod(template.shape, 2).astype(
|
119
|
-
int
|
120
|
-
)
|
305
|
+
def get_initial_values(self) -> Tuple[float]:
|
306
|
+
ret = tuple(float(x) for x in self.filter_parameters.values())
|
307
|
+
return ret
|
121
308
|
|
122
|
-
|
123
|
-
|
309
|
+
def format_parameters(self, parameter_values: Tuple[float]) -> Dict:
|
310
|
+
ret = {}
|
311
|
+
for value, key in zip(parameter_values, ret.keys()):
|
312
|
+
ret[key] = value
|
313
|
+
if isinstance(self.filter_parameters[key], bool):
|
314
|
+
ret[key] = value > 0.5
|
315
|
+
return ret
|
124
316
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
317
|
+
def __call__(self, x: Tuple[float]):
|
318
|
+
filter_parameters = self.format_parameters(x)
|
319
|
+
self.match_template_args.update(filter_parameters)
|
320
|
+
match_template = argdict_to_command(
|
321
|
+
self.match_template_args,
|
322
|
+
executable="python3 /Users/vmaurer/src/pytme/scripts/match_template_filters.py"
|
131
323
|
)
|
132
|
-
|
133
|
-
)
|
134
|
-
observation_starts = observation_starts[keep_peaks]
|
135
|
-
observation_stops = observation_stops[keep_peaks]
|
324
|
+
_ = subprocess.run(match_template, capture_output=True, shell = True)
|
136
325
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
326
|
+
# Assume we get a new peak for each input in the same order
|
327
|
+
postprocess = argdict_to_command(
|
328
|
+
self.postprocess_args,
|
329
|
+
executable="python3 /Users/vmaurer/src/pytme/scripts/postprocess.py"
|
330
|
+
)
|
331
|
+
_ = subprocess.run(postprocess, capture_output=True, shell = True)
|
141
332
|
|
142
|
-
|
143
|
-
|
333
|
+
orientations_new = Orientations.from_file(
|
334
|
+
f"{self.postprocess_args['--output_prefix']}.tsv"
|
335
|
+
)
|
336
|
+
orientations_new = orientations_new[np.argsort(orientations_new.translations[:, 0])]
|
144
337
|
|
145
|
-
|
146
|
-
|
338
|
+
label, dist = self.orientations.details, orientations_new.scores
|
339
|
+
loss = np.add(
|
340
|
+
(1 - label) * np.square(dist),
|
341
|
+
label * np.square(np.fmax(.5 - dist, 0.0))
|
342
|
+
)
|
343
|
+
return np.sum(loss)
|
147
344
|
|
148
|
-
observations = np.zeros((len(observation_slices), *out_shape))
|
149
345
|
|
150
346
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
347
|
+
def main():
|
348
|
+
args = parse_args()
|
349
|
+
|
350
|
+
if args.input_file is not None:
|
351
|
+
data = load_pickle(args.input_file)
|
352
|
+
target_origin, _, sampling_rate, cli_args = data[-1]
|
353
|
+
args.target, args.template = cli_args.target, cli_args.template
|
354
|
+
|
355
|
+
args.candidate_stack_path = generate_tempfile_name(suffix = ".h5")
|
356
|
+
args.new_orientations_path = generate_tempfile_name()
|
357
|
+
args.match_template_path = generate_tempfile_name()
|
358
|
+
|
359
|
+
match_deep = DeepMatcher(args)
|
360
|
+
initial_values = match_deep.get_initial_values()
|
361
|
+
|
362
|
+
# Do a single pass over the data
|
363
|
+
if len(initial_values) == 0:
|
364
|
+
create_image_stack = create_stacking_argdict(args)
|
365
|
+
create_image_stack = argdict_to_command(
|
366
|
+
create_image_stack,
|
367
|
+
executable="python3 /Users/vmaurer/src/pytme/scripts/extract_candidates.py"
|
156
368
|
)
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
matching_setup, matching_score = MATCHING_EXHAUSTIVE_REGISTER[scoring_method]
|
190
|
-
|
191
|
-
start = time()
|
192
|
-
candidates = scan_subsets(
|
193
|
-
matching_data=matching_data,
|
194
|
-
matching_score=matching_score,
|
195
|
-
matching_setup=matching_setup,
|
196
|
-
callback_class=callback_class,
|
197
|
-
callback_class_args={
|
198
|
-
# "score_space_shape" : (
|
199
|
-
# matching_data.rotations.shape[0], observations.shape[0]
|
200
|
-
# ),
|
201
|
-
# "score_space_dtype" : backend._default_dtype,
|
202
|
-
# "template_shape" : (matching_data.rotations.shape[0], *matching_data._template.shape)
|
203
|
-
},
|
204
|
-
target_splits=splits,
|
205
|
-
job_schedule=schedule,
|
206
|
-
pad_target_edges=False,
|
207
|
-
pad_fourier=False,
|
208
|
-
interpolation_order=cli_args.interpolation_order,
|
209
|
-
)
|
210
|
-
print(candidates[0].max())
|
211
|
-
Density(candidates[0][0]).to_file("scores.mrc")
|
212
|
-
|
213
|
-
runtime = time() - start
|
214
|
-
print(f"\nRuntime real: {runtime:.3f}s user: {(runtime * args.cores):.3f}s.")
|
369
|
+
_ = subprocess.run(create_image_stack, capture_output=True, shell = True)
|
370
|
+
if args.verbose:
|
371
|
+
copyfile(args.candidate_stack_path, f"{args.output_prefix}_stack.h5")
|
372
|
+
_ = match_deep(x = ())
|
373
|
+
if args.verbose:
|
374
|
+
copyfile(args.match_template_path, f"{args.output_prefix}_stack.pickle")
|
375
|
+
orientations = Orientations.from_file(f"{args.new_orientations_path}.tsv")
|
376
|
+
orientations = update_orientations(
|
377
|
+
new = orientations,
|
378
|
+
old = Orientations.from_file(args.orientations),
|
379
|
+
args= args
|
380
|
+
)
|
381
|
+
orientations.to_file(f"{args.output_prefix}.tsv")
|
382
|
+
exit(0)
|
383
|
+
|
384
|
+
for current_iteration in range(args.iterations):
|
385
|
+
create_image_stack = create_stacking_argdict(args)
|
386
|
+
create_image_stack = argdict_to_command(
|
387
|
+
create_image_stack,
|
388
|
+
executable="python3 /Users/vmaurer/src/pytme/scripts/extract_candidates.py"
|
389
|
+
)
|
390
|
+
_ = subprocess.run(create_image_stack, capture_output=True, shell = True)
|
391
|
+
|
392
|
+
# Perhaps we need a different optimizer here to use sensible steps for each parameter
|
393
|
+
match_deep = DeepMatcher(args)
|
394
|
+
parameters = optimize.minimize(
|
395
|
+
x0=match_deep.get_initial_values(),
|
396
|
+
fun=match_deep,
|
397
|
+
options = {"maxiter" : 2}
|
398
|
+
)
|
399
|
+
parameter_dict = match_deep.format_parameters(parameters)
|
215
400
|
|
401
|
+
match_template = create_matching_argdict(args)
|
402
|
+
match_template.update(parameter_dict)
|
403
|
+
match_template = argdict_to_command(
|
404
|
+
match_template,
|
405
|
+
executable="python3 /Users/vmaurer/src/pytme/scripts/match_template_filters.py"
|
406
|
+
)
|
407
|
+
_ = subprocess.run(match_template, capture_output=True, shell = True)
|
408
|
+
|
409
|
+
# Some form of labelling is necessary for these matches
|
410
|
+
# 1. All of them are true positives
|
411
|
+
# 2. All of them are true positives up to a certain threshold
|
412
|
+
# 3. Kernel fitting
|
413
|
+
# 4. Perhaps also sensible to include a certain percentage of low scores as true negatives
|
414
|
+
postprocess = create_postprocessing_argdict(args)
|
415
|
+
postprocess = argdict_to_command(postprocess, executable="postprocess.py")
|
416
|
+
_ = subprocess.run(postprocess, capture_output=True, shell = True)
|
417
|
+
args.orientations = f"{args.new_orientations_path}.tsv"
|
418
|
+
orientations = Orientations.from_file(args.orientations)
|
419
|
+
orientations.to_file(f"{args.output_prefix}_{current_iteration}.tsv")
|
216
420
|
|
217
421
|
if __name__ == "__main__":
|
218
422
|
main()
|
tme/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.2.
|
1
|
+
__version__ = "0.2.1"
|