emdbva 0.0.1.dev1__tar.gz → 0.0.1.dev2__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 (35) hide show
  1. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/MANIFEST.in +1 -0
  2. {emdbva-0.0.1.dev1/emdbva.egg-info → emdbva-0.0.1.dev2}/PKG-INFO +2 -1
  3. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2/emdbva.egg-info}/PKG-INFO +2 -1
  4. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/emdbva.egg-info/SOURCES.txt +2 -0
  5. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/emdbva.egg-info/requires.txt +1 -0
  6. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/setup.py +1 -1
  7. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/mainva.py +7 -0
  8. emdbva-0.0.1.dev2/va/metrics/contour_level_predicator.py +157 -0
  9. emdbva-0.0.1.dev2/va/metrics/projections.py +355 -0
  10. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/preparation.py +10 -116
  11. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/validationanalysis.py +40 -65
  12. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/version.py +1 -1
  13. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/LICENSE +0 -0
  14. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/README.rst +0 -0
  15. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/emdbva.egg-info/dependency_links.txt +0 -0
  16. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/emdbva.egg-info/entry_points.txt +0 -0
  17. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/emdbva.egg-info/top_level.txt +0 -0
  18. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/setup.cfg +0 -0
  19. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/__init__.py +0 -0
  20. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/__init__.py +0 -0
  21. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/bars.py +0 -0
  22. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/emda_mmcc.py +0 -0
  23. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/emringer.py +0 -0
  24. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/phaserandomization.py +0 -0
  25. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/phenix_cc.py +0 -0
  26. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/phenix_mm.py +0 -0
  27. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/qscore.py +0 -0
  28. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/resmap.py +0 -0
  29. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/smoc.py +0 -0
  30. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/strudel.py +0 -0
  31. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/metrics/threedfsc.py +0 -0
  32. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/qscores.csv +0 -0
  33. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/utils/__init__.py +0 -0
  34. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/utils/misc.py +0 -0
  35. {emdbva-0.0.1.dev1 → emdbva-0.0.1.dev2}/va/utils/stars.py +0 -0
@@ -7,6 +7,7 @@ exclude va/PATHS_loc.py
7
7
  exclude va/PATHS_codon.py
8
8
  exclude va/prepareandrun.py
9
9
  exclude va/prepareandrun_codon.py
10
+ exclude va/prepareandrun_codon_slurm.py
10
11
  exclude va/test.log
11
12
  exclude va/vtkrender_nomodel.py
12
13
  exclude va/test/*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: emdbva
3
- Version: 0.0.1.dev1
3
+ Version: 0.0.1.dev2
4
4
  Summary: CryoEM validation toolkit
5
5
  Home-page: https://test.pypi.org/project/va/
6
6
  Author: Zhe Wang
@@ -26,6 +26,7 @@ Requires-Dist: matplotlib
26
26
  Requires-Dist: pandas
27
27
  Requires-Dist: biopython
28
28
  Requires-Dist: mrcfile
29
+ Requires-Dist: torch
29
30
  Requires-Dist: opencv-python
30
31
 
31
32
  CryoEM validation analysis pipeline
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: emdbva
3
- Version: 0.0.1.dev1
3
+ Version: 0.0.1.dev2
4
4
  Summary: CryoEM validation toolkit
5
5
  Home-page: https://test.pypi.org/project/va/
6
6
  Author: Zhe Wang
@@ -26,6 +26,7 @@ Requires-Dist: matplotlib
26
26
  Requires-Dist: pandas
27
27
  Requires-Dist: biopython
28
28
  Requires-Dist: mrcfile
29
+ Requires-Dist: torch
29
30
  Requires-Dist: opencv-python
30
31
 
31
32
  CryoEM validation analysis pipeline
@@ -16,11 +16,13 @@ va/validationanalysis.py
16
16
  va/version.py
17
17
  va/metrics/__init__.py
18
18
  va/metrics/bars.py
19
+ va/metrics/contour_level_predicator.py
19
20
  va/metrics/emda_mmcc.py
20
21
  va/metrics/emringer.py
21
22
  va/metrics/phaserandomization.py
22
23
  va/metrics/phenix_cc.py
23
24
  va/metrics/phenix_mm.py
25
+ va/metrics/projections.py
24
26
  va/metrics/qscore.py
25
27
  va/metrics/resmap.py
26
28
  va/metrics/smoc.py
@@ -7,4 +7,5 @@ matplotlib
7
7
  pandas
8
8
  biopython
9
9
  mrcfile
10
+ torch
10
11
  opencv-python
@@ -48,7 +48,7 @@ setup(
48
48
  "pandas",
49
49
  "biopython",
50
50
  "mrcfile",
51
- # "emda>=1.1.3.post3",
51
+ "torch",
52
52
  cv,
53
53
  ],
54
54
  classifiers=[
@@ -53,6 +53,9 @@ def allruns(validationobj, runs):
53
53
  """
54
54
 
55
55
  # Projections
56
+ # if 'projection':
57
+ # validationobj.new_projection()
58
+
56
59
  if 'projection' in runs:
57
60
  validationobj.orthogonal_projections()
58
61
  validationobj.rawmap_projections()
@@ -65,6 +68,10 @@ def allruns(validationobj, runs):
65
68
  validationobj.orthogonal_std()
66
69
  validationobj.rawmap_std()
67
70
 
71
+ # Predicated contour
72
+ if 'predictcontour' in runs:
73
+ validationobj.cl_prediction()
74
+
68
75
  # Central slice
69
76
  if 'central' in runs:
70
77
  validationobj.central_slice()
@@ -0,0 +1,157 @@
1
+ import os
2
+ os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
3
+ import torch
4
+ import torch.nn as nn
5
+ import numpy as np
6
+ torch.manual_seed(42)
7
+ import warnings
8
+ import mrcfile
9
+
10
+ warnings.filterwarnings("ignore", message="CUDA initialization: The NVIDIA driver on your system is too old.*")
11
+ warnings.filterwarnings("ignore", category=RuntimeWarning)
12
+ warnings.filterwarnings("ignore", message="User provided device_type of 'cuda', but CUDA is not available. Disabling")
13
+
14
+
15
+ # Convolutional layers adapted from https://www.nature.com/articles/s41598-022-19212-6
16
+ class CNNModel(nn.Module):
17
+ def __init__(self):
18
+ super(CNNModel, self).__init__()
19
+ self.conv = nn.Sequential(
20
+ nn.Conv3d(1, 32, 7, 1, padding_mode='replicate'),
21
+ nn.BatchNorm3d(32),
22
+ nn.ReLU(),
23
+ nn.Conv3d(32, 64, 5, 1, padding_mode='replicate'),
24
+ nn.BatchNorm3d(64),
25
+ nn.ReLU(),
26
+ nn.MaxPool3d(2),
27
+ nn.Conv3d(64, 128, 5, 1, padding_mode='replicate'),
28
+ nn.BatchNorm3d(128),
29
+ nn.ReLU(),
30
+ nn.MaxPool3d(2),
31
+ nn.Conv3d(128, 256, 3, 1, padding_mode='replicate'),
32
+ nn.BatchNorm3d(256),
33
+ nn.ReLU(),
34
+ nn.MaxPool3d(2),
35
+ nn.Conv3d(256, 384, 1, 1, padding_mode='replicate'),
36
+ nn.ReLU(),
37
+ nn.AvgPool3d(3, stride=2),
38
+ nn.Dropout(0.3))
39
+
40
+ self.mlp = nn.Sequential(nn.Linear(in_features=384, out_features=64),
41
+ nn.ReLU(),
42
+ nn.Linear(in_features=64, out_features=1))
43
+
44
+ def forward(self, x):
45
+ x = x.view(-1, 1, 64, 64, 64)
46
+ x = self.conv(x)
47
+ x = x.view(x.size(0), -1)
48
+ x = self.mlp(x)
49
+ return x
50
+
51
+
52
+ def check_boxsize(vol):
53
+ return vol.shape[0]
54
+
55
+
56
+ def load_data(vol_d_norm):
57
+ vol_array = np.empty(shape=(1, 64, 64, 64), dtype=np.float32)
58
+ vol_array[:] = vol_d_norm
59
+ data_generator = torch.utils.data.DataLoader(vol_array, batch_size=1, shuffle=False)
60
+ return data_generator
61
+
62
+
63
+ def downsample(vol):
64
+ boxsize = check_boxsize(vol)
65
+ vol_ft = np.fft.fftshift(np.fft.fftn(np.fft.fftshift(vol)))
66
+ start = boxsize // 2 - 64 // 2
67
+ stop = boxsize // 2 + 64 // 2
68
+ vol_ft_d = vol_ft[start:stop, start:stop, start:stop]
69
+ vol_d = np.fft.ifftshift(np.fft.ifftn(np.fft.ifftshift(vol_ft_d)))
70
+ vol_d = vol_d.real
71
+ vol_d *= ((64 / boxsize) ** 3)
72
+ vol_d = vol_d.astype(np.float32)
73
+ return vol_d
74
+
75
+
76
+ def upsample(
77
+ vol): # through interpolation of maps in Fourier space; based on https://www.sciencedirect.com/science/article/pii/S001046551400335X
78
+ boxsize = check_boxsize(vol)
79
+ new_box_size = 64
80
+ vol_ft = np.fft.fftshift(np.fft.fftn(np.fft.fftshift(vol)))
81
+ padded_vol_ft = np.zeros((new_box_size, new_box_size, new_box_size), dtype=np.float32)
82
+ padded_vol_ft[:vol.shape[0], :vol.shape[1], :vol.shape[2]] = vol_ft
83
+ interpolated_density_map = np.fft.ifftshift(np.fft.ifftn(np.fft.ifftshift((padded_vol_ft))))
84
+ interpolated_density_map = interpolated_density_map.real
85
+ interpolated_density_map *= ((64 / boxsize) ** 3)
86
+ return interpolated_density_map
87
+
88
+
89
+ def normalize(vol_data):
90
+ d_upper = np.percentile(vol_data, 99.999)
91
+ d_lower = np.percentile(vol_data, 0.001)
92
+ vol_data = np.where(vol_data > d_upper, d_upper, vol_data)
93
+ vol_data = np.where(vol_data < d_lower, d_lower, vol_data)
94
+ vol_d_norm = np.where(vol_data <= 0, 0, vol_data)
95
+ vol_d_min = np.min(vol_data[vol_data > 0])
96
+ vol_d_max = np.max(vol_d_norm)
97
+ vol_d_norm = (vol_d_norm - vol_d_min) / (vol_d_max - vol_d_min)
98
+ vol_d_norm = 2 * vol_d_norm - 1
99
+ return vol_d_norm, vol_d_min, vol_d_max
100
+
101
+
102
+ device = torch.device("cuda") if torch.cuda.is_available() else torch.device('cpu')
103
+ model = CNNModel()
104
+ dir = os.path.dirname(os.path.abspath(__file__))
105
+ parent_dir = os.path.dirname(dir)
106
+ weights_dir = os.path.join(parent_dir, 'utils')
107
+ checkpoint = torch.load(os.path.join(weights_dir, 'cl_weights.pth'), map_location=device)
108
+ model.load_state_dict(checkpoint['model_state_dict'])
109
+
110
+
111
+ def model_pred(data_generator):
112
+ model.eval()
113
+ pred_list = []
114
+ with torch.no_grad():
115
+ with torch.cuda.amp.autocast():
116
+ for (idx, x) in enumerate(data_generator):
117
+ x = x.to(device)
118
+ prediction = model(x)
119
+ prediction = (prediction.squeeze(dim=1))
120
+ pred_list.append(prediction)
121
+ return pred_list
122
+
123
+
124
+ def calc_level_dev(vol_data):
125
+ boxsize = check_boxsize(vol_data)
126
+
127
+ if boxsize > 64:
128
+ _, vol_min, vol_max = normalize(vol_data)
129
+ vol_d = downsample(vol_data)
130
+ vol_d_norm, _, _ = normalize(vol_d)
131
+
132
+ elif boxsize < 64:
133
+ _, vol_min, vol_max = normalize(vol_data)
134
+ vol_d = upsample(vol_data)
135
+ vol_d_norm, _, _ = normalize(vol_d)
136
+
137
+ else:
138
+ vol_d = vol_data
139
+ vol_d_norm, vol_d_min, vol_d_max = normalize(vol_d)
140
+
141
+ data_generator = load_data(vol_d_norm)
142
+ pred_list = model_pred(data_generator)
143
+ all_preds = np.concatenate(pred_list, axis=0)
144
+ int_preds = (all_preds + 1) / 2
145
+
146
+ if boxsize != 64:
147
+ norm_preds = (int_preds * (vol_max - vol_min)) + vol_min
148
+ else:
149
+ norm_preds = (int_preds * (vol_d_max - vol_d_min)) + vol_d_min
150
+
151
+ return norm_preds
152
+
153
+
154
+
155
+
156
+
157
+
@@ -0,0 +1,355 @@
1
+ import os
2
+ import sys
3
+ import timeit
4
+ import json
5
+ import codecs
6
+ import cv2
7
+ import numpy as np
8
+ from math import ceil
9
+ from scipy import ndimage
10
+ from mrcfile.mrcfile import MrcFile
11
+ import inspect
12
+ from va.utils.misc import out_json
13
+
14
+ class Projections:
15
+ def __init__(self, primary_map, rawmap=None, workdir=None, platform=None):
16
+ self.map = primary_map
17
+ self.rawmap = rawmap
18
+ self.workdir = workdir
19
+ self.platform = platform
20
+ self.errlist = []
21
+
22
+ def mapincheck(self, mapin, workdirin):
23
+ frame = inspect.currentframe()
24
+ func = inspect.getframeinfo(frame.f_back).function
25
+ map, workdir = None, None
26
+
27
+ if mapin is not None:
28
+ if isinstance(mapin, str):
29
+ if os.path.isfile(mapin):
30
+ map = MrcFile(mapin, mode='r')
31
+ else:
32
+ print('Map does not exist.')
33
+ elif isinstance(mapin, MrcFile):
34
+ map = mapin
35
+ else:
36
+ print(f'Function:{func} only accepts a string of the full map name or a TEMPy Map object as input.')
37
+
38
+ if workdirin is not None:
39
+ if isinstance(workdirin, str):
40
+ if os.path.isdir(workdirin):
41
+ workdir = workdirin
42
+ else:
43
+ print('Output directory does not exist.')
44
+ else:
45
+ print(f'Function:{func} only accepts a string as the directory parameter.')
46
+
47
+ return map, workdir
48
+
49
+ def resize_img(self, input_arr, output_img):
50
+ height, width = input_arr.shape[0:2]
51
+ if width >= height:
52
+ largerscaler = 300. / width
53
+ newheight = int(ceil(largerscaler * height))
54
+ resized_img = cv2.resize(input_arr, (300, newheight), interpolation=cv2.INTER_LANCZOS4)
55
+ else:
56
+ largerscaler = 300. / height
57
+ newwidth = int(ceil(largerscaler * width))
58
+ resized_img = cv2.resize(input_arr, (newwidth, 300), interpolation=cv2.INTER_LANCZOS4)
59
+
60
+ cv2.imwrite(output_img, resized_img)
61
+
62
+ def scale_img(self, projection):
63
+ onevalue = True if projection.min() == projection.max() else False
64
+ if onevalue:
65
+ rescaled = np.full((projection.shape), 0.0).astype('uint8')
66
+ else:
67
+ rescaled = (((projection - projection.min()) * 255.0) / (projection.max() - projection.min())).astype('uint8')
68
+ return rescaled
69
+
70
+ def get_projection(self, map, type, axis):
71
+ mapdata = map.data
72
+ ind = None
73
+ if type == 'projection':
74
+ projection = np.sum(mapdata, axis=axis)
75
+ elif type == 'max':
76
+ projection = np.amax(mapdata, axis=axis)
77
+ elif type == 'min':
78
+ projection = np.amin(mapdata, axis=axis)
79
+ elif type == 'std':
80
+ projection = np.std(mapdata, axis=axis)
81
+ elif type == 'median':
82
+ projection = np.median(mapdata, axis=axis)
83
+ elif type == 'central':
84
+ projection = map.data[:, :, int(map.header.nx / 2)] if axis == 2 else \
85
+ map.data[:, int(map.header.ny / 2), :] if axis == 1 else \
86
+ map.data[int(map.header.nz / 2), :, :] if axis == 0 else None
87
+ if axis == 2:
88
+ ind = {'x': int(map.header.nx / 2)}
89
+ elif axis == 1:
90
+ ind = {'y': int(map.header.ny / 2)}
91
+ elif axis == 0:
92
+ ind = {'z': int(map.header.nz / 2)}
93
+ else:
94
+ ind = None
95
+
96
+ elif type == 'largestvariance':
97
+ if axis == 2:
98
+ xvar = [ndimage.variance(map.data[:, :, i]) for i in range(map.data.shape[2])]
99
+ xlargeind = int(np.argmax(xvar))
100
+ ind = {'x': xlargeind}
101
+ projection = map.data[:, :, xlargeind]
102
+ elif axis == 1:
103
+ yvar = [ndimage.variance(map.data[:, i, :]) for i in range(map.data.shape[1])]
104
+ ylargeind = int(np.argmax(yvar))
105
+ ind = {'y': ylargeind}
106
+ projection = map.data[:, ylargeind, :]
107
+ elif axis == 0:
108
+ zvar = [ndimage.variance(map.data[i, :, :]) for i in range(map.data.shape[0])]
109
+ zlargeind = int(np.argmax(zvar))
110
+ ind = {'z': zlargeind}
111
+ projection = map.data[zlargeind, :, :]
112
+ else:
113
+ projection = None
114
+ else:
115
+ projection = None
116
+ print('Wrong type. Use one of: projection, max, min, std, median, central, largestvariance.')
117
+ return projection, ind
118
+
119
+
120
+ def output_filename(self, axis_letter, mapname, type, proc_fun=None):
121
+ if proc_fun:
122
+ suffix = 'glow_' if proc_fun == self.glowimage else ''
123
+ else:
124
+ suffix = ''
125
+
126
+ if type == 'central' or type == 'largestvariance':
127
+ output_name = f'{self.workdir}{mapname}_{axis_letter}{type}_slice.jpeg'
128
+ scaled_output_name = f'{self.workdir}{mapname}_scaled_{axis_letter}{type}_slice.jpeg'
129
+ else:
130
+ output_name = f'{self.workdir}{mapname}_{suffix}{axis_letter}{type}.jpeg'
131
+ scaled_output_name = f'{self.workdir}{mapname}_scaled_{suffix}{axis_letter}{type}.jpeg'
132
+
133
+ return output_name, scaled_output_name
134
+
135
+ def save_scale(self, reposition, output_name, scaled_output_name, errlist):
136
+
137
+ try:
138
+ cv2.imwrite(output_name, reposition)
139
+ except IOError as ioerr:
140
+ err = f'Saving {output_name} projection err: {ioerr}'
141
+ errlist.append(err)
142
+ sys.stderr.write(err + '\n')
143
+
144
+ try:
145
+ self.resize_img(reposition, scaled_output_name)
146
+ except Exception as e:
147
+ err = f'Saving scaled {scaled_output_name} image err: {e}'
148
+ errlist.append(err)
149
+ sys.stderr.write(err + '\n')
150
+
151
+ def map_to_img(self, map, axis, type, errlist, proc_fun=None):
152
+ projection, ind = self.get_projection(map, type, axis)
153
+ org = {}
154
+ scale = {}
155
+ if projection is not None:
156
+ rescaled = self.scale_img(projection)
157
+ if axis == 2:
158
+ reposition = np.flipud(rescaled)
159
+ axis_letter = 'x'
160
+ elif axis == 1:
161
+ reposition = np.rot90(rescaled)
162
+ axis_letter = 'y'
163
+ elif axis == 0:
164
+ reposition = np.flipud(rescaled)
165
+ axis_letter = 'z'
166
+ else:
167
+ return None
168
+
169
+ mapname = os.path.basename(map.fullname)
170
+ output_name, scaled_output_name = self.output_filename(axis_letter, mapname, type, proc_fun)
171
+ org[axis_letter] = os.path.basename(output_name)
172
+ scale[axis_letter] = os.path.basename(scaled_output_name)
173
+
174
+ self.save_scale(reposition, output_name, scaled_output_name, errlist)
175
+ if proc_fun:
176
+ glowimage = proc_fun(reposition)
177
+ self.save_scale(glowimage, output_name, scaled_output_name, errlist)
178
+
179
+ return ind, org, scale
180
+
181
+ def orthogonal_projections(self, mapin=None, workdir=None, type=None, label=''):
182
+ map, workdir = self.mapincheck(mapin, workdir)
183
+ if map is not None and workdir is not None:
184
+ start = timeit.default_timer()
185
+ self.errlist = []
186
+ mapname = os.path.basename(map.fullname)
187
+ if not type:
188
+ types = ['projection', 'max', 'min', 'std', 'median', 'central', 'largestvariance']
189
+ else:
190
+ types = [type]
191
+ result_dict = {}
192
+ for type in types:
193
+ ind_result = {}
194
+ org_result = {}
195
+ scale_result = {}
196
+ final_org = {}
197
+ final_scale = {}
198
+ final_ind = {}
199
+ glow_ind_result = {}
200
+ glow_org_result = {}
201
+ glow_scale_result = {}
202
+ for axis in range(2, -1, -1):
203
+ ind, org, scale = self.map_to_img(map, axis, type, self.errlist)
204
+ if type != 'max' or type == 'projection' or type == 'std':
205
+ glow_ind, glow_org, glow_scale = self.map_to_img(map, axis, type, self.errlist, self.glowimage)
206
+ glow_org_result.update(glow_org)
207
+ glow_scale_result.update(glow_scale)
208
+ if type == 'central' or type == 'largestvariance':
209
+ glow_ind_result.update(glow_ind)
210
+ if type == 'central' or type == 'largestvariance':
211
+ ind_result.update(ind)
212
+ org_result.update(org)
213
+ scale_result.update(scale)
214
+ final_org['original'] = org_result
215
+ final_scale['scaled'] = scale_result
216
+ if type == 'central' or type == 'largestvariance':
217
+ final_ind['indices'] = ind_result
218
+
219
+ if type == 'largestvariance':
220
+ result_dict['largest_variance_slice'] = {**final_org, **final_scale, **final_ind}
221
+ elif type == 'central':
222
+ result_dict['central_slice'] = {**final_org, **final_scale, **final_ind}
223
+ else:
224
+ result_dict[f'orthogonal_{type}'] = {**final_org, **final_scale}
225
+
226
+ if len(types) == 1:
227
+ json_file = f'{self.workdir}{mapname}_{type}.json'
228
+ else:
229
+ if not label:
230
+ json_file = f'{self.workdir}{mapname}_primary_projections.json'
231
+ else:
232
+ json_file = f'{self.workdir}{mapname}_raw_projections.json'
233
+
234
+ out_json(result_dict, json_file)
235
+ end = timeit.default_timer()
236
+ print(f'Projections and their glow projections time for {mapname}: {end - start}')
237
+ print('------------------------------------')
238
+ else:
239
+ print('No orthogonal projections without proper map input and the output directory information.')
240
+
241
+ def rawmap_projections(self):
242
+ if self.rawmap is not None:
243
+ self.orthogonal_projections(self.rawmap, self.workdir, 'rawmap_')
244
+ else:
245
+ print('No raw map to calculate orthogonal projections.')
246
+
247
+
248
+ def save_to_json(self, errlist, mapname, workdir, label):
249
+ bothjson = {}
250
+ projectionjson = {}
251
+ orgprojectionjson = {}
252
+
253
+ for axis_letter in ['x', 'y', 'z']:
254
+ projectionjson[axis_letter] = {}
255
+ orgprojectionjson[axis_letter] = {}
256
+
257
+ for axis in range(3):
258
+ for type in ['projection', 'max', 'min', 'std', 'median', 'central', 'largestvariance']:
259
+ for axis_letter in ['x', 'y', 'z']:
260
+ projection_name = f'{workdir}{mapname}_{axis_letter}{type}.jpeg'
261
+ scaled_projection_name = f'{workdir}{mapname}_scaled_{axis_letter}{type}.jpeg'
262
+ projectionjson[axis_letter][type] = os.path.basename(projection_name) if os.path.isfile(projection_name) else None
263
+ orgprojectionjson[axis_letter][type] = os.path.basename(scaled_projection_name) if os.path.isfile(scaled_projection_name) else None
264
+
265
+ bothjson['original'] = orgprojectionjson
266
+ bothjson['scaled'] = projectionjson
267
+
268
+ if errlist:
269
+ bothjson['err'] = {'orthogonal_median_err': errlist}
270
+ finaldict = {label + 'orthogonal_median': bothjson}
271
+
272
+ try:
273
+ with codecs.open(f'{workdir}{mapname}_median.json', 'w', encoding='utf-8') as f:
274
+ json.dump(finaldict, f)
275
+ except IOError as ioerr:
276
+ jsonerr = f'Saving median projection into json error: {ioerr}'
277
+ sys.stderr.write(jsonerr + '\n')
278
+
279
+ def glowimage(self, im_gray):
280
+ """Applies a glow color map using cv2.applyColorMap()"""
281
+
282
+ # Create the LUT:
283
+ lut = np.zeros((256, 1, 3), dtype=np.uint8)
284
+ lut[:, 0, 2] = [0, 1, 1, 2, 2, 3, 4, 6, 8, 11, 13, 15, 18,
285
+ 21, 23, 24, 27, 30, 31, 33, 36, 37, 40, 42, 45, 46,
286
+ 49, 51, 53, 56, 58, 60, 62, 65, 68, 70, 72, 74, 78,
287
+ 80, 82, 84, 86, 89, 91, 93, 96, 98, 100, 102, 104, 106,
288
+ 108, 110, 113, 115, 117, 119, 122, 125, 127, 129, 132, 135, 135,
289
+ 137, 140, 141, 142, 145, 148, 149, 152, 154, 156, 157, 158, 160,
290
+ 162, 164, 166, 168, 170, 171, 173, 174, 176, 178, 179, 180, 182,
291
+ 183, 185, 186, 189, 192, 193, 193, 194, 195, 195, 196, 198, 199,
292
+ 201, 203, 204, 204, 205, 206, 207, 209, 211, 211, 211, 211, 213,
293
+ 215, 216, 216, 216, 216, 218, 219, 219, 219, 220, 222, 223, 223,
294
+ 223, 223, 224, 224, 226, 227, 227, 227, 227, 228, 229, 231, 231,
295
+ 231, 231, 231, 231, 231, 232, 233, 234, 234, 234, 234, 234, 234,
296
+ 235, 237, 238, 238, 238, 238, 238, 238, 238, 238, 239, 240, 242,
297
+ 242, 242, 242, 242, 242, 242, 242, 242, 243, 245, 246, 246, 246,
298
+ 246, 245, 245, 245, 245, 245, 245, 245, 247, 248, 249, 249, 249,
299
+ 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
300
+ 249, 250, 252, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
301
+ 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
302
+ 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
303
+ 253, 253, 253, 253, 253, 253, 253, 253, 0]
304
+
305
+ lut[:, 0, 1] = [138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
306
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
307
+ 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 5,
308
+ 6, 6, 6, 7, 7, 8, 9, 9, 9, 9, 10, 10, 11,
309
+ 12, 13, 14, 14, 14, 14, 15, 16, 16, 17, 18, 19, 19,
310
+ 19, 20, 21, 22, 23, 24, 24, 25, 27, 28, 28, 28, 29,
311
+ 31, 32, 32, 33, 35, 36, 36, 37, 39, 40, 40, 41, 42,
312
+ 43, 45, 46, 47, 48, 50, 51, 52, 54, 55, 56, 57, 59,
313
+ 62, 63, 65, 66, 68, 70, 71, 73, 74, 75, 77, 79, 81,
314
+ 83, 85, 87, 89, 92, 93, 96, 98, 99, 100, 103, 105, 107,
315
+ 109, 111, 113, 116, 117, 119, 121, 123, 125, 126, 128, 130, 132,
316
+ 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 152, 154, 156,
317
+ 158, 160, 161, 162, 164, 166, 168, 171, 172, 172, 174, 176, 177,
318
+ 179, 180, 182, 183, 185, 187, 188, 189, 191, 192, 192, 192, 196,
319
+ 200, 201, 201, 202, 203, 204, 206, 208, 210, 212, 213, 213, 214,
320
+ 215, 217, 218, 220, 221, 222, 223, 224, 225, 226, 226, 227, 228,
321
+ 229, 231, 232, 233, 234, 235, 236, 237, 238, 239, 239, 239, 239,
322
+ 241, 242, 243, 243, 243, 244, 245, 247, 247, 247, 247, 247, 247,
323
+ 248, 249, 250, 251, 251, 251, 252, 252, 252, 252, 252, 252, 252,
324
+ 252, 252, 252, 252, 252, 252, 253, 253, 0]
325
+
326
+ lut[:, 0, 0] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
327
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 4,
328
+ 4, 4, 4, 4, 3, 3, 3, 3, 4, 6, 6, 6, 6,
329
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
330
+ 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 7, 9, 10,
331
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
332
+ 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
333
+ 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8,
334
+ 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7,
335
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
336
+ 6, 6, 6, 6, 7, 10, 12, 12, 12, 12, 12, 12, 13,
337
+ 15, 17, 18, 18, 19, 20, 22, 23, 23, 24, 26, 27, 27,
338
+ 28, 30, 32, 33, 34, 35, 37, 39, 40, 41, 43, 45, 46,
339
+ 48, 50, 52, 54, 55, 57, 58, 61, 63, 65, 67, 70, 72,
340
+ 73, 76, 79, 80, 83, 86, 88, 89, 92, 95, 96, 99, 102,
341
+ 104, 107, 108, 110, 113, 116, 120, 121, 123, 125, 127, 129, 132,
342
+ 135, 137, 140, 143, 146, 149, 150, 153, 155, 158, 160, 162, 165,
343
+ 168, 171, 173, 175, 178, 180, 183, 186, 188, 191, 192, 195, 198,
344
+ 201, 203, 206, 209, 210, 213, 215, 218, 221, 223, 225, 228, 231,
345
+ 233, 236, 238, 241, 244, 246, 250, 252, 255]
346
+
347
+ im_color = cv2.applyColorMap(im_gray, lut)
348
+ return im_color
349
+
350
+ # Example usage:
351
+ # rawmap = MrcFile("/Users/zhe/Downloads/tests/VA/nfs/msd/work2/emdb/development/staging/em/81/8117/va/emd_8117_rawmap.map")
352
+ # workdir = "/Users/zhe/Downloads/tests/VA/nfs/msd/work2/emdb/development/staging/em/81/8117/va"
353
+ # op = Projections(rawmap, workdir)
354
+ # op.rawmap_projections()
355
+ # op.rawmap_median()
@@ -327,7 +327,7 @@ class PreParation:
327
327
  'volume': False, 'fsc': False, 'raps': False, 'mapmodel': False, 'inclusion': False,
328
328
  'largestvariance': False, 'mask': False, 'symmetry': False, 'rmmcc': False, 'smoc': False,
329
329
  'resccc': False, 'emringer': False, 'strudel': False, '3dfsc': False, 'locres': False,
330
- 'phrand': False}
330
+ 'phrand': False, 'predictcontour': False}
331
331
  for key in resdict.keys():
332
332
  if key in runs:
333
333
  resdict[key] = True
@@ -341,7 +341,7 @@ class PreParation:
341
341
  if self.mapname is not None:
342
342
  runlist.extend(['projection', 'central', 'surface', 'volume', 'density', 'raps', 'largestvariance',
343
343
  'mask', 'fsc', 'mmfsc', 'rmmcc', 'symmetry', 'qscore', 'strudel', 'emringer', '3dfsc',
344
- 'smoc', 'resccc', 'locres', 'phrand'
344
+ 'smoc', 'resccc', 'locres', 'phrand', 'predictcontour',
345
345
  ])
346
346
 
347
347
  if self.masks is None:
@@ -705,119 +705,6 @@ class PreParation:
705
705
  return None
706
706
 
707
707
 
708
- def swap_axes(self, header):
709
- """
710
-
711
- Swap the axes to make the data arranged as z, y, z by indices
712
-
713
- :param header:
714
- :return:
715
- """
716
- pass
717
-
718
-
719
- # def frommrc_totempy(self, fullmapname):
720
- # """
721
- # Transfer the mrcfile map object to TEMPy map object
722
- #
723
- # :param fullmapname:
724
- # :return: TEMPy map object
725
- # """
726
- #
727
- # mrcmap = mrcfile.mmap(fullmapname, mode='r+')
728
- # mrcheader = mrcmap.header
729
- # # mapdata = mrcmap.data.astype('float')
730
- # mapdata = mrcmap.data
731
- # crs = (mrcheader.mapc, mrcheader.mapr, mrcheader.maps)
732
- # print('----original start------')
733
- # print(mrcheader)
734
- # print(mapdata.shape)
735
- # print('------------------')
736
- # reversecrs = crs[::-1]
737
- # nstarts = (mrcheader.nxstart, mrcheader.nystart, mrcheader.nzstart)
738
- # stdcrs = (3, 2, 1)
739
- # diffcrs = tuple(x-y for x, y in zip(reversecrs, stdcrs))
740
- # if diffcrs != (0, 0, 0):
741
- # if 1 in diffcrs and -1 in diffcrs:
742
- # mapdata = np.swapaxes(mapdata, diffcrs.index(-1), diffcrs.index(1))
743
- # if -2 in diffcrs and 2 in diffcrs:
744
- # mapdata = np.swapaxes(mapdata, diffcrs.index(-2), diffcrs.index(2))
745
- # if 1 in diffcrs and -2 in diffcrs:
746
- # mapdata = np.swapaxes(np.swapaxes(mapdata, 0, 1), 1, 2)
747
- # if -1 in diffcrs and 2 in diffcrs:
748
- # mapdata = np.swapaxes(np.swapaxes(mapdata, 1, 2), 0, 1)
749
- # # mapdata = np.swapaxes(mapdata, 0, 2)
750
- #
751
- # print(mapdata.shape)
752
- # # mrcmap.set_data(mapdata)
753
- # # mrcmap.update_header_from_data()
754
- # # mapdata = np.swapaxes(np.swapaxes(mapdata, 0, 2), 1, 2)
755
- # tempyheader = MapParser.readMRCHeader(fullmapname)
756
- #
757
- # # nx, ny, nz and nxstart, nystart, nzstart haver to be changed accordingly to the data
758
- # tempyheader = list(tempyheader)
759
- # tempyheader[0] = mapdata.shape[2]
760
- # tempyheader[1] = mapdata.shape[1]
761
- # tempyheader[2] = mapdata.shape[0]
762
- # tempyheader[3] = mrcheader.mode.item(0)
763
- # tempyheader[4] = nstarts[0].item(0)
764
- # tempyheader[5] = nstarts[1].item(0)
765
- # tempyheader[6] = nstarts[2].item(0)
766
- # tempyheader[7] = mrcheader.mx.item(0)
767
- # tempyheader[8] = mrcheader.my.item(0)
768
- # tempyheader[9] = mrcheader.mz.item(0)
769
- # tempyheader[10] = mrcheader.cella.x.item(0)
770
- # tempyheader[11] = mrcheader.cella.y.item(0)
771
- # tempyheader[12] = mrcheader.cella.z.item(0)
772
- # tempyheader[13:16] = mrcheader.cellb.tolist()
773
- # tempyheader[16] = crs[0].item(0)
774
- # tempyheader[17] = crs[1].item(0)
775
- # tempyheader[18] = crs[2].item(0)
776
- # tempyheader[19] = mrcheader.dmin.item(0)
777
- # tempyheader[20] = mrcheader.dmax.item(0)
778
- # tempyheader[21] = mrcheader.dmean.item(0)
779
- # tempyheader[22] = mrcheader.ispg.item(0)
780
- # tempyheader[23] = mrcheader.nsymbt.item(0)
781
- #
782
- # # tempyheader[24] = mrcheader.extra1.item(0)
783
- # # tempyheader[25] = mrcheader.exttyp.item(0)
784
- # # tempyheader[26] = mrcheader.nversion.item(0)
785
- # # tempyheader[27] = mrcheader.extra2.item(0)
786
- #
787
- # tempyheader[49] = mrcheader.origin.x.item(0)
788
- # tempyheader[50] = mrcheader.origin.y.item(0)
789
- # tempyheader[51] = mrcheader.origin.z.item(0)
790
- # tempyheader[52:55] = ['M', 'A', 'P']
791
- #
792
- # tempyheader[56] = mrcheader.machst
793
- # tempyheader[57] = mrcheader.rms.item(0)
794
- # # tempyheader[58] = mrcheader.nlabl.item(0)
795
- # # tempyheader[59] = mrcheader.label.item(0)
796
- #
797
- #
798
- #
799
- # # tempyheader[13] = mrcheader.cellb.x.item(0)
800
- # # tempyheader[14] = mrcheader.cellb.y.item(0)
801
- # # tempyheader[15] = mrcheader.cellb.z.item(0)
802
- # # here also keep the nstarts position according to original crs order as in __getindices it automaticlly
803
- # # adjust the calculation based on the
804
- # # tempyheader[4] = int(nstarts[crs.index(1)])
805
- # # tempyheader[5] = int(nstarts[crs.index(2)])
806
- # # tempyheader[6] = int(nstarts[crs.index(3)])
807
- # tempyheader = tuple(tempyheader)
808
- # origin = (float(mrcheader.origin.x), float(mrcheader.origin.y), float(mrcheader.origin.z))
809
- # apix = (mrcheader.cella.x/mrcheader.mx, mrcheader.cella.y/mrcheader.my, mrcheader.cella.z/mrcheader.mz)[0]
810
- #
811
- # finalmap = Map(mapdata, origin, apix, fullmapname, header=tempyheader)
812
- # print(finalmap.box_size())
813
- # print('---box---')
814
- #
815
- # # inputmap.fullMap = np.swapaxes(np.swapaxes(mrcfile.mmap(fullmapname).data, 0, 2), 1, 2)
816
- # # print(inputmap.fullMap.shape)
817
- # # print(inputmap.fullMap[1, 3, 66])
818
- #
819
- # return finalmap
820
-
821
708
  # @profile
822
709
  def write_map(self, outmap_name, mapdata, nstarts, org_header):
823
710
  """
@@ -1557,7 +1444,14 @@ class PreParation:
1557
1444
  if key in obj1 and key in obj2 and isinstance(obj1[key], dict) and isinstance(obj2[key], dict):
1558
1445
  merged_obj[key] = self.merge_json_objects(obj1[key], obj2[key])
1559
1446
  elif key in obj1 and key in obj2:
1560
- merged_obj[key] = {**obj1[key], **obj2[key]}
1447
+ if isinstance(obj1[key], dict) and isinstance(obj2[key], dict):
1448
+ merged_obj[key] = {**obj1[key], **obj2[key]}
1449
+ elif isinstance(obj1[key], dict) and not isinstance(obj2[key], dict):
1450
+ merged_obj[key] = obj1[key]
1451
+ elif not isinstance(obj1[key], dict) and isinstance(obj2[key], dict):
1452
+ merged_obj[key] = obj2[key]
1453
+ else:
1454
+ merged_obj[key] = obj1[key]
1561
1455
  elif key in obj1:
1562
1456
  merged_obj[key] = obj1[key]
1563
1457
  elif key in obj2:
@@ -74,6 +74,8 @@ from va.metrics.bars import *
74
74
  from va.metrics.phaserandomization import *
75
75
  from va.utils.stars import *
76
76
  from va.utils.misc import *
77
+ from va.metrics.contour_level_predicator import *
78
+ from va.metrics.projections import *
77
79
  import va
78
80
 
79
81
  try:
@@ -295,71 +297,6 @@ class ValidationAnalysis:
295
297
  201, 203, 206, 209, 210, 213, 215, 218, 221, 223, 225, 228, 231,
296
298
  233, 236, 238, 241, 244, 246, 250, 252, 255]
297
299
 
298
- # Modified Glow LUT which make the first four smallest value as green
299
- # lut[:, 0, 2] = [0, 0, 0, 0, 2, 3, 4, 6, 8, 11, 13, 15, 18,
300
- # 21, 23, 24, 27, 30, 31, 33, 36, 37, 40, 42, 45, 46,
301
- # 49, 51, 53, 56, 58, 60, 62, 65, 68, 70, 72, 74, 78,
302
- # 80, 82, 84, 86, 89, 91, 93, 96, 98, 100, 102, 104, 106,
303
- # 108, 110, 113, 115, 117, 119, 122, 125, 127, 129, 132, 135, 135,
304
- # 137, 140, 141, 142, 145, 148, 149, 152, 154, 156, 157, 158, 160,
305
- # 162, 164, 166, 168, 170, 171, 173, 174, 176, 178, 179, 180, 182,
306
- # 183, 185, 186, 189, 192, 193, 193, 194, 195, 195, 196, 198, 199,
307
- # 201, 203, 204, 204, 205, 206, 207, 209, 211, 211, 211, 211, 213,
308
- # 215, 216, 216, 216, 216, 218, 219, 219, 219, 220, 222, 223, 223,
309
- # 223, 223, 224, 224, 226, 227, 227, 227, 227, 228, 229, 231, 231,
310
- # 231, 231, 231, 231, 231, 232, 233, 234, 234, 234, 234, 234, 234,
311
- # 235, 237, 238, 238, 238, 238, 238, 238, 238, 238, 239, 240, 242,
312
- # 242, 242, 242, 242, 242, 242, 242, 242, 243, 245, 246, 246, 246,
313
- # 246, 245, 245, 245, 245, 245, 245, 245, 247, 248, 249, 249, 249,
314
- # 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
315
- # 249, 250, 252, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
316
- # 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
317
- # 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
318
- # 253, 253, 253, 253, 253, 253, 253, 253, 0]
319
- #
320
- # lut[:, 0, 1] = [138, 138, 138, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0,
321
- # 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
322
- # 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 5,
323
- # 6, 6, 6, 7, 7, 8, 9, 9, 9, 9, 10, 10, 11,
324
- # 12, 13, 14, 14, 14, 14, 15, 16, 16, 17, 18, 19, 19,
325
- # 19, 20, 21, 22, 23, 24, 24, 25, 27, 28, 28, 28, 29,
326
- # 31, 32, 32, 33, 35, 36, 36, 37, 39, 40, 40, 41, 42,
327
- # 43, 45, 46, 47, 48, 50, 51, 52, 54, 55, 56, 57, 59,
328
- # 62, 63, 65, 66, 68, 70, 71, 73, 74, 75, 77, 79, 81,
329
- # 83, 85, 87, 89, 92, 93, 96, 98, 99, 100, 103, 105, 107,
330
- # 109, 111, 113, 116, 117, 119, 121, 123, 125, 126, 128, 130, 132,
331
- # 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 152, 154, 156,
332
- # 158, 160, 161, 162, 164, 166, 168, 171, 172, 172, 174, 176, 177,
333
- # 179, 180, 182, 183, 185, 187, 188, 189, 191, 192, 192, 192, 196,
334
- # 200, 201, 201, 202, 203, 204, 206, 208, 210, 212, 213, 213, 214,
335
- # 215, 217, 218, 220, 221, 222, 223, 224, 225, 226, 226, 227, 228,
336
- # 229, 231, 232, 233, 234, 235, 236, 237, 238, 239, 239, 239, 239,
337
- # 241, 242, 243, 243, 243, 244, 245, 247, 247, 247, 247, 247, 247,
338
- # 248, 249, 250, 251, 251, 251, 252, 252, 252, 252, 252, 252, 252,
339
- # 252, 252, 252, 252, 252, 252, 253, 253, 0]
340
- #
341
- # lut[:, 0, 0] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
342
- # 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 4,
343
- # 4, 4, 4, 4, 3, 3, 3, 3, 4, 6, 6, 6, 6,
344
- # 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
345
- # 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 7, 9, 10,
346
- # 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
347
- # 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
348
- # 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8,
349
- # 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7,
350
- # 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
351
- # 6, 6, 6, 6, 7, 10, 12, 12, 12, 12, 12, 12, 13,
352
- # 15, 17, 18, 18, 19, 20, 22, 23, 23, 24, 26, 27, 27,
353
- # 28, 30, 32, 33, 34, 35, 37, 39, 40, 41, 43, 45, 46,
354
- # 48, 50, 52, 54, 55, 57, 58, 61, 63, 65, 67, 70, 72,
355
- # 73, 76, 79, 80, 83, 86, 88, 89, 92, 95, 96, 99, 102,
356
- # 104, 107, 108, 110, 113, 116, 120, 121, 123, 125, 127, 129, 132,
357
- # 135, 137, 140, 143, 146, 149, 150, 153, 155, 158, 160, 162, 165,
358
- # 168, 171, 173, 175, 178, 180, 183, 186, 188, 191, 192, 195, 198,
359
- # 201, 203, 206, 209, 210, 213, 215, 218, 221, 223, 225, 228, 231,
360
- # 233, 236, 238, 241, 244, 246, 250, 252, 255]
361
-
362
- # Apply color map using cv2.applyColorMap()
363
300
  im_color = cv2.applyColorMap(im_gray, lut)
364
301
  return im_color
365
302
 
@@ -442,6 +379,13 @@ class ValidationAnalysis:
442
379
  im_color = cv2.applyColorMap(im_gray, lut)
443
380
  return im_color
444
381
 
382
+
383
+ def new_projection(self, type=None):
384
+ op = Projections(self.map, self.rawmap, self.workdir, self.platform)
385
+ op.orthogonal_projections(self.map, self.workdir, type)
386
+ if self.rawmap:
387
+ op.orthogonal_projections(self.rawmap, self.workdir, type, 'rawmap_')
388
+
445
389
  def mapincheck(self, mapin, workdirin):
446
390
 
447
391
  import inspect
@@ -7655,6 +7599,37 @@ class ValidationAnalysis:
7655
7599
  phaserandomization(self.mapname, self.hmodd.fullname, self.hmeven.fullname, self.workdir)
7656
7600
 
7657
7601
 
7602
+ def cl_prediction(self):
7603
+ """
7604
+ To predicate contour level for both primary map and raw map output as json file
7605
+ """
7606
+
7607
+ pred_primary = {}
7608
+ pred_raw = {}
7609
+ if self.map.fullname:
7610
+ m = mrcfile.open(self.map.fullname)
7611
+ d = m.data
7612
+ norm_pred = calc_level_dev(d)[0]
7613
+ pred_primary['primary'] = keep_three_significant_digits(float(norm_pred))
7614
+
7615
+ if self.rawmap:
7616
+ m = mrcfile.open(self.rawmap.fullname)
7617
+ d = m.data
7618
+ norm_pred = calc_level_dev(d)[0]
7619
+ pred_raw['raw'] = keep_three_significant_digits(float(norm_pred))
7620
+
7621
+ result_dict = {}
7622
+ if pred_primary or pred_raw:
7623
+ result_dict['predicated_contour_level'] = {**pred_primary, **pred_raw} if pred_primary and pred_raw \
7624
+ else pred_primary or pred_raw
7625
+ print(result_dict)
7626
+ else:
7627
+ print('Predicated contour level does not exist for either primary or raw map.')
7628
+
7629
+ if result_dict:
7630
+ file_name = f'{self.workdir}{self.mapname}_predicated_contour_level.json'
7631
+ out_json(result_dict, file_name)
7632
+
7658
7633
 
7659
7634
  def emringer(self):
7660
7635
  """
@@ -28,4 +28,4 @@ under the License.
28
28
 
29
29
  """
30
30
 
31
- __version__ = '0.0.1.dev01'
31
+ __version__ = '0.0.1.dev02'
File without changes
File without changes
File without changes
File without changes
File without changes