Skip to content

Commit 3d50a67

Browse files
committed
Refactor and Reformat entire codebase:
- Introduced a .pre-commi-config.yaml to enforce standards when commiting to this repository. - Includes Black, pre-commit-hooks, flake8 and isort. - Applied 'pre-commit run --all-files', this automatically formatted a majority of the code, some manual intervention was needed. - Addressed issue #41 with ensuring any instances of numpy is refered to as np. and not .nmp
1 parent 3230cf6 commit 3d50a67

38 files changed

Lines changed: 1023 additions & 794 deletions

.pre-commit-config.yaml

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,14 @@ repos:
1515
- id: check-toml
1616
- id: check-yaml
1717

18-
# - repo: https://github.com/pycqa/flake8
19-
# rev: 7.0.0
20-
# hooks:
21-
# - id: flake8
22-
# additional_dependencies: [flake8-pyproject]
18+
- repo: https://github.com/pycqa/flake8
19+
rev: 7.0.0
20+
hooks:
21+
- id: flake8
22+
additional_dependencies: [flake8-pyproject]
2323

2424
- repo: https://github.com/pycqa/isort
2525
rev: 5.12.0
2626
hooks:
2727
- id: isort
28-
args: ["--profile=black"]
29-
30-
# - repo: https://github.com/PyCQA/pylint
31-
# rev: v3.3.4
32-
# hooks:
33-
# - id: pylint
34-
# additional_dependencies: ['pylint>=2.16.0']
28+
args: ["--profile=black"]

CodeEntropy/ConformationFunctions.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import numpy as nmp
2-
from MDAnalysis.analysis.dihedrals import Dihedral
1+
import numpy as np
2+
3+
# from MDAnalysis.analysis.dihedrals import Dihedral
34

45

56
def assign_conformation(
@@ -10,7 +11,8 @@ def assign_conformation(
1011
as a function of time. The function creates a histogram from the timeseries of the
1112
dihedral angle values and identifies points of dominant occupancy
1213
(called CONVEX TURNING POINTS).
13-
Based on the identified TPs, states are assigned to each configuration of the dihedral.
14+
Based on the identified TPs, states are assigned to each configuration of the
15+
dihedral.
1416
1517
Input
1618
-----
@@ -26,22 +28,23 @@ def assign_conformation(
2628
A timeseries with integer labels describing the state at each point in time.
2729
2830
"""
29-
conformations = nmp.zeros(number_frames)
30-
phi = nmp.zeros(number_frames)
31+
conformations = np.zeros(number_frames)
32+
phi = np.zeros(number_frames)
3133

3234
# get the values of the angle for the dihedral
3335
# dihedral angle values have a range from -180 to 180
3436
for timestep in data_container.trajectory[start:end:step]:
3537
value = dihedral.value()
3638
# we want postive values in range 0 to 360 to make the peak assignment work
37-
# using the fact that dihedrals have circular symetry (i.e. -15 degrees = +345 degrees)
39+
# using the fact that dihedrals have circular symetry
40+
# (i.e. -15 degrees = +345 degrees)
3841
if value < 0:
3942
value += 360
4043
phi[timestep.frame] = value
4144

4245
# create a histogram using numpy
4346
number_bins = int(360 / bin_width)
44-
popul, bin_edges = nmp.histogram(a=phi, bins=number_bins, range=(0, 360))
47+
popul, bin_edges = np.histogram(a=phi, bins=number_bins, range=(0, 360))
4548
bin_value = [0.5 * (bin_edges[i] + bin_edges[i + 1]) for i in range(0, len(popul))]
4649

4750
# identify "convex turning-points" and populate a list of peaks
@@ -53,7 +56,8 @@ def assign_conformation(
5356
# if there is no dihedrals in a bin then it cannot be a peak
5457
if popul[bin_index] == 0:
5558
pass
56-
# being careful of the last bin (dihedrals have circular symmetry, the histogram does not)
59+
# being careful of the last bin
60+
# (dihedrals have circular symmetry, the histogram does not)
5761
elif (
5862
bin_index == number_bins - 1
5963
): # the -1 is because the index starts with 0 not 1
@@ -73,7 +77,7 @@ def assign_conformation(
7377
for frame in range(number_frames):
7478
# find the TP that the snapshot is least distant from
7579
distances = [abs(phi[frame] - peak) for peak in peak_values]
76-
conformations[frame] = nmp.argmin(distances)
80+
conformations[frame] = np.argmin(distances)
7781

7882
return conformations
7983

CodeEntropy/EntropyFunctions.py

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
import math
2-
import sys
3-
from ast import arg
42

5-
import matplotlib.pyplot as plt
6-
import MDAnalysis as mda
7-
import numpy as nmp
8-
import pandas as pd
3+
# import matplotlib.pyplot as plt
4+
# import MDAnalysis as mda
5+
import numpy as np
6+
7+
# import pandas as pd
98
from numpy import linalg as la
109

1110
from CodeEntropy import ConformationFunctions as CONF
1211
from CodeEntropy import UnitsAndConversions as UAC
1312

13+
# import sys
14+
# from ast import arg
15+
16+
1417
# from CodeEntropy import NeighbourFunctions as NF
1518

1619

1720
def frequency_calculation(lambdas, temp):
1821
"""
19-
Function to calculate an array of vibrational frequencies from the eigenvalues of the
20-
covariance matrix.
22+
Function to calculate an array of vibrational frequencies from the eigenvalues of
23+
the covariance matrix.
2124
22-
Calculated from eq. (3) in Higham, S.-Y. Chou, F. Gräter and R. H. Henchman, Molecular
23-
Physics, 2018, 116, 1965–1976//eq. (3) in A. Chakravorty, J. Higham and R. H. Henchman,
24-
J. Chem. Inf. Model., 2020, 60, 5540–5551
25+
Calculated from eq. (3) in Higham, S.-Y. Chou, F. Gräter and R. H. Henchman,
26+
Molecular Physics, 2018, 116, 1965–1976//eq. (3) in A. Chakravorty, J. Higham
27+
and R. H. Henchman, J. Chem. Inf. Model., 2020, 60, 5540–5551
2528
2629
frequency=sqrt(λ/kT)/2π
2730
@@ -34,10 +37,10 @@ def frequency_calculation(lambdas, temp):
3437
-------
3538
frequencies : array of floats - corresponding vibrational frequencies
3639
"""
37-
pi = nmp.pi
40+
pi = np.pi
3841
# get kT in Joules from given temperature
3942
kT = UAC.get_KT2J(temp)
40-
frequencies = 1 / (2 * pi) * nmp.sqrt(lambdas / kT)
43+
frequencies = 1 / (2 * pi) * np.sqrt(lambdas / kT)
4144

4245
return frequencies
4346

@@ -47,9 +50,9 @@ def frequency_calculation(lambdas, temp):
4750

4851
def vibrational_entropy(matrix, matrix_type, temp, highest_level):
4952
"""
50-
Function to calculate the vibrational entropy for each level calculated from eq. (4) in
51-
J. Higham, S.-Y. Chou, F. Gräter and R. H. Henchman, Molecular Physics, 2018, 116,
52-
1965–1976 / eq. (2) in A. Chakravorty, J. Higham and R. H. Henchman,
53+
Function to calculate the vibrational entropy for each level calculated from eq. (4)
54+
in J. Higham, S.-Y. Chou, F. Gräter and R. H. Henchman, Molecular Physics, 2018,
55+
116, 1965–1976 / eq. (2) in A. Chakravorty, J. Higham and R. H. Henchman,
5356
J. Chem. Inf. Model., 2020, 60, 5540–5551.
5457
5558
Input
@@ -72,13 +75,13 @@ def vibrational_entropy(matrix, matrix_type, temp, highest_level):
7275
frequencies = frequency_calculation(lambdas, temp)
7376

7477
# Sort frequencies lowest to highest
75-
frequencies = nmp.sort(frequencies)
78+
frequencies = np.sort(frequencies)
7679

7780
kT = UAC.get_KT2J(temp)
7881
exponent = UAC.PLANCK_CONST * frequencies / kT
79-
power_positive = nmp.power(nmp.e, exponent)
80-
power_negative = nmp.power(nmp.e, -exponent)
81-
S_components = exponent / (power_positive - 1) - nmp.log(1 - power_negative)
82+
power_positive = np.power(np.e, exponent)
83+
power_negative = np.power(np.e, -exponent)
84+
S_components = exponent / (power_positive - 1) - np.log(1 - power_negative)
8285
S_components = (
8386
S_components * UAC.GAS_CONST
8487
) # multiply by R - get entropy in J mol^{-1} K^{-1}
@@ -87,8 +90,9 @@ def vibrational_entropy(matrix, matrix_type, temp, highest_level):
8790
if highest_level: # whole molecule level - we take all frequencies into account
8891
S_vib_total = sum(S_components)
8992

90-
# discard the 6 lowest frequencies to discard translation and rotation of the whole unit
91-
# the overall translation and rotation of a unit is an internal motion of the level above
93+
# discard the 6 lowest frequencies to discard translation and rotation of the
94+
# whole unit the overall translation and rotation of a unit is an internal
95+
# motion of the level above
9296
else:
9397
S_vib_total = sum(S_components[6:])
9498

@@ -107,7 +111,8 @@ def conformational_entropy(
107111
"""
108112
Function to calculate conformational entropies using eq. (7) in Higham, S.-Y. Chou,
109113
F. Gräter and R. H. Henchman, Molecular Physics, 2018, 116, 1965–1976 / eq. (4) in
110-
A. Chakravorty, J. Higham and R. H. Henchman, J. Chem. Inf. Model., 2020, 60, 5540–5551.
114+
A. Chakravorty, J. Higham and R. H. Henchman, J. Chem. Inf. Model., 2020, 60,
115+
5540–5551.
111116
112117
Uses the adaptive enumeration method (AEM).
113118
@@ -123,7 +128,7 @@ def conformational_entropy(
123128

124129
# For each dihedral, identify the conformation in each frame
125130
num_dihedrals = len(dihedrals)
126-
conformation = nmp.zeros((num_dihedrals, number_frames))
131+
conformation = np.zeros((num_dihedrals, number_frames))
127132
index = 0
128133
for dihedral in dihedrals:
129134
conformation[index] = CONF.assign_conformation(
@@ -137,13 +142,14 @@ def conformational_entropy(
137142
for index in range(num_dihedrals):
138143
states[frame_index] += str(conformation[index][frame_index])
139144

140-
# Count how many times each state occurs, then use the probability to get the entropy
145+
# Count how many times each state occurs, then use the probability to get the
146+
# entropy
141147
# entropy = sum over states p*ln(p)
142-
values, counts = nmp.unique(states, return_counts=True)
148+
values, counts = np.unique(states, return_counts=True)
143149
for state in range(len(values)):
144150
count = counts[state]
145151
probability = count / number_frames
146-
entropy = probability * nmp.log(probability)
152+
entropy = probability * np.log(probability)
147153
S_conf_total += entropy
148154

149155
# multiply by gas constant to get the units J/mol/K
@@ -157,15 +163,17 @@ def conformational_entropy(
157163

158164
def orientational_entropy(neighbours_dict):
159165
"""
160-
Function to calculate orientational entropies from eq. (10) in J. Higham, S.-Y. Chou,
161-
F. Gräter and R. H. Henchman, Molecular Physics, 2018, 116,3 1965–1976. Number of
162-
orientations, Ω, is calculated using eq. (8) in J. Higham, S.-Y. Chou, F. Gräter and
163-
R. H. Henchman, Molecular Physics, 2018, 116,3 1965–1976.
166+
Function to calculate orientational entropies from eq. (10) in J. Higham, S.-Y.
167+
Chou, F. Gräter and R. H. Henchman, Molecular Physics, 2018, 116,3 1965–1976.
168+
Number of orientations, Ω, is calculated using eq. (8) in J. Higham,
169+
S.-Y. Chou, F. Gräter and R. H. Henchman, Molecular Physics, 2018, 116,
170+
3 1965–1976.
164171
165172
σ is assumed to be 1 for the molecules we're concerned with and hence,
166173
max {1, (Nc^3*π)^(1/2)} will always be (Nc^3*π)^(1/2).
167174
168-
TODO future release - function for determing symmetry and symmetry numbers maybe?
175+
TODO future release - function for determing symmetry and symmetry numbers
176+
maybe?
169177
170178
Input
171179
-----
@@ -177,20 +185,23 @@ def orientational_entropy(neighbours_dict):
177185
-------
178186
S_or_total : float - orientational entropy
179187
"""
188+
189+
# Replaced molecule with neighbour as this is what the for loop uses
180190
S_or_total = 0
181191
for neighbour in neighbours_dict: # we are going through neighbours
182-
if molecule in []: # water molecules - call POSEIDON functions
192+
if neighbour in []: # water molecules - call POSEIDON functions
183193
pass # TODO temporary until function is written
184194
else:
185-
omega = nmp.sqrt(
186-
(neighbours_dict[molecule] ** 3) * math.pi
187-
) # the bound ligand is always going to be a neighbour
188-
S_or_component = math.log(
189-
omega
190-
) # orientational entropy arising from each neighbouring species - we know the species is going to be a neighbour
195+
# the bound ligand is always going to be a neighbour
196+
omega = np.sqrt((neighbours_dict[neighbour] ** 3) * math.pi)
197+
# orientational entropy arising from each neighbouring species
198+
# - we know the species is going to be a neighbour
199+
S_or_component = math.log(omega)
191200
S_or_component *= UAC.GAS_CONST
192201
S_or_total += S_or_component
193-
# TODO for future releases - implement a case for molecules with hydrogen bonds but to a lesser extent than water
202+
# TODO for future releases
203+
# implement a case for molecules with hydrogen bonds but to a lesser
204+
# extent than water
194205
return S_or_total
195206

196207

0 commit comments

Comments
 (0)