ambermeta 1.4.0__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 (201) hide show
  1. ambermeta-1.4.0/LICENSE +101 -0
  2. ambermeta-1.4.0/PKG-INFO +438 -0
  3. ambermeta-1.4.0/README.md +379 -0
  4. ambermeta-1.4.0/ambermeta/__init__.py +43 -0
  5. ambermeta-1.4.0/ambermeta/acknowledgements.py +70 -0
  6. ambermeta-1.4.0/ambermeta/cli.py +2232 -0
  7. ambermeta-1.4.0/ambermeta/coords.py +39 -0
  8. ambermeta-1.4.0/ambermeta/errors.py +41 -0
  9. ambermeta-1.4.0/ambermeta/gui/__init__.py +13 -0
  10. ambermeta-1.4.0/ambermeta/gui/api/__init__.py +9 -0
  11. ambermeta-1.4.0/ambermeta/gui/api/core_bridge.py +1235 -0
  12. ambermeta-1.4.0/ambermeta/gui/api/document.py +840 -0
  13. ambermeta-1.4.0/ambermeta/gui/api/files.py +95 -0
  14. ambermeta-1.4.0/ambermeta/gui/api/routes.py +796 -0
  15. ambermeta-1.4.0/ambermeta/gui/api/schemas.py +542 -0
  16. ambermeta-1.4.0/ambermeta/gui/server.py +385 -0
  17. ambermeta-1.4.0/ambermeta/gui/static/assets/index-C721b_S-.css +1 -0
  18. ambermeta-1.4.0/ambermeta/gui/static/assets/index-KoaQq9e9.js +150 -0
  19. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
  20. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
  21. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
  22. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
  23. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-600-normal-4D_pXhcN.woff +0 -0
  24. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
  25. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
  26. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
  27. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
  28. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
  29. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-ext-600-normal-Bcila6Z-.woff +0 -0
  30. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
  31. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
  32. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
  33. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
  34. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
  35. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-600-normal-BZpKdvQh.woff +0 -0
  36. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
  37. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
  38. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
  39. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
  40. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
  41. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-ext-600-normal-B8X0CLgF.woff +0 -0
  42. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
  43. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
  44. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
  45. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
  46. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
  47. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
  48. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
  49. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
  50. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
  51. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
  52. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
  53. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-ext-600-normal-CIVaiw4L.woff +0 -0
  54. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
  55. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
  56. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
  57. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
  58. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
  59. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-vietnamese-600-normal-BuLX-rYi.woff +0 -0
  60. ambermeta-1.4.0/ambermeta/gui/static/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
  61. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  62. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  63. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  64. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  65. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  66. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  67. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  68. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  69. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  70. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  71. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  72. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  73. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  74. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  75. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  76. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  77. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  78. ambermeta-1.4.0/ambermeta/gui/static/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  79. ambermeta-1.4.0/ambermeta/gui/static/index.html +14 -0
  80. ambermeta-1.4.0/ambermeta/legacy_extractors/__init__.py +11 -0
  81. ambermeta-1.4.0/ambermeta/legacy_extractors/inpcrd.py +417 -0
  82. ambermeta-1.4.0/ambermeta/legacy_extractors/mdcrd.py +548 -0
  83. ambermeta-1.4.0/ambermeta/legacy_extractors/mdin.py +1054 -0
  84. ambermeta-1.4.0/ambermeta/legacy_extractors/mdout.py +677 -0
  85. ambermeta-1.4.0/ambermeta/legacy_extractors/prmtop.py +647 -0
  86. ambermeta-1.4.0/ambermeta/lineages.py +700 -0
  87. ambermeta-1.4.0/ambermeta/logging_config.py +150 -0
  88. ambermeta-1.4.0/ambermeta/manifest.py +196 -0
  89. ambermeta-1.4.0/ambermeta/mdout_header.py +372 -0
  90. ambermeta-1.4.0/ambermeta/methods_summary.py +1630 -0
  91. ambermeta-1.4.0/ambermeta/netcdf_backend.py +93 -0
  92. ambermeta-1.4.0/ambermeta/parse_cache.py +155 -0
  93. ambermeta-1.4.0/ambermeta/parsers/__init__.py +18 -0
  94. ambermeta-1.4.0/ambermeta/parsers/inpcrd.py +31 -0
  95. ambermeta-1.4.0/ambermeta/parsers/mdcrd.py +31 -0
  96. ambermeta-1.4.0/ambermeta/parsers/mdin.py +31 -0
  97. ambermeta-1.4.0/ambermeta/parsers/mdout.py +31 -0
  98. ambermeta-1.4.0/ambermeta/parsers/prmtop.py +32 -0
  99. ambermeta-1.4.0/ambermeta/protocol.py +3471 -0
  100. ambermeta-1.4.0/ambermeta/recorded_inputs.py +128 -0
  101. ambermeta-1.4.0/ambermeta/roles.py +104 -0
  102. ambermeta-1.4.0/ambermeta/run_order.py +248 -0
  103. ambermeta-1.4.0/ambermeta/simulation.py +546 -0
  104. ambermeta-1.4.0/ambermeta/systems.py +112 -0
  105. ambermeta-1.4.0/ambermeta/topology_pool.py +68 -0
  106. ambermeta-1.4.0/ambermeta/utils.py +106 -0
  107. ambermeta-1.4.0/ambermeta.egg-info/PKG-INFO +438 -0
  108. ambermeta-1.4.0/ambermeta.egg-info/SOURCES.txt +199 -0
  109. ambermeta-1.4.0/ambermeta.egg-info/dependency_links.txt +1 -0
  110. ambermeta-1.4.0/ambermeta.egg-info/entry_points.txt +2 -0
  111. ambermeta-1.4.0/ambermeta.egg-info/requires.txt +43 -0
  112. ambermeta-1.4.0/ambermeta.egg-info/top_level.txt +1 -0
  113. ambermeta-1.4.0/pyproject.toml +127 -0
  114. ambermeta-1.4.0/setup.cfg +4 -0
  115. ambermeta-1.4.0/tests/test_bugfixes.py +24 -0
  116. ambermeta-1.4.0/tests/test_clear_verdicts_and_wording.py +162 -0
  117. ambermeta-1.4.0/tests/test_cli_audit_fixes.py +161 -0
  118. ambermeta-1.4.0/tests/test_cli_color_and_format.py +52 -0
  119. ambermeta-1.4.0/tests/test_cli_completion.py +40 -0
  120. ambermeta-1.4.0/tests/test_cli_discover.py +214 -0
  121. ambermeta-1.4.0/tests/test_cli_export.py +82 -0
  122. ambermeta-1.4.0/tests/test_cli_export_env_and_init_name.py +67 -0
  123. ambermeta-1.4.0/tests/test_cli_gui_launch.py +51 -0
  124. ambermeta-1.4.0/tests/test_cli_init.py +100 -0
  125. ambermeta-1.4.0/tests/test_cli_init_v2.py +43 -0
  126. ambermeta-1.4.0/tests/test_cli_output_encoding.py +92 -0
  127. ambermeta-1.4.0/tests/test_cli_path_and_output.py +160 -0
  128. ambermeta-1.4.0/tests/test_cli_plan.py +130 -0
  129. ambermeta-1.4.0/tests/test_cli_plan_findings.py +126 -0
  130. ambermeta-1.4.0/tests/test_cli_plan_v2.py +232 -0
  131. ambermeta-1.4.0/tests/test_cli_protocol_output.py +97 -0
  132. ambermeta-1.4.0/tests/test_cli_totals_delta.py +187 -0
  133. ambermeta-1.4.0/tests/test_cli_validate.py +83 -0
  134. ambermeta-1.4.0/tests/test_cli_validate_manifest.py +80 -0
  135. ambermeta-1.4.0/tests/test_cli_validate_unreadable.py +76 -0
  136. ambermeta-1.4.0/tests/test_continuity_new_velocities.py +130 -0
  137. ambermeta-1.4.0/tests/test_continuity_p1.py +794 -0
  138. ambermeta-1.4.0/tests/test_coords.py +27 -0
  139. ambermeta-1.4.0/tests/test_core_hardening.py +461 -0
  140. ambermeta-1.4.0/tests/test_corpus_fixes.py +227 -0
  141. ambermeta-1.4.0/tests/test_crd_parsed_by_content.py +47 -0
  142. ambermeta-1.4.0/tests/test_discover_record_chain.py +217 -0
  143. ambermeta-1.4.0/tests/test_gap_zero_is_stated.py +86 -0
  144. ambermeta-1.4.0/tests/test_gui_api_sim.py +887 -0
  145. ambermeta-1.4.0/tests/test_gui_bulk_lineage.py +254 -0
  146. ambermeta-1.4.0/tests/test_gui_concurrent_writeback.py +120 -0
  147. ambermeta-1.4.0/tests/test_gui_core_bridge.py +86 -0
  148. ambermeta-1.4.0/tests/test_gui_core_bridge_sim.py +534 -0
  149. ambermeta-1.4.0/tests/test_gui_crd_typing.py +47 -0
  150. ambermeta-1.4.0/tests/test_gui_document.py +656 -0
  151. ambermeta-1.4.0/tests/test_gui_files.py +45 -0
  152. ambermeta-1.4.0/tests/test_gui_proposal.py +225 -0
  153. ambermeta-1.4.0/tests/test_gui_relative_paths.py +91 -0
  154. ambermeta-1.4.0/tests/test_gui_reorder_recorded_links.py +92 -0
  155. ambermeta-1.4.0/tests/test_gui_save_format.py +65 -0
  156. ambermeta-1.4.0/tests/test_gui_save_target.py +117 -0
  157. ambermeta-1.4.0/tests/test_gui_schemas_sim.py +35 -0
  158. ambermeta-1.4.0/tests/test_gui_security.py +272 -0
  159. ambermeta-1.4.0/tests/test_gui_validate_coalescing.py +91 -0
  160. ambermeta-1.4.0/tests/test_lineage_backcompat.py +367 -0
  161. ambermeta-1.4.0/tests/test_lineage_coherence.py +695 -0
  162. ambermeta-1.4.0/tests/test_lineage_plumbing.py +151 -0
  163. ambermeta-1.4.0/tests/test_lineage_totals.py +322 -0
  164. ambermeta-1.4.0/tests/test_lineages.py +527 -0
  165. ambermeta-1.4.0/tests/test_manifest.py +27 -0
  166. ambermeta-1.4.0/tests/test_mdcrd_truncated.py +112 -0
  167. ambermeta-1.4.0/tests/test_mdin_without_cntrl.py +55 -0
  168. ambermeta-1.4.0/tests/test_mdout_completion.py +191 -0
  169. ambermeta-1.4.0/tests/test_mdout_header.py +201 -0
  170. ambermeta-1.4.0/tests/test_methods_summary.py +544 -0
  171. ambermeta-1.4.0/tests/test_methods_summary_markdown.py +173 -0
  172. ambermeta-1.4.0/tests/test_netcdf_text_attributes.py +37 -0
  173. ambermeta-1.4.0/tests/test_netcdf_thread_safety.py +182 -0
  174. ambermeta-1.4.0/tests/test_parser_fixes.py +249 -0
  175. ambermeta-1.4.0/tests/test_parsers_smoke.py +45 -0
  176. ambermeta-1.4.0/tests/test_prior_summary_unreadable.py +57 -0
  177. ambermeta-1.4.0/tests/test_prmtop_solute.py +32 -0
  178. ambermeta-1.4.0/tests/test_protocol.py +690 -0
  179. ambermeta-1.4.0/tests/test_protocol_begin_time_overflow.py +259 -0
  180. ambermeta-1.4.0/tests/test_protocol_fresh_start_clock.py +228 -0
  181. ambermeta-1.4.0/tests/test_protocol_queued.py +118 -0
  182. ambermeta-1.4.0/tests/test_protocol_sample_data.py +77 -0
  183. ambermeta-1.4.0/tests/test_protocol_totals_from_mdout.py +302 -0
  184. ambermeta-1.4.0/tests/test_protocol_unusable_mdout.py +126 -0
  185. ambermeta-1.4.0/tests/test_readable_manifest.py +137 -0
  186. ambermeta-1.4.0/tests/test_recorded_checks.py +337 -0
  187. ambermeta-1.4.0/tests/test_robustness.py +170 -0
  188. ambermeta-1.4.0/tests/test_roles.py +112 -0
  189. ambermeta-1.4.0/tests/test_scan_recorded_order.py +205 -0
  190. ambermeta-1.4.0/tests/test_scan_self_restart.py +183 -0
  191. ambermeta-1.4.0/tests/test_scan_stem_collision.py +61 -0
  192. ambermeta-1.4.0/tests/test_separate_systems.py +185 -0
  193. ambermeta-1.4.0/tests/test_sequence_key.py +67 -0
  194. ambermeta-1.4.0/tests/test_settle_findings.py +255 -0
  195. ambermeta-1.4.0/tests/test_simulation.py +634 -0
  196. ambermeta-1.4.0/tests/test_starting_structure_evidence.py +42 -0
  197. ambermeta-1.4.0/tests/test_topology_pool.py +48 -0
  198. ambermeta-1.4.0/tests/test_unknown_input_source.py +107 -0
  199. ambermeta-1.4.0/tests/test_unreadable_global_prmtop.py +39 -0
  200. ambermeta-1.4.0/tests/test_unstated_mdout_timestep.py +54 -0
  201. ambermeta-1.4.0/tests/test_validation_same_name_steps.py +41 -0
@@ -0,0 +1,101 @@
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: Dr. Michele Bonus
6
+ Licensed Work: AmberMeta
7
+ The Licensed Work is (c) 2026 Dr. Michele Bonus.
8
+ All rights reserved.
9
+ Change Date: 2029-03-26
10
+ Change License: MIT
11
+
12
+ For information about alternative licensing arrangements for the Licensed Work,
13
+ please contact the Licensor directly.
14
+
15
+ -----------------------------------------------------------------------------
16
+
17
+ Business Source License 1.1
18
+
19
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
20
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
21
+
22
+ -----------------------------------------------------------------------------
23
+
24
+ Terms
25
+
26
+ The Licensor hereby grants you the right to copy, modify, create derivative
27
+ works, redistribute, and make non-production use of the Licensed Work. The
28
+ Licensor may make an Additional Use Grant, above, permitting limited production
29
+ use.
30
+
31
+ Effective on the Change Date, or the fourth anniversary of the first publicly
32
+ available distribution of a specific version of the Licensed Work under this
33
+ License, whichever comes first, the Licensor hereby grants you rights under
34
+ the terms of the Change License, and the rights granted in the paragraph above
35
+ terminate.
36
+
37
+ If your use of the Licensed Work does not comply with the requirements
38
+ currently in effect as described in this file, you must purchase a commercial
39
+ license from the Licensor, its affiliated entities, or authorized resellers, or
40
+ you must refrain from using the Licensed Work.
41
+
42
+ All copies of the original and modified Licensed Work, and derivative works of
43
+ the Licensed Work, are subject to this License. This License applies separately
44
+ for each version of the Licensed Work, and the Change Date may vary for each
45
+ version of the Licensed Work released by the Licensor.
46
+
47
+ You must conspicuously display this License on each original or modified copy
48
+ of the Licensed Work. If you receive the original or modified Licensed Work
49
+ from a third party, the terms and conditions set forth in this License apply
50
+ to your use of that work.
51
+
52
+ Any use of the Licensed Work in violation of this License will automatically
53
+ terminate your rights under this License for the current and all other versions
54
+ of the Licensed Work.
55
+
56
+ This License does not grant you any right in any trademark or logo of the
57
+ Licensor or its affiliates (provided that you may use a trademark or logo of
58
+ the Licensor as expressly required by this License).
59
+
60
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
61
+ AN "AS IS" BASIS. THE LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
62
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
63
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
64
+
65
+ MariaDB hereby grants you permission to use this License's text to license your
66
+ works, and to refer to it using the trademark "Business Source License", as
67
+ long as you comply with the Covenants of Licensor below.
68
+
69
+ Covenants of Licensor
70
+
71
+ In consideration of the right to use this License's text and the "Business
72
+ Source License" name and trademark, Licensor covenants to MariaDB, and to all
73
+ who receive the Licensed Work under this License, to honor and faithfully
74
+ comply with the following provisions:
75
+
76
+ 1. Licensor will specify as the Change License the GPL Version 2.0 or any
77
+ later version, or a license that is compatible with GPL Version 2.0 or a
78
+ later version, where "compatible" means that software provided under the
79
+ Change License can be included in a program with software provided under
80
+ GPL Version 2.0 or a later version. Licensor may specify additional Change
81
+ Licenses without limitation.
82
+
83
+ 2. Licensor will either: (a) specify an additional grant of rights to use
84
+ that does not impose any additional restriction on the right granted in this
85
+ License, as the Additional Use Grant; or (b) insert the text "None" in the
86
+ space of the Additional Use Grant.
87
+
88
+ 3. Licensor will specify a Change Date.
89
+
90
+ 4. Licensor will not modify this License in any other way.
91
+
92
+ -----------------------------------------------------------------------------
93
+
94
+ Notice
95
+
96
+ The Business Source License (this document, or the "License") is not an Open
97
+ Source license. However, the Licensed Work will eventually be made available
98
+ under an Open Source License, as stated in this License.
99
+
100
+ For more information on the use of the Business Source License, please visit
101
+ https://mariadb.com/bsl-faq-adopting/
@@ -0,0 +1,438 @@
1
+ Metadata-Version: 2.4
2
+ Name: ambermeta
3
+ Version: 1.4.0
4
+ Summary: Simulation provenance extraction utilities for AMBER molecular dynamics runs.
5
+ Author: AmberMeta Contributors
6
+ License-Expression: BUSL-1.1
7
+ Project-URL: Homepage, https://github.com/CPCLab/ambermeta
8
+ Project-URL: Documentation, https://github.com/CPCLab/ambermeta#readme
9
+ Project-URL: Repository, https://github.com/CPCLab/ambermeta.git
10
+ Project-URL: Issues, https://github.com/CPCLab/ambermeta/issues
11
+ Keywords: amber,molecular-dynamics,simulation,provenance,metadata,bioinformatics
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
22
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Provides-Extra: netcdf
27
+ Requires-Dist: netCDF4>=1.6; extra == "netcdf"
28
+ Requires-Dist: scipy>=1.8; extra == "netcdf"
29
+ Requires-Dist: numpy>=1.23; extra == "netcdf"
30
+ Provides-Extra: gui
31
+ Requires-Dist: fastapi>=0.100.0; extra == "gui"
32
+ Requires-Dist: uvicorn>=0.23.0; extra == "gui"
33
+ Requires-Dist: websockets>=11.0; extra == "gui"
34
+ Requires-Dist: python-multipart>=0.0.6; extra == "gui"
35
+ Requires-Dist: pyyaml>=6.0; extra == "gui"
36
+ Provides-Extra: yaml
37
+ Requires-Dist: pyyaml>=6.0; extra == "yaml"
38
+ Provides-Extra: toml
39
+ Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "toml"
40
+ Provides-Extra: tests
41
+ Requires-Dist: pytest>=7; extra == "tests"
42
+ Requires-Dist: pytest-cov>=4.0; extra == "tests"
43
+ Requires-Dist: httpx>=0.24; extra == "tests"
44
+ Provides-Extra: dev
45
+ Requires-Dist: black>=23.0; extra == "dev"
46
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
47
+ Requires-Dist: mypy>=1.0; extra == "dev"
48
+ Provides-Extra: all
49
+ Requires-Dist: netCDF4>=1.6; extra == "all"
50
+ Requires-Dist: scipy>=1.8; extra == "all"
51
+ Requires-Dist: numpy>=1.23; extra == "all"
52
+ Requires-Dist: fastapi>=0.100.0; extra == "all"
53
+ Requires-Dist: uvicorn>=0.23.0; extra == "all"
54
+ Requires-Dist: websockets>=11.0; extra == "all"
55
+ Requires-Dist: python-multipart>=0.0.6; extra == "all"
56
+ Requires-Dist: pyyaml>=6.0; extra == "all"
57
+ Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "all"
58
+ Dynamic: license-file
59
+
60
+ <p align="center">
61
+ <picture>
62
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/CPCLab/ambermeta/main/docs/assets/logo/ambermeta_logo_dark.svg">
63
+ <img src="https://raw.githubusercontent.com/CPCLab/ambermeta/main/docs/assets/logo/ambermeta_logo.svg" alt="AmberMeta" width="520">
64
+ </picture>
65
+ </p>
66
+
67
+ # AmberMeta
68
+
69
+ **AmberMeta is a provenance engine for AMBER molecular-dynamics workflows. It reads the files a run already produced — `prmtop`, `mdin`, `mdout`, `mdcrd`, `inpcrd` — reconstructs the simulation behind them as a `Simulation → Phase → Step` document, validates that the steps actually connect, and exports a machine-readable record you can drop into a methods section or a downstream pipeline.**
70
+
71
+ You point it at a directory (or a manifest), and it answers the questions that are tedious to answer by hand: *What was actually run? In what order? Do the restarts line up? Is any topology hydrogen-mass-repartitioned? What were the ensemble, thermostat, barostat, and cutoff? Did the run finish? Is a member of a numbered sequence missing?*
72
+
73
+ - **Version:** 1.4.0 · **Python:** 3.9+ · **License:** BUSL-1.1
74
+ - **Repository:** <https://github.com/CPCLab/ambermeta>
75
+
76
+ ---
77
+
78
+ ## 1. The model
79
+
80
+ A **Simulation** is the whole document. It owns a **topology pool** (one or more prmtops, each labeled `normal` or `hmr`) and a single **starting structure**. A **Phase** is a named, role-bearing container — minimization / heating / equilibration / production — that groups related runs. A **Step** is one actual run: it binds one topology from the pool, names its `mdin`/`mdout`/`mdcrd`, and declares where its input coordinates come from (the Simulation's starting structure, a previous step's output restart, or an explicit path).
81
+
82
+ That last part is what makes continuity checking exact: AmberMeta follows the declared input-coordinate chain from step to step, compares each hand-off's timing against a frame-interval-based tolerance, and flags both broken continuity and holes in numbered sequences (`prod_0001, prod_0002, prod_0004, …` → `0003` is missing) as first-class findings — not as an afterthought bolted onto a flat stage list.
83
+
84
+ A Step can also carry a **`lineage`** tag naming which member of a parallel set it belongs to — a replica, a branch off a shared restart, a pose. Steps sharing a tag are one member; untagged means the single implicit member, and a document that declares none behaves exactly as it always did. Every chaining and continuity path honours the tag: replicas are chained and measured within themselves, so a set of replicas is no longer reported as one long serial run.
85
+
86
+ | Capability | What you get |
87
+ |---|---|
88
+ | **Metadata extraction** | Per-file parsers for topology, input, output, trajectory, and restart files. Atom/residue counts, box geometry, density, solvent model, HMR status, ensemble, thermostat/barostat, cutoff, SHAKE, completion status, and streaming thermodynamic statistics (temperature/pressure/density/energy, mean ± σ). |
89
+ | **Simulation discovery** | Scans a directory into a `Simulation` draft: builds the topology pool, detects numbered sequences, infers each step's role (minimization / heating / equilibration / production) from content then path, and resolves the input-coordinate chain — all as explainable, one-click-undoable suggestions. Where the layout names members (`rep1/`, `rep2/`, … running the same runs) each is tagged and chained separately; an ambiguous layout is left untagged rather than guessed at. |
90
+ | **Continuity & sequence validation** | Per-run checks (atom-count agreement across a run's files, mdin against mdout, a time step above 2 fs on a topology with standard hydrogen masses, a run that did not finish, and the input coordinates a step declares against the INPCRD its mdout records) and whole-simulation checks (timing gaps between chained steps against a tolerance, missing members of a numbered run), with configurable per-step tolerances. The whole-simulation checks are scoped per lineage, so a replica that stopped early is named instead of pooled with its siblings, and one member's first run is never measured against another member's last. |
91
+ | **Manifest format v2** | One reader and one writer for the `Simulation → Phase → Step` document, in JSON or YAML. The GUI and CLI share the same document. |
92
+ | **Reproducibility exports** | A full simulation/protocol summary (JSON/YAML); a methods summary, a compact digest of it for writing a Methods section (settings stated once per phase with their source and the runs that differ, the system by residue class, replicas, findings, and what no run file records); and a per-stage statistics CSV. |
93
+
94
+ Two interfaces sit on one shared core:
95
+
96
+ | Surface | Use it when | Entry point |
97
+ |---|---|---|
98
+ | **CLI** | Scripting, CI, SSH/cluster, headless batch processing | `ambermeta <command>` |
99
+ | **GUI** | Interactively assembling or auditing a manifest in a browser | `ambermeta gui` |
100
+
101
+ > The CLI is the complete, headless interface — everything AmberMeta does is reachable without the GUI. The GUI is an optional, offline, localhost-only manifest editor built on the same engine (it imports the core through a single bridge module, `ambermeta.gui.api.core_bridge`; it does not re-implement any logic). There is no separate TUI.
102
+
103
+ ---
104
+
105
+ ## 2. Install
106
+
107
+ AmberMeta requires **Python 3.9+**. The base install is dependency-light; optional features live behind extras.
108
+
109
+ ```bash
110
+ python -m pip install ambermeta # from PyPI
111
+ python -m pip install "ambermeta[all]" # with all runtime features
112
+ ```
113
+
114
+ From a clone of the repository, for development:
115
+
116
+ ```bash
117
+ python -m pip install -e .
118
+ ```
119
+
120
+ | Extra | Pulls in | Enables |
121
+ |---|---|---|
122
+ | _(base)_ | stdlib only | All parsers except NetCDF; JSON manifests; full CLI |
123
+ | `netcdf` | `netCDF4`, `scipy`, `numpy` | NetCDF trajectory (`.nc`) and NetCDF restart (`.ncrst`) parsing |
124
+ | `gui` | `fastapi`, `uvicorn`, `websockets`, `python-multipart`, `pyyaml` | The browser GUI (`ambermeta gui`) |
125
+ | `yaml` | `pyyaml` | YAML manifests |
126
+ | `toml` | `tomli` (only on Python < 3.11) | Nothing any more — AmberMeta neither reads nor writes TOML. Retained so an existing `pip install ambermeta[toml]` keeps resolving |
127
+ | `tests` | `pytest`, `pytest-cov`, `httpx` | Running the test suite |
128
+ | `dev` | `black`, `ruff`, `mypy` | Linting and type checking |
129
+ | `all` | everything runtime (netcdf + gui + yaml + toml) | The full feature set (does **not** include `tests`/`dev`) |
130
+
131
+ ```bash
132
+ python -m pip install -e ".[all]" # all runtime features
133
+ python -m pip install -e ".[gui]" # just the GUI
134
+ ```
135
+
136
+ > ⚠️ The GUI ships a **pre-built, offline frontend bundle** under `ambermeta/gui/static/`. No Node.js, no build step, and no CDN at runtime — it works on an air-gapped workstation. The `gui` extra only adds the Python web server.
137
+
138
+ ---
139
+
140
+ ## 3. Sixty-second quickstart (CLI)
141
+
142
+ Every command below is run against the sample data in `tests/data/amber/md_test_files/` — a real 64,528-atom glycoprotein system with a five-run NPT production sequence (`ntp_prod_0001` … `ntp_prod_0005`).
143
+
144
+ **Discover the directory into a Simulation draft and save it as a v2 manifest:**
145
+
146
+ ```text
147
+ $ ambermeta discover tests/data/amber/md_test_files --write sim.yaml
148
+
149
+ Simulation summary
150
+ ==================
151
+ Topologies (pool): 1
152
+ - top_CH3L1_HUMAN_6NAG [normal] CH3L1_HUMAN_6NAG.top
153
+ Starting structure: ntp_prod_0000.rst
154
+ Phases: 1
155
+
156
+ Phase: Production [production]
157
+ - ntp_prod_0001 from the starting structure
158
+ - ntp_prod_0002 from ntp_prod_0001
159
+ - ntp_prod_0003 from ntp_prod_0002
160
+ - ntp_prod_0004 from ntp_prod_0003
161
+ - ntp_prod_0005 from ntp_prod_0004
162
+
163
+ Suggestions:
164
+ - [applied] ntp_prod_0000.rst set as the starting structure
165
+ - [applied] Phase roles inferred from file content/names
166
+
167
+ Wrote v2 draft manifest: sim.yaml (yaml)
168
+ NOTE: the manifest is not in /abs/path/tests/data/amber/md_test_files, so its file paths are written relative to its own directory (/abs/path), where `validate --manifest` and `plan -m` read them.
169
+ ```
170
+
171
+ **Inspect a single file in depth:**
172
+
173
+ ```text
174
+ $ ambermeta info tests/data/amber/md_test_files/CH3L1_HUMAN_6NAG.top
175
+
176
+ File Information: CH3L1_HUMAN_6NAG.top
177
+ ============================================================
178
+ natom: 64528
179
+ nres: 15102
180
+ nbond: 64539
181
+ total_charge: 8.020996347271433e-05
182
+ is_neutral: True
183
+ box_dimensions: [98.3405545, 76.0526585, 81.2272985]
184
+ density: 0.8433970648221194
185
+ solvent_type: Explicit Solvent
186
+ simulation_category: Protein / Ligand in Explicit Water
187
+ num_solvent_molecules: 14659
188
+ num_solute_residues: 371
189
+ iptres: 443
190
+ hmr_active: False
191
+ hmr_hydrogen_mass_summary: 1.008-1.008 amu across 32188 H
192
+ hmr_detection_method: atomic_number
193
+ ... (also: version, title, force_field_features, total_mass, box_angles,
194
+ box_volume, box_is_topology_time, residue_composition — run it yourself for
195
+ the full field list)
196
+ ```
197
+
198
+ **Validate the whole Simulation — continuity, sequence holes, per-run checks, and suggestions (exit code `0`/`1` for CI):**
199
+
200
+ ```text
201
+ $ ambermeta validate --manifest sim.yaml
202
+
203
+ Simulation validation
204
+
205
+ Simulated time: 100 ns
206
+
207
+ Findings:
208
+ - Run check: ntp_prod_0001: Time step of 4 fs, but the topology has standard hydrogen masses (no hydrogen mass repartitioning); a time step above 2 fs needs repartitioned hydrogen masses.
209
+ - Run check: ntp_prod_0002: Time step of 4 fs, but the topology has standard hydrogen masses (no hydrogen mass repartitioning); a time step above 2 fs needs repartitioned hydrogen masses.
210
+ - Run check: ntp_prod_0003: Time step of 4 fs, but the topology has standard hydrogen masses (no hydrogen mass repartitioning); a time step above 2 fs needs repartitioned hydrogen masses.
211
+ - Run check: ntp_prod_0004: Time step of 4 fs, but the topology has standard hydrogen masses (no hydrogen mass repartitioning); a time step above 2 fs needs repartitioned hydrogen masses.
212
+ - Run check: ntp_prod_0005: Time step of 4 fs, but the topology has standard hydrogen masses (no hydrogen mass repartitioning); a time step above 2 fs needs repartitioned hydrogen masses.
213
+
214
+ Validation: OK, 5 findings to review
215
+ ```
216
+
217
+ The chain is intact, so the verdict is `OK`, but each run is compared with what AMBER recorded, and the sample as bundled ran at `dt = 0.004` ps with a topology whose 32,188 hydrogens all weigh 1.008 amu. A 4-fs time step needs repartitioned hydrogen masses, so either the runs used a different (HMR) topology than the one bundled, or they were integrated at a step their hydrogens do not support. On your own data with an HMR topology this finding does not appear. Findings leave the exit code at `0` by default; `--strict` makes any finding exit `1`, so `--strict` on the untouched sample exits `1`.
218
+
219
+ **Write the summary files** (`summary.json`, the methods summary as JSON and as Markdown to read, and per-run statistics) into one folder:
220
+
221
+ ```text
222
+ $ ambermeta plan -m sim.yaml --out results/
223
+ ...
224
+ Wrote summary: /abs/path/results/summary.json
225
+ Wrote methods_summary: /abs/path/results/methods_summary.json
226
+ Wrote methods_summary_md: /abs/path/results/methods_summary.md
227
+ Wrote stats_csv: /abs/path/results/stats.csv
228
+ ```
229
+
230
+ That is the whole path: `discover --write`, read and fix the manifest, `validate --manifest`, then `plan -m ... --out`. `ambermeta --help` lists the same four steps. Editing a manifest by hand, converting it between YAML and JSON (`export`), and each summary file in detail are in the [CLI reference](https://github.com/CPCLab/ambermeta/blob/main/docs/cli.md) and the [tutorials](https://github.com/CPCLab/ambermeta/blob/main/docs/tutorials.md).
231
+
232
+ ---
233
+
234
+ ## 4. The manifest
235
+
236
+ A manifest is the durable, hand-editable description of a simulation: a topology pool, a starting structure, an ordered list of phases, and the steps inside them. This is **manifest format v2** — the canonical, current shape:
237
+
238
+ ```yaml
239
+ version: 2
240
+ simulation:
241
+ topologies:
242
+ - id: top_wt
243
+ path: wt.prmtop
244
+ kind: normal # "normal" | "hmr" (detected, overridable)
245
+ - id: top_wt_hmr
246
+ path: wt_hmr.prmtop
247
+ kind: hmr
248
+ starting_structure: wt.inpcrd
249
+ phases:
250
+ - { id: ph_min, name: Minimization, role: minimization, order: 0 }
251
+ - { id: ph_prod, name: Production, role: production, order: 1 }
252
+ steps:
253
+ - id: st_min
254
+ name: minimize
255
+ phase: ph_min
256
+ order: 0
257
+ topology: top_wt # reference into the pool
258
+ input_coords: { source: starting_structure }
259
+ mdin: min.in
260
+ mdout: min.out
261
+ rst: min.rst # the restart THIS step writes
262
+ - id: st_prod_001
263
+ name: prod_001
264
+ phase: ph_prod
265
+ order: 0
266
+ topology: top_wt_hmr
267
+ input_coords: { source: step, ref: st_min } # or { source: path, path: "..." }
268
+ mdin: prod_001.in
269
+ mdout: prod_001.out
270
+ mdcrd: prod_001.nc
271
+ rst: prod_001.rst
272
+ gaps: { expected: null, tolerance: null }
273
+ ```
274
+
275
+ Each step's `input_coords.source` is one of `starting_structure`, `step` (with `ref: <step id>`), or `path` (with an explicit `path:`) — that's the continuity anchor the validator walks. A chained step names *only* the step it continues from: the restart file itself is recorded once, as `rst` on the step that wrote it, and `ref` is followed to reach it. `gaps.expected`/`gaps.tolerance` are the per-step expected inter-run gap and tolerance, in ps; both may be `null`.
276
+
277
+ **v2 is read and written as JSON or YAML** (`load_simulation`/`write_simulation`) — those are the only manifest formats AmberMeta has. A `.toml` or `.csv` manifest is refused with a message saying so, rather than being half-parsed.
278
+
279
+ ```bash
280
+ ambermeta validate --manifest simulation.yaml --format json
281
+ ```
282
+
283
+ A finding you have reviewed (a replica stopped on purpose, a run that was not deposited) can be settled in the manifest with a note, under `acknowledged:`; it is then listed apart with that note, no longer fails `--strict`, and is carried into the summaries. See [manifest §9.3](https://github.com/CPCLab/ambermeta/blob/main/docs/manifest.md#93-settling-a-finding-acknowledged).
284
+
285
+ The complete schema — every key, all input-coordinate sources, gap configuration, environment-variable expansion, and role tokens — is documented in the [manifest schema reference](https://github.com/CPCLab/ambermeta/blob/main/docs/manifest.md).
286
+
287
+ ### Coming from v1?
288
+
289
+ **The v1 flat manifest file format has been removed.** A file whose top level is a `stages:` list (with `global_prmtop`/`hmr_prmtop`/`initial_coordinates`) no longer opens anywhere — not in `plan -m`, `validate --manifest`, `export`, or the GUI. Each of them fails cleanly, naming the file:
290
+
291
+ ```text
292
+ $ ambermeta plan tests/data/amber/md_test_files -m old_manifest.yaml
293
+
294
+ ERROR: old_manifest.yaml is not a v2 manifest (no 'steps' key). Rebuild it with `ambermeta discover <dir> --write <path>`.
295
+ ```
296
+
297
+ There is no migration command and no in-memory migration. Rebuild the document from the run directory it describes:
298
+
299
+ ```bash
300
+ ambermeta discover runs/ --write sim.yaml # a v2 draft from the files on disk
301
+ ambermeta init runs/ -o sim.yaml # or start from a blank v2 template
302
+ ```
303
+
304
+ `discover` reads the same files the old manifest pointed at, so the rebuilt document is derived from the runs themselves rather than from the stale paths in the v1 file. Check the inferred phase roles and the topology pool before relying on it.
305
+
306
+ ---
307
+
308
+ ## 5. Python API
309
+
310
+ The same engine is a library, with two layers. For the new model, work with `ambermeta.simulation` directly — it is not (yet) re-exported at the `ambermeta` top level:
311
+
312
+ ```python
313
+ from ambermeta.simulation import load_simulation
314
+
315
+ sim = load_simulation("sim.yaml") # a v2 manifest: JSON or YAML
316
+ print(sim.topologies)
317
+ # -> [Topology(id='top_CH3L1_HUMAN_6NAG', path='CH3L1_HUMAN_6NAG.top', kind='normal')]
318
+ print(sim.starting_structure)
319
+ # -> ntp_prod_0000.rst
320
+ for phase in sim.phases:
321
+ print(phase.name, phase.role, [s.name for s in phase.steps])
322
+ # -> Production production ['ntp_prod_0001', 'ntp_prod_0002', 'ntp_prod_0003', 'ntp_prod_0004', 'ntp_prod_0005']
323
+ ```
324
+
325
+ `write_simulation(sim, path, fmt)` (`fmt` is `"json"` or `"yaml"`) writes it back out; `simulation_to_payload`/`payload_to_simulation` round-trip a `Simulation` through the same JSON-shaped dict the GUI's HTTP API uses.
326
+
327
+ The retained parsing engine — file discovery, the flat `SimulationProtocol`/`SimulationStage` model, and the per-file parsers — is still the public top-level `ambermeta.*` surface, and still powers `discover`/`validate --manifest` under the hood via `ambermeta.gui.api.core_bridge`:
328
+
329
+ ```python
330
+ from ambermeta import auto_discover
331
+
332
+ # Reconstruct a flat protocol from a directory (the path `plan --recursive` uses)
333
+ protocol = auto_discover("runs/", recursive=True, auto_detect_restarts=True)
334
+ print(len(protocol.stages), protocol.totals())
335
+
336
+ # Per-file parsing — note the .details accessor
337
+ from ambermeta.parsers import PrmtopParser
338
+ result = PrmtopParser("system.prmtop").parse()
339
+ meta = result.details
340
+ print(meta.natom, meta.hmr_active, meta.solvent_type)
341
+ ```
342
+
343
+ The full surface — every `ambermeta.simulation` dataclass, the retained `SimulationProtocol`/`SimulationStage`/`ProtocolBuilder`, the `core_bridge.discover_draft`/`validate_simulation` helpers that back the CLI and GUI, and every parser metadata field — is in the [Python API reference](https://github.com/CPCLab/ambermeta/blob/main/docs/api.md).
344
+
345
+ ---
346
+
347
+ ## 6. GUI
348
+
349
+ ```bash
350
+ ambermeta gui tests/data/amber/md_test_files # opens http://127.0.0.1:8765
351
+ ambermeta gui runs/ --port 9000 --no-browser
352
+ ```
353
+
354
+ A rebuilt three-pane browser app for assembling and auditing a Simulation:
355
+
356
+ - **Files** (left) — a searchable file list; drag a file onto the topology pool, the starting-structure slot, a step's topology, or a step's `mdin`/`mdout`/`mdcrd` slot.
357
+ - **Canvas** (center) — a continuous vertical timeline: phases as sections, steps as cards showing their bound topology and input-coordinate source, continuity arrows between chained steps (amber where a real gap exists), and ghost cards for missing members of a numbered sequence. Drag to reorder steps, move a step across phases, or reorder phases.
358
+ - **Inspector** (right) — peek and full-details/raw tabs for whatever's selected, plus assign actions and inline editors for the selected step or phase (name, topology, input-coordinate source and "continues from", restart, gaps, notes; name and role for a phase).
359
+
360
+ A **Suggestions** tray surfaces every inferred thing (roles, HMR topology, starting structure, sequence holes, continuity gaps) as an explainable, undoable suggestion rather than applying it silently. **Discover** re-runs discover-as-draft on the launch directory; **Open**/**Save** read and write the same v2 manifest the CLI does; **Validate** lists issues.
361
+
362
+ Run lineages are **proposed, never written**. After a Discover that found a grouping, a **proposal strip** shows the members it inferred, the directories each was built from, an editable name per member, and a segment picker for regrouping by a different part of the path — plus the cross-directory restart handoffs that AMBER's own mdout `File Assignments` records (`equil/01/18_ntp_equi → prod/01/nvt_prod_0001`). Discover already follows a record that identifies one run, in every directory, so the draft chain is what AMBER recorded wherever it recorded something usable. Nothing lands until you press **Accept**. The inference refuses more layouts than it accepts; **Define replicas…** in the top bar opens the same picker on demand and never refuses, so a tree it could not reconcile is still one click from being declared. See [GUI guide §5a](https://github.com/CPCLab/ambermeta/blob/main/docs/gui.md).
363
+
364
+ The server is server-authoritative (a single document held server-side; every mutation returns the new document; undo/redo call the server), single-user, **localhost-only**, and confines all file access to the launch directory. Full walkthrough, including the HTTP API surface: [GUI guide](https://github.com/CPCLab/ambermeta/blob/main/docs/gui.md).
365
+
366
+ ---
367
+
368
+ ## 7. Command reference
369
+
370
+ | Command | Purpose |
371
+ |---|---|
372
+ | `ambermeta discover` | Scan a directory into a Simulation draft (topology pool, phases, steps with input-coord sources) and optionally write a v2 manifest |
373
+ | `ambermeta plan` | Build and summarize a Simulation from a v2 manifest, or a flat protocol via recursive discovery / interactive prompts; export summaries and stats |
374
+ | `ambermeta validate` | Validate individual files, or a whole Simulation manifest (`--manifest`) for continuity and sequence holes |
375
+ | `ambermeta export` | Re-emit a v2 manifest as canonical v2, converting between JSON and YAML |
376
+ | `ambermeta init` | Write a starting v2 manifest template (`--force` to overwrite) |
377
+ | `ambermeta info` | Print parsed metadata for a single file (text / JSON / YAML) |
378
+ | `ambermeta gui` | Launch the browser GUI |
379
+ | `ambermeta completion` | Emit a shell-completion script (bash / zsh / fish) |
380
+
381
+ Global options (`--log-level`, `--log-file`, `-q/--quiet`) and every flag are documented — and kept in sync with the parser by CI — in the [CLI reference](https://github.com/CPCLab/ambermeta/blob/main/docs/cli.md).
382
+
383
+ ---
384
+
385
+ ## 8. Documentation
386
+
387
+ | Document | What's inside |
388
+ |---|---|
389
+ | [Architecture](https://github.com/CPCLab/ambermeta/blob/main/docs/architecture.md) | How the engine is built: the Simulation → Phase → Step model, the topology pool and input-coordinate sources, continuity/sequence detection, manifest v2 and its reader, the shared role classifier, the parser layer, and the GUI's single-engine bridge |
390
+ | [CLI reference](https://github.com/CPCLab/ambermeta/blob/main/docs/cli.md) | Every command, flag, exit code, and environment variable |
391
+ | [Python API reference](https://github.com/CPCLab/ambermeta/blob/main/docs/api.md) | Classes, functions, parser metadata fields, and worked examples |
392
+ | [Manifest schema](https://github.com/CPCLab/ambermeta/blob/main/docs/manifest.md) | The full v2 schema, environment-variable expansion, and role tokens |
393
+ | [GUI guide](https://github.com/CPCLab/ambermeta/blob/main/docs/gui.md) | The browser app, its API surface, and its security model |
394
+ | [Tutorials](https://github.com/CPCLab/ambermeta/blob/main/docs/tutorials.md) | Task-oriented, step-by-step walkthroughs |
395
+ | [Recipes](https://github.com/CPCLab/ambermeta/blob/main/docs/recipes.md) | Copy-paste CLI one-liners for common jobs |
396
+ | [Depositor SOP](https://github.com/CPCLab/ambermeta/blob/main/docs/sop/ambermeta-sop.pdf) | The procedure for applying AmberMeta to a collected dataset, one system at a time — prerequisites, the layout to use, the GUI walkthrough, and what to do with each finding ([source](https://github.com/CPCLab/ambermeta/blob/main/docs/sop/ambermeta-sop.tex)) |
397
+ | [Replica layouts](https://github.com/CPCLab/ambermeta/blob/main/docs/sop/replica-layouts.pdf) | Which directory conventions the layout inference detects, which it declines and why, and how to declare the rest by hand ([source](https://github.com/CPCLab/ambermeta/blob/main/docs/sop/replica-layouts.tex)) |
398
+
399
+ A single-page, fully offline HTML version of these docs lives at [`docs/ambermeta.html`](https://github.com/CPCLab/ambermeta/blob/main/docs/ambermeta.html) — open it in any browser (no server, no network).
400
+
401
+ ---
402
+
403
+ ## 9. Compatibility & limitations
404
+
405
+ - **v1 manifests no longer open.** A bare `stages:` list or a `global_prmtop`/`hmr_prmtop`/`initial_coordinates` manifest is refused with a clean error by every entry point, and there is no migration path. Rebuild from the run directory — see [Coming from v1?](#coming-from-v1) above.
406
+ - **AMBER engines:** parses output from both `pmemd`/`pmemd.cuda` and `sander`. GPU model and ns/day come from the `mdout` footer where present. Completion and wall-time are read per engine: `pmemd` writes a `Final Performance Info` block and a `Total wall time:` line, `sander` writes neither — its completion is taken from its own end-of-run markers (`Run done at`, `wallclock() was called`) and its wall clock from the `Total time` line in `TIMINGS`.
407
+ - **NetCDF:** `.nc` trajectories and `.ncrst` restarts require the `netcdf` extra. Without it, ASCII trajectories/restarts still parse; NetCDF files are reported as unreadable rather than crashing the run, and continuity reads each run's start time from its `mdout` instead. A run that set its own clock (`irest = 0`, new velocities) is then not measured against the run before it: it gets an INFO note that continuity follows the recorded input coordinates.
408
+ - **Incomplete trajectories are not read as complete ones.** NetCDF-3 stores record variables interleaved at the end of the file, so records that were never written back read as fill. A trajectory that is truncated, still being written, or half-copied is detected by its frame times ceasing to increase: AmberMeta reports the frames that are really on disk, warns that the times are not reported, and lets continuity fall through to the `mdout` rather than taking a fill value as the run's end time. Box records that read as empty are dropped from the box and volume statistics with a warning of their own.
409
+ - **One simulation per folder.** A folder whose runs report different atom counts holds several systems, so `discover`, `plan --recursive` and the GUI's Discover refuse it and name each system; run each system's folder on its own, or pass `--as-one-simulation` for a false alarm. See [Several systems in one folder](https://github.com/CPCLab/ambermeta/blob/main/docs/cli.md#several-systems-in-one-folder).
410
+ - **Fault tolerance:** `ambermeta plan` is fault-tolerant by default — an unreadable or malformed file is skipped, the error is recorded against its stage/step, and the run still completes (exit `0`). Pass `--strict` to make the first bad file a hard error.
411
+ - **Role inference is heuristic.** When a phase or stage omits its role, AmberMeta infers it from `imin` in the `mdin`/`mdout`, the file/path name, and other content (restraints, a temperature ramp, run length), via the shared classifier in `ambermeta/roles.py`, and records that it did so. Name cues are matched per path component, directories first: `min`/`em`, `heat`, `equil`/`equi`/`eq`, `prod`, then `nvt`/`npt` (so `nvt_prod_0001` is production), each followed by `_`, `.`, `-`, a digit or the end of the name (`prod1`, `eq0001`); the full table is in the [manifest schema](https://github.com/CPCLab/ambermeta/blob/main/docs/manifest.md#7-canonical-role-tokens). Verify inferred roles before publishing.
412
+ - **Manifest formats:** JSON or YAML, in both directions. TOML and CSV are not manifest formats — a `.toml`/`.csv` manifest path is refused with a message that says so. (`--stats-csv` still writes a per-stage statistics CSV; that is a report, not a manifest.)
413
+
414
+ ### Behavior changes in 1.4.0
415
+
416
+ - **A finding can be settled with a note.** A manifest may list findings you have reviewed under `acknowledged:`, each with a note that says why it stands. `validate` and `plan` show them apart under "Acknowledged", they no longer count for the verdict or for `--strict`, and an entry that no longer matches a finding is listed as no longer found. The notes are kept in `summary.json` and in the methods summary. In the GUI, a finding offers **Acknowledge…** and an acknowledged one offers **Reopen**. See [Settling a finding](https://github.com/CPCLab/ambermeta/blob/main/docs/manifest.md#93-settling-a-finding-acknowledged).
417
+ - **The methods summary as Markdown.** `plan --methods-summary-md FILE` writes a readable Markdown version beside the JSON, `plan --out DIR` writes it as `methods_summary.md`, and `python -m ambermeta.methods_summary summary.json -o methods_summary.md` converts any existing summary. The GUI's Plan dialog writes it by default.
418
+ - **One simulation per folder.** `discover`, `plan --recursive` and the GUI's Discover refuse a folder whose runs report different atom counts and name each system, where 1.3.0 merged them. `--as-one-simulation` keeps the old behavior.
419
+ - **Plainer output.** The verdict counts what is left to check (`Validation: OK, N findings to review`), findings are worded in plain language, and a gap in a numbered series names the run that is missing. `--help` shows the typical workflow, `plan`'s options are grouped, `plan --out DIR` writes every summary into one folder, and the run listing is compact (`-v` for full lines).
420
+ - **Readable manifests.** Ids are readable: a step's id is its run's name and a phase's id is its name in lower case (`production`). A YAML draft written with `discover --write` starts with a comment that says what to check.
421
+ - **No silent overwrites.** `discover --write` and `export -o` refuse to replace an existing file without the new `--force`, so a script that rewrites a manifest needs the flag. A missing parent directory is created.
422
+ - **Smaller CLI changes:** `ambermeta --version`; `NO_COLOR` is honoured; `export --format yaml` prints YAML; `export` keeps `$VARS` as written; `init` refuses a name that is not `.yaml`/`.yml`; `--help` no longer crashes when piped on Windows.
423
+ - **Fixes that change results:** a stated gap or tolerance of `0` is honoured; an unknown `input_coords.source` is refused when the manifest is loaded; an `.in` file without `&cntrl` (`tleap.in`) gets a warning and a finding instead of passing as an MD run; `validate <files>` reports an empty or cut-off file instead of OK; where two files of a run share a stem (`prod_0001.mdcrd` beside `prod_0001.nc`), the run names the one it read and the one it did not; reordering steps in the GUI keeps the links that AMBER recorded.
424
+ - **Packaging:** `pyproject.toml` is the only packaging file.
425
+
426
+ ### Behavior changes in 1.3.0
427
+
428
+ - **Replicas are compared per role.** Settings (`dt`, `temp0`, `cut`, `ntt`, `ntp`) are compared between replicas role by role for minimization, heating and equilibration runs, and on all other runs (production, custom roles, unclassified) together, so replicas whose production runs differ in `temp0` are reported even when each replica's equilibration runs use several temperatures (`Members differ in temp0 in their production runs (...)`). `temp0` is compared on those production runs (among the replicas that have them), and on the last equilibration (or heating) role only where no replica has such runs; per-segment or per-replica equilibration temperatures before production are not reported.
429
+ - **`plan --recursive` follows the recorded inputs.** The directory scan orders and links runs by the input coordinates each `mdout` records, as `discover` does, so names that do not sort in run order (`eq_0001 -> prod_0001 -> eq_0002 -> ...`) no longer produce false gaps and overlaps. A run that no record links to a run here (a job script that copies every restart to one fixed name, restarts not deposited) is still measured against the run before it, so real gaps are reported, and continuity problems are now listed under Findings and count for `--strict`. Topology and starting-structure groups are listed but not measured.
430
+ - **Simulated time per role.** Where the runs hold more than one role, `summary.json` totals and each lineage gain `time_ps_<role>` (`time_ps_equilibration`, `time_ps_production`, ...), and `plan`/`validate` print `Simulated time: 63 ns (equilibration 3 ns; production 60 ns)`.
431
+ - **Repeated phases are numbered.** A protocol that alternates roles gets `Equilibration`, `Production`, `Equilibration 2`, `Production 2`, ... from `discover`; the methods summary still describes each phase once.
432
+ - **Smaller fixes:** `stats.csv` has a `lineage` column when lineages exist; `discover --write` outside the scanned directory writes paths relative to the manifest (a manifest in a subdirectory keeps paths relative to the scanned directory, for the GUI); replica directories holding byte-identical copies of the starting restart give one starting structure; NetCDF attributes read through SciPy are decoded (`pmemd`, not `b'pmemd'`); `num_solute_residues` no longer counts ions (371, not 443, on the sample; LEaP's raw value is the new `iptres`); the methods summary of an older `summary.json` keeps the ensemble of NPT runs.
433
+
434
+ ---
435
+
436
+ ## 10. License
437
+
438
+ AmberMeta is distributed under the **Business Source License 1.1 (BUSL-1.1)**. See [`LICENSE`](https://github.com/CPCLab/ambermeta/blob/main/LICENSE) for the full terms.