Skip to content

Commit 25e58b8

Browse files
committed
Merge branch 'main' of https://github.com/CCPBioSim/CodeEntropy into 74-yaml-input-bug
2 parents 37a568c + 0b96f22 commit 25e58b8

15 files changed

+532
-243
lines changed

CodeEntropy/ConformationFunctions.py renamed to CodeEntropy/calculations/ConformationFunctions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import logging
2+
13
import numpy as np
24

5+
logger = logging.getLogger(__name__)
6+
37
# from MDAnalysis.analysis.dihedrals import Dihedral
48

59

@@ -79,4 +83,6 @@ def assign_conformation(
7983
distances = [abs(phi[frame] - peak) for peak in peak_values]
8084
conformations[frame] = np.argmin(distances)
8185

86+
logger.debug(f"Final conformations: {conformations}")
87+
8288
return conformations

CodeEntropy/EntropyFunctions.py renamed to CodeEntropy/calculations/EntropyFunctions.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import math
23

34
# import matplotlib.pyplot as plt
@@ -7,8 +8,10 @@
78
# import pandas as pd
89
from numpy import linalg as la
910

10-
from CodeEntropy import ConformationFunctions as CONF
11-
from CodeEntropy import UnitsAndConversions as UAC
11+
from CodeEntropy.calculations import ConformationFunctions as CONF
12+
from CodeEntropy.calculations import UnitsAndConversions as UAC
13+
14+
logger = logging.getLogger(__name__)
1215

1316
# import sys
1417
# from ast import arg
@@ -40,15 +43,19 @@ def frequency_calculation(lambdas, temp):
4043
pi = np.pi
4144
# get kT in Joules from given temperature
4245
kT = UAC.get_KT2J(temp)
46+
logger.debug(f"Temperature: {temp}, kT: {kT}")
4347

4448
lambdas = np.array(lambdas) # Ensure input is a NumPy array
49+
logger.debug(f"Eigenvalues (lambdas): {lambdas}")
4550

4651
# Check for negatives and raise an error if any are found
4752
if np.any(lambdas < 0):
53+
logger.error(f"Negative eigenvalues encountered: {lambdas[lambdas < 0]}")
4854
raise ValueError(f"Negative eigenvalues encountered: {lambdas[lambdas < 0]}")
4955

5056
# Compute frequencies safely
5157
frequencies = 1 / (2 * pi) * np.sqrt(lambdas / kT)
58+
logger.debug(f"Calculated frequencies: {frequencies}")
5259

5360
return frequencies
5461

@@ -74,22 +81,31 @@ def vibrational_entropy(matrix, matrix_type, temp, highest_level):
7481
# N beads at a level => 3N x 3N covariance matrix => 3N eigenvalues
7582
# Get eigenvalues of the given matrix and change units to SI units
7683
lambdas = la.eigvals(matrix)
84+
logger.debug(f"Eigenvalues (lambdas) before unit change: {lambdas}")
7785
lambdas = UAC.change_lambda_units(lambdas)
86+
logger.debug(f"Eigenvalues (lambdas) after unit change: {lambdas}")
7887

7988
# Calculate frequencies from the eigenvalues
8089
frequencies = frequency_calculation(lambdas, temp)
90+
logger.debug(f"Calculated frequencies: {frequencies}")
8191

8292
# Sort frequencies lowest to highest
8393
frequencies = np.sort(frequencies)
94+
logger.debug(f"Sorted frequencies: {frequencies}")
8495

8596
kT = UAC.get_KT2J(temp)
97+
logger.debug(f"Temperature: {temp}, kT: {kT}")
8698
exponent = UAC.PLANCK_CONST * frequencies / kT
99+
logger.debug(f"Exponent values: {exponent}")
87100
power_positive = np.power(np.e, exponent)
88101
power_negative = np.power(np.e, -exponent)
102+
logger.debug(f"Power positive values: {power_positive}")
103+
logger.debug(f"Power negative values: {power_negative}")
89104
S_components = exponent / (power_positive - 1) - np.log(1 - power_negative)
90105
S_components = (
91106
S_components * UAC.GAS_CONST
92107
) # multiply by R - get entropy in J mol^{-1} K^{-1}
108+
logger.debug(f"Entropy components: {S_components}")
93109
# N beads at a level => 3N x 3N covariance matrix => 3N eigenvalues
94110
if matrix_type == "force": # force covariance matrix
95111
if highest_level: # whole molecule level - we take all frequencies into account
@@ -104,6 +120,8 @@ def vibrational_entropy(matrix, matrix_type, temp, highest_level):
104120
else: # torque covariance matrix - we always take all values into account
105121
S_vib_total = sum(S_components)
106122

123+
logger.debug(f"Total vibrational entropy: {S_vib_total}")
124+
107125
return S_vib_total
108126

109127

@@ -138,17 +156,23 @@ def conformational_entropy(
138156
)
139157
index += 1
140158

159+
logger.debug(f"Conformation matrix: {conformation}")
160+
141161
# For each frame, convert the conformation of all dihedrals into a state string
142162
states = ["" for x in range(number_frames)]
143163
for frame_index in range(number_frames):
144164
for index in range(num_dihedrals):
145165
states[frame_index] += str(conformation[index][frame_index])
146166

167+
logger.debug(f"States: {states}")
168+
147169
# Count how many times each state occurs, then use the probability to get the
148170
# entropy
149171
# entropy = sum over states p*ln(p)
150172
values, counts = np.unique(states, return_counts=True)
151173
for state in range(len(values)):
174+
logger.debug(f"Unique states: {values}")
175+
logger.debug(f"Counts: {counts}")
152176
count = counts[state]
153177
probability = count / number_frames
154178
entropy = probability * np.log(probability)
@@ -157,6 +181,8 @@ def conformational_entropy(
157181
# multiply by gas constant to get the units J/mol/K
158182
S_conf_total *= -1 * UAC.GAS_CONST
159183

184+
logger.debug(f"Total conformational entropy: {S_conf_total}")
185+
160186
return S_conf_total
161187

162188

@@ -193,12 +219,28 @@ def orientational_entropy(neighbours_dict):
193219
else:
194220
# the bound ligand is always going to be a neighbour
195221
omega = np.sqrt((neighbours_dict[neighbour] ** 3) * math.pi)
222+
logger.debug(f"Omega for neighbour {neighbour}: {omega}")
196223
# orientational entropy arising from each neighbouring species
197224
# - we know the species is going to be a neighbour
198225
S_or_component = math.log(omega)
226+
logger.debug(
227+
f"S_or_component (log(omega)) for neighbour {neighbour}: "
228+
f"{S_or_component}"
229+
)
199230
S_or_component *= UAC.GAS_CONST
231+
logger.debug(
232+
f"S_or_component after multiplying by GAS_CONST for neighbour "
233+
f"{neighbour}: {S_or_component}"
234+
)
200235
S_or_total += S_or_component
236+
logger.debug(
237+
f"S_or_total after adding component for neighbour {neighbour}: "
238+
f"{S_or_total}"
239+
)
201240
# TODO for future releases
202241
# implement a case for molecules with hydrogen bonds but to a lesser
203242
# extent than water
243+
244+
logger.debug(f"Final total orientational entropy: {S_or_total}")
245+
204246
return S_or_total

CodeEntropy/GeometricFunctions.py renamed to CodeEntropy/calculations/GeometricFunctions.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import logging
2+
13
import numpy as np
24

5+
logger = logging.getLogger(__name__)
6+
37

48
def get_beads(data_container, level):
59
"""
@@ -40,6 +44,8 @@ def get_beads(data_container, level):
4044
)
4145
list_of_beads.append(data_container.select_atoms(atom_group))
4246

47+
logger.debug(f"List of beads: {list_of_beads}")
48+
4349
return list_of_beads
4450

4551

@@ -120,6 +126,9 @@ def get_axes(data_container, level, index=0):
120126
# use spherical coordinates function to get rotational axes
121127
rot_axes = get_sphCoord_axes(vector)
122128

129+
logger.debug(f"Translational Axes: {trans_axes}")
130+
logger.debug(f"Rotational Axes: {rot_axes}")
131+
123132
return trans_axes, rot_axes
124133

125134

@@ -159,6 +168,8 @@ def get_avg_pos(atom_set, center):
159168
# transform the average position to a coordinate system with the origin at center
160169
avg_position = avg_position - center
161170

171+
logger.debug(f"Average Position: {avg_position}")
172+
162173
return avg_position
163174

164175

@@ -231,6 +242,8 @@ def get_sphCoord_axes(arg_r):
231242
# Phi^
232243
spherical_basis[2, :] = np.asarray([-sin_phi, cos_phi, 0.0])
233244

245+
logger.debug(f"Spherical Basis: {spherical_basis}")
246+
234247
return spherical_basis
235248

236249

@@ -276,6 +289,8 @@ def get_weighted_forces(
276289

277290
weighted_force = forces_trans / np.sqrt(mass)
278291

292+
logger.debug(f"Weighted Force: {weighted_force}")
293+
279294
return weighted_force
280295

281296

@@ -361,6 +376,8 @@ def get_weighted_torques(data_container, bead, rot_axes, force_partitioning=0.5)
361376
moment_of_inertia[dimension, dimension]
362377
)
363378

379+
logger.debug(f"Weighted Torque: {weighted_torque}")
380+
364381
return weighted_torque
365382

366383

@@ -390,6 +407,8 @@ def create_submatrix(data_i, data_j, number_frames):
390407
# Divide by the number of frames to get the average
391408
submatrix /= number_frames
392409

410+
logger.debug(f"Submatrix: {submatrix}")
411+
393412
return submatrix
394413

395414

@@ -432,11 +451,13 @@ def filter_zero_rows_columns(arg_matrix, verbose):
432451
# get the final shape
433452
final_shape = np.shape(arg_matrix)
434453

435-
if verbose and init_shape != final_shape:
436-
print(
437-
"A shape change has occured ({},{}) -> ({}, {})".format(
454+
if init_shape != final_shape:
455+
logger.debug(
456+
"A shape change has occurred ({},{}) -> ({}, {})".format(
438457
*init_shape, *final_shape
439458
)
440459
)
441460

461+
logger.debug(f"arg_matrix: {arg_matrix}")
462+
442463
return arg_matrix

CodeEntropy/LevelFunctions.py renamed to CodeEntropy/calculations/LevelFunctions.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
# import MDAnalysis as mda
2+
import logging
3+
24
import numpy as np
35

4-
from CodeEntropy import GeometricFunctions as GF
6+
from CodeEntropy.calculations import GeometricFunctions as GF
7+
8+
logger = logging.getLogger(__name__)
59

610

711
def select_levels(data_container, verbose):
@@ -23,7 +27,7 @@ def select_levels(data_container, verbose):
2327

2428
# fragments is MDAnalysis terminology for what chemists would call molecules
2529
number_molecules = len(data_container.atoms.fragments)
26-
print("The number of molecules is {}.".format(number_molecules))
30+
logger.debug("The number of molecules is {}.".format(number_molecules))
2731
fragments = data_container.atoms.fragments
2832
levels = [[] for _ in range(number_molecules)]
2933

@@ -42,8 +46,7 @@ def select_levels(data_container, verbose):
4246
if number_residues > 1:
4347
levels[molecule].append("polymer")
4448

45-
if verbose:
46-
print(levels)
49+
logger.debug(f"levels {levels}")
4750

4851
return number_molecules, levels
4952

@@ -142,12 +145,8 @@ def get_matrices(
142145
force_matrix = GF.filter_zero_rows_columns(force_matrix, verbose)
143146
torque_matrix = GF.filter_zero_rows_columns(torque_matrix, verbose)
144147

145-
if verbose:
146-
with open("matrix.out", "a") as f:
147-
print("force_matrix \n", file=f)
148-
print(force_matrix, file=f)
149-
print("torque_matrix \n", file=f)
150-
print(torque_matrix, file=f)
148+
logger.debug(f"Force Matrix: {force_matrix}")
149+
logger.debug(f"Torque Matrix: {torque_matrix}")
151150

152151
return force_matrix, torque_matrix
153152

@@ -181,7 +180,7 @@ def get_dihedrals(data_container, level):
181180
if level == "residue":
182181
num_residues = len(data_container.residues)
183182
if num_residues < 4:
184-
print("no residue level dihedrals")
183+
logger.debug("no residue level dihedrals")
185184

186185
else:
187186
# find bonds between residues N-3:N-2 and N-1:N
@@ -224,4 +223,6 @@ def get_dihedrals(data_container, level):
224223
atom_group = atom1 + atom2 + atom3 + atom4
225224
dihedrals.append(atom_group.dihedral)
226225

226+
logger.debug(f"Dihedrals: {dihedrals}")
227+
227228
return dihedrals

CodeEntropy/MDAUniverseHelper.py renamed to CodeEntropy/calculations/MDAUniverseHelper.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import logging
12
import pickle
23

34
import MDAnalysis as mda
45
from MDAnalysis.analysis.base import AnalysisFromFunction
56
from MDAnalysis.coordinates.memory import MemoryReader
67

8+
logger = logging.getLogger(__name__)
9+
710

811
def new_U_select_frame(u, start=None, end=None, step=1):
912
"""Create a reduced universe by dropping frames according to user selection
@@ -46,6 +49,7 @@ def new_U_select_frame(u, start=None, end=None, step=1):
4649
)
4750
u2 = mda.Merge(select_atom)
4851
u2.load_new(coordinates, format=MemoryReader, forces=forces, dimensions=dimensions)
52+
logger.debug(f"MDAnalysis.Universe - reduced universe: {u2}")
4953
return u2
5054

5155

@@ -83,6 +87,7 @@ def new_U_select_atom(u, select_string="all"):
8387
)
8488
u2 = mda.Merge(select_atom)
8589
u2.load_new(coordinates, format=MemoryReader, forces=forces, dimensions=dimensions)
90+
logger.debug(f"MDAnalysis.Universe - reduced universe: {u2}")
8691
return u2
8792

8893

CodeEntropy/NeighbourFunctions.py renamed to CodeEntropy/calculations/NeighbourFunctions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# import os
2+
import logging
23
import sys
34

45
# import matplotlib.pyplot as plt
56
import MDAnalysis as mda
67
import numpy as np
78

9+
logger = logging.getLogger(__name__)
10+
11+
812
# from ast import arg
913

1014

@@ -85,4 +89,8 @@ def get_neighbours(molecule_i, reduced_atom):
8589
# print(r_ij)
8690
neighbours_array.append(molecule_j.atoms.resids[0])
8791
neighbours_dict[molecule_j.atoms.resnames[0]] = 1
92+
93+
logger.debug(f"Neighbours dictionary: {neighbours_dict}")
94+
logger.debug(f"Neighbours array: {neighbours_array}")
95+
8896
return neighbours_dict, neighbours_array
File renamed without changes.

0 commit comments

Comments
 (0)