-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Detect negative rate and give a nice error when that happens #215
Labels
bug
Defects or errors in the code.
enhancement
Request for improvement or addition of new feature(s).
gempyor
Concerns the Python core.
low priority
Low priority.
Comments
TimothyWillard
added
bug
Defects or errors in the code.
enhancement
Request for improvement or addition of new feature(s).
gempyor
Concerns the Python core.
low priority
Low priority.
labels
Nov 18, 2024
The bit of code that @emprzy put together that does this, and the test: def neg_params(parsed_parameters, parameter_names, dates, subpop_names):
# If any values in the array are below zero:
if ((parsed_parameters)< 0).any():
# Create an array with the indices of each negative param
# (parameter, day, subpop)
negative_index_parameters = np.argwhere(parsed_parameters<0)
# This loop will record redundant rows in negative_index array
unique_param_sp_combinations = []
row_index = -1
redundant_rows = []
for row in negative_index_parameters:
row_index += 1
# If the (param, subpop) combination already exists in the list, count that row as one that needs to be removed
if (row[0],row[2]) in unique_param_sp_combinations:
redundant_rows.append(row_index)
# If the (param, sbupop) combination does not exist in the list, add it to the list
if (row[0],row[2]) not in unique_param_sp_combinations:
unique_param_sp_combinations.append((row[0],row[2]))
# Remove the redundant rows
non_redundant_negative_parameters = np.delete(negative_index_parameters, (redundant_rows), axis=0)
# If there are any negative params, error will be raised and negative param locales will be cited
print("The earliest date negative for each subpop and unique parameter are:")
for param_idx, day_idx, sp_idx in non_redundant_negative_parameters:
print("subpop: ", subpop_names[sp_idx], ", parameter ", parameter_names[param_idx], ": ", dates[day_idx].date(), sep="")
raise ValueError("There are negative parsed-parameters, which is likely to result in incorrect integration.") import pytest
from random import randint
# Test the negative_parameters() function
def test_negative_parameters():
parameter_names = ['1*1*1*1', 'alpha*1*1*1', 'sigma_OMICRON*1*1*1', '3*gamma*1*1*1', 'epsilon+omegaph4*1*1*1', '1*zeta*1*1', 'r0*gamma*theta10*1*chi_OMICRON*1', 'r0*gamma*theta9*1*chi_OMICRON*1', 'r0*gamma*theta8*1*chi_OMICRON*1', 'r0*gamma*theta7*1*chi_OMICRON*1', 'r0*gamma*theta6*1*chi_OMICRON*1', 'r0*gamma*theta5*1*chi_OMICRON*1', 'r0*gamma*theta4*1*chi_OMICRON*1', 'r0*gamma*theta3*1*chi_OMICRON*1', 'r0*gamma*theta2*1*chi_OMICRON*1', 'r0*gamma*theta1*1*chi_OMICRON*1', 'r0*gamma*theta0*1*chi_OMICRON*1', 'eta_X0toX3_highIE*1*1*nuage0to17', 'eta_X0toX3_highIE*1*1*nuage18to64LR', 'eta_X0toX3_highIE*1*1*nuage18to64HR', 'eta_X0toX3_highIE*1*1*nuage65to100', 'eta_X0toX4_highIE*1*1*nuage0to17', 'eta_X0toX4_highIE*1*1*nuage18to64LR', 'eta_X0toX4_highIE*1*1*nuage18to64HR', 'eta_X0toX4_highIE*1*1*nuage65to100', 'eta_X0toX5_highIE*1*1*nuage0to17', 'eta_X0toX5_highIE*1*1*nuage18to64LR', 'eta_X0toX5_highIE*1*1*nuage18to64HR', 'eta_X0toX5_highIE*1*1*nuage65to100', 'eta_X1toX4_highIE*1*1*nuage0to17', 'eta_X1toX4_highIE*1*1*nuage18to64LR', 'eta_X1toX4_highIE*1*1*nuage18to64HR', 'eta_X1toX4_highIE*1*1*nuage65to100', 'eta_X1toX5_highIE*1*1*nuage0to17', 'eta_X1toX5_highIE*1*1*nuage18to64LR', 'eta_X1toX5_highIE*1*1*nuage18to64HR', 'eta_X1toX5_highIE*1*1*nuage65to100', 'eta_X2toX4_highIE*1*1*nuage0to17', 'eta_X2toX4_highIE*1*1*nuage18to64LR', 'eta_X2toX4_highIE*1*1*nuage18to64HR', 'eta_X2toX4_highIE*1*1*nuage65to100', 'eta_X2toX5_highIE*1*1*nuage0to17', 'eta_X2toX5_highIE*1*1*nuage18to64LR', 'eta_X2toX5_highIE*1*1*nuage18to64HR', 'eta_X2toX5_highIE*1*1*nuage65to100', 'eta_X2toX6_highIE*1*1*nuage0to17', 'eta_X2toX6_highIE*1*1*nuage18to64LR', 'eta_X2toX6_highIE*1*1*nuage18to64HR', 'eta_X2toX6_highIE*1*1*nuage65to100', 'eta_X3toX5_highIE*1*1*nuage0to17', 'eta_X3toX5_highIE*1*1*nuage18to64LR', 'eta_X3toX5_highIE*1*1*nuage18to64HR', 'eta_X3toX5_highIE*1*1*nuage65to100', 'eta_X3toX6_highIE*1*1*nuage0to17', 'eta_X3toX6_highIE*1*1*nuage18to64LR', 'eta_X3toX6_highIE*1*1*nuage18to64HR', 'eta_X3toX6_highIE*1*1*nuage65to100', 'eta_X4toX6_highIE*1*1*nuage0to17', 'eta_X4toX6_highIE*1*1*nuage18to64LR', 'eta_X4toX6_highIE*1*1*nuage18to64HR', 'eta_X4toX6_highIE*1*1*nuage65to100', 'eta_X4toX7_highIE*1*1*nuage0to17', 'eta_X4toX7_highIE*1*1*nuage18to64LR', 'eta_X4toX7_highIE*1*1*nuage18to64HR', 'eta_X4toX7_highIE*1*1*nuage65to100', 'eta_X5toX7_highIE*1*1*nuage0to17', 'eta_X5toX7_highIE*1*1*nuage18to64LR', 'eta_X5toX7_highIE*1*1*nuage18to64HR', 'eta_X5toX7_highIE*1*1*nuage65to100', 'eta_X6toX7_highIE*1*1*nuage0to17', 'eta_X6toX7_highIE*1*1*nuage18to64LR', 'eta_X6toX7_highIE*1*1*nuage18to64HR', 'eta_X6toX7_highIE*1*1*nuage65to100', 'eta_X6toX8_highIE*1*1*nuage0to17', 'eta_X6toX8_highIE*1*1*nuage18to64LR', 'eta_X6toX8_highIE*1*1*nuage18to64HR', 'eta_X6toX8_highIE*1*1*nuage65to100', 'eta_X7toX8_highIE*1*1*nuage0to17', 'eta_X7toX8_highIE*1*1*nuage18to64LR', 'eta_X7toX8_highIE*1*1*nuage18to64HR', 'eta_X7toX8_highIE*1*1*nuage65to100', 'eta_X8toX9_highIE*1*1*nuage0to17', 'eta_X8toX9_highIE*1*1*nuage18to64LR', 'eta_X8toX9_highIE*1*1*nuage18to64HR', 'eta_X8toX9_highIE*1*1*nuage65to100', 'eta_X9toX9_highIE*1*1*nuage0to17', 'eta_X9toX9_highIE*1*1*nuage18to64LR', 'eta_X9toX9_highIE*1*1*nuage18to64HR', 'eta_X9toX9_highIE*1*1*nuage65to100', 'eta_X10toX10_highIE*1*1*nuage0to17', 'eta_X10toX10_highIE*1*1*nuage18to64LR', 'eta_X10toX10_highIE*1*1*nuage18to64HR', 'eta_X10toX10_highIE*1*1*nuage65to100']
dates = pd.date_range('2023-03-19', '2025-08-31', freq="D")
subpop_names = ['56000', '50000', '11000', '02000', '38000', '46000', '10000', '30000', '44000', '23000', '33000', '15000', '16000', '54000', '31000', '35000', '20000', '32000', '28000', '05000', '49000', '19000', '09000', '40000', '41000', '21000', '22000', '01000', '45000', '27000', '08000', '55000', '24000', '29000', '18000', '47000', '25000', '04000', '53000', '51000', '34000', '26000', '37000', '13000', '39000', '17000', '42000', '36000', '12000', '48000', '06000']
# Test case 1: no negative params
test_array1 = np.zeros((93,897,51))
# Test case 2: randomized negative params
test_array2 = np.zeros((93,897,51))
for num in range(5):
test_array2[randint(0,93)][randint(0,897)][randint(0,51)] = -1
# Test case 3: set negative params with redundancy
test_array3 = np.zeros((93,897,51))
test_array3[0][0][0] = -1
test_array3[50,400:,2] =-1
test_array3[6][7][15] = -1
test_array3[6][8][15] = -1
neg_params(test_array1, parameter_names, dates, subpop_names) # NoError
with pytest.raises(ValueError):
assert neg_params(test_array2, parameter_names, dates, subpop_names) # ValueError
assert neg_params(test_array3, parameter_names, dates, subpop_names) # ValueError which gives: |
@jcblemai Do you want the error that results from having negative parameters to be fatal? Or just a warning? |
An error is good at this stage |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
bug
Defects or errors in the code.
enhancement
Request for improvement or addition of new feature(s).
gempyor
Concerns the Python core.
low priority
Low priority.
instead of letting the RK4 fail and catching this-
The text was updated successfully, but these errors were encountered: