From c5d60e75822e6362de9078ce581e3d2c431be5a1 Mon Sep 17 00:00:00 2001 From: howew Date: Thu, 30 Jul 2026 12:35:25 -0400 Subject: [PATCH 1/5] #220 - PRCDA algorithm updates --- CHANGELOG.md | 2 + .../com/imsweb/algorithms/Algorithms.java | 2 - .../algorithms/internal/CountryData.java | 1 - .../algorithms/internal/CountyData.java | 9 - .../algorithms/prcda/PrcdaAlgorithm.java | 4 - .../algorithms/prcda/PrcdaDataProvider.java | 29 +- .../algorithms/prcda/PrcdaOutputDto.java | 9 - .../imsweb/algorithms/prcda/PrcdaUtils.java | 12 +- .../ruralurban/RuralUrbanUtils.java | 2 +- src/main/resources/prcda/prcda.csv | 1297 ++++++++++------- src/main/resources/prcda/readme.txt | 2 +- .../com/imsweb/algorithms/AlgorithmsTest.java | 1 - .../algorithms/prcda/PrcdaUtilsTest.java | 6 - 13 files changed, 801 insertions(+), 575 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bf54df..69c2a07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ **Changes in version 5.11 (not released yet)** - Added 2023 calculated field for Rural Urban Continuum algorithm. +- Updated the lookup for item #194 in the PRCDA algorithm to use 2024 PRCDA counties +- Removed the 2017 calculated field from the PRCDA algorithm. - Updated dependencies. **Changes in version 5.10** diff --git a/src/main/java/com/imsweb/algorithms/Algorithms.java b/src/main/java/com/imsweb/algorithms/Algorithms.java index 14dec2f..b0a4ebd 100644 --- a/src/main/java/com/imsweb/algorithms/Algorithms.java +++ b/src/main/java/com/imsweb/algorithms/Algorithms.java @@ -195,7 +195,6 @@ public final class Algorithms { public static final String FIELD_IARC_MP_INDICATOR = "iarcMpIndicator"; public static final String FIELD_COUNTY_AT_DX_ANALYSIS_FLAG = "countyAtDxAnalysisFlag"; public static final String FIELD_IHS_PRCDA = "ihsPurchRefCareDeliveryArea"; - public static final String FIELD_IHS_PRCDA_2017 = "ihsPurchRefCareDeliveryArea2017"; public static final String FIELD_UIHO = "urbanIndianHealthOrganization"; public static final String FIELD_UIHO_CITY = "uihoFacility"; public static final String FIELD_ACS_YOST_QUINTILE_US = "yostQuintileUS"; @@ -360,7 +359,6 @@ public static void initialize() { addField(AlgorithmField.of(FIELD_IARC_MP_INDICATOR, 9400, 1, "IARC Multiple Primary Indicator", "IARC MP", DATA_LEVEL_TUMOR, false)); addField(AlgorithmField.of(FIELD_COUNTY_AT_DX_ANALYSIS_FLAG, 9440, 4, "County at DX Analysis Flag", "DX Anlys Cty Fg", DATA_LEVEL_TUMOR, false)); addField(AlgorithmField.of(FIELD_RURAL_CONT_2023, 9470, 2, "RuralUrban Continuum 2023", "Rur Urb Cont 23", DATA_LEVEL_TUMOR, false)); - addField(AlgorithmField.of(FIELD_IHS_PRCDA_2017, 9970, 1, "IHS PRCDA 2017", "IHS PRCDA 2017", DATA_LEVEL_TUMOR, false)); addField(AlgorithmField.of(FIELD_ACS_YOST_QUINTILE_US, 9610, 1, "Yost Quintile (Across States)", "Yost US", DATA_LEVEL_TUMOR, false)); addField(AlgorithmField.of(FIELD_ACS_YOST_QUINTILE_STATE, 9611, 1, "Yost Quintile (State Specific)", "Yost State", DATA_LEVEL_TUMOR, false)); addField(AlgorithmField.of(FIELD_ACS_POV_ALL_RACES, 9612, 6, "ACS Pct Poverty (All Races)", "ACS Pov All", DATA_LEVEL_TUMOR, false)); diff --git a/src/main/java/com/imsweb/algorithms/internal/CountryData.java b/src/main/java/com/imsweb/algorithms/internal/CountryData.java index eaf28f3..9f757ac 100644 --- a/src/main/java/com/imsweb/algorithms/internal/CountryData.java +++ b/src/main/java/com/imsweb/algorithms/internal/CountryData.java @@ -513,7 +513,6 @@ public void initializePrcdaData(Map> data) { for (Map.Entry countyEntry : stateEntry.getValue().entrySet()) { CountyData countyData = stateData.getData().computeIfAbsent(countyEntry.getKey(), k -> new CountyData()); countyData.setPrcda(countyEntry.getValue().getPrcda()); - countyData.setPrcda2017(countyEntry.getValue().getPrcda2017()); } } } diff --git a/src/main/java/com/imsweb/algorithms/internal/CountyData.java b/src/main/java/com/imsweb/algorithms/internal/CountyData.java index a5890f0..5f99320 100644 --- a/src/main/java/com/imsweb/algorithms/internal/CountyData.java +++ b/src/main/java/com/imsweb/algorithms/internal/CountyData.java @@ -13,7 +13,6 @@ public class CountyData { // prcda, uiho data private String _prcda; - private String _prcda2017; private String _uiho; private String _uihoCity; @@ -30,18 +29,10 @@ public String getPrcda() { return _prcda; } - public String getPrcda2017() { - return _prcda2017; - } - public void setPrcda(String prcda) { _prcda = prcda; } - public void setPrcda2017(String prcda2017) { - _prcda2017 = prcda2017; - } - public String getUiho() { return _uiho; } diff --git a/src/main/java/com/imsweb/algorithms/prcda/PrcdaAlgorithm.java b/src/main/java/com/imsweb/algorithms/prcda/PrcdaAlgorithm.java index e7d913f..a999eaf 100644 --- a/src/main/java/com/imsweb/algorithms/prcda/PrcdaAlgorithm.java +++ b/src/main/java/com/imsweb/algorithms/prcda/PrcdaAlgorithm.java @@ -16,7 +16,6 @@ import static com.imsweb.algorithms.Algorithms.FIELD_COUNTY_AT_DX_ANALYSIS; import static com.imsweb.algorithms.Algorithms.FIELD_IHS_PRCDA; -import static com.imsweb.algorithms.Algorithms.FIELD_IHS_PRCDA_2017; import static com.imsweb.algorithms.Algorithms.FIELD_STATE_DX; import static com.imsweb.algorithms.prcda.PrcdaUtils.PRCDA_UNKNOWN; @@ -29,10 +28,8 @@ public PrcdaAlgorithm() { _inputFields.add(Algorithms.getField(FIELD_COUNTY_AT_DX_ANALYSIS)); _outputFields.add(Algorithms.getField(FIELD_IHS_PRCDA)); - _outputFields.add(Algorithms.getField(FIELD_IHS_PRCDA_2017)); _unknownValues.put(FIELD_IHS_PRCDA, Collections.singletonList(PRCDA_UNKNOWN)); - _unknownValues.put(FIELD_IHS_PRCDA_2017, Collections.singletonList(PRCDA_UNKNOWN)); } @Override @@ -48,7 +45,6 @@ public AlgorithmOutput execute(AlgorithmInput input) { Map outputTumor = new HashMap<>(); outputTumor.put(FIELD_IHS_PRCDA, outputDto.getPrcda()); - outputTumor.put(FIELD_IHS_PRCDA_2017, outputDto.getPrcda2017()); Utils.addTumorOutput(outputPatient, outputTumor); } diff --git a/src/main/java/com/imsweb/algorithms/prcda/PrcdaDataProvider.java b/src/main/java/com/imsweb/algorithms/prcda/PrcdaDataProvider.java index 781992c..0ffefd0 100644 --- a/src/main/java/com/imsweb/algorithms/prcda/PrcdaDataProvider.java +++ b/src/main/java/com/imsweb/algorithms/prcda/PrcdaDataProvider.java @@ -30,25 +30,7 @@ */ public class PrcdaDataProvider { - private enum PrcdaYear { - YR2017, YR2020; - - public static PrcdaYear getDefault() { - return YR2020; - } - } - public String getPrcda(String state, String county) { - return getPrcdaData(PrcdaYear.getDefault(), state, county); - } - - public String getPrcda2017(String state, String county) { - return getPrcdaData(PrcdaYear.YR2017, state, county); - } - - private String getPrcdaData(PrcdaYear prcdaYear, String state, String county) { - prcdaYear = prcdaYear == null ? PrcdaYear.getDefault() : prcdaYear; - if (ENTIRE_STATE_PRCDA.contains(state)) return PRCDA_YES; else if (ENTIRE_STATE_NON_PRCDA.contains(state)) @@ -67,10 +49,7 @@ else if (isInvalidStateOrCounty(state, county) || isUnknownStateOrCounty(state, if (countyData == null) return PRCDA_NO; - if (PrcdaYear.YR2017.equals(prcdaYear)) - return countyData.getPrcda2017(); - else - return countyData.getPrcda(); + return countyData.getPrcda(); } private Map> loadPrcdaData() { @@ -80,11 +59,9 @@ private Map> loadPrcdaData() { String state = line.getField(0); String county = line.getField(1); - String prcda2017 = line.getField(2); - String prcda2020 = line.getField(3); + String prcda2024 = line.getField(2); CountyData dto = result.computeIfAbsent(state, k -> new HashMap<>()).computeIfAbsent(county, k -> new CountyData()); - dto.setPrcda2017(StringUtils.leftPad(prcda2017, 1, '0')); - dto.setPrcda(StringUtils.leftPad(prcda2020, 1, '0')); + dto.setPrcda(StringUtils.leftPad(prcda2024, 1, '0')); }); return result; diff --git a/src/main/java/com/imsweb/algorithms/prcda/PrcdaOutputDto.java b/src/main/java/com/imsweb/algorithms/prcda/PrcdaOutputDto.java index cfb5ea8..210e4a0 100644 --- a/src/main/java/com/imsweb/algorithms/prcda/PrcdaOutputDto.java +++ b/src/main/java/com/imsweb/algorithms/prcda/PrcdaOutputDto.java @@ -6,21 +6,12 @@ public class PrcdaOutputDto { private String _prcda; - private String _prcda2017; public String getPrcda() { return _prcda; } - public String getPrcda2017() { - return _prcda2017; - } - public void setPrcda(String str) { _prcda = str; } - - public void setPrcda2017(String str) { - _prcda2017 = str; - } } diff --git a/src/main/java/com/imsweb/algorithms/prcda/PrcdaUtils.java b/src/main/java/com/imsweb/algorithms/prcda/PrcdaUtils.java index 2ae187a..692f3b7 100644 --- a/src/main/java/com/imsweb/algorithms/prcda/PrcdaUtils.java +++ b/src/main/java/com/imsweb/algorithms/prcda/PrcdaUtils.java @@ -23,7 +23,7 @@ public final class PrcdaUtils { public static final String ALG_NAME = "NPCR PRCDA Linkage Program"; - public static final String ALG_VERSION = "version 2.2 released in June 2022"; + public static final String ALG_VERSION = "July 30, 2026"; public static final String PRCDA_NO = "0"; public static final String PRCDA_YES = "1"; @@ -53,7 +53,7 @@ private PrcdaUtils() { } /** - * Calculates PRCDA and PRCDA2017 for the provided record + * Calculates PRCDA for the provided record *

* The provided record doesn't need to contain all the input variables, but the algorithm will use the following ones: *
    @@ -62,7 +62,7 @@ private PrcdaUtils() { *
* All those properties are defined as constants in this class. *

- * PRCDA and PRCDA2017 will have one the following values: + * PRCDA will have one the following values: * 0 = Not a PRCDA county * 1 = PRCDA county * 9 = Unknown @@ -77,28 +77,22 @@ public static PrcdaOutputDto computePrcda(StateCountyInputDto input) { if (ENTIRE_STATE_PRCDA.contains(input.getAddressAtDxState())) { result.setPrcda(PRCDA_YES); - result.setPrcda2017(PRCDA_YES); } else if (ENTIRE_STATE_NON_PRCDA.contains(input.getAddressAtDxState())) { result.setPrcda(PRCDA_NO); - result.setPrcda2017(PRCDA_NO); } else { if (input.hasInvalidStateOrCounty() || input.hasUnknownStateOrCounty() || input.countyIsNotReported()) { result.setPrcda(PRCDA_UNKNOWN); - result.setPrcda2017(PRCDA_UNKNOWN); } else { result.setPrcda(_PROVIDER.getPrcda(input.getAddressAtDxState(), input.getCountyAtDxAnalysis())); - result.setPrcda2017(_PROVIDER.getPrcda2017(input.getAddressAtDxState(), input.getCountyAtDxAnalysis())); } } // get methods should never return null, but let's make sure we don't return null value anyway if (result.getPrcda() == null) result.setPrcda(PRCDA_NO); - if (result.getPrcda2017() == null) - result.setPrcda2017(PRCDA_NO); return result; } diff --git a/src/main/java/com/imsweb/algorithms/ruralurban/RuralUrbanUtils.java b/src/main/java/com/imsweb/algorithms/ruralurban/RuralUrbanUtils.java index e7caef9..5f71285 100644 --- a/src/main/java/com/imsweb/algorithms/ruralurban/RuralUrbanUtils.java +++ b/src/main/java/com/imsweb/algorithms/ruralurban/RuralUrbanUtils.java @@ -13,7 +13,7 @@ public final class RuralUrbanUtils { public static final String ALG_NAME = "NAACCR Rural Urban Program"; - public static final String ALG_VERSION = "released in September 2025"; + public static final String ALG_VERSION = "July 8, 2026"; // unknown values for each code public static final String URBAN_RURAL_INDICATOR_CODE_UNKNOWN = "C"; diff --git a/src/main/resources/prcda/prcda.csv b/src/main/resources/prcda/prcda.csv index 7ac7ab0..3f048a3 100644 --- a/src/main/resources/prcda/prcda.csv +++ b/src/main/resources/prcda/prcda.csv @@ -1,506 +1,791 @@ -state,county,prcda2017,prcda2020 -"AL","003","1","1" -"AL","051","1","1" -"AL","053","1","1" -"AL","097","1","1" -"AL","099","1","1" -"AZ","001","1","1" -"AZ","003","1","1" -"AZ","005","1","1" -"AZ","007","1","1" -"AZ","009","1","1" -"AZ","011","1","1" -"AZ","012","1","1" -"AZ","013","1","1" -"AZ","015","1","1" -"AZ","017","1","1" -"AZ","019","1","1" -"AZ","021","1","1" -"AZ","025","1","1" -"AZ","027","1","1" -"CA","003","1","1" -"CA","005","1","1" -"CA","007","1","1" -"CA","009","1","1" -"CA","011","1","1" -"CA","015","1","1" -"CA","017","1","1" -"CA","019","1","1" -"CA","021","1","1" -"CA","023","1","1" -"CA","025","1","1" -"CA","027","1","1" -"CA","029","1","1" -"CA","031","1","1" -"CA","033","1","1" -"CA","035","1","1" -"CA","039","1","1" -"CA","043","1","1" -"CA","045","1","1" -"CA","049","1","1" -"CA","051","1","1" -"CA","057","1","1" -"CA","061","1","1" -"CA","063","1","1" -"CA","065","1","1" -"CA","067","1","1" -"CA","071","1","1" -"CA","073","1","1" -"CA","083","1","1" -"CA","089","1","1" -"CA","091","1","1" -"CA","093","1","1" -"CA","097","1","1" -"CA","101","1","1" -"CA","103","1","1" -"CA","105","1","1" -"CA","107","1","1" -"CA","109","1","1" -"CA","113","1","1" -"CA","115","1","1" -"CO","007","1","1" -"CO","067","1","1" -"CO","083","1","1" -"CO","103","1","1" -"FL","011","1","1" -"FL","021","1","1" -"FL","033","1","1" -"FL","043","1","1" -"FL","051","1","1" -"FL","086","1","1" -"IA","133","1","1" -"IA","155","1","1" -"IA","171","1","1" -"IA","193","1","1" -"ID","005","1","1" -"ID","009","1","1" -"ID","011","1","1" -"ID","021","1","1" -"ID","029","1","1" -"ID","035","1","1" -"ID","049","1","1" -"ID","055","1","1" -"ID","057","1","1" -"ID","059","1","1" -"ID","061","1","1" -"ID","069","1","1" -"ID","073","1","1" -"ID","077","1","1" -"IN","039","1","1" -"IN","085","1","1" -"IN","091","1","1" -"IN","099","1","1" -"IN","141","1","1" -"IN","149","1","1" -"KS","013","1","1" -"KS","043","1","1" -"KS","045","1","1" -"KS","085","1","1" -"LA","003","1","1" -"LA","009","1","1" -"LA","043","1","1" -"LA","059","1","1" -"LA","079","1","1" -"LA","101","1","1" -"MA","001","1","1" -"MA","005","1","1" -"MA","007","1","1" -"MA","021","1","1" -"MA","023","1","1" -"MA","025","1","1" -"ME","003","1","1" -"ME","009","1","1" -"ME","019","1","1" -"ME","029","1","1" -"MI","001","1","1" -"MI","003","1","1" -"MI","005","1","1" -"MI","007","1","1" -"MI","009","1","1" -"MI","011","1","1" -"MI","013","1","1" -"MI","015","1","1" -"MI","019","1","1" -"MI","021","1","1" -"MI","023","1","1" -"MI","025","1","1" -"MI","027","1","1" -"MI","029","1","1" -"MI","031","1","1" -"MI","033","1","1" -"MI","035","1","1" -"MI","039","1","1" -"MI","041","1","1" -"MI","047","1","1" -"MI","053","1","1" -"MI","055","1","1" -"MI","061","1","1" -"MI","069","1","1" -"MI","073","1","1" -"MI","077","1","1" -"MI","079","1","1" -"MI","081","1","1" -"MI","085","1","1" -"MI","089","1","1" -"MI","095","1","1" -"MI","097","1","1" -"MI","101","1","1" -"MI","103","1","1" -"MI","105","1","1" -"MI","109","1","1" -"MI","111","1","1" -"MI","113","1","1" -"MI","119","1","1" -"MI","121","1","1" -"MI","123","1","1" -"MI","127","1","1" -"MI","129","1","1" -"MI","131","1","1" -"MI","135","1","1" -"MI","137","1","1" -"MI","139","1","1" -"MI","141","1","1" -"MI","143","1","1" -"MI","153","1","1" -"MI","159","1","1" -"MI","165","1","1" -"MN","001","1","1" -"MN","005","1","1" -"MN","007","1","1" -"MN","017","1","1" -"MN","021","1","1" -"MN","023","1","1" -"MN","029","1","1" -"MN","031","1","1" -"MN","035","0","1" -"MN","049","1","1" -"MN","055","1","1" -"MN","057","1","1" -"MN","061","1","1" -"MN","065","1","1" -"MN","071","1","1" -"MN","077","1","1" -"MN","087","1","1" -"MN","089","1","1" -"MN","095","1","1" -"MN","097","0","1" -"MN","107","1","1" -"MN","113","1","1" -"MN","115","1","1" -"MN","119","1","1" -"MN","127","1","1" -"MN","129","1","1" -"MN","135","1","1" -"MN","139","1","1" -"MN","137","1","1" -"MN","155","1","1" -"MN","173","1","1" -"MS","007","1","1" -"MS","061","1","1" -"MS","067","1","1" -"MS","069","1","1" -"MS","079","1","1" -"MS","099","1","1" -"MS","101","1","1" -"MS","103","1","1" -"MS","123","1","1" -"MS","159","1","1" -"MT","003","1","1" -"MT","005","1","1" -"MT","009","1","1" -"MT","011","1","1" -"MT","013","0","1" -"MT","015","1","1" -"MT","019","1","1" -"MT","029","1","1" -"MT","035","1","1" -"MT","041","1","1" -"MT","047","1","1" -"MT","051","1","1" -"MT","055","1","1" -"MT","063","1","1" -"MT","071","1","1" -"MT","073","1","1" -"MT","083","1","1" -"MT","085","1","1" -"MT","087","1","1" -"MT","089","1","1" -"MT","091","1","1" -"MT","103","1","1" -"MT","105","1","1" -"MT","111","1","1" -"NC","025","1","1" -"NC","039","1","1" -"NC","045","1","1" -"NC","071","1","1" -"NC","075","1","1" -"NC","087","1","1" -"NC","099","1","1" -"NC","119","1","1" -"NC","161","1","1" -"NC","173","1","1" -"NC","179","1","1" -"ND","001","1","1" -"ND","005","1","1" -"ND","023","1","1" -"ND","025","1","1" -"ND","027","1","1" -"ND","029","1","1" -"ND","037","1","1" -"ND","053","1","1" -"ND","055","1","1" -"ND","057","1","1" -"ND","059","1","1" -"ND","061","1","1" -"ND","063","1","1" -"ND","071","1","1" -"ND","077","1","1" -"ND","079","1","1" -"ND","081","1","1" -"ND","085","1","1" -"ND","101","1","1" -"ND","105","1","1" -"NE","015","1","1" -"NE","021","1","1" -"NE","031","1","1" -"NE","039","1","1" -"NE","043","1","1" -"NE","045","1","1" -"NE","051","1","1" -"NE","055","1","1" -"NE","079","1","1" -"NE","089","1","1" -"NE","107","1","1" -"NE","109","1","1" -"NE","119","1","1" -"NE","141","1","1" -"NE","147","1","1" -"NE","153","1","1" -"NE","161","1","1" -"NE","167","1","1" -"NE","173","1","1" -"NE","179","1","1" -"NM","001","1","1" -"NM","005","1","1" -"NM","006","1","1" -"NM","007","1","1" -"NM","027","1","1" -"NM","028","1","1" -"NM","031","1","1" -"NM","035","1","1" -"NM","039","1","1" -"NM","045","1","1" -"NM","043","1","1" -"NM","049","1","1" -"NM","053","1","1" -"NM","055","1","1" -"NM","057","1","1" -"NM","061","1","1" -"NY","003","1","1" -"NY","009","1","1" -"NY","013","1","1" -"NY","017","1","1" -"NY","023","1","1" -"NY","029","1","1" -"NY","033","1","1" -"NY","037","1","1" -"NY","043","1","1" -"NY","053","1","1" -"NY","059","1","1" -"NY","063","1","1" -"NY","065","1","1" -"NY","067","1","1" -"NY","089","1","1" -"NY","103","1","1" -"OR","003","1","1" -"OR","005","1","1" -"OR","009","1","1" -"OR","011","1","1" -"OR","015","1","1" -"OR","017","1","1" -"OR","019","1","1" -"OR","025","1","1" -"OR","029","1","1" -"OR","031","1","1" -"OR","033","1","1" -"OR","035","1","1" -"OR","039","1","1" -"OR","041","1","1" -"OR","043","1","1" -"OR","045","1","1" -"OR","047","1","1" -"OR","051","1","1" -"OR","053","1","1" -"OR","057","1","1" -"OR","059","1","1" -"OR","061","1","1" -"OR","065","1","1" -"OR","067","1","1" -"OR","071","1","1" -"PA","123","1","1" -"RI","009","1","1" -"SD","007","1","1" -"SD","009","1","1" -"SD","015","1","1" -"SD","017","1","1" -"SD","021","1","1" -"SD","023","1","1" -"SD","029","1","1" -"SD","031","1","1" -"SD","033","1","1" -"SD","037","1","1" -"SD","041","1","1" -"SD","043","1","1" -"SD","047","1","1" -"SD","051","1","1" -"SD","053","1","1" -"SD","055","1","1" -"SD","059","1","1" -"SD","065","1","1" -"SD","067","1","1" -"SD","069","1","1" -"SD","071","1","1" -"SD","085","1","1" -"SD","091","1","1" -"SD","093","1","1" -"SD","095","1","1" -"SD","101","1","1" -"SD","103","1","1" -"SD","105","1","1" -"SD","107","1","1" -"SD","109","1","1" -"SD","113","1","1" -"SD","117","1","1" -"SD","119","1","1" -"SD","121","1","1" -"SD","123","1","1" -"SD","129","1","1" -"SD","137","1","1" -"TX","141","1","1" -"TX","323","1","1" -"TX","373","1","1" -"UT","003","1","1" -"UT","007","1","1" -"UT","009","1","1" -"UT","011","0","1" -"UT","013","1","1" -"UT","015","1","1" -"UT","019","1","1" -"UT","021","1","1" -"UT","023","1","1" -"UT","025","1","1" -"UT","027","1","1" -"UT","035","0","1" -"UT","037","1","1" -"UT","041","1","1" -"UT","043","1","1" -"UT","045","1","1" -"UT","047","1","1" -"UT","049","1","1" -"UT","051","1","1" -"UT","053","1","1" -"UT","057","0","1" -"VA","003","0","1" -"VA","009","0","1" -"VA","011","0","1" -"VA","015","0","1" -"VA","019","0","1" -"VA","023","0","1" -"VA","029","0","1" -"VA","530","0","1" -"VA","031","0","1" -"VA","033","1","1" -"VA","036","0","1" -"VA","540","0","1" -"VA","550","0","1" -"VA","057","0","1" -"VA","650","0","1" -"VA","085","1","1" -"VA","087","1","1" -"VA","095","0","1" -"VA","097","1","1" -"VA","101","1","1" -"VA","678","0","1" -"VA","680","0","1" -"VA","119","0","1" -"VA","125","0","1" -"VA","127","1","1" -"VA","700","0","1" -"VA","710","0","1" -"VA","740","0","1" -"VA","159","0","1" -"VA","760","1","1" -"VA","163","0","1" -"VA","790","0","1" -"VA","800","0","1" -"VA","810","0","1" -"VA","820","0","1" -"WA","007","1","1" -"WA","009","1","1" -"WA","011","1","1" -"WA","015","1","1" -"WA","017","1","1" -"WA","019","1","1" -"WA","025","1","1" -"WA","027","1","1" -"WA","029","1","1" -"WA","031","1","1" -"WA","033","1","1" -"WA","035","1","1" -"WA","037","1","1" -"WA","039","1","1" -"WA","041","1","1" -"WA","043","1","1" -"WA","045","1","1" -"WA","047","1","1" -"WA","049","1","1" -"WA","051","1","1" -"WA","053","1","1" -"WA","055","1","1" -"WA","057","1","1" -"WA","059","1","1" -"WA","061","1","1" -"WA","063","1","1" -"WA","065","1","1" -"WA","067","1","1" -"WA","069","1","1" -"WA","073","1","1" -"WA","075","1","1" -"WA","077","1","1" -"WI","001","1","1" -"WI","003","1","1" -"WI","005","1","1" -"WI","007","1","1" -"WI","009","1","1" -"WI","013","1","1" -"WI","019","1","1" -"WI","021","1","1" -"WI","023","1","1" -"WI","025","1","1" -"WI","035","1","1" -"WI","041","1","1" -"WI","051","1","1" -"WI","053","1","1" -"WI","057","1","1" -"WI","063","1","1" -"WI","067","1","1" -"WI","073","1","1" -"WI","075","1","1" -"WI","078","1","1" -"WI","081","1","1" -"WI","083","1","1" -"WI","085","1","1" -"WI","087","1","1" -"WI","095","1","1" -"WI","111","1","1" -"WI","113","1","1" -"WI","115","1","1" -"WI","123","1","1" -"WI","125","1","1" -"WI","129","1","1" -"WI","141","1","1" -"WY","003","1","1" -"WY","013","1","1" -"WY","017","1","1" -"WY","033","1","1" -"WY","035","1","1" \ No newline at end of file +state,county,prcda2024 +AK,013,1 +AK,016,1 +AK,020,1 +AK,050,1 +AK,060,1 +AK,068,1 +AK,070,1 +AK,090,1 +AK,100,1 +AK,105,1 +AK,110,1 +AK,122,1 +AK,130,1 +AK,150,1 +AK,158,1 +AK,164,1 +AK,170,1 +AK,180,1 +AK,185,1 +AK,188,1 +AK,195,1 +AK,198,1 +AK,201,1 +AK,220,1 +AK,230,1 +AK,232,1 +AK,240,1 +AK,261,1 +AK,275,1 +AK,280,1 +AK,282,1 +AK,290,1 +AL,003,1 +AL,051,1 +AL,053,1 +AL,097,1 +AL,099,1 +AZ,001,1 +AZ,003,1 +AZ,005,1 +AZ,007,1 +AZ,009,1 +AZ,011,1 +AZ,012,1 +AZ,013,1 +AZ,015,1 +AZ,017,1 +AZ,019,1 +AZ,021,1 +AZ,025,1 +AZ,027,1 +CA,003,1 +CA,005,1 +CA,007,1 +CA,009,1 +CA,011,1 +CA,015,1 +CA,017,1 +CA,019,1 +CA,021,1 +CA,023,1 +CA,025,1 +CA,027,1 +CA,029,1 +CA,031,1 +CA,033,1 +CA,035,1 +CA,039,1 +CA,043,1 +CA,045,1 +CA,049,1 +CA,051,1 +CA,057,1 +CA,061,1 +CA,063,1 +CA,065,1 +CA,067,1 +CA,071,1 +CA,073,1 +CA,083,1 +CA,089,1 +CA,091,1 +CA,093,1 +CA,097,1 +CA,101,1 +CA,103,1 +CA,105,1 +CA,107,1 +CA,109,1 +CA,113,1 +CA,115,1 +CO,007,1 +CO,067,1 +CO,083,1 +CO,103,1 +CT,001,1 +CT,003,1 +CT,005,1 +CT,007,1 +CT,009,1 +CT,011,1 +CT,013,1 +CT,015,1 +FL,011,1 +FL,021,1 +FL,033,1 +FL,043,1 +FL,051,1 +FL,086,1 +IA,133,1 +IA,155,1 +IA,171,1 +IA,193,1 +ID,005,1 +ID,009,1 +ID,011,1 +ID,021,1 +ID,029,1 +ID,035,1 +ID,049,1 +ID,055,1 +ID,057,1 +ID,059,1 +ID,061,1 +ID,069,1 +ID,073,1 +ID,077,1 +IN,039,1 +IN,085,1 +IN,091,1 +IN,099,1 +IN,141,1 +IN,149,1 +KS,013,1 +KS,043,1 +KS,045,1 +KS,085,1 +LA,003,1 +LA,009,1 +LA,043,1 +LA,059,1 +LA,079,1 +LA,101,1 +MA,001,1 +MA,005,1 +MA,007,1 +MA,021,1 +MA,023,1 +MA,025,1 +MD,001,1 +MD,003,1 +MD,005,1 +MD,009,1 +MD,013,1 +MD,015,1 +MD,017,1 +MD,021,1 +MD,025,1 +MD,027,1 +MD,029,1 +MD,031,1 +MD,033,1 +MD,035,1 +MD,037,1 +MD,043,1 +MD,510,1 +ME,003,1 +ME,009,1 +ME,019,1 +ME,029,1 +MI,001,1 +MI,003,1 +MI,005,1 +MI,007,1 +MI,009,1 +MI,011,1 +MI,013,1 +MI,015,1 +MI,019,1 +MI,021,1 +MI,023,1 +MI,025,1 +MI,027,1 +MI,029,1 +MI,031,1 +MI,033,1 +MI,035,1 +MI,039,1 +MI,041,1 +MI,047,1 +MI,053,1 +MI,055,1 +MI,061,1 +MI,069,1 +MI,073,1 +MI,077,1 +MI,079,1 +MI,081,1 +MI,085,1 +MI,089,1 +MI,095,1 +MI,097,1 +MI,101,1 +MI,103,1 +MI,105,1 +MI,109,1 +MI,111,1 +MI,113,1 +MI,119,1 +MI,121,1 +MI,123,1 +MI,127,1 +MI,129,1 +MI,131,1 +MI,135,1 +MI,137,1 +MI,139,1 +MI,141,1 +MI,143,1 +MI,153,1 +MI,159,1 +MI,165,1 +MN,001,1 +MN,005,1 +MN,007,1 +MN,017,1 +MN,021,1 +MN,023,1 +MN,029,1 +MN,031,1 +MN,035,1 +MN,049,1 +MN,055,1 +MN,057,1 +MN,061,1 +MN,065,1 +MN,071,1 +MN,077,1 +MN,087,1 +MN,089,1 +MN,095,1 +MN,097,1 +MN,107,1 +MN,113,1 +MN,115,1 +MN,119,1 +MN,127,1 +MN,129,1 +MN,135,1 +MN,137,1 +MN,139,1 +MN,155,1 +MN,173,1 +MS,007,1 +MS,015,1 +MS,059,1 +MS,061,1 +MS,067,1 +MS,069,1 +MS,079,1 +MS,099,1 +MS,101,1 +MS,103,1 +MS,123,1 +MS,159,1 +MT,003,1 +MT,005,1 +MT,009,1 +MT,011,1 +MT,013,1 +MT,015,1 +MT,019,1 +MT,029,1 +MT,035,1 +MT,041,1 +MT,047,1 +MT,051,1 +MT,055,1 +MT,063,1 +MT,071,1 +MT,073,1 +MT,083,1 +MT,085,1 +MT,087,1 +MT,089,1 +MT,091,1 +MT,103,1 +MT,105,1 +MT,111,1 +NC,003,1 +NC,025,1 +NC,029,1 +NC,035,1 +NC,039,1 +NC,041,1 +NC,045,1 +NC,053,1 +NC,057,1 +NC,059,1 +NC,063,1 +NC,067,1 +NC,069,1 +NC,071,1 +NC,073,1 +NC,075,1 +NC,077,1 +NC,081,1 +NC,087,1 +NC,099,1 +NC,101,1 +NC,119,1 +NC,135,1 +NC,139,1 +NC,151,1 +NC,159,1 +NC,161,1 +NC,167,1 +NC,169,1 +NC,173,1 +NC,179,1 +NC,183,1 +ND,001,1 +ND,005,1 +ND,023,1 +ND,025,1 +ND,027,1 +ND,029,1 +ND,037,1 +ND,053,1 +ND,055,1 +ND,057,1 +ND,059,1 +ND,061,1 +ND,063,1 +ND,071,1 +ND,077,1 +ND,079,1 +ND,081,1 +ND,085,1 +ND,101,1 +ND,105,1 +NE,015,1 +NE,021,1 +NE,031,1 +NE,039,1 +NE,043,1 +NE,045,1 +NE,051,1 +NE,055,1 +NE,079,1 +NE,089,1 +NE,107,1 +NE,109,1 +NE,119,1 +NE,141,1 +NE,147,1 +NE,153,1 +NE,161,1 +NE,167,1 +NE,173,1 +NE,179,1 +NM,001,1 +NM,005,1 +NM,006,1 +NM,007,1 +NM,027,1 +NM,028,1 +NM,031,1 +NM,035,1 +NM,039,1 +NM,043,1 +NM,045,1 +NM,049,1 +NM,053,1 +NM,055,1 +NM,057,1 +NM,061,1 +NV,001,1 +NV,003,1 +NV,005,1 +NV,007,1 +NV,009,1 +NV,011,1 +NV,013,1 +NV,015,1 +NV,017,1 +NV,019,1 +NV,021,1 +NV,023,1 +NV,027,1 +NV,029,1 +NV,031,1 +NV,033,1 +NV,510,1 +NY,003,1 +NY,009,1 +NY,013,1 +NY,017,1 +NY,023,1 +NY,029,1 +NY,033,1 +NY,037,1 +NY,043,1 +NY,053,1 +NY,059,1 +NY,063,1 +NY,065,1 +NY,067,1 +NY,089,1 +NY,103,1 +OK,001,1 +OK,003,1 +OK,005,1 +OK,007,1 +OK,009,1 +OK,011,1 +OK,013,1 +OK,015,1 +OK,017,1 +OK,019,1 +OK,021,1 +OK,023,1 +OK,025,1 +OK,027,1 +OK,029,1 +OK,031,1 +OK,033,1 +OK,035,1 +OK,037,1 +OK,039,1 +OK,041,1 +OK,043,1 +OK,045,1 +OK,047,1 +OK,049,1 +OK,051,1 +OK,053,1 +OK,055,1 +OK,057,1 +OK,059,1 +OK,061,1 +OK,063,1 +OK,065,1 +OK,067,1 +OK,069,1 +OK,071,1 +OK,073,1 +OK,075,1 +OK,077,1 +OK,079,1 +OK,081,1 +OK,083,1 +OK,085,1 +OK,087,1 +OK,089,1 +OK,091,1 +OK,093,1 +OK,095,1 +OK,097,1 +OK,099,1 +OK,101,1 +OK,103,1 +OK,105,1 +OK,107,1 +OK,109,1 +OK,111,1 +OK,113,1 +OK,115,1 +OK,117,1 +OK,119,1 +OK,121,1 +OK,123,1 +OK,125,1 +OK,127,1 +OK,129,1 +OK,131,1 +OK,133,1 +OK,135,1 +OK,137,1 +OK,139,1 +OK,141,1 +OK,143,1 +OK,145,1 +OK,147,1 +OK,149,1 +OK,151,1 +OK,153,1 +OR,003,1 +OR,005,1 +OR,009,1 +OR,011,1 +OR,015,1 +OR,017,1 +OR,019,1 +OR,025,1 +OR,029,1 +OR,031,1 +OR,033,1 +OR,035,1 +OR,039,1 +OR,041,1 +OR,043,1 +OR,045,1 +OR,047,1 +OR,051,1 +OR,053,1 +OR,057,1 +OR,059,1 +OR,061,1 +OR,065,1 +OR,067,1 +OR,071,1 +PA,123,1 +RI,009,1 +SC,001,1 +SC,003,1 +SC,005,1 +SC,007,1 +SC,009,1 +SC,011,1 +SC,013,1 +SC,015,1 +SC,017,1 +SC,019,1 +SC,021,1 +SC,023,1 +SC,025,1 +SC,027,1 +SC,029,1 +SC,031,1 +SC,033,1 +SC,035,1 +SC,037,1 +SC,039,1 +SC,041,1 +SC,043,1 +SC,045,1 +SC,047,1 +SC,049,1 +SC,051,1 +SC,053,1 +SC,055,1 +SC,057,1 +SC,059,1 +SC,061,1 +SC,063,1 +SC,065,1 +SC,067,1 +SC,069,1 +SC,071,1 +SC,073,1 +SC,075,1 +SC,077,1 +SC,079,1 +SC,081,1 +SC,083,1 +SC,085,1 +SC,087,1 +SC,089,1 +SC,091,1 +SD,007,1 +SD,009,1 +SD,015,1 +SD,017,1 +SD,021,1 +SD,023,1 +SD,029,1 +SD,031,1 +SD,033,1 +SD,037,1 +SD,041,1 +SD,043,1 +SD,047,1 +SD,051,1 +SD,053,1 +SD,055,1 +SD,059,1 +SD,065,1 +SD,067,1 +SD,069,1 +SD,071,1 +SD,085,1 +SD,091,1 +SD,093,1 +SD,095,1 +SD,101,1 +SD,102,1 +SD,103,1 +SD,105,1 +SD,107,1 +SD,109,1 +SD,113,1 +SD,117,1 +SD,119,1 +SD,121,1 +SD,123,1 +SD,129,1 +SD,137,1 +TN,097,1 +TX,141,1 +TX,323,1 +TX,373,1 +UT,003,1 +UT,007,1 +UT,009,1 +UT,011,1 +UT,013,1 +UT,015,1 +UT,019,1 +UT,021,1 +UT,023,1 +UT,025,1 +UT,027,1 +UT,035,1 +UT,037,1 +UT,041,1 +UT,043,1 +UT,045,1 +UT,047,1 +UT,049,1 +UT,051,1 +UT,053,1 +UT,057,1 +VA,001,1 +VA,003,1 +VA,005,1 +VA,007,1 +VA,009,1 +VA,011,1 +VA,013,1 +VA,015,1 +VA,017,1 +VA,019,1 +VA,023,1 +VA,029,1 +VA,031,1 +VA,033,1 +VA,036,1 +VA,037,1 +VA,041,1 +VA,043,1 +VA,047,1 +VA,049,1 +VA,053,1 +VA,057,1 +VA,061,1 +VA,063,1 +VA,065,1 +VA,073,1 +VA,075,1 +VA,079,1 +VA,081,1 +VA,085,1 +VA,087,1 +VA,093,1 +VA,095,1 +VA,097,1 +VA,099,1 +VA,101,1 +VA,103,1 +VA,107,1 +VA,109,1 +VA,111,1 +VA,115,1 +VA,117,1 +VA,119,1 +VA,121,1 +VA,125,1 +VA,127,1 +VA,135,1 +VA,137,1 +VA,139,1 +VA,141,1 +VA,143,1 +VA,145,1 +VA,147,1 +VA,149,1 +VA,153,1 +VA,155,1 +VA,159,1 +VA,163,1 +VA,165,1 +VA,175,1 +VA,177,1 +VA,179,1 +VA,187,1 +VA,193,1 +VA,199,1 +VA,510,1 +VA,530,1 +VA,540,1 +VA,550,1 +VA,570,1 +VA,580,1 +VA,595,1 +VA,600,1 +VA,610,1 +VA,620,1 +VA,630,1 +VA,650,1 +VA,660,1 +VA,670,1 +VA,678,1 +VA,680,1 +VA,683,1 +VA,685,1 +VA,700,1 +VA,710,1 +VA,730,1 +VA,735,1 +VA,740,1 +VA,750,1 +VA,760,1 +VA,770,1 +VA,775,1 +VA,790,1 +VA,800,1 +VA,810,1 +VA,820,1 +VA,830,1 +VA,917,1 +WA,007,1 +WA,009,1 +WA,011,1 +WA,015,1 +WA,017,1 +WA,019,1 +WA,025,1 +WA,027,1 +WA,029,1 +WA,031,1 +WA,033,1 +WA,035,1 +WA,037,1 +WA,039,1 +WA,041,1 +WA,043,1 +WA,045,1 +WA,047,1 +WA,049,1 +WA,051,1 +WA,053,1 +WA,055,1 +WA,057,1 +WA,059,1 +WA,061,1 +WA,063,1 +WA,065,1 +WA,067,1 +WA,069,1 +WA,073,1 +WA,075,1 +WA,077,1 +WI,001,1 +WI,003,1 +WI,005,1 +WI,007,1 +WI,009,1 +WI,013,1 +WI,019,1 +WI,021,1 +WI,023,1 +WI,025,1 +WI,035,1 +WI,041,1 +WI,051,1 +WI,053,1 +WI,057,1 +WI,063,1 +WI,067,1 +WI,073,1 +WI,075,1 +WI,078,1 +WI,081,1 +WI,083,1 +WI,085,1 +WI,087,1 +WI,095,1 +WI,111,1 +WI,113,1 +WI,115,1 +WI,123,1 +WI,125,1 +WI,129,1 +WI,141,1 +WY,003,1 +WY,013,1 +WY,017,1 +WY,033,1 +WY,035,1 \ No newline at end of file diff --git a/src/main/resources/prcda/readme.txt b/src/main/resources/prcda/readme.txt index 32c3ab5..135cfb4 100644 --- a/src/main/resources/prcda/readme.txt +++ b/src/main/resources/prcda/readme.txt @@ -1 +1 @@ -The data was provided by CDC. See NAACCR Call for Data issue #76. \ No newline at end of file +The data was provided by CDC. See NAACCR Call for Data issue #145. \ No newline at end of file diff --git a/src/test/java/com/imsweb/algorithms/AlgorithmsTest.java b/src/test/java/com/imsweb/algorithms/AlgorithmsTest.java index e1f40bf..49052c5 100644 --- a/src/test/java/com/imsweb/algorithms/AlgorithmsTest.java +++ b/src/test/java/com/imsweb/algorithms/AlgorithmsTest.java @@ -314,7 +314,6 @@ public void testDefaultAlgorithms() { tumMap.put(Algorithms.FIELD_COUNTY_AT_DX_ANALYSIS, "035"); patMap.put(Algorithms.FIELD_TUMORS, Collections.singletonList(tumMap)); tumor = Utils.extractTumors(alg.execute(input).getPatient()).getFirst(); - Assert.assertEquals("0", tumor.get(Algorithms.FIELD_IHS_PRCDA_2017)); Assert.assertEquals("1", tumor.get(Algorithms.FIELD_IHS_PRCDA)); // UIHO diff --git a/src/test/java/com/imsweb/algorithms/prcda/PrcdaUtilsTest.java b/src/test/java/com/imsweb/algorithms/prcda/PrcdaUtilsTest.java index 6cea063..b0fc207 100644 --- a/src/test/java/com/imsweb/algorithms/prcda/PrcdaUtilsTest.java +++ b/src/test/java/com/imsweb/algorithms/prcda/PrcdaUtilsTest.java @@ -27,13 +27,11 @@ public void testComputePrcda() { input.setAddressAtDxState("LO"); input.setCountyAtDxAnalysis("071"); Assert.assertEquals("1", PrcdaUtils.computePrcda(input).getPrcda()); - Assert.assertEquals("1", PrcdaUtils.computePrcda(input).getPrcda2017()); // test Puerto Rico input.setAddressAtDxState("PR"); input.setCountyAtDxAnalysis("001"); Assert.assertEquals("0", PrcdaUtils.computePrcda(input).getPrcda()); - Assert.assertEquals("0", PrcdaUtils.computePrcda(input).getPrcda2017()); // test for when the entire state is PRCDA // if the entire state is PRCDA then we should always return 1 regardless of what the county is @@ -42,7 +40,6 @@ public void testComputePrcda() { input.setCountyAtDxAnalysis(county); String key = String.format("%s|%s", input.getAddressAtDxState(), county); Assert.assertEquals(key, "1", PrcdaUtils.computePrcda(input).getPrcda()); - Assert.assertEquals(key, "1", PrcdaUtils.computePrcda(input).getPrcda2017()); } // test for when the entire state is NOT PRCDA @@ -52,7 +49,6 @@ public void testComputePrcda() { input.setCountyAtDxAnalysis(county); String key = String.format("%s|%s", input.getAddressAtDxState(), county); Assert.assertEquals(key, "0", PrcdaUtils.computePrcda(input).getPrcda()); - Assert.assertEquals(key, "0", PrcdaUtils.computePrcda(input).getPrcda2017()); } // test missing or invalid state or county - or county not reported @@ -63,11 +59,9 @@ public void testComputePrcda() { String key = String.format("%s|%s", state, county); if ("MN".equals(state) && "035".equals(county)) { Assert.assertEquals(key, "1", PrcdaUtils.computePrcda(input).getPrcda()); - Assert.assertEquals(key, "0", PrcdaUtils.computePrcda(input).getPrcda2017()); } else { Assert.assertEquals(key, "9", PrcdaUtils.computePrcda(input).getPrcda()); - Assert.assertEquals(key, "9", PrcdaUtils.computePrcda(input).getPrcda2017()); } } } From 551fccba17bc548cb1e030f83475f13ef57960f7 Mon Sep 17 00:00:00 2001 From: howew Date: Thu, 13 Aug 2026 10:09:15 -0400 Subject: [PATCH 2/5] #222 - Updated the Yost/ACS algorithm to extend the second-to-last range of the "year for lookup" by one year and to implement the A,B,C,D codes that are found in other census tract lookups. Also corrected a capitalization error in the isInvalidCounty function ("v" should have been lowercase). --- CHANGELOG.md | 1 + .../algorithms/StateCountyInputDto.java | 4 +- .../algorithms/StateCountyTractInputDto.java | 4 +- .../YostAcsPovertyInputDto.java | 77 +++-- .../YostAcsPovertyOutputDto.java | 12 + .../yostacspoverty/YostAcsPovertyUtils.java | 108 +++++-- .../YostAcsPovertyUtilsTest.java | 290 ++++++++++++++---- 7 files changed, 379 insertions(+), 117 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69c2a07..94b1c13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ **Changes in version 5.11 (not released yet)** +- Updated the Yost/ACS algorithm to extend the second-to-last range of the "year for lookup" by one year and to implement the A,B,C,D codes that are found in other census tract lookups. - Added 2023 calculated field for Rural Urban Continuum algorithm. - Updated the lookup for item #194 in the PRCDA algorithm to use 2024 PRCDA counties - Removed the 2017 calculated field from the PRCDA algorithm. diff --git a/src/main/java/com/imsweb/algorithms/StateCountyInputDto.java b/src/main/java/com/imsweb/algorithms/StateCountyInputDto.java index e1bf554..a4761c3 100644 --- a/src/main/java/com/imsweb/algorithms/StateCountyInputDto.java +++ b/src/main/java/com/imsweb/algorithms/StateCountyInputDto.java @@ -57,7 +57,7 @@ public boolean hasUnknownStateOrCounty() { return isUnknownStateOrCounty(_addressAtDxState, _countyAtDxAnalysis); } - public static boolean isInValidCounty(String county) { + public static boolean isInvalidCounty(String county) { return !(isValidCounty(county) || isUnknownCounty(county)); } @@ -66,7 +66,7 @@ public static boolean isInvalidState(String state) { } public static boolean isInvalidStateOrCounty(String state, String county) { - return isInvalidState(state) || isInValidCounty(county); + return isInvalidState(state) || isInvalidCounty(county); } public static boolean isUnknownCounty(String county) { diff --git a/src/main/java/com/imsweb/algorithms/StateCountyTractInputDto.java b/src/main/java/com/imsweb/algorithms/StateCountyTractInputDto.java index 93c0649..cc37667 100644 --- a/src/main/java/com/imsweb/algorithms/StateCountyTractInputDto.java +++ b/src/main/java/com/imsweb/algorithms/StateCountyTractInputDto.java @@ -30,7 +30,7 @@ public void applyRecodes() { _censusTract2020 = _censusTract2020 == null ? "" : _censusTract2020.trim(); } - private String getCensusTractVariable(CensusTract censusTract) { + protected String getCensusTractVariable(CensusTract censusTract) { if (CensusTract.CENSUS_2000.equals(censusTract)) return _censusTract2000; if (CensusTract.CENSUS_2010.equals(censusTract)) @@ -53,7 +53,7 @@ public static boolean isInvalidCensusTract(String censusTract) { } public static boolean isInvalidStateCountyOrCensusTract(String state, String county, String censusTract) { - return isInvalidState(state) || isInValidCounty(county) || isInvalidCensusTract(censusTract); + return isInvalidState(state) || isInvalidCounty(county) || isInvalidCensusTract(censusTract); } public static boolean isUnknownCensusTract(String censusTract) { diff --git a/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyInputDto.java b/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyInputDto.java index 7518c3a..c521c05 100644 --- a/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyInputDto.java +++ b/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyInputDto.java @@ -1,54 +1,77 @@ package com.imsweb.algorithms.yostacspoverty; -public class YostAcsPovertyInputDto { +import com.imsweb.algorithms.StateCountyTractInputDto; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; - private String _addressAtDxState; +import static com.imsweb.algorithms.yostacspoverty.YostAcsPovertyUtils.YOST_ACS_CENSUS_TRACT_PIVOT_YEAR; - private String _countyAtDxAnalysis; +public class YostAcsPovertyInputDto extends StateCountyTractInputDto { - private String _censusTract2010; - - private String _censusTract2020; + private static final String MISSING_YEAR = ""; private String _dateOfDiagnosis; + private String _yearOfDiagnosis; - public String getAddressAtDxState() { - return _addressAtDxState; + @Override + public void applyRecodes() { + super.applyRecodes(); + _dateOfDiagnosis = _dateOfDiagnosis == null ? "" : _dateOfDiagnosis.trim(); + _yearOfDiagnosis = _yearOfDiagnosis == null ? "" : _yearOfDiagnosis.trim(); } - public void setAddressAtDxState(String addressAtDxState) { - _addressAtDxState = addressAtDxState; + public int computeYearOfDiagnosis() { + if (isValidYear(_yearOfDiagnosis)) { + return Integer.parseInt(_yearOfDiagnosis); + } + return -1; } - public String getCountyAtDxAnalysis() { - return _countyAtDxAnalysis; + public String getDateOfDiagnosis() { + return _dateOfDiagnosis; } - public void setCountyAtDxAnalysis(String countyAtDxAnalysis) { - _countyAtDxAnalysis = countyAtDxAnalysis; + public void setDateOfDiagnosis(String dateOfDiagnosis) { + _dateOfDiagnosis = dateOfDiagnosis; + _yearOfDiagnosis = dateOfDiagnosis == null ? null : StringUtils.rightPad(dateOfDiagnosis, 4).substring(0, 4).trim(); } - public String getCensusTract2010() { - return _censusTract2010; + public boolean hasInvalidStateCountyCensusTractOrYear() { + if (isInvalidState(getAddressAtDxState()) || isInvalidCounty(getCountyAtDxAnalysis()) || isInvalidYear(_yearOfDiagnosis)) + return true; + // if year is missing we don't know which census tract is the right one to use, so just check both + if (isUnknownYear(_yearOfDiagnosis)) + return isInvalidCensusTract(getCensusTract2010()) || isInvalidCensusTract(getCensusTract2020()); + // year isn't missing, so check the census tract we'll end up using for the lookup + int dxYear = Integer.parseInt(_yearOfDiagnosis); + CensusTract censusTract = dxYear <= YOST_ACS_CENSUS_TRACT_PIVOT_YEAR ? CensusTract.CENSUS_2010 : CensusTract.CENSUS_2020; + return isInvalidCensusTract(getCensusTractVariable(censusTract)); } - public void setCensusTract2010(String censusTract2010) { - _censusTract2010 = censusTract2010; + public boolean hasUnknownStateCountyCensusTractOrYear() { + if (isUnknownState(getAddressAtDxState()) || isUnknownCounty(getCountyAtDxAnalysis()) || isUnknownYear(_yearOfDiagnosis)) + return true; + // if year is invalid we don't know which census tract is the right one to use, so just check both + if (isInvalidYear(_yearOfDiagnosis)) + return isUnknownCensusTract(getCensusTract2010()) || isUnknownCensusTract(getCensusTract2020()); + // year isn't invalid, so check the census tract we'll end up using for the lookup + int dxYear = Integer.parseInt(_yearOfDiagnosis); + CensusTract censusTract = dxYear <= YOST_ACS_CENSUS_TRACT_PIVOT_YEAR ? CensusTract.CENSUS_2010 : CensusTract.CENSUS_2020; + return isUnknownCensusTract(getCensusTractVariable(censusTract)); } - public String getCensusTract2020() { - return _censusTract2020; + public static boolean isInvalidYear(String year) { + return !(isValidYear(year) || isUnknownYear(year)); } - public void setCensusTract2020(String censusTract2020) { - _censusTract2020 = censusTract2020; + public static boolean isUnknownYear(String year) { + return MISSING_YEAR.equals(year); } - public String getDateOfDiagnosis() { - return _dateOfDiagnosis; + // this is private because it's meant to be more of a helper function + // I want users of this class to use the "Invalid" and "Unknown" functions + private static boolean isValidYear(String year) { + return year != null && year.length() == 4 && NumberUtils.isDigits(year); } - public void setDateOfDiagnosis(String dateOfDiagnosis) { - _dateOfDiagnosis = dateOfDiagnosis; - } } diff --git a/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyOutputDto.java b/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyOutputDto.java index 91bf669..3004989 100644 --- a/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyOutputDto.java +++ b/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyOutputDto.java @@ -24,6 +24,18 @@ public String getYostQuintileUS() { return _yostQuintileUS; } + public void setAllFields(String value) { + _yostQuintileUS = value; + _yostQuintileState = value; + _acsPctPovAllRaces = value; + _acsPctPovWhite = value; + _acsPctPovBlack = value; + _acsPctPovAIAN = value; + _acsPctPovAsianNHOPI = value; + _acsPctPovWhiteNonHisp = value; + _acsPctPovHispanic = value; + } + public void setYostQuintileUS(String yostQuintileUS) { _yostQuintileUS = yostQuintileUS; } diff --git a/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtils.java b/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtils.java index 35bea00..26fa5d6 100644 --- a/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtils.java +++ b/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtils.java @@ -1,16 +1,13 @@ package com.imsweb.algorithms.yostacspoverty; -import java.time.LocalDate; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.math.NumberUtils; - import com.imsweb.algorithms.internal.CensusData; import com.imsweb.algorithms.internal.CountryData; import com.imsweb.algorithms.internal.CountyData; import com.imsweb.algorithms.internal.StateData; import com.imsweb.algorithms.internal.YearData; +import java.time.LocalDate; + /** * This class can be used to calculate ACS Linkage variables. * Created on Oct 13, 2017 by howew @@ -19,16 +16,54 @@ public final class YostAcsPovertyUtils { public static final String ALG_NAME = "NAACCR Yost Quintile & Area-Based Social Measures Linkage Program"; - public static final String ALG_VERSION = "released in September 2025"; + public static final String ALG_VERSION = "August 13, 2026"; + + public static final int YOST_ACS_CENSUS_TRACT_PIVOT_YEAR = 2015; + + //Unknown values for each code + public static final String YOST_ACS_UNK_A = "A"; + public static final String YOST_ACS_UNK_B = "B"; + public static final String YOST_ACS_UNK_C = "C"; + public static final String YOST_ACS_UNK_D = "D"; private YostAcsPovertyUtils() { // no instances of this class allowed! } + /** + * Helper method to compute the lookup year. + * The algorithm uses data from 2006 to 2024, but it uses 5-years estimate data points, meaning it only has data points from 2008 to 2022. + * Different DX years use different data points: + * - 2006-2007 use the 2008 data point from 2010 census + * - 2008-2015 use the provided year data point for 2010 census (so 2008 uses the 2008 data point, 2009 uses the 2009 data point, etc...) + * - 2016-2017 use the 2018 data point from 2020 census + * - 2018-2022 use the provided year data point for 2020 census (so 2018 uses the 2018 data point, etc...) + * - 2023+ use the 2022 data point from 2020 census + * @param dxYear the year of diagnosis from the input dto + * @return the dx year to use for the lookup + */ + private static int computeYearForLookup(int dxYear) { + int yearForLookup = dxYear; + if (dxYear == 2006 || dxYear == 2007) + yearForLookup = 2008; + else if (dxYear == 2016 || dxYear == 2017) + yearForLookup = 2018; + else if (dxYear >= 2023) + yearForLookup = 2022; + return yearForLookup; + } + /** * Calculates the ACS data for the provided ACS data input dto *

* The returned dto will contain yost indices and acs poverty percentages across a number of time periods + * or one of the unknown values listed below: + *
    + *
  • A = State, county, tract, or year of dx are invalid
  • + *
  • B = State, tract, and year of dx are valid, but county was not reported
  • + *
  • C = State + county + tract + year combination was not found
  • + *
  • D = State, county, tract, or year of dx are blank or unknown/li> + *
*

* @param input a ACSLinkageInputDto input object * @return the computed ACS data @@ -36,24 +71,21 @@ private YostAcsPovertyUtils() { public static YostAcsPovertyOutputDto computeYostAcsPovertyData(YostAcsPovertyInputDto input) { YostAcsPovertyOutputDto result = new YostAcsPovertyOutputDto(); - String state = input.getAddressAtDxState(); - String county = input.getCountyAtDxAnalysis(); - String census2010 = input.getCensusTract2010(); - String census2020 = input.getCensusTract2020(); - String year = input.getDateOfDiagnosis() == null ? null : StringUtils.rightPad(input.getDateOfDiagnosis(), 4).substring(0, 4).trim(); - - if (state != null && county != null && (census2010 != null || census2020 != null) && NumberUtils.isDigits(year)) { - int dxYear = Integer.parseInt(year); - - // The algorithm uses data from 2006 to 2023, but it uses 5-years estimate data points, meaning it only has data points from 2008 to 2021. - // Different DX years use different data points: - // - 2006-2007 use the 2008 data point from 2010 census - // - 2008-2015 use the provided year data point for 2010 census (so 2008 uses the 2008 data point, 2009 uses the 2009 data point, etc...) - // - 2016-2017 use the 2018 data point from 2020 census - // - 2018-2021 use the provided year data point for 2020 census (so 2018 uses the 2018 data point, etc...) - // - 2022+ use the 2021 data point from 2020 census + input.applyRecodes(); + if (input.hasInvalidStateCountyCensusTractOrYear()) + result.setAllFields(YOST_ACS_UNK_A); + else if (input.hasUnknownStateCountyCensusTractOrYear()) + result.setAllFields(YOST_ACS_UNK_D); + else if (input.countyIsNotReported()) + result.setAllFields(YOST_ACS_UNK_B); + else { + int dxYear = input.computeYearOfDiagnosis(); if (dxYear >= 2006 && dxYear <= LocalDate.now().getYear()) { + String state = input.getAddressAtDxState(); + String county = input.getCountyAtDxAnalysis(); + String census2010 = input.getCensusTract2010(); + String census2020 = input.getCensusTract2020(); if (!CountryData.getInstance().isYearBasedTractDataInitialized(state)) CountryData.getInstance().initializeYearBasedTractData(state); @@ -62,17 +94,9 @@ public static YostAcsPovertyOutputDto computeYostAcsPovertyData(YostAcsPovertyIn if (stateData != null) { CountyData countyData = stateData.getCountyData(county); if (countyData != null) { - CensusData censusData = countyData.getCensusData(dxYear <= 2015 ? census2010 : census2020); + CensusData censusData = countyData.getCensusData(dxYear <= YOST_ACS_CENSUS_TRACT_PIVOT_YEAR ? census2010 : census2020); if (censusData != null) { - - int yearForLookup = dxYear; - if (dxYear == 2006 || dxYear == 2007) - yearForLookup = 2008; - else if (dxYear == 2016 || dxYear == 2017) - yearForLookup = 2018; - else if (dxYear >= 2022) - yearForLookup = 2021; - + int yearForLookup = computeYearForLookup(dxYear); YearData yearData = censusData.getYearData(String.valueOf(yearForLookup)); if (yearData != null) { result.setYostQuintileUS(yearData.getYostQuintileUS()); @@ -90,7 +114,25 @@ else if (dxYear >= 2022) } } } + if (result.getYostQuintileUS() == null) + result.setYostQuintileUS(YOST_ACS_UNK_C); + if (result.getYostQuintileState() == null) + result.setYostQuintileState(YOST_ACS_UNK_C); + if (result.getAcsPctPovAllRaces() == null) + result.setAcsPctPovAllRaces(YOST_ACS_UNK_C); + if (result.getAcsPctPovWhite() == null) + result.setAcsPctPovWhite(YOST_ACS_UNK_C); + if (result.getAcsPctPovBlack() == null) + result.setAcsPctPovBlack(YOST_ACS_UNK_C); + if (result.getAcsPctPovAsianNHOPI() == null) + result.setAcsPctPovAsianNHOPI(YOST_ACS_UNK_C); + if (result.getAcsPctPovAIAN() == null) + result.setAcsPctPovAIAN(YOST_ACS_UNK_C); + if (result.getAcsPctPovWhiteNonHisp() == null) + result.setAcsPctPovWhiteNonHisp(YOST_ACS_UNK_C); + if (result.getAcsPctPovHispanic() == null) + result.setAcsPctPovHispanic(YOST_ACS_UNK_C); return result; } -} +} \ No newline at end of file diff --git a/src/test/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtilsTest.java b/src/test/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtilsTest.java index b519492..a2afe92 100644 --- a/src/test/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtilsTest.java +++ b/src/test/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtilsTest.java @@ -11,27 +11,234 @@ public class YostAcsPovertyUtilsTest { @Test public void testYostAcsPoverty() { YostAcsPovertyInputDto idto = new YostAcsPovertyInputDto(); + YostAcsPovertyOutputDto odto; + + // invalid state + idto.setAddressAtDxState("12345"); + idto.setCountyAtDxAnalysis("020"); + idto.setCensusTract2010("001702"); + idto.setCensusTract2020("001702"); + idto.setDateOfDiagnosis("2021"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("A", odto.getYostQuintileUS()); + Assert.assertEquals("A", odto.getYostQuintileState()); + Assert.assertEquals("A", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("A", odto.getAcsPctPovWhite()); + Assert.assertEquals("A", odto.getAcsPctPovBlack()); + Assert.assertEquals("A", odto.getAcsPctPovAIAN()); + Assert.assertEquals("A", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("A", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("A", odto.getAcsPctPovHispanic()); + + // invalid county + idto.setAddressAtDxState("AK"); + idto.setCountyAtDxAnalysis("ABCDE"); + idto.setCensusTract2010("001702"); + idto.setCensusTract2020("001702"); + idto.setDateOfDiagnosis("2021"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("A", odto.getYostQuintileUS()); + Assert.assertEquals("A", odto.getYostQuintileState()); + Assert.assertEquals("A", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("A", odto.getAcsPctPovWhite()); + Assert.assertEquals("A", odto.getAcsPctPovBlack()); + Assert.assertEquals("A", odto.getAcsPctPovAIAN()); + Assert.assertEquals("A", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("A", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("A", odto.getAcsPctPovHispanic()); + + // invalid 2010 census tract + idto.setAddressAtDxState("AK"); + idto.setCountyAtDxAnalysis("001"); + idto.setCensusTract2010("ABCDEF"); + idto.setCensusTract2020("001702"); + idto.setDateOfDiagnosis("2012"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("A", odto.getYostQuintileUS()); + Assert.assertEquals("A", odto.getYostQuintileState()); + Assert.assertEquals("A", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("A", odto.getAcsPctPovWhite()); + Assert.assertEquals("A", odto.getAcsPctPovBlack()); + Assert.assertEquals("A", odto.getAcsPctPovAIAN()); + Assert.assertEquals("A", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("A", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("A", odto.getAcsPctPovHispanic()); + + // invalid 2020 census tract + idto.setAddressAtDxState("AK"); + idto.setCountyAtDxAnalysis("001"); + idto.setCensusTract2010("001702"); + idto.setCensusTract2020("ABCDEF"); + idto.setDateOfDiagnosis("2020"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("A", odto.getYostQuintileUS()); + Assert.assertEquals("A", odto.getYostQuintileState()); + Assert.assertEquals("A", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("A", odto.getAcsPctPovWhite()); + Assert.assertEquals("A", odto.getAcsPctPovBlack()); + Assert.assertEquals("A", odto.getAcsPctPovAIAN()); + Assert.assertEquals("A", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("A", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("A", odto.getAcsPctPovHispanic()); + + // invalid date of dx + idto.setAddressAtDxState("AK"); + idto.setCountyAtDxAnalysis("001"); + idto.setCensusTract2010("001702"); + idto.setCensusTract2020("001702"); + idto.setDateOfDiagnosis("ABCDEF"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("A", odto.getYostQuintileUS()); + Assert.assertEquals("A", odto.getYostQuintileState()); + Assert.assertEquals("A", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("A", odto.getAcsPctPovWhite()); + Assert.assertEquals("A", odto.getAcsPctPovBlack()); + Assert.assertEquals("A", odto.getAcsPctPovAIAN()); + Assert.assertEquals("A", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("A", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("A", odto.getAcsPctPovHispanic()); + + // county not reported (ie, 000) + idto.setAddressAtDxState("AK"); + idto.setCountyAtDxAnalysis("000"); + idto.setCensusTract2010(""); + idto.setCensusTract2020("001702"); + idto.setDateOfDiagnosis("2020"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("B", odto.getYostQuintileUS()); + Assert.assertEquals("B", odto.getYostQuintileState()); + Assert.assertEquals("B", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("B", odto.getAcsPctPovWhite()); + Assert.assertEquals("B", odto.getAcsPctPovBlack()); + Assert.assertEquals("B", odto.getAcsPctPovAIAN()); + Assert.assertEquals("B", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("B", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("B", odto.getAcsPctPovHispanic()); + + // blank state + idto.setAddressAtDxState(""); + idto.setCountyAtDxAnalysis("020"); + idto.setCensusTract2010("001702"); + idto.setCensusTract2020("001702"); + idto.setDateOfDiagnosis("2018"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("D", odto.getYostQuintileUS()); + Assert.assertEquals("D", odto.getYostQuintileState()); + Assert.assertEquals("D", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("D", odto.getAcsPctPovWhite()); + Assert.assertEquals("D", odto.getAcsPctPovBlack()); + Assert.assertEquals("D", odto.getAcsPctPovAIAN()); + Assert.assertEquals("D", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("D", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("D", odto.getAcsPctPovHispanic()); + + // blank county + idto.setAddressAtDxState("AK"); + idto.setCountyAtDxAnalysis(""); + idto.setCensusTract2010("001702"); + idto.setCensusTract2020("001702"); + idto.setDateOfDiagnosis("2018"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("D", odto.getYostQuintileUS()); + Assert.assertEquals("D", odto.getYostQuintileState()); + Assert.assertEquals("D", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("D", odto.getAcsPctPovWhite()); + Assert.assertEquals("D", odto.getAcsPctPovBlack()); + Assert.assertEquals("D", odto.getAcsPctPovAIAN()); + Assert.assertEquals("D", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("D", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("D", odto.getAcsPctPovHispanic()); + + // blank census tract 2010 + idto.setAddressAtDxState("AK"); + idto.setCountyAtDxAnalysis("020"); + idto.setCensusTract2010(""); + idto.setCensusTract2020("001702"); + idto.setDateOfDiagnosis("2012"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("D", odto.getYostQuintileUS()); + Assert.assertEquals("D", odto.getYostQuintileState()); + Assert.assertEquals("D", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("D", odto.getAcsPctPovWhite()); + Assert.assertEquals("D", odto.getAcsPctPovBlack()); + Assert.assertEquals("D", odto.getAcsPctPovAIAN()); + Assert.assertEquals("D", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("D", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("D", odto.getAcsPctPovHispanic()); + + // blank census tract 2020 + idto.setAddressAtDxState("AK"); + idto.setCountyAtDxAnalysis("020"); + idto.setCensusTract2010("001702"); + idto.setCensusTract2020(""); + idto.setDateOfDiagnosis("2018"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("D", odto.getYostQuintileUS()); + Assert.assertEquals("D", odto.getYostQuintileState()); + Assert.assertEquals("D", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("D", odto.getAcsPctPovWhite()); + Assert.assertEquals("D", odto.getAcsPctPovBlack()); + Assert.assertEquals("D", odto.getAcsPctPovAIAN()); + Assert.assertEquals("D", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("D", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("D", odto.getAcsPctPovHispanic()); + + // blank date of diagnosis + idto.setAddressAtDxState("AK"); + idto.setCountyAtDxAnalysis("020"); + idto.setCensusTract2010("001702"); + idto.setCensusTract2020("001702"); + idto.setDateOfDiagnosis(""); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("D", odto.getYostQuintileUS()); + Assert.assertEquals("D", odto.getYostQuintileState()); + Assert.assertEquals("D", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("D", odto.getAcsPctPovWhite()); + Assert.assertEquals("D", odto.getAcsPctPovBlack()); + Assert.assertEquals("D", odto.getAcsPctPovAIAN()); + Assert.assertEquals("D", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("D", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("D", odto.getAcsPctPovHispanic()); // 2005 -> no data available idto.setAddressAtDxState("AL"); idto.setCountyAtDxAnalysis("001"); idto.setCensusTract2010("020200"); + idto.setCensusTract2020(""); idto.setDateOfDiagnosis("2005"); - YostAcsPovertyOutputDto odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); - Assert.assertNull(odto.getYostQuintileUS()); - Assert.assertNull(odto.getYostQuintileState()); - Assert.assertNull(odto.getAcsPctPovAllRaces()); - Assert.assertNull(odto.getAcsPctPovWhite()); - Assert.assertNull(odto.getAcsPctPovBlack()); - Assert.assertNull(odto.getAcsPctPovAIAN()); - Assert.assertNull(odto.getAcsPctPovAsianNHOPI()); - Assert.assertNull(odto.getAcsPctPovWhiteNonHisp()); - Assert.assertNull(odto.getAcsPctPovHispanic()); - - // 2007 using census2010 with year 2008 + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("C", odto.getYostQuintileUS()); + Assert.assertEquals("C", odto.getYostQuintileState()); + Assert.assertEquals("C", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("C", odto.getAcsPctPovWhite()); + Assert.assertEquals("C", odto.getAcsPctPovBlack()); + Assert.assertEquals("C", odto.getAcsPctPovAIAN()); + Assert.assertEquals("C", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("C", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("C", odto.getAcsPctPovHispanic()); + + // test a SEER recode + idto.setAddressAtDxState("LO"); + idto.setCountyAtDxAnalysis("071"); + idto.setCensusTract2010("007903"); + idto.setCensusTract2020(""); + idto.setDateOfDiagnosis("2010"); + odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); + Assert.assertEquals("5", odto.getYostQuintileUS()); + Assert.assertEquals("4", odto.getYostQuintileState()); + Assert.assertEquals("3.03", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("3.81", odto.getAcsPctPovWhite()); + Assert.assertEquals("4.71", odto.getAcsPctPovBlack()); + Assert.assertEquals("", odto.getAcsPctPovAIAN()); + Assert.assertEquals("0.00", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("4.93", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("0.70", odto.getAcsPctPovHispanic()); + + // 2007 using census2010 with yearForLookup 2008 idto.setAddressAtDxState("AL"); idto.setCountyAtDxAnalysis("001"); idto.setCensusTract2010("020200"); + idto.setCensusTract2020(""); idto.setDateOfDiagnosis("2007"); odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); Assert.assertEquals("2", odto.getYostQuintileUS()); @@ -48,6 +255,7 @@ public void testYostAcsPoverty() { idto.setAddressAtDxState("AL"); idto.setCountyAtDxAnalysis("001"); idto.setCensusTract2010("020200"); + idto.setCensusTract2020(""); idto.setDateOfDiagnosis("2008"); odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); Assert.assertEquals("2", odto.getYostQuintileUS()); @@ -64,6 +272,7 @@ public void testYostAcsPoverty() { idto.setAddressAtDxState("AL"); idto.setCountyAtDxAnalysis("001"); idto.setCensusTract2010("020200"); + idto.setCensusTract2020(""); idto.setDateOfDiagnosis("2010"); odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); Assert.assertEquals("2", odto.getYostQuintileUS()); @@ -80,6 +289,7 @@ public void testYostAcsPoverty() { idto.setAddressAtDxState("AK"); idto.setCountyAtDxAnalysis("020"); idto.setCensusTract2010("001702"); + idto.setCensusTract2020(""); idto.setDateOfDiagnosis("20150101"); odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); Assert.assertEquals("5", odto.getYostQuintileUS()); @@ -92,39 +302,10 @@ public void testYostAcsPoverty() { Assert.assertEquals("3.23", odto.getAcsPctPovWhiteNonHisp()); Assert.assertEquals("0.00", odto.getAcsPctPovHispanic()); - // 2016 using census2020 with year 2018 - idto.setAddressAtDxState("AK"); - idto.setCountyAtDxAnalysis("020"); - idto.setCensusTract2010("001702"); - idto.setDateOfDiagnosis("2016"); - odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); - Assert.assertNull(odto.getYostQuintileState()); - Assert.assertNull(odto.getAcsPctPovAllRaces()); - Assert.assertNull(odto.getAcsPctPovWhite()); - Assert.assertNull(odto.getAcsPctPovBlack()); - Assert.assertNull(odto.getAcsPctPovAIAN()); - Assert.assertNull(odto.getAcsPctPovAsianNHOPI()); - Assert.assertNull(odto.getAcsPctPovWhiteNonHisp()); - Assert.assertNull(odto.getAcsPctPovHispanic()); - - // 2018 using census2020 - idto.setAddressAtDxState("AK"); - idto.setCountyAtDxAnalysis("020"); - idto.setCensusTract2010("001702"); - idto.setDateOfDiagnosis("2018"); - odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); - Assert.assertNull(odto.getYostQuintileState()); - Assert.assertNull(odto.getAcsPctPovAllRaces()); - Assert.assertNull(odto.getAcsPctPovWhite()); - Assert.assertNull(odto.getAcsPctPovBlack()); - Assert.assertNull(odto.getAcsPctPovAIAN()); - Assert.assertNull(odto.getAcsPctPovAsianNHOPI()); - Assert.assertNull(odto.getAcsPctPovWhiteNonHisp()); - Assert.assertNull(odto.getAcsPctPovHispanic()); - // 2020 using census2020 idto.setAddressAtDxState("AK"); idto.setCountyAtDxAnalysis("020"); + idto.setCensusTract2010(""); idto.setCensusTract2020("001702"); idto.setDateOfDiagnosis("2020"); odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); @@ -141,7 +322,8 @@ public void testYostAcsPoverty() { // 2021 using census2020 idto.setAddressAtDxState("AK"); idto.setCountyAtDxAnalysis("020"); - idto.setCensusTract2010("001702"); + idto.setCensusTract2010(""); + idto.setCensusTract2020("001702"); idto.setDateOfDiagnosis("2021"); odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); Assert.assertEquals("4", odto.getYostQuintileUS()); @@ -154,20 +336,22 @@ public void testYostAcsPoverty() { Assert.assertEquals("3.09", odto.getAcsPctPovWhiteNonHisp()); Assert.assertEquals("8.09", odto.getAcsPctPovHispanic()); - // 2025 using census2020 with year 2021 + // 2025 using census2020 with yearForLookup 2022 + // note: this may fail once 2022 data is added to the big SEER data file idto.setAddressAtDxState("AK"); idto.setCountyAtDxAnalysis("020"); + idto.setCensusTract2010(""); idto.setCensusTract2020("001702"); idto.setDateOfDiagnosis("2025"); odto = YostAcsPovertyUtils.computeYostAcsPovertyData(idto); - Assert.assertEquals("4", odto.getYostQuintileUS()); - Assert.assertEquals("5", odto.getYostQuintileState()); - Assert.assertEquals("7.12", odto.getAcsPctPovAllRaces()); - Assert.assertEquals("3.03", odto.getAcsPctPovWhite()); - Assert.assertEquals("13.46", odto.getAcsPctPovBlack()); - Assert.assertEquals("34.10", odto.getAcsPctPovAIAN()); - Assert.assertEquals("0.00", odto.getAcsPctPovAsianNHOPI()); - Assert.assertEquals("3.09", odto.getAcsPctPovWhiteNonHisp()); - Assert.assertEquals("8.09", odto.getAcsPctPovHispanic()); + Assert.assertEquals("C", odto.getYostQuintileUS()); + Assert.assertEquals("C", odto.getYostQuintileState()); + Assert.assertEquals("C", odto.getAcsPctPovAllRaces()); + Assert.assertEquals("C", odto.getAcsPctPovWhite()); + Assert.assertEquals("C", odto.getAcsPctPovBlack()); + Assert.assertEquals("C", odto.getAcsPctPovAIAN()); + Assert.assertEquals("C", odto.getAcsPctPovAsianNHOPI()); + Assert.assertEquals("C", odto.getAcsPctPovWhiteNonHisp()); + Assert.assertEquals("C", odto.getAcsPctPovHispanic()); } } From c4a9038e103bd2f79f72d4a0e064c1480931d325 Mon Sep 17 00:00:00 2001 From: howew Date: Thu, 13 Aug 2026 10:26:35 -0400 Subject: [PATCH 3/5] #222 - fixed a unit test, see comment --- .../CensusTractPovertyIndicatorUtilsTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java b/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java index 68fd010..97ebdc6 100644 --- a/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java +++ b/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java @@ -107,10 +107,10 @@ public void testComputePovertyIndicator() { rec.put("censusTract2020", "020600"); rec.put("dateOfDiagnosisYear", "2021"); Assert.assertEquals("2", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); - // test 2025 (census2020) + // test 2025 (census2020) - this may fail once 2022 data is added to the SEER big data file rec.put("censusTract2020", "020600"); rec.put("dateOfDiagnosisYear", "2025"); - Assert.assertEquals("2", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); + Assert.assertEquals("9", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); //test unknown year rec.put("dateOfDiagnosisYear", "9999"); Assert.assertEquals("9", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); From e5e5a2996c2a1df096fbb77586e35cdad19adfe3 Mon Sep 17 00:00:00 2001 From: howew Date: Thu, 13 Aug 2026 10:30:10 -0400 Subject: [PATCH 4/5] #222 - fixed a unit test, see comment --- .../CensusTractPovertyIndicatorUtilsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java b/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java index 97ebdc6..d29891a 100644 --- a/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java +++ b/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java @@ -107,7 +107,7 @@ public void testComputePovertyIndicator() { rec.put("censusTract2020", "020600"); rec.put("dateOfDiagnosisYear", "2021"); Assert.assertEquals("2", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); - // test 2025 (census2020) - this may fail once 2022 data is added to the SEER big data file + // test 2025 (census2020) - note: this may fail once 2022 data is added to the SEER big data file rec.put("censusTract2020", "020600"); rec.put("dateOfDiagnosisYear", "2025"); Assert.assertEquals("9", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); From b10b303b601988d98e627bd80d583d3bdcdc6943 Mon Sep 17 00:00:00 2001 From: howew Date: Thu, 13 Aug 2026 13:18:26 -0400 Subject: [PATCH 5/5] #222 - changed the pivot year to 2017 and updated the logic for computeYearForLookup. 2016 and 2017 now use the provided year instead of 2018 and they now use the 2010 census --- .../yostacspoverty/YostAcsPovertyUtils.java | 7 ++----- .../CensusTractPovertyIndicatorUtilsTest.java | 17 +++++++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtils.java b/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtils.java index 26fa5d6..d1cccd1 100644 --- a/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtils.java +++ b/src/main/java/com/imsweb/algorithms/yostacspoverty/YostAcsPovertyUtils.java @@ -18,7 +18,7 @@ public final class YostAcsPovertyUtils { public static final String ALG_NAME = "NAACCR Yost Quintile & Area-Based Social Measures Linkage Program"; public static final String ALG_VERSION = "August 13, 2026"; - public static final int YOST_ACS_CENSUS_TRACT_PIVOT_YEAR = 2015; + public static final int YOST_ACS_CENSUS_TRACT_PIVOT_YEAR = 2017; //Unknown values for each code public static final String YOST_ACS_UNK_A = "A"; @@ -35,8 +35,7 @@ private YostAcsPovertyUtils() { * The algorithm uses data from 2006 to 2024, but it uses 5-years estimate data points, meaning it only has data points from 2008 to 2022. * Different DX years use different data points: * - 2006-2007 use the 2008 data point from 2010 census - * - 2008-2015 use the provided year data point for 2010 census (so 2008 uses the 2008 data point, 2009 uses the 2009 data point, etc...) - * - 2016-2017 use the 2018 data point from 2020 census + * - 2008-2017 use the provided year data point for 2010 census (so 2008 uses the 2008 data point, 2009 uses the 2009 data point, etc...) * - 2018-2022 use the provided year data point for 2020 census (so 2018 uses the 2018 data point, etc...) * - 2023+ use the 2022 data point from 2020 census * @param dxYear the year of diagnosis from the input dto @@ -46,8 +45,6 @@ private static int computeYearForLookup(int dxYear) { int yearForLookup = dxYear; if (dxYear == 2006 || dxYear == 2007) yearForLookup = 2008; - else if (dxYear == 2016 || dxYear == 2017) - yearForLookup = 2018; else if (dxYear >= 2023) yearForLookup = 2022; return yearForLookup; diff --git a/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java b/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java index d29891a..16ad7a4 100644 --- a/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java +++ b/src/test/java/com/imsweb/algorithms/censustractpovertyindicator/CensusTractPovertyIndicatorUtilsTest.java @@ -95,19 +95,24 @@ public void testComputePovertyIndicator() { rec.put("censusTract2010", "020600"); rec.put("dateOfDiagnosisYear", "2015"); Assert.assertEquals("3", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); - // test 2016 (census2020) - rec.put("censusTract2020", "020600"); + // test 2016 (census2010) - note: this may fail if 2017 data is added to the SEER big data file (2010 geographies) + rec.put("censusTract2010", "020600"); rec.put("dateOfDiagnosisYear", "2016"); - Assert.assertEquals("4", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); - // test 2017 (census2020) - rec.put("censusTract2020", "020600"); + Assert.assertEquals("9", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); + // test 2017 (census2010) - note: this may fail if 2017 data is added to the SEER big data file (2010 geographies) + rec.put("censusTract2010", "020600"); rec.put("dateOfDiagnosisYear", "2017"); + Assert.assertEquals("9", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); + // test 2018 (census2020) + rec.put("censusTract2010", ""); + rec.put("censusTract2020", "020600"); + rec.put("dateOfDiagnosisYear", "2018"); Assert.assertEquals("4", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); // test 2021 (census2020) rec.put("censusTract2020", "020600"); rec.put("dateOfDiagnosisYear", "2021"); Assert.assertEquals("2", computePovertyIndicator(rec).getCensusTractPovertyIndicator()); - // test 2025 (census2020) - note: this may fail once 2022 data is added to the SEER big data file + // test 2025 (census2020) - note: this may fail once 2022 data is added to the SEER big data file (2020 geographies) rec.put("censusTract2020", "020600"); rec.put("dateOfDiagnosisYear", "2025"); Assert.assertEquals("9", computePovertyIndicator(rec).getCensusTractPovertyIndicator());