emdbva 0.0.1.dev150__tar.gz → 0.0.1.dev152__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 (56) hide show
  1. {emdbva-0.0.1.dev150/emdbva.egg-info → emdbva-0.0.1.dev152}/PKG-INFO +1 -1
  2. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152/emdbva.egg-info}/PKG-INFO +1 -1
  3. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/emdbva.egg-info/SOURCES.txt +1 -0
  4. emdbva-0.0.1.dev152/va/metrics/map_map_cc.py +139 -0
  5. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/preparation.py +2 -1
  6. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/prepareandrun_codon_airflow.py +2 -1
  7. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/schemas/emdb_entry_full.schema.json +1 -1
  8. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/validationanalysis.py +5 -9
  9. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/version.py +1 -1
  10. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/LICENSE +0 -0
  11. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/MANIFEST.in +0 -0
  12. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/README.rst +0 -0
  13. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/emdbva.egg-info/dependency_links.txt +0 -0
  14. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/emdbva.egg-info/entry_points.txt +0 -0
  15. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/emdbva.egg-info/requires.txt +0 -0
  16. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/emdbva.egg-info/top_level.txt +0 -0
  17. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/setup.cfg +0 -0
  18. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/setup.py +0 -0
  19. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/PATHS_codon_airflow.py +0 -0
  20. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/__init__.py +0 -0
  21. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/audit/__init__.py +0 -0
  22. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/audit/cif_revision.py +0 -0
  23. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/mainva.py +0 -0
  24. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/__init__.py +0 -0
  25. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/bars.py +0 -0
  26. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/connected_percentage.py +0 -0
  27. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/contour_level_predicator.py +0 -0
  28. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/emda_mmcc.py +0 -0
  29. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/emringer.py +0 -0
  30. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/inclusion.py +0 -0
  31. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/map_data_validation.py +0 -0
  32. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/overlap_percentage.py +0 -0
  33. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/phaserandomization.py +0 -0
  34. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/phenix_cc.py +0 -0
  35. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/phenix_mm.py +0 -0
  36. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/projections.py +0 -0
  37. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/qscore.py +0 -0
  38. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/residue_locres.py +0 -0
  39. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/resmap.py +0 -0
  40. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/smoc.py +0 -0
  41. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/strudel.py +0 -0
  42. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/surfaces.py +0 -0
  43. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/metrics/threedfsc.py +0 -0
  44. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/qscores.csv +0 -0
  45. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/schemas/__init__.py +0 -0
  46. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/schemas/loader.py +0 -0
  47. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/Checker.py +0 -0
  48. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/ChimeraxViews.py +0 -0
  49. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/MapProcessor.py +0 -0
  50. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/Model.py +0 -0
  51. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/__init__.py +0 -0
  52. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/cl_weights.pth +0 -0
  53. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/log_utils.py +0 -0
  54. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/misc.py +0 -0
  55. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/rescolor.py +0 -0
  56. {emdbva-0.0.1.dev150 → emdbva-0.0.1.dev152}/va/utils/stars.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: emdbva
3
- Version: 0.0.1.dev150
3
+ Version: 0.0.1.dev152
4
4
  Summary: CryoEM validation toolkit
5
5
  Home-page: https://test.pypi.org/project/va/
6
6
  Author: Zhe Wang
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: emdbva
3
- Version: 0.0.1.dev150
3
+ Version: 0.0.1.dev152
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 @@ va/metrics/emda_mmcc.py
26
26
  va/metrics/emringer.py
27
27
  va/metrics/inclusion.py
28
28
  va/metrics/map_data_validation.py
29
+ va/metrics/map_map_cc.py
29
30
  va/metrics/overlap_percentage.py
30
31
  va/metrics/phaserandomization.py
31
32
  va/metrics/phenix_cc.py
@@ -0,0 +1,139 @@
1
+ """PHENIX map-map correlation metric helpers."""
2
+
3
+ import os
4
+ import re
5
+ import subprocess
6
+ from distutils.spawn import find_executable
7
+
8
+
9
+ _MAP_MAP_CC_PATTERN = re.compile(
10
+ r"Map-map CC is\s+([-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?)"
11
+ )
12
+
13
+
14
+ def parse_map_map_cc_output(stdout_text):
15
+ """Extract the map-map correlation value from PHENIX output.
16
+
17
+ Args:
18
+ stdout_text (str): Combined standard output and error text from
19
+ ``phenix.map_correlations``.
20
+
21
+ Returns:
22
+ float or None: The parsed correlation, or ``None`` when the expected
23
+ result line is absent or cannot be converted to a number.
24
+ """
25
+ if not isinstance(stdout_text, str):
26
+ return None
27
+ match = _MAP_MAP_CC_PATTERN.search(stdout_text)
28
+ if match is None:
29
+ return None
30
+ try:
31
+ return float(match.group(1))
32
+ except (TypeError, ValueError):
33
+ return None
34
+
35
+
36
+ def run_map_map_cc(map1_path, map2_path, output_path, echo=True):
37
+ """Run PHENIX map-map correlation for two map files.
38
+
39
+ Args:
40
+ map1_path (str): Path to the first map.
41
+ map2_path (str): Path to the second map.
42
+ output_path (str): Directory for the PHENIX stdout diagnostic file.
43
+ echo (bool): Whether to print captured PHENIX output.
44
+
45
+ Returns:
46
+ tuple: ``(errlist, result, stdout_text)``. ``result`` is empty when
47
+ the executable, inputs, subprocess, or parser fails.
48
+ """
49
+ errlist = []
50
+ result = {}
51
+ stdout_text = ""
52
+
53
+ phenix_path = find_executable("phenix.map_correlations")
54
+ if phenix_path is None:
55
+ return ["Phenix executable phenix.map_correlations is not available."], result, stdout_text
56
+
57
+ if not os.path.isfile(map1_path):
58
+ errlist.append("Map file does not exist: {}".format(map1_path))
59
+ if not os.path.isfile(map2_path):
60
+ errlist.append("Map file does not exist: {}".format(map2_path))
61
+ if errlist:
62
+ return errlist, result, stdout_text
63
+
64
+ try:
65
+ os.makedirs(output_path, exist_ok=True)
66
+ except OSError as exc:
67
+ return ["Could not create output directory {}: {}".format(output_path, exc)], result, stdout_text
68
+
69
+ command = [phenix_path, map1_path, map2_path]
70
+ try:
71
+ completed = subprocess.run(
72
+ command,
73
+ cwd=output_path,
74
+ stdout=subprocess.PIPE,
75
+ stderr=subprocess.STDOUT,
76
+ text=True,
77
+ check=False,
78
+ )
79
+ stdout_text = completed.stdout or ""
80
+ except OSError as exc:
81
+ return ["Failed to run phenix.map_correlations: {}".format(exc)], result, stdout_text
82
+ finally:
83
+ log_path = os.path.join(output_path, "map_correlations.stdout")
84
+ try:
85
+ with open(log_path, "w", encoding="utf-8") as log_file:
86
+ log_file.write(stdout_text)
87
+ except OSError as exc:
88
+ errlist.append("Could not write {}: {}".format(log_path, exc))
89
+
90
+ if echo:
91
+ print(stdout_text, end="")
92
+ if completed.returncode != 0:
93
+ errlist.append("phenix.map_correlations exited with code {}".format(completed.returncode))
94
+ if "error" in stdout_text.lower():
95
+ errlist.extend(
96
+ line.strip() for line in stdout_text.splitlines() if "error" in line.lower()
97
+ )
98
+
99
+ correlation = parse_map_map_cc_output(stdout_text)
100
+ if correlation is None:
101
+ errlist.append("Could not parse 'Map-map CC is ...' from PHENIX output.")
102
+
103
+ if not errlist:
104
+ map1_name = os.path.basename(map1_path)
105
+ map2_name = os.path.basename(map2_path)
106
+ result = {"name": [map1_name, map2_name], "value": correlation}
107
+ return errlist, result, stdout_text
108
+
109
+
110
+ def write_map_map_cc_json(map1_path, map2_path, correlation, output_path):
111
+ """Write a successful map-map correlation result as a JSON fragment.
112
+
113
+ Args:
114
+ map1_path (str): Path to the first map.
115
+ map2_path (str): Path to the second map.
116
+ correlation (float): Parsed map-map correlation value.
117
+ output_path (str): Directory in which to write the fragment.
118
+
119
+ Returns:
120
+ str: Path to the written JSON file.
121
+ """
122
+ import json
123
+
124
+ os.makedirs(output_path, exist_ok=True)
125
+ map1_name = os.path.basename(map1_path)
126
+ map2_name = os.path.basename(map2_path)
127
+ pair_name = "{}_{}".format(map1_name, map2_name)
128
+ output_file = os.path.join(output_path, pair_name + "_cc.json")
129
+ data = {
130
+ "map_map_cc": {
131
+ pair_name: {
132
+ "names": [map1_name, map2_name],
133
+ "value": correlation,
134
+ }
135
+ }
136
+ }
137
+ with open(output_file, "w", encoding="utf-8") as handle:
138
+ json.dump(data, handle, indent=2)
139
+ return output_file
@@ -961,7 +961,8 @@ class PreParation:
961
961
 
962
962
  breakdigits = 2
963
963
  emdbidmin = 4
964
- if len(emdid) >= emdbidmin and isinstance(emdid, str):
964
+ emdbidmax = 7
965
+ if isinstance(emdid, str) and emdid.isdigit() and emdbidmin <= len(emdid) <= emdbidmax:
965
966
  topsubpath = emdid[:breakdigits]
966
967
  middlesubpath = emdid[breakdigits:-breakdigits]
967
968
  subpath = os.path.join(topsubpath, middlesubpath, emdid)
@@ -149,8 +149,9 @@ class prepareandrun():
149
149
  idsubdirs = collections.OrderedDict()
150
150
  breakdigits = 2
151
151
  emdbidmin = 4
152
+ emdbidmax = 7
152
153
  for id in emdids:
153
- if len(id) >= emdbidmin and isinstance(id, str):
154
+ if isinstance(id, str) and id.isdigit() and emdbidmin <= len(id) <= emdbidmax:
154
155
  topsubpath = id[:breakdigits]
155
156
  middlesubpath = id[breakdigits:-breakdigits]
156
157
  subpath = os.path.join(topsubpath, middlesubpath, id)
@@ -4,7 +4,7 @@
4
4
  "type": "object",
5
5
  "description": "Root object keyed by EMDB id(s), e.g. \"8117\", or map output keys, e.g. \"emd_8117.map\".",
6
6
  "patternProperties": {
7
- "^\\d{4,5}$": {
7
+ "^\\d{4,7}$": {
8
8
  "$ref": "#/definitions/EmdbEntry"
9
9
  },
10
10
  "^[A-Za-z0-9._-]+\\.map$": {
@@ -211,15 +211,11 @@ class ValidationAnalysis:
211
211
  else:
212
212
  self.cl = contourlevel
213
213
  if self.emdid:
214
- digits = [i for i in str(self.emdid)]
215
- if len(digits) == 4:
216
- subdir = '{}/{}/'.format(digits[0] + digits[1], self.emdid)
217
- self.workdir = MAP_SERVER_PATH + subdir + 'va/'
218
- elif len(digits) == 5:
219
- subdir = '{}/{}/{}/'.format(digits[0] + digits[1], digits[2], self.emdid)
220
- self.workdir = MAP_SERVER_PATH + subdir + 'va/'
221
- else:
222
- pass
214
+ emdid_text = str(self.emdid)
215
+ if not emdid_text.isdigit() or not 4 <= len(emdid_text) <= 7:
216
+ raise ValueError('EMDB IDs must contain 4 to 7 digits.')
217
+ subdir = os.path.join(emdid_text[:2], emdid_text[2:-2], emdid_text)
218
+ self.workdir = os.path.join(MAP_SERVER_PATH, subdir, 'va') + '/'
223
219
  self.queue = queue
224
220
  else:
225
221
  self.workdir = workdir
@@ -18,5 +18,5 @@ under the License.
18
18
 
19
19
  """
20
20
 
21
- __version__ = '0.0.1.dev150'
21
+ __version__ = '0.0.1.dev152'
22
22
  __em_statistics_version__ = '202505.v01'
File without changes
File without changes
File without changes
File without changes
File without changes