Skip to content

Commit e7183f0

Browse files
authored
Merge pull request #53 from CCPBioSim/7-nan-error-handling
Add error handling for NaN and invalid values in calculations:
2 parents 0adf3a7 + 9e86895 commit e7183f0

File tree

3 files changed

+85
-6
lines changed

3 files changed

+85
-6
lines changed

CodeEntropy/EntropyFunctions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ def frequency_calculation(lambdas, temp):
4040
pi = np.pi
4141
# get kT in Joules from given temperature
4242
kT = UAC.get_KT2J(temp)
43+
44+
lambdas = np.array(lambdas) # Ensure input is a NumPy array
45+
46+
# Check for negatives and raise an error if any are found
47+
if np.any(lambdas < 0):
48+
raise ValueError(f"Negative eigenvalues encountered: {lambdas[lambdas < 0]}")
49+
50+
# Compute frequencies safely
4351
frequencies = 1 / (2 * pi) * np.sqrt(lambdas / kT)
4452

4553
return frequencies

CodeEntropy/GeometricFunctions.py

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,26 @@ def get_sphCoord_axes(arg_r):
181181
x2y2 = arg_r[0] ** 2 + arg_r[1] ** 2
182182
r2 = x2y2 + arg_r[2] ** 2
183183

184+
# Check for division by zero
185+
if r2 == 0.0:
186+
raise ValueError("r2 is zero, cannot compute spherical coordinates.")
187+
188+
if x2y2 == 0.0:
189+
raise ValueError("x2y2 is zero, cannot compute sin_phi and cos_phi.")
190+
191+
# Check for non-negative values inside the square root
192+
if x2y2 / r2 < 0:
193+
raise ValueError(
194+
f"Negative value encountered for sin_theta calculation: {x2y2 / r2}. "
195+
f"Cannot take square root."
196+
)
197+
198+
if x2y2 < 0:
199+
raise ValueError(
200+
f"Negative value encountered for sin_phi and cos_phi calculation: {x2y2}. "
201+
f"Cannot take square root."
202+
)
203+
184204
if x2y2 != 0.0:
185205
sin_theta = np.sqrt(x2y2 / r2)
186206
cos_theta = arg_r[2] / np.sqrt(r2)
@@ -259,6 +279,13 @@ def get_weighted_forces(
259279
# divide the sum of forces by the mass of the bead to get the weighted forces
260280
mass = bead.total_mass()
261281

282+
# Check that mass is positive to avoid division by 0 or negative values inside sqrt
283+
if mass <= 0:
284+
raise ValueError(
285+
f"Invalid mass value: {mass}. Mass must be positive to compute the square "
286+
f"root."
287+
)
288+
262289
weighted_force = forces_trans / np.sqrt(mass)
263290

264291
return weighted_force
@@ -309,14 +336,18 @@ def get_weighted_torques(data_container, bead, rot_axes, force_partitioning=0.5)
309336
moment_of_inertia = bead.moment_of_inertia()
310337

311338
for dimension in range(3):
312-
# cannot divide by zero
313-
if np.isclose(moment_of_inertia[dimension, dimension], 0):
314-
weighted_torque[dimension] = torques[dimension]
315-
else:
316-
weighted_torque[dimension] = torques[dimension] / np.sqrt(
317-
moment_of_inertia[dimension, dimension]
339+
# Check if the moment of inertia is valid for square root calculation
340+
inertia_value = moment_of_inertia[dimension, dimension]
341+
342+
if np.isclose(inertia_value, 0):
343+
raise ValueError(
344+
f"Invalid moment of inertia value: {inertia_value}. "
345+
f"Cannot compute weighted torque."
318346
)
319347

348+
# compute weighted torque if moment of inertia is valid
349+
weighted_torque[dimension] = torques[dimension] / np.sqrt(inertia_value)
350+
320351
return weighted_torque
321352

322353

CodeEntropy/poseidon/extractData/generalFunctions.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ def distance(x0, x1, dimensions):
1818
x1 = np.array(x1)
1919
delta = np.abs(x1 - x0)
2020
delta = np.where(delta > 0.5 * dimensions, delta - dimensions, delta)
21+
22+
if np.any(delta < 0):
23+
negative_indices = np.where(delta < 0)
24+
negative_values = delta[negative_indices]
25+
raise ValueError(
26+
f"Negative values encountered in 'delta' at indices {negative_indices} "
27+
f"with values {negative_values}. "
28+
f"Cannot take square root of negative values."
29+
)
30+
2131
dist = np.sqrt((delta**2).sum(axis=-1))
2232
return dist
2333

@@ -173,8 +183,38 @@ def angle(a, b, c, dimensions):
173183
ba = np.where(ba > 0.5 * dimensions, ba - dimensions, ba)
174184
bc = np.where(bc > 0.5 * dimensions, bc - dimensions, bc)
175185
ac = np.where(ac > 0.5 * dimensions, ac - dimensions, ac)
186+
187+
if np.any(ba < 0):
188+
negative_indices = np.where(ba < 0)
189+
negative_values = ba[negative_indices]
190+
raise ValueError(
191+
f"Negative values encountered in 'ba' at indices {negative_indices} "
192+
f"with values {negative_values}. "
193+
f"Cannot take square root of negative values."
194+
)
195+
176196
dist_ba = np.sqrt((ba**2).sum(axis=-1))
197+
198+
if np.any(bc < 0):
199+
negative_indices = np.where(bc < 0)
200+
negative_values = bc[negative_indices]
201+
raise ValueError(
202+
f"Negative values encountered in 'bc' at indices {negative_indices} "
203+
f"with values {negative_values}. "
204+
f"Cannot take square root of negative values."
205+
)
206+
177207
dist_bc = np.sqrt((bc**2).sum(axis=-1))
208+
209+
if np.any(ac < 0):
210+
negative_indices = np.where(ac < 0)
211+
negative_values = ac[negative_indices]
212+
raise ValueError(
213+
f"Negative values encountered in 'ac' at indices {negative_indices} "
214+
f"with values {negative_values}. "
215+
f"Cannot take square root of negative values."
216+
)
217+
178218
dist_ac = np.sqrt((ac**2).sum(axis=-1))
179219

180220
cosine_angle = (dist_ac**2 - dist_bc**2 - dist_ba**2) / (-2 * dist_bc * dist_ba)

0 commit comments

Comments
 (0)