Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4a28a3f
Introduction of splash screen and metadata for `CodeEntropy`:
harryswift01 Jul 8, 2025
576e6c5
Merge branch 'main' of https://github.com/CCPBioSim/CodeEntropy into …
harryswift01 Jul 22, 2025
42daf6e
removal of `save_consolve_output` function
harryswift01 Jul 31, 2025
117255e
remove duplicated `rich_handler` import setup
harryswift01 Jul 31, 2025
4529923
changed the level of formatting detail within the `program.err` file …
harryswift01 Jul 31, 2025
df0504e
Simplify logging setup and add Rich console output capture:
harryswift01 Jul 31, 2025
0cc5bd2
Merge branch 'main' of https://github.com/CCPBioSim/CodeEntropy into …
harryswift01 Aug 4, 2025
61fb6f2
Further refinements to the `Rich` library integration:
harryswift01 Aug 11, 2025
0e3193c
Merge branch 'main' of https://github.com/CCPBioSim/CodeEntropy into …
harryswift01 Aug 14, 2025
23b0627
Merge branch 'main' of https://github.com/CCPBioSim/CodeEntropy into …
harryswift01 Aug 18, 2025
496911b
Refactor progress bars for entropy calculations:
harryswift01 Aug 18, 2025
f551c57
Remove reliance on locally stored `CITATION.cff` file:
harryswift01 Aug 19, 2025
c53294e
Merge branch 'main' of https://github.com/CCPBioSim/CodeEntropy into …
harryswift01 Aug 19, 2025
df84587
Ensure correct `GitHub` page is linked for `CITATION.cff` file and in…
harryswift01 Aug 19, 2025
7e32c8e
Fix `test_build_covariance_matrices_atomic` unit test by adding in mo…
harryswift01 Aug 19, 2025
9f39fbc
Add frame count to final output and ensure consistency across entropy…
harryswift01 Aug 20, 2025
088dfff
Refactor water entropy handling into group-aware pipeline:
harryswift01 Aug 21, 2025
b49afd0
fix and update unit tests to reflect changes made within this refactor
harryswift01 Aug 21, 2025
2ae06fd
removed config yaml file warning as this is now redundant
harryswift01 Aug 21, 2025
a96d1ca
Refactor water residue handling and add test for dynamic residue group:
harryswift01 Aug 22, 2025
65045ed
Include Jonathan Higham within the `CITATION.cff` file
harryswift01 Aug 22, 2025
ad77383
change from `list(range(start, end, step))` to `list(range(number_fra…
harryswift01 Aug 22, 2025
d4cf3e8
Refactor water entropy calculations and update tests:
harryswift01 Aug 22, 2025
fa2ff15
Fix residue and atom counts outputted for each group
jkalayan Aug 22, 2025
c625fde
apply pre-commit and linting
harryswift01 Aug 22, 2025
52c310b
fixed broken `test_process_united_atom_entropy` unit test
harryswift01 Aug 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ authors:
email: rhen7213@uni.sydney.edu.au
affiliation: University of Sydney
orcid: 'https://orcid.org/0000-0002-0461-6625'
- given-names: Jonathan
family-names: Higham
email: j.higham4@lancaster.ac.uk
affiliation: Lancaster University
orcid: 'https://orcid.org/0000-0002-9779-9968'
- given-names: Jas
family-names: Kalayan
email: jas.kalayan@stfc.ac.uk
Expand Down
5 changes: 0 additions & 5 deletions CodeEntropy/config/arg_config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,6 @@ def load_config(self, file_path):
yaml_files = glob.glob(os.path.join(file_path, "*.yaml"))

if not yaml_files:
logger.warning(
f"No YAML configuration files found in directory: {file_path}. "
"Expected a file with extension '.yaml'. "
"Proceeding with default configuration: {'run1': {}}."
)
return {"run1": {}}

try:
Expand Down
102 changes: 70 additions & 32 deletions CodeEntropy/config/data_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@
import logging
import re

from tabulate import tabulate
import numpy as np
from rich.console import Console
from rich.table import Table

from CodeEntropy.config.logging_config import LoggingConfig

# Set up logger
logger = logging.getLogger(__name__)
console = LoggingConfig.get_console()


class DataLogger:
def __init__(self):
def __init__(self, console=None):
self.console = console or Console()
self.molecule_data = []
self.residue_data = []
self.group_labels = {}

def save_dataframes_as_json(self, molecule_df, residue_df, output_file):
"""Save multiple DataFrames into a single JSON file with separate keys"""
Expand All @@ -28,44 +35,75 @@ def clean_residue_name(self, resname):
"""Ensures residue names are stripped and cleaned before being stored"""
return re.sub(r"[-–—]", "", str(resname))

def add_results_data(self, resname, level, entropy_type, value):
def add_results_data(self, group_id, level, entropy_type, value):
"""Add data for molecule-level entries"""
resname = self.clean_residue_name(resname)
self.molecule_data.append((resname, level, entropy_type, value))
self.molecule_data.append((group_id, level, entropy_type, value))

def add_residue_data(self, resid, resname, level, entropy_type, value):
def add_residue_data(
self, group_id, resname, level, entropy_type, frame_count, value
):
"""Add data for residue-level entries"""
resname = self.clean_residue_name(resname)
self.residue_data.append([resid, resname, level, entropy_type, value])
if isinstance(frame_count, np.ndarray):
frame_count = frame_count.tolist()
self.residue_data.append(
[group_id, resname, level, entropy_type, frame_count, value]
)

def add_group_label(self, group_id, label, residue_count=None, atom_count=None):
"""Store a mapping from group ID to a descriptive label and metadata"""
self.group_labels[group_id] = {
"label": label,
"residue_count": residue_count,
"atom_count": atom_count,
}

def log_tables(self):
"""Log both tables at once"""
# Log molecule data
"""Display rich tables in terminal"""

if self.molecule_data:
logger.info("Molecule Data Table:")
table_str = tabulate(
self.molecule_data,
headers=["Residue Name", "Level", "Type", "Result (J/mol/K)"],
tablefmt="grid",
numalign="center",
stralign="center",
table = Table(
title="Molecule Entropy Results", show_lines=True, expand=True
)
logger.info(f"\n{table_str}")
table.add_column("Group ID", justify="center", style="bold cyan")
table.add_column("Level", justify="center", style="magenta")
table.add_column("Type", justify="center", style="green")
table.add_column("Result (J/mol/K)", justify="center", style="yellow")

for row in self.molecule_data:
table.add_row(*[str(cell) for cell in row])

console.print(table)

# Log residue data
if self.residue_data:
logger.info("Residue Data Table:")
table_str = tabulate(
self.residue_data,
headers=[
"Residue ID",
"Residue Name",
"Level",
"Type",
"Result (J/mol/K)",
],
tablefmt="grid",
numalign="center",
stralign="center",
table = Table(title="Residue Entropy Results", show_lines=True, expand=True)
table.add_column("Group ID", justify="center", style="bold cyan")
table.add_column("Residue Name", justify="center", style="cyan")
table.add_column("Level", justify="center", style="magenta")
table.add_column("Type", justify="center", style="green")
table.add_column("Count", justify="center", style="green")
table.add_column("Result (J/mol/K)", justify="center", style="yellow")

for row in self.residue_data:
table.add_row(*[str(cell) for cell in row])

console.print(table)

if self.group_labels:
label_table = Table(
title="Group ID to Residue Label Mapping", show_lines=True, expand=True
)
logger.info(f"\n{table_str}")
label_table.add_column("Group ID", justify="center", style="bold cyan")
label_table.add_column("Residue Label", justify="center", style="green")
label_table.add_column("Residue Count", justify="center", style="magenta")
label_table.add_column("Atom Count", justify="center", style="yellow")

for group_id, info in self.group_labels.items():
label_table.add_row(
str(group_id),
info["label"],
str(info.get("residue_count", "")),
str(info.get("atom_count", "")),
)

console.print(label_table)
Loading