ambermeta 1.4.0__py3-none-any.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.
- ambermeta/__init__.py +43 -0
- ambermeta/acknowledgements.py +70 -0
- ambermeta/cli.py +2232 -0
- ambermeta/coords.py +39 -0
- ambermeta/errors.py +41 -0
- ambermeta/gui/__init__.py +13 -0
- ambermeta/gui/api/__init__.py +9 -0
- ambermeta/gui/api/core_bridge.py +1235 -0
- ambermeta/gui/api/document.py +840 -0
- ambermeta/gui/api/files.py +95 -0
- ambermeta/gui/api/routes.py +796 -0
- ambermeta/gui/api/schemas.py +542 -0
- ambermeta/gui/server.py +385 -0
- ambermeta/gui/static/assets/index-C721b_S-.css +1 -0
- ambermeta/gui/static/assets/index-KoaQq9e9.js +150 -0
- ambermeta/gui/static/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-600-normal-4D_pXhcN.woff +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-ext-600-normal-Bcila6Z-.woff +0 -0
- ambermeta/gui/static/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
- ambermeta/gui/static/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
- ambermeta/gui/static/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
- ambermeta/gui/static/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
- ambermeta/gui/static/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
- ambermeta/gui/static/assets/inter-greek-600-normal-BZpKdvQh.woff +0 -0
- ambermeta/gui/static/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
- ambermeta/gui/static/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
- ambermeta/gui/static/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
- ambermeta/gui/static/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
- ambermeta/gui/static/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
- ambermeta/gui/static/assets/inter-greek-ext-600-normal-B8X0CLgF.woff +0 -0
- ambermeta/gui/static/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
- ambermeta/gui/static/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- ambermeta/gui/static/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
- ambermeta/gui/static/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
- ambermeta/gui/static/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- ambermeta/gui/static/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
- ambermeta/gui/static/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
- ambermeta/gui/static/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
- ambermeta/gui/static/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
- ambermeta/gui/static/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
- ambermeta/gui/static/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
- ambermeta/gui/static/assets/inter-latin-ext-600-normal-CIVaiw4L.woff +0 -0
- ambermeta/gui/static/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
- ambermeta/gui/static/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
- ambermeta/gui/static/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
- ambermeta/gui/static/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
- ambermeta/gui/static/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
- ambermeta/gui/static/assets/inter-vietnamese-600-normal-BuLX-rYi.woff +0 -0
- ambermeta/gui/static/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
- ambermeta/gui/static/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
- ambermeta/gui/static/index.html +14 -0
- ambermeta/legacy_extractors/__init__.py +11 -0
- ambermeta/legacy_extractors/inpcrd.py +417 -0
- ambermeta/legacy_extractors/mdcrd.py +548 -0
- ambermeta/legacy_extractors/mdin.py +1054 -0
- ambermeta/legacy_extractors/mdout.py +677 -0
- ambermeta/legacy_extractors/prmtop.py +647 -0
- ambermeta/lineages.py +700 -0
- ambermeta/logging_config.py +150 -0
- ambermeta/manifest.py +196 -0
- ambermeta/mdout_header.py +372 -0
- ambermeta/methods_summary.py +1630 -0
- ambermeta/netcdf_backend.py +93 -0
- ambermeta/parse_cache.py +155 -0
- ambermeta/parsers/__init__.py +18 -0
- ambermeta/parsers/inpcrd.py +31 -0
- ambermeta/parsers/mdcrd.py +31 -0
- ambermeta/parsers/mdin.py +31 -0
- ambermeta/parsers/mdout.py +31 -0
- ambermeta/parsers/prmtop.py +32 -0
- ambermeta/protocol.py +3471 -0
- ambermeta/recorded_inputs.py +128 -0
- ambermeta/roles.py +104 -0
- ambermeta/run_order.py +248 -0
- ambermeta/simulation.py +546 -0
- ambermeta/systems.py +112 -0
- ambermeta/topology_pool.py +68 -0
- ambermeta/utils.py +106 -0
- ambermeta-1.4.0.dist-info/METADATA +438 -0
- ambermeta-1.4.0.dist-info/RECORD +109 -0
- ambermeta-1.4.0.dist-info/WHEEL +5 -0
- ambermeta-1.4.0.dist-info/entry_points.txt +2 -0
- ambermeta-1.4.0.dist-info/licenses/LICENSE +101 -0
- ambermeta-1.4.0.dist-info/top_level.txt +1 -0
ambermeta/__init__.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""AmberMeta - Simulation provenance extraction for AMBER molecular dynamics."""
|
|
2
|
+
|
|
3
|
+
__version__ = "1.4.0"
|
|
4
|
+
|
|
5
|
+
from ambermeta.protocol import (
|
|
6
|
+
SimulationProtocol,
|
|
7
|
+
SimulationStage,
|
|
8
|
+
ProtocolBuilder,
|
|
9
|
+
auto_discover,
|
|
10
|
+
detect_numeric_sequences,
|
|
11
|
+
infer_stage_role_from_content,
|
|
12
|
+
auto_detect_restart_chain,
|
|
13
|
+
smart_group_files,
|
|
14
|
+
)
|
|
15
|
+
from ambermeta.errors import AmberMetaError, FileLoadError
|
|
16
|
+
# `lineages` the function is deliberately NOT re-exported: binding that name here would
|
|
17
|
+
# overwrite the `ambermeta.lineages` submodule attribute, and `import ambermeta.lineages
|
|
18
|
+
# as L` would then hand the caller the function instead of the module. Import it as
|
|
19
|
+
# `from ambermeta.lineages import lineages` at the call site.
|
|
20
|
+
from ambermeta.lineages import (
|
|
21
|
+
UNTAGGED,
|
|
22
|
+
infer_lineages_from_layout,
|
|
23
|
+
is_multi_lineage,
|
|
24
|
+
members,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"__version__",
|
|
29
|
+
"AmberMetaError",
|
|
30
|
+
"FileLoadError",
|
|
31
|
+
"UNTAGGED",
|
|
32
|
+
"infer_lineages_from_layout",
|
|
33
|
+
"is_multi_lineage",
|
|
34
|
+
"members",
|
|
35
|
+
"SimulationProtocol",
|
|
36
|
+
"SimulationStage",
|
|
37
|
+
"ProtocolBuilder",
|
|
38
|
+
"auto_discover",
|
|
39
|
+
"detect_numeric_sequences",
|
|
40
|
+
"infer_stage_role_from_content",
|
|
41
|
+
"auto_detect_restart_chain",
|
|
42
|
+
"smart_group_files",
|
|
43
|
+
]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""Findings the user has settled: matching a manifest's `acknowledged` list to a report.
|
|
2
|
+
|
|
3
|
+
A finding could only be dismissed in the GUI, which recorded nothing, so the same missing
|
|
4
|
+
run came back on every Validate, failed every `--strict` run and sat in the methods summary
|
|
5
|
+
with no word of explanation. An acknowledgement is the user's answer, kept in the manifest:
|
|
6
|
+
the finding's exact text and a note saying why it stands.
|
|
7
|
+
|
|
8
|
+
The text is the `title: evidence` line `validate` prints for a card, and the message for a
|
|
9
|
+
replica-coherence warning, so it can be copied from the terminal. Matching on the exact
|
|
10
|
+
text is deliberate: a finding whose text changes (new data, a rerun, new wording) is a new
|
|
11
|
+
finding and shows again rather than staying hidden under an old note, and an
|
|
12
|
+
acknowledgement that matches nothing any more is reported as stale.
|
|
13
|
+
|
|
14
|
+
What can be acknowledged is what `--strict` fails on: the problem cards below and coherence
|
|
15
|
+
warnings. A coherence *error* (members of different sizes, or minimisation beside dynamics)
|
|
16
|
+
is a category error that fails with or without `--strict`, and no note changes that.
|
|
17
|
+
|
|
18
|
+
Core, not GUI: the CLI and the GUI's validate both reach it through
|
|
19
|
+
`core_bridge.validate_simulation`.
|
|
20
|
+
"""
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from typing import Any, Dict, Iterable, List
|
|
24
|
+
|
|
25
|
+
#: The suggestion kinds that are problems (the findings block, `--strict`), as opposed to
|
|
26
|
+
#: `[applied]` inferences.
|
|
27
|
+
PROBLEM_KINDS = ("continuity_gap", "missing_run",
|
|
28
|
+
"step_check", "unfinished_run", "input_mismatch")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def finding_text(item: Dict[str, Any]) -> str:
|
|
32
|
+
"""The text a finding is known by: `title: evidence`, or a coherence message."""
|
|
33
|
+
if "title" not in item and "message" in item:
|
|
34
|
+
return str(item["message"])
|
|
35
|
+
return f"{item.get('title')}: {item.get('evidence')}"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def apply_acknowledgements(report: Dict[str, Any], acknowledged: Iterable[Any]) -> None:
|
|
39
|
+
"""Mark each acknowledged finding in `report`, and list what matched and what did not.
|
|
40
|
+
|
|
41
|
+
A matching problem card or coherence warning gains `"acknowledged": <note>`.
|
|
42
|
+
`report["acknowledged"]` lists the acknowledgements that matched a finding and
|
|
43
|
+
`report["stale_acknowledgements"]` the ones that matched none, both as
|
|
44
|
+
`{"finding", "note"}` in manifest order.
|
|
45
|
+
"""
|
|
46
|
+
entries = list(acknowledged or [])
|
|
47
|
+
notes = {a.finding: a.note for a in entries}
|
|
48
|
+
matched = set()
|
|
49
|
+
for card in report.get("suggestions") or []:
|
|
50
|
+
if card.get("kind") in PROBLEM_KINDS:
|
|
51
|
+
text = finding_text(card)
|
|
52
|
+
if text in notes:
|
|
53
|
+
card["acknowledged"] = notes[text]
|
|
54
|
+
matched.add(text)
|
|
55
|
+
for finding in report.get("coherence") or []:
|
|
56
|
+
if finding.get("severity") == "warning":
|
|
57
|
+
text = finding_text(finding)
|
|
58
|
+
if text in notes:
|
|
59
|
+
finding["acknowledged"] = notes[text]
|
|
60
|
+
matched.add(text)
|
|
61
|
+
report["acknowledged"] = [{"finding": a.finding, "note": a.note}
|
|
62
|
+
for a in entries if a.finding in matched]
|
|
63
|
+
report["stale_acknowledgements"] = [{"finding": a.finding, "note": a.note}
|
|
64
|
+
for a in entries if a.finding not in matched]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def open_problems(report: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
68
|
+
"""The problem cards nobody has acknowledged."""
|
|
69
|
+
return [s for s in (report.get("suggestions") or [])
|
|
70
|
+
if s.get("kind") in PROBLEM_KINDS and not s.get("acknowledged")]
|