emdbva 0.0.1.dev135__tar.gz → 0.0.1.dev137__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.
- {emdbva-0.0.1.dev135/emdbva.egg-info → emdbva-0.0.1.dev137}/PKG-INFO +1 -1
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137/emdbva.egg-info}/PKG-INFO +1 -1
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/emdbva.egg-info/SOURCES.txt +1 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/mainva.py +1 -0
- emdbva-0.0.1.dev137/va/metrics/map_data_validation.py +59 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/projections.py +41 -5
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/validationanalysis.py +43 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/version.py +1 -1
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/LICENSE +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/MANIFEST.in +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/README.rst +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/emdbva.egg-info/dependency_links.txt +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/emdbva.egg-info/entry_points.txt +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/emdbva.egg-info/requires.txt +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/emdbva.egg-info/top_level.txt +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/setup.cfg +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/setup.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/__init__.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/__init__.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/bars.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/connected_percentage.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/contour_level_predicator.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/emda_mmcc.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/emringer.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/inclusion.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/overlap_percentage.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/phaserandomization.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/phenix_cc.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/phenix_mm.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/qscore.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/residue_locres.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/resmap.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/smoc.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/strudel.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/surfaces.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/metrics/threedfsc.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/preparation.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/qscores.csv +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/Checker.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/ChimeraxViews.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/MapProcessor.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/Model.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/__init__.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/cl_weights.pth +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/log_utils.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/misc.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/rescolor.py +0 -0
- {emdbva-0.0.1.dev135 → emdbva-0.0.1.dev137}/va/utils/stars.py +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import os
|
|
3
|
+
from collections import OrderedDict
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import mrcfile
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _normalise_map_input(map_input):
|
|
9
|
+
if hasattr(map_input, "fullname"):
|
|
10
|
+
return map_input.fullname
|
|
11
|
+
if hasattr(map_input, "filename"):
|
|
12
|
+
return map_input.filename
|
|
13
|
+
return str(map_input)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def validate_single_map(map_input):
|
|
17
|
+
map_path = Path(_normalise_map_input(map_input))
|
|
18
|
+
messages = io.StringIO()
|
|
19
|
+
|
|
20
|
+
result = OrderedDict([
|
|
21
|
+
("file", str(map_path)),
|
|
22
|
+
("exists", map_path.exists()),
|
|
23
|
+
("valid", False),
|
|
24
|
+
("messages", ""),
|
|
25
|
+
("error", None),
|
|
26
|
+
])
|
|
27
|
+
|
|
28
|
+
if not map_path.exists():
|
|
29
|
+
result["error"] = "File does not exist"
|
|
30
|
+
return result
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
valid = mrcfile.validate(str(map_path), print_file=messages)
|
|
34
|
+
result["valid"] = bool(valid)
|
|
35
|
+
result["messages"] = messages.getvalue().strip()
|
|
36
|
+
except Exception as exc:
|
|
37
|
+
result["error"] = str(exc)
|
|
38
|
+
result["messages"] = messages.getvalue().strip()
|
|
39
|
+
|
|
40
|
+
return result
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def run_map_data_validation(map_inputs):
|
|
44
|
+
map_results = OrderedDict()
|
|
45
|
+
|
|
46
|
+
for map_input in map_inputs:
|
|
47
|
+
if map_input is None:
|
|
48
|
+
continue
|
|
49
|
+
|
|
50
|
+
map_path = _normalise_map_input(map_input)
|
|
51
|
+
map_name = os.path.basename(map_path)
|
|
52
|
+
|
|
53
|
+
map_results[map_name] = validate_single_map(map_input)
|
|
54
|
+
|
|
55
|
+
return OrderedDict([
|
|
56
|
+
("data_validation", OrderedDict([
|
|
57
|
+
("map_data_validation", map_results)
|
|
58
|
+
]))
|
|
59
|
+
])
|
|
@@ -183,7 +183,10 @@ class Projections:
|
|
|
183
183
|
def _green_percentage(self, image_obj):
|
|
184
184
|
"""
|
|
185
185
|
image_obj can be a file path, PIL Image, or numpy array.
|
|
186
|
-
Returns
|
|
186
|
+
Returns a dictionary with:
|
|
187
|
+
- percentage: total green percentage in the whole image
|
|
188
|
+
- diff_vertical: left-half green percentage minus right-half green percentage
|
|
189
|
+
- diff_horizontal: top-half green percentage minus bottom-half green percentage
|
|
187
190
|
"""
|
|
188
191
|
if isinstance(image_obj, str):
|
|
189
192
|
img = Image.open(image_obj).convert("RGB")
|
|
@@ -193,10 +196,43 @@ class Projections:
|
|
|
193
196
|
img = Image.fromarray(image_obj).convert("RGB")
|
|
194
197
|
|
|
195
198
|
img_array = np.array(img)
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
199
|
+
green_mask = np.all(img_array == [0, 138, 0], axis=-1)
|
|
200
|
+
height, width = green_mask.shape
|
|
201
|
+
total_pixels = height * width
|
|
202
|
+
if total_pixels == 0:
|
|
203
|
+
return {
|
|
204
|
+
'percentage': 0.0,
|
|
205
|
+
'diff_vertical': 0.0,
|
|
206
|
+
'diff_horizontal': 0.0,
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
green_pixels = np.sum(green_mask)
|
|
210
|
+
proportion_green = (green_pixels / total_pixels) * 100
|
|
211
|
+
|
|
212
|
+
mid_vertical = width // 2
|
|
213
|
+
left_total = height * mid_vertical
|
|
214
|
+
right_total = height * (width - mid_vertical)
|
|
215
|
+
green_pixels_left_half = np.sum(green_mask[:, :mid_vertical])
|
|
216
|
+
green_pixels_right_half = np.sum(green_mask[:, mid_vertical:])
|
|
217
|
+
proportion_green_left_half = (green_pixels_left_half / left_total) * 100 if left_total else 0.0
|
|
218
|
+
proportion_green_right_half = (green_pixels_right_half / right_total) * 100 if right_total else 0.0
|
|
219
|
+
diff_vertical = proportion_green_left_half - proportion_green_right_half
|
|
220
|
+
|
|
221
|
+
mid_horizontal = height // 2
|
|
222
|
+
top_total = mid_horizontal * width
|
|
223
|
+
bottom_total = (height - mid_horizontal) * width
|
|
224
|
+
green_pixels_top_half = np.sum(green_mask[:mid_horizontal, :])
|
|
225
|
+
green_pixels_bottom_half = np.sum(green_mask[mid_horizontal:, :])
|
|
226
|
+
proportion_green_top_half = (green_pixels_top_half / top_total) * 100 if top_total else 0.0
|
|
227
|
+
proportion_green_bottom_half = (green_pixels_bottom_half / bottom_total) * 100 if bottom_total else 0.0
|
|
228
|
+
diff_horizontal = proportion_green_top_half - proportion_green_bottom_half
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
'percentage': round(proportion_green, 2),
|
|
232
|
+
'diff_vertical': round(diff_vertical, 2),
|
|
233
|
+
'diff_horizontal': round(diff_horizontal, 2),
|
|
234
|
+
}
|
|
235
|
+
|
|
200
236
|
|
|
201
237
|
def orthogonal_projections(self, mapin=None, workdir=None, type=None, label=''):
|
|
202
238
|
map, workdir = self.mapincheck(mapin, workdir)
|
|
@@ -77,6 +77,7 @@ from va.metrics.qscore import *
|
|
|
77
77
|
from va.metrics.inclusion import *
|
|
78
78
|
from va.metrics.connected_percentage import *
|
|
79
79
|
from va.metrics.overlap_percentage import *
|
|
80
|
+
from metrics.map_data_validation import run_map_data_validation
|
|
80
81
|
import va
|
|
81
82
|
|
|
82
83
|
try:
|
|
@@ -1158,6 +1159,48 @@ class ValidationAnalysis:
|
|
|
1158
1159
|
viewer.new_surface_view_chimerax(primary_input_map, primary_input_contour, 'mask', '',
|
|
1159
1160
|
mask_name, mask_contour)
|
|
1160
1161
|
|
|
1162
|
+
@profile_peak_memory()
|
|
1163
|
+
def map_data_validation(self):
|
|
1164
|
+
"""
|
|
1165
|
+
Validate map/header data using mrcfile.validate().
|
|
1166
|
+
|
|
1167
|
+
Output JSON structure:
|
|
1168
|
+
data_validation -> map_data_validation -> mapname -> validation results
|
|
1169
|
+
"""
|
|
1170
|
+
|
|
1171
|
+
start = timeit.default_timer()
|
|
1172
|
+
map_inputs = []
|
|
1173
|
+
|
|
1174
|
+
for attr in ("map", "rawmap", "hmodd", "hmeven"):
|
|
1175
|
+
try:
|
|
1176
|
+
value = getattr(self, attr, None)
|
|
1177
|
+
if value is not None:
|
|
1178
|
+
map_inputs.append(value)
|
|
1179
|
+
except AttributeError:
|
|
1180
|
+
pass
|
|
1181
|
+
|
|
1182
|
+
try:
|
|
1183
|
+
result_dict = run_map_data_validation(map_inputs)
|
|
1184
|
+
|
|
1185
|
+
out_json = os.path.join(
|
|
1186
|
+
self.workdir,
|
|
1187
|
+
f"{self.mapname}_map_data_validation.json"
|
|
1188
|
+
)
|
|
1189
|
+
|
|
1190
|
+
with codecs.open(out_json, "w", encoding="utf-8") as f:
|
|
1191
|
+
json.dump(result_dict, f)
|
|
1192
|
+
|
|
1193
|
+
print("Map data validation results were collected.")
|
|
1194
|
+
|
|
1195
|
+
except:
|
|
1196
|
+
err = "Map data validation error: {}.".format(sys.exc_info()[1])
|
|
1197
|
+
sys.stderr.write(err + "\n")
|
|
1198
|
+
|
|
1199
|
+
end = timeit.default_timer()
|
|
1200
|
+
print("Map data validation time: %s" % (end - start))
|
|
1201
|
+
print("------------------------------------")
|
|
1202
|
+
|
|
1203
|
+
return None
|
|
1161
1204
|
|
|
1162
1205
|
# Surface Chimera way
|
|
1163
1206
|
# def new_surface_view_chimerax(self, input_map, input_contour, type='surface', raw='', mask_map=None,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|