Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 53 additions & 0 deletions src/main/java/simpaths/data/Parameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.apache.commons.io.FileUtils;
import simpaths.data.startingpop.DataParser;
import simpaths.model.AnnuityRates;
import simpaths.model.BenefitUnit;
import simpaths.model.Person;
import simpaths.model.enums.*;
import org.apache.commons.collections4.keyvalue.MultiKey;
import org.apache.commons.collections4.map.LinkedMap;
Expand Down Expand Up @@ -1138,6 +1140,8 @@ public static void loadParameters(Country country, int maxAgeModel, boolean enab
coeffCovarianceHM2CaseMales = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + "reg_health_mental.xlsx", countryString + "_HM2_Males_C", 1);
coeffCovarianceHM2CaseFemales = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + "reg_health_mental.xlsx", countryString + "_HM2_Females_C", 1);

validateRegressors(coeffCovarianceHM2CaseMales, "reg_health_mental.xlsx", "HM2_Males_C");

Comment on lines +1143 to 1144
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should come out as was put in to test. Will be run automatically if safeReadExcel is implemented.

Suggested change
validateRegressors(coeffCovarianceHM2CaseMales, "reg_health_mental.xlsx", "HM2_Males_C");

//Health
coeffCovarianceDHE_MCS1 = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + "reg_health_wellbeing.xlsx", countryString + "_DHE_MCS1", 1);
coeffCovarianceDHE_MCS2Males = ExcelAssistant.loadCoefficientMap(Parameters.getInputDirectory() + "reg_health_wellbeing.xlsx", countryString + "_DHE_MCS2_Males", 1);
Expand Down Expand Up @@ -3230,6 +3234,55 @@ public static void setEuromodOutputDirectory(String euromodOutputDirectory) {
EUROMOD_TRAINING_DIRECTORY = EUROMOD_OUTPUT_DIRECTORY + "training" + File.separator;
}

public static void validateRegressors(MultiKeyCoefficientMap map, String excelFileName, String sheetName) {
if (map == null) return;

// Get the values read from the REGRESSOR column by ExcelAssistant (excludes 'Constant')
Set<Object> regressorNames = map.keySet();

// Check across all
for (Object regressor : regressorNames) {
if (regressor instanceof MultiKey mk) {
String keyName = mk.getKey(0).toString();

// Test if a Person Enum
try {
Person.DoublesVariables.valueOf(keyName);
} catch (IllegalArgumentException e) {
try {
BenefitUnit.Regressors.valueOf(keyName);
} catch (IllegalArgumentException e2) {
Comment on lines +3249 to +3254
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a hacky test - checking whether looking up both Person and BenefitUnit enums errors out. The error IllegalArgumentException isn't the best fit, perhaps needs to go deeper to get a better error in each of these cases, or do a more literal check of what enum values are present in each set?

Or leave as-is if checking valueOf and returning IllegalArgumentException is a good standard way of testing?


// This fires if the string isn't in the Enum
throw new RuntimeException("Validation failed for " + excelFileName + " in " + sheetName +
": Regressor '" + keyName + "' not found in Person.DoublesVariables. " +
"Check for typos in Excel or missing Enums in Person.java.");
Comment on lines +3256 to +3259
}
}
}
}
}

public static MultiKeyCoefficientMap safeReadExcel(String excelFileName, String sheetName, int keyColumns) {

MultiKeyCoefficientMap map = ExcelAssistant.loadCoefficientMap(excelFileName, sheetName, keyColumns);

validateRegressors(map, excelFileName, sheetName);

return map;

}

public static MultiKeyCoefficientMap safeReadExcel(String excelFileName, String sheetName, int keyColumns, int valueColumns) {

MultiKeyCoefficientMap map = ExcelAssistant.loadCoefficientMap(excelFileName, sheetName, keyColumns, valueColumns);

validateRegressors(map, excelFileName, sheetName);

return map;

}

public static String getInputDirectory() {
return INPUT_DIRECTORY;
}
Expand Down
32 changes: 32 additions & 0 deletions src/test/java/simpaths/data/ParametersTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package simpaths.data;

import microsim.data.MultiKeyCoefficientMap;
import org.junit.jupiter.api.Test;

import java.util.Arrays;

Comment on lines +6 to +7
import static org.junit.jupiter.api.Assertions.*;

class ParametersTest {

/**
* Tests regressor validation logic using valid/invalid maps
*/
@Test
void validateRegressors() {

String[] badValueVector = new String[] {"Dag", "Not_a_valid_value"};
String[] goodValueVector = new String[] {"Dag", "D_Home_owner", "PovertyToNonPoverty"};
String[] keyVector = new String[] {"REGRESSOR"};
Comment on lines +18 to +20
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'good' values depend on stable enums being in Person.java (e.g. D_Home_owner). If this changes, the test will fail, though the method would still work correctly.


MultiKeyCoefficientMap badMap = new MultiKeyCoefficientMap(keyVector, badValueVector);
for (String badValue : badValueVector) {badMap.putValue(badValue, 0);}

MultiKeyCoefficientMap goodMap = new MultiKeyCoefficientMap(keyVector, goodValueVector);
for (String goodValue : goodValueVector) {goodMap.putValue(goodValue, 0);}

assertThrows(RuntimeException.class, () -> Parameters.validateRegressors(badMap, "A map designed to contain invalid values", "Sheet1"));
assertDoesNotThrow(() -> Parameters.validateRegressors(goodMap, "A map designed to contain valid values", "Sheet1"));
Comment on lines +18 to +29

}
}
Loading