CodeEntropy 2.5.0__py3-none-any.whl → 2.6.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.
CodeEntropy/__init__.py CHANGED
@@ -8,4 +8,4 @@ entropy estimates, supporting a wide range of applications in molecular simulati
8
8
  and statistical mechanics.
9
9
  """
10
10
 
11
- __version__ = "2.5.0"
11
+ __version__ = "2.6.0"
CodeEntropy/cli.py CHANGED
@@ -4,16 +4,18 @@ This module provides the CLI entry point used to run the multiscale cell
4
4
  correlation entropy workflow.
5
5
 
6
6
  The entry point is intentionally small and only responsible for:
7
- 1) Creating a job folder.
8
- 2) Constructing a CodeEntropyRunner.
9
- 3) Executing the entropy workflow.
10
- 4) Handling fatal errors with a non-zero exit code.
7
+ 1) Handling informational flags such as ``--version``.
8
+ 2) Creating a job folder.
9
+ 3) Constructing a CodeEntropyRunner.
10
+ 4) Executing the entropy workflow.
11
+ 5) Handling fatal errors with a non-zero exit code.
11
12
  """
12
13
 
13
14
  from __future__ import annotations
14
15
 
15
16
  import logging
16
17
 
18
+ from CodeEntropy.config.argparse import ConfigResolver
17
19
  from CodeEntropy.config.runtime import CodeEntropyRunner
18
20
 
19
21
  logger = logging.getLogger(__name__)
@@ -22,9 +24,15 @@ logger = logging.getLogger(__name__)
22
24
  def main() -> None:
23
25
  """Run the entropy workflow.
24
26
 
27
+ Arguments are parsed before any side effects so that informational flags such
28
+ as ``--version`` and ``--help`` exit without creating a job folder or
29
+ rendering the splash screen.
30
+
25
31
  Raises:
26
32
  SystemExit: Exits with status code 1 on any unhandled exception.
27
33
  """
34
+ ConfigResolver().build_parser().parse_known_args()
35
+
28
36
  folder = CodeEntropyRunner.create_job_folder()
29
37
 
30
38
  try:
@@ -31,6 +31,7 @@ from typing import Any
31
31
 
32
32
  import yaml
33
33
 
34
+ from CodeEntropy import __version__
34
35
  from CodeEntropy.core.dask_clusters import HPCDaskManager
35
36
 
36
37
  logger = logging.getLogger(__name__)
@@ -318,6 +319,11 @@ class ConfigResolver:
318
319
  parser = argparse.ArgumentParser(
319
320
  description="CodeEntropy: entropy calculation with the MCC method."
320
321
  )
322
+ parser.add_argument(
323
+ "--version",
324
+ action="version",
325
+ version=f"CodeEntropy {__version__}",
326
+ )
321
327
 
322
328
  for name, spec in self._arg_specs.items():
323
329
  arg_name = f"--{name}"
@@ -32,6 +32,7 @@ from rich.rule import Rule
32
32
  from rich.table import Table
33
33
  from rich.text import Text
34
34
 
35
+ from CodeEntropy import __version__
35
36
  from CodeEntropy.config.argparse import ConfigResolver
36
37
  from CodeEntropy.core.dask_clusters import HPCDaskManager
37
38
  from CodeEntropy.core.logging import LoggingConfig
@@ -135,20 +136,21 @@ class CodeEntropyRunner:
135
136
  return None
136
137
 
137
138
  def show_splash(self) -> None:
138
- """Render a Rich splash screen with optional citation metadata."""
139
+ """Render a Rich splash screen.
140
+
141
+ The version shown is that of the locally installed package. Remaining
142
+ metadata (authors, description, URL) comes from the online citation file
143
+ when it is reachable.
144
+ """
139
145
  citation = self.load_citation_data()
146
+ version_text = Align.center(Text(f"Version {__version__}", style="green"))
140
147
 
141
148
  if citation:
142
149
  ascii_title = text2art(citation.get("title", "CodeEntropy"))
143
150
  ascii_render = Align.center(Text(ascii_title, style="bold white"))
144
151
 
145
- version = citation.get("version", "?")
146
- release_date = citation.get("date-released", "?")
147
152
  url = citation.get("url", citation.get("repository-code", ""))
148
153
 
149
- version_text = Align.center(
150
- Text(f"Version {version} | Released {release_date}", style="green")
151
- )
152
154
  url_text = Align.center(Text(url, style="blue underline"))
153
155
 
154
156
  abstract = citation.get("abstract", "No description available.")
@@ -193,7 +195,7 @@ class CodeEntropyRunner:
193
195
  else:
194
196
  ascii_title = text2art("CodeEntropy")
195
197
  ascii_render = Align.center(Text(ascii_title, style="bold white"))
196
- splash_content = Group(ascii_render)
198
+ splash_content = Group(ascii_render, Rule(style="cyan"), version_text)
197
199
 
198
200
  splash_panel = Panel(
199
201
  splash_content,
@@ -46,7 +46,12 @@ class ConformationStateBuilder(ConformationPeakDetector, ConformationStateAssign
46
46
  frame_selection: FrameSelection,
47
47
  progress: _RichProgressSink | None = None,
48
48
  chunk_size: int | None = None,
49
- ) -> tuple[dict[UAKey, list[str]], list[list[str]], dict[UAKey, int], list[int]]:
49
+ ) -> tuple[
50
+ dict[UAKey, list[str]],
51
+ dict[int, list[str]],
52
+ dict[UAKey, int],
53
+ dict[int, int],
54
+ ]:
50
55
  """Build conformational state labels from selected trajectory frames.
51
56
 
52
57
  Args:
@@ -87,7 +92,12 @@ class ConformationStateBuilder(ConformationPeakDetector, ConformationStateAssign
87
92
  frame_selection: FrameSelection,
88
93
  chunk_size: int,
89
94
  progress: _RichProgressSink | None = None,
90
- ) -> tuple[dict[UAKey, list[str]], list[list[str]], dict[UAKey, int], list[int]]:
95
+ ) -> tuple[
96
+ dict[UAKey, list[str]],
97
+ dict[int, list[str]],
98
+ dict[UAKey, int],
99
+ dict[int, int],
100
+ ]:
91
101
  """Build conformational states with serial frame-chunk map-reduce.
92
102
 
93
103
  Args:
@@ -108,11 +118,10 @@ class ConformationStateBuilder(ConformationPeakDetector, ConformationStateAssign
108
118
  if chunk_size < 1:
109
119
  raise ValueError("chunk_size must be >= 1")
110
120
 
111
- number_groups = len(groups)
112
121
  states_ua: dict[UAKey, list[str]] = {}
113
- states_res: list[list[str]] = [[] for _ in range(number_groups)]
122
+ states_res: dict[int, list[str]] = {}
114
123
  flexible_ua: dict[UAKey, int] = {}
115
- flexible_res: list[int] = []
124
+ flexible_res: dict[int, int] = {}
116
125
 
117
126
  task: TaskID | None = None
118
127
  if progress is not None:
@@ -186,6 +195,7 @@ class ConformationStateBuilder(ConformationPeakDetector, ConformationStateAssign
186
195
  state_data = self._reduce_state_partials(state_partials)
187
196
 
188
197
  self._merge_group_state_data(
198
+ group_id=group_id,
189
199
  state_data=state_data,
190
200
  states_ua=states_ua,
191
201
  states_res=states_res,
@@ -170,20 +170,23 @@ class ConformationStateAssigner:
170
170
 
171
171
  @staticmethod
172
172
  def _merge_group_state_data(
173
+ group_id: int,
173
174
  state_data: ConformationStateData,
174
175
  states_ua: dict[UAKey, list[str]],
175
- states_res: list[list[str]],
176
+ states_res: dict[int, list[str]],
176
177
  flexible_ua: dict[UAKey, int],
177
- flexible_res: list[int],
178
+ flexible_res: dict[int, int],
178
179
  ) -> None:
179
180
  """Merge one group's state data into final output accumulators.
180
181
 
181
182
  Args:
183
+ group_id: Id of the group the state data belongs to.
182
184
  state_data: Serial conformational state data for one group.
183
185
  states_ua: UA state accumulator to mutate.
184
- states_res: Residue state accumulator to mutate.
186
+ states_res: Residue state accumulator, keyed by group id, to mutate.
185
187
  flexible_ua: UA flexible-dihedral accumulator to mutate.
186
- flexible_res: Residue flexible-dihedral accumulator to mutate.
188
+ flexible_res: Residue flexible-dihedral accumulator, keyed by group id,
189
+ to mutate.
187
190
 
188
191
  Returns:
189
192
  None. Mutates the provided accumulators.
@@ -199,8 +202,8 @@ class ConformationStateAssigner:
199
202
  state_data.flexible_ua_updates[key],
200
203
  )
201
204
 
202
- states_res.append(state_data.state_res)
203
- flexible_res.append(state_data.flex_res)
205
+ states_res[group_id] = state_data.state_res
206
+ flexible_res[group_id] = state_data.flex_res
204
207
 
205
208
  def _process_conformations_from_angles(
206
209
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: CodeEntropy
3
- Version: 2.5.0
3
+ Version: 2.6.0
4
4
  Summary: CodeEntropy is a Python package for computing the configurational entropy of macromolecular systems using forces sampled from molecular dynamics (MD) simulations. It implements the multiscale cell correlation method to provide accurate and efficient entropy estimates, supporting a wide range of applications in molecular simulation and statistical mechanics.
5
5
  Keywords: entropy,macromolecular systems,MD simulation
6
6
  Author-email: Arghya 'Argo' Chakravorty <arghyac@umich.edu>, Donald Chung-HK <donald.chung@stfc.ac.uk>, Sarah Fegan <sarah.fegan@stfc.ac.uk>, James Gebbie-Rayet <james.gebbie@stfc.ac.uk>, Sarah Harris <sarah.harris@sheffield.ac.uk>, Richard Henchman <rhen7213@uni.sydney.edu.au>, Jonathan Higham <j.higham4@lancaster.ac.uk>, Jas Kalayan <jas.kalayan@stfc.ac.uk>, Ioana Papa <iapapa1@sheffield.ac.uk>
@@ -16,21 +16,21 @@ Classifier: License :: OSI Approved :: MIT License
16
16
  Classifier: Natural Language :: English
17
17
  Classifier: Development Status :: 5 - Production/Stable
18
18
  License-File: LICENSE
19
- Requires-Dist: numpy>=2.3.2,<2.5.0
19
+ Requires-Dist: numpy>=2.3.5,<2.6.0
20
20
  Requires-Dist: mdanalysis>=2.10,<3.0
21
21
  Requires-Dist: pandas>=2.3.3,<4.0
22
- Requires-Dist: psutil>=5.9.4,<8.0
22
+ Requires-Dist: psutil>=7.1.3,<8.0
23
23
  Requires-Dist: PyYAML>=6.0.3,<7.0
24
24
  Requires-Dist: rich>=13.0.0,<16.0
25
25
  Requires-Dist: art>=5.0,<7.0
26
26
  Requires-Dist: networkx>=2.8,<4.0
27
27
  Requires-Dist: waterEntropy>=2,<3.0
28
28
  Requires-Dist: requests>=2.32.2,<3.0
29
- Requires-Dist: rdkit>=2025.3.4,<2026
29
+ Requires-Dist: rdkit>=2025.3.4,<2027
30
30
  Requires-Dist: numba>=0.63.0,<0.70
31
- Requires-Dist: dask>=2025.4.0,<2027.1.0
31
+ Requires-Dist: dask>=2025.7.0,<2027.1.0
32
32
  Requires-Dist: dask-jobqueue>=0.9.0,<1.0
33
- Requires-Dist: distributed>=2025.4.0,<2027.1.0
33
+ Requires-Dist: distributed>=2025.7.0,<2027.1.0
34
34
  Requires-Dist: sphinx>=8.0.0,<10.0 ; extra == "docs"
35
35
  Requires-Dist: nbsphinx>=0.9.3,<1.0 ; extra == "docs"
36
36
  Requires-Dist: sphinx_copybutton>=0.5,<1.0 ; extra == "docs"
@@ -56,7 +56,7 @@ CodeEntropy
56
56
 
57
57
  | Category | Badges |
58
58
  |----------------|--------|
59
- | **Build** | [![PR Checks](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/pr.yaml/badge.svg)](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/pr.yaml) [![Daily Tests](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/daily.yaml/badge.svg)](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/daily.yaml) |
59
+ | **Build** | [![PR Checks](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/pr.yaml/badge.svg)](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/pr.yaml) [![Daily Tests](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/daily.yaml/badge.svg)](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/daily.yaml) [![Dependency Floors](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/dependency-floors.yaml/badge.svg)](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/dependency-floors.yaml) |
60
60
  | **Regression** | [![Weekly Regression](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/weekly-regression.yaml/badge.svg)](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/weekly-regression.yaml) |
61
61
  | **Documentation** | [![Weekly Docs](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/weekly-docs.yaml/badge.svg)](https://github.com/CCPBioSim/CodeEntropy/actions/workflows/weekly-docs.yaml) [![Docs - Status](https://app.readthedocs.org/projects/codeentropy/badge/?version=latest)](https://codeentropy.readthedocs.io/en/latest/?badge=latest) |
62
62
  | **Citation** | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.17570721.svg)](https://doi.org/10.5281/zenodo.17570721) |
@@ -1,9 +1,9 @@
1
- CodeEntropy/__init__.py,sha256=QM8PCDQ0OM8HKjPNiIHHpPFtqLhnyTcGo8Tc6-_Nh-s,404
1
+ CodeEntropy/__init__.py,sha256=hAmtMNRexWP67gOAWLWAag9bka7HMDFyE3BMl7IRJHw,404
2
2
  CodeEntropy/__main__.py,sha256=5i_ZrxQaq0q2aPllbB4SZ6BApV6oUFCgx0cGyjfMPrU,108
3
- CodeEntropy/cli.py,sha256=xgSgagCV6HQ3CoXUpG7p7Ef5hCExgxp7orz6dZZWA6c,960
3
+ CodeEntropy/cli.py,sha256=nSshc8P7F7n3jAW36vzwXsFdffLfFdCpkfLvA-tJb3c,1318
4
4
  CodeEntropy/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- CodeEntropy/config/argparse.py,sha256=Yjb2SWNdfKhHmfznU439cZPtdPM_QjhUD4uug2fnsek,19515
6
- CodeEntropy/config/runtime.py,sha256=iyeUrSAmz3eGpkAslAGsDzEzu7s4T8npy_Di3d8tnaU,14846
5
+ CodeEntropy/config/argparse.py,sha256=SBDTrFpEStgKeremqhpHA8ZWTJGH6IirthLFFcTitFY,19695
6
+ CodeEntropy/config/runtime.py,sha256=1lfLy57vv6nF6ND0cspGpIWQdfwj_ZiZpU9GohfvkwI,14914
7
7
  CodeEntropy/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  CodeEntropy/core/dask_clusters.py,sha256=FsvLyYQPImTWRf9J4x7wUILqf3syS0Ji5JUsJN-Qp1A,8992
9
9
  CodeEntropy/core/logging.py,sha256=XLr2lSSC5kGPq7rQDhWCi7Vcvh3DGO9e5TDbI4l2Bvc,7775
@@ -28,10 +28,10 @@ CodeEntropy/levels/neighbors.py,sha256=vswveQCIVBlDPQBFGc0e3whzmTJD01GjEJTpJ2UMn
28
28
  CodeEntropy/levels/search.py,sha256=p4aqyj6GV7YGLDnlmZqi12cDbjfajSIB8IIcBAoUmaQ,8769
29
29
  CodeEntropy/levels/dihedrals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  CodeEntropy/levels/dihedrals/angle_observations.py,sha256=ZsIaXRvNRzZQjBxafiWD2_3zn_GnKjc9EkN8GjrVh6Q,9861
31
- CodeEntropy/levels/dihedrals/conformational_state_builder.py,sha256=3ajT_v1Cga1JocIvuJtHPx2JZwGUtleemuF45S31iAQ,7598
31
+ CodeEntropy/levels/dihedrals/conformational_state_builder.py,sha256=OU1Tzi3bGWADReVbFh4N4P2mS-nOH0XlIPR3ddhjUMg,7673
32
32
  CodeEntropy/levels/dihedrals/kernels.py,sha256=gX75jgDDs-dv-IdI0V-u7NM-M4RVmpVppDAADFkHWxc,3594
33
33
  CodeEntropy/levels/dihedrals/peak_detection.py,sha256=h8j78gczkf9tlYFTMqITDc51K9l9NxS5Y-ul1gHytzw,9486
34
- CodeEntropy/levels/dihedrals/state_assignment.py,sha256=QtfYjXEBbW95lomT9linK1_5uU0nsHh1P6PyMT_VR1g,9672
34
+ CodeEntropy/levels/dihedrals/state_assignment.py,sha256=d4en88oTSH37vGNavoRZ4xWrxSLxjCJ-LX_8xahBKJE,9834
35
35
  CodeEntropy/levels/dihedrals/topology.py,sha256=LJ_u6cY-N91A5CuNBYzk_I0xHEpvqYSC30u9T4aku7c,8825
36
36
  CodeEntropy/levels/execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  CodeEntropy/levels/execution/chunks.py,sha256=VD1LQA-thRaJZKVR_5qIQk5VZQWHGE2e2JzF5JspDe0,754
@@ -58,8 +58,8 @@ CodeEntropy/trajectory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
58
58
  CodeEntropy/trajectory/frames.py,sha256=MSx_swzFjo4TgkZTR1y6W-1zuKNPg_C36I_uFqvOKpk,4354
59
59
  CodeEntropy/trajectory/mda.py,sha256=epKpAzxkNQi3rE7HJc_tsK_ZY4c575LdXmWewJoP1qE,16954
60
60
  CodeEntropy/trajectory/source.py,sha256=NfYsdm1amr29h2tmJP-RKyCp3phb1SOAtAELJmGm740,1475
61
- codeentropy-2.5.0.dist-info/entry_points.txt,sha256=8Oa3H9ErsrGtx5Hc6hIHOw73wK3Ylkvfgtl_4cBb_GU,52
62
- codeentropy-2.5.0.dist-info/licenses/LICENSE,sha256=hgMaAAVW1Q6dL586OHoz8vFO-6BYn-d2aAFBpVQylFc,1072
63
- codeentropy-2.5.0.dist-info/WHEEL,sha256=lqN8jXt_QloFOGcx9kStvWbryhfEXoI2F2z-YURm350,81
64
- codeentropy-2.5.0.dist-info/METADATA,sha256=OAUfGJ1rsObNQ9ftW76e4CZr3m6PFxG1ycdM6B5HdsI,6348
65
- codeentropy-2.5.0.dist-info/RECORD,,
61
+ codeentropy-2.6.0.dist-info/entry_points.txt,sha256=8Oa3H9ErsrGtx5Hc6hIHOw73wK3Ylkvfgtl_4cBb_GU,52
62
+ codeentropy-2.6.0.dist-info/licenses/LICENSE,sha256=hgMaAAVW1Q6dL586OHoz8vFO-6BYn-d2aAFBpVQylFc,1072
63
+ codeentropy-2.6.0.dist-info/WHEEL,sha256=lqN8jXt_QloFOGcx9kStvWbryhfEXoI2F2z-YURm350,81
64
+ codeentropy-2.6.0.dist-info/METADATA,sha256=dDomybrlzZoHk5m116Ap4v8TI9QtKclsW6XIJhSkQ5E,6547
65
+ codeentropy-2.6.0.dist-info/RECORD,,