hccinfhir 0.2.5__py3-none-any.whl → 0.2.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hccinfhir/data/ra_hierarchies_2026.csv +88 -88
- hccinfhir/data/ra_labels_2026.csv +495 -495
- hccinfhir/model_calculate.py +2 -0
- hccinfhir/model_coefficients.py +17 -1
- hccinfhir/model_interactions.py +116 -21
- {hccinfhir-0.2.5.dist-info → hccinfhir-0.2.7.dist-info}/METADATA +1 -1
- {hccinfhir-0.2.5.dist-info → hccinfhir-0.2.7.dist-info}/RECORD +9 -9
- {hccinfhir-0.2.5.dist-info → hccinfhir-0.2.7.dist-info}/WHEEL +0 -0
- {hccinfhir-0.2.5.dist-info → hccinfhir-0.2.7.dist-info}/licenses/LICENSE +0 -0
hccinfhir/model_calculate.py
CHANGED
|
@@ -115,6 +115,8 @@ def calculate_raf(diagnosis_codes: List[str],
|
|
|
115
115
|
demographic_interactions[key] = value
|
|
116
116
|
elif key.startswith('OriginallyDisabled_'):
|
|
117
117
|
demographic_interactions[key] = value
|
|
118
|
+
elif key == 'LTIMCAID':
|
|
119
|
+
demographic_interactions[key] = value
|
|
118
120
|
|
|
119
121
|
coefficients_demographics = apply_coefficients(demographics,
|
|
120
122
|
set(),
|
hccinfhir/model_coefficients.py
CHANGED
|
@@ -101,7 +101,11 @@ def apply_coefficients(demographics: Demographics,
|
|
|
101
101
|
|
|
102
102
|
# Apply the coefficients
|
|
103
103
|
for hcc in hcc_set:
|
|
104
|
-
|
|
104
|
+
# For RxHCC models, use RXHCC prefix instead of HCC
|
|
105
|
+
if 'RxHCC' in model_name:
|
|
106
|
+
key = (f"{prefix}RXHCC{hcc}".lower(), model_name)
|
|
107
|
+
else:
|
|
108
|
+
key = (f"{prefix}HCC{hcc}".lower(), model_name)
|
|
105
109
|
|
|
106
110
|
if key in coefficients:
|
|
107
111
|
value = coefficients[key]
|
|
@@ -112,11 +116,23 @@ def apply_coefficients(demographics: Demographics,
|
|
|
112
116
|
if interaction_value < 1:
|
|
113
117
|
continue
|
|
114
118
|
|
|
119
|
+
# Standard prefix-based lookup
|
|
115
120
|
key = (f"{prefix}{interaction_key}".lower(), model_name)
|
|
116
121
|
if key in coefficients:
|
|
117
122
|
value = coefficients[key]
|
|
118
123
|
output[interaction_key] = value
|
|
119
124
|
|
|
125
|
+
# No-prefix lookup for ESRD duration coefficients stored without prefix
|
|
126
|
+
# ESRD V21: GE65_DUR*, LT65_DUR*; ESRD V24: FGC_*, FGI_*, LTI_GE65/LT65
|
|
127
|
+
if (interaction_key.startswith('FGC') or
|
|
128
|
+
interaction_key.startswith('FGI') or
|
|
129
|
+
interaction_key.startswith('GE65_DUR') or
|
|
130
|
+
interaction_key.startswith('LT65_DUR') or
|
|
131
|
+
interaction_key in ('LTI_GE65', 'LTI_LT65')):
|
|
132
|
+
key = (interaction_key.lower(), model_name)
|
|
133
|
+
if key in coefficients:
|
|
134
|
+
value = coefficients[key]
|
|
135
|
+
output[interaction_key] = value
|
|
120
136
|
|
|
121
137
|
return output
|
|
122
138
|
|
hccinfhir/model_interactions.py
CHANGED
|
@@ -6,50 +6,145 @@ def has_any_hcc(hcc_list: List[str], hcc_set: Set[str]) -> int:
|
|
|
6
6
|
return int(bool(set(hcc_list) & hcc_set))
|
|
7
7
|
|
|
8
8
|
def create_demographic_interactions(demographics: Demographics) -> dict:
|
|
9
|
-
"""Creates common demographic-based interactions
|
|
9
|
+
"""Creates common demographic-based interactions.
|
|
10
|
+
|
|
11
|
+
This function creates interaction variables that are model-agnostic.
|
|
12
|
+
The coefficient lookup will match only the relevant coefficients for
|
|
13
|
+
each model. Comments indicate which models primarily use each interaction.
|
|
14
|
+
"""
|
|
10
15
|
interactions = {}
|
|
11
|
-
|
|
12
|
-
#
|
|
16
|
+
|
|
17
|
+
# Common demographic flags
|
|
13
18
|
is_female = demographics.sex in ('F', '2')
|
|
14
19
|
is_male = demographics.sex in ('M', '1')
|
|
15
20
|
is_aged = not demographics.non_aged
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
lti = int(demographics.lti) if demographics.lti else 0
|
|
22
|
+
fbd = demographics.fbd
|
|
23
|
+
pbd = demographics.pbd
|
|
24
|
+
graft_months = demographics.graft_months
|
|
25
|
+
|
|
26
|
+
# Medicaid indicator (any dual status)
|
|
27
|
+
mcaid = 1 if demographics.dual_elgbl_cd in {
|
|
28
|
+
'01', '02', '03', '04', '05', '06', '07', '08', '09', '10'
|
|
29
|
+
} else 0
|
|
30
|
+
|
|
31
|
+
# Original Disability interactions (V22, V24, V28, ESRD V21, V24)
|
|
32
|
+
# Only for aged (65+); looked up with prefix (e.g., CNA_, DI_)
|
|
18
33
|
if is_aged:
|
|
19
34
|
interactions['OriginallyDisabled_Female'] = int(demographics.orig_disabled) * int(is_female)
|
|
20
35
|
interactions['OriginallyDisabled_Male'] = int(demographics.orig_disabled) * int(is_male)
|
|
21
|
-
else:
|
|
22
|
-
interactions['OriginallyDisabled_Female'] = 0
|
|
23
|
-
interactions['OriginallyDisabled_Male'] = 0
|
|
24
36
|
|
|
25
|
-
#
|
|
26
|
-
if demographics.
|
|
37
|
+
# Originally ESRD interactions (ESRD V21, V24 Dialysis); looked up as DI_Originally_ESRD_*
|
|
38
|
+
if is_aged and demographics.orec in ('2', '3'):
|
|
39
|
+
interactions['Originally_ESRD_Female'] = int(is_female)
|
|
40
|
+
interactions['Originally_ESRD_Male'] = int(is_male)
|
|
41
|
+
|
|
42
|
+
# MCAID × sex × age interactions (ESRD V21 Dialysis and Community Graft only)
|
|
43
|
+
# V21 used MCAID; V24 uses FBDual/PBDual (handled in create_dual_interactions)
|
|
44
|
+
if mcaid:
|
|
45
|
+
interactions['MCAID_Female_Aged'] = int(is_female) * int(is_aged)
|
|
46
|
+
interactions['MCAID_Female_NonAged'] = int(is_female) * int(not is_aged)
|
|
47
|
+
interactions['MCAID_Male_Aged'] = int(is_male) * int(is_aged)
|
|
48
|
+
interactions['MCAID_Male_NonAged'] = int(is_male) * int(not is_aged)
|
|
49
|
+
|
|
50
|
+
# LTI interactions for ESRD models
|
|
51
|
+
if lti:
|
|
52
|
+
# ESRD V24 Dialysis: looked up as DI_LTI_Aged, DI_LTI_NonAged
|
|
27
53
|
interactions['LTI_Aged'] = int(is_aged)
|
|
28
54
|
interactions['LTI_NonAged'] = int(not is_aged)
|
|
29
|
-
|
|
30
|
-
interactions['
|
|
31
|
-
interactions['
|
|
32
|
-
|
|
55
|
+
# ESRD V24 Graft Institutional: looked up WITHOUT prefix as LTI_GE65, LTI_LT65
|
|
56
|
+
interactions['LTI_GE65'] = int(is_aged)
|
|
57
|
+
interactions['LTI_LT65'] = int(not is_aged)
|
|
58
|
+
|
|
59
|
+
# LTIMCAID for V24, V28 Institutional model; looked up as INS_LTIMCAID
|
|
60
|
+
if lti and mcaid:
|
|
61
|
+
interactions['LTIMCAID'] = lti * mcaid
|
|
62
|
+
|
|
63
|
+
# New Enrollee interactions for V24, V28, ESRD V21, ESRD V24
|
|
33
64
|
nemcaid = False
|
|
34
|
-
if demographics.new_enrollee and demographics.dual_elgbl_cd in {
|
|
65
|
+
if demographics.new_enrollee and demographics.dual_elgbl_cd in {
|
|
66
|
+
'01', '02', '03', '04', '05', '06', '08'
|
|
67
|
+
}:
|
|
35
68
|
nemcaid = True
|
|
36
|
-
ne_origds = int(
|
|
37
|
-
|
|
38
|
-
|
|
69
|
+
ne_origds = int(
|
|
70
|
+
demographics.age >= 65 and
|
|
71
|
+
demographics.orec is not None and
|
|
72
|
+
demographics.orec == "1"
|
|
73
|
+
)
|
|
39
74
|
|
|
40
|
-
#
|
|
75
|
+
# V24, V28, ESRD V21: MCAID/NMCAID style; looked up with NE_ or SNPNE_ prefix
|
|
41
76
|
interactions.update({
|
|
42
77
|
f'NMCAID_NORIGDIS_{demographics.category}': int(not nemcaid and not ne_origds),
|
|
43
78
|
f'MCAID_NORIGDIS_{demographics.category}': int(nemcaid and not ne_origds),
|
|
44
79
|
f'NMCAID_ORIGDIS_{demographics.category}': int(not nemcaid and ne_origds),
|
|
45
80
|
f'MCAID_ORIGDIS_{demographics.category}': int(nemcaid and ne_origds),
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
# ESRD V24: FBD/ND_PBD style; looked up with DNE_ or GNE_ prefix
|
|
84
|
+
interactions.update({
|
|
46
85
|
f'FBD_NORIGDIS_{demographics.category}': int(fbd and not ne_origds),
|
|
47
86
|
f'FBD_ORIGDIS_{demographics.category}': int(fbd and ne_origds),
|
|
48
87
|
f'ND_PBD_NORIGDIS_{demographics.category}': int(not fbd and not ne_origds),
|
|
49
88
|
f'ND_PBD_ORIGDIS_{demographics.category}': int(not fbd and ne_origds)
|
|
50
89
|
})
|
|
51
90
|
|
|
52
|
-
#
|
|
91
|
+
# Functioning Graft Duration "transplant bumps" for ESRD models
|
|
92
|
+
# All looked up WITHOUT prefix - they match directly by name
|
|
93
|
+
if graft_months and graft_months >= 4:
|
|
94
|
+
is_dur4_9 = (4 <= graft_months <= 9)
|
|
95
|
+
is_dur10pl = (graft_months >= 10)
|
|
96
|
+
|
|
97
|
+
# ESRD V21: simple age-based bumps (GE65_DUR4_9, LT65_DUR4_9, etc.)
|
|
98
|
+
if is_dur4_9:
|
|
99
|
+
interactions['GE65_DUR4_9'] = int(is_aged)
|
|
100
|
+
interactions['LT65_DUR4_9'] = int(not is_aged)
|
|
101
|
+
if is_dur10pl:
|
|
102
|
+
interactions['GE65_DUR10PL'] = int(is_aged)
|
|
103
|
+
interactions['LT65_DUR10PL'] = int(not is_aged)
|
|
104
|
+
|
|
105
|
+
# ESRD V24: FGC (Community) / FGI (Institutional) stratified by dual status
|
|
106
|
+
if not fbd:
|
|
107
|
+
# Non-Dual and Partial Benefit Dual (ND_PBD)
|
|
108
|
+
if is_dur4_9:
|
|
109
|
+
interactions.update({
|
|
110
|
+
'FGC_GE65_DUR4_9_ND_PBD': int(is_aged) * int(not lti),
|
|
111
|
+
'FGC_LT65_DUR4_9_ND_PBD': int(not is_aged) * int(not lti),
|
|
112
|
+
'FGI_GE65_DUR4_9_ND_PBD': int(is_aged) * lti,
|
|
113
|
+
'FGI_LT65_DUR4_9_ND_PBD': int(not is_aged) * lti,
|
|
114
|
+
})
|
|
115
|
+
if is_dur10pl:
|
|
116
|
+
interactions.update({
|
|
117
|
+
'FGC_GE65_DUR10PL_ND_PBD': int(is_aged) * int(not lti),
|
|
118
|
+
'FGC_LT65_DUR10PL_ND_PBD': int(not is_aged) * int(not lti),
|
|
119
|
+
'FGI_GE65_DUR10PL_ND_PBD': int(is_aged) * lti,
|
|
120
|
+
'FGI_LT65_DUR10PL_ND_PBD': int(not is_aged) * lti,
|
|
121
|
+
})
|
|
122
|
+
# Extra PBD flag for Partial Benefit Dual members
|
|
123
|
+
if pbd:
|
|
124
|
+
interactions.update({
|
|
125
|
+
'FGC_PBD_GE65_flag': int(is_aged) * int(not lti),
|
|
126
|
+
'FGC_PBD_LT65_flag': int(not is_aged) * int(not lti),
|
|
127
|
+
'FGI_PBD_GE65_flag': int(is_aged) * lti,
|
|
128
|
+
'FGI_PBD_LT65_flag': int(not is_aged) * lti,
|
|
129
|
+
})
|
|
130
|
+
else:
|
|
131
|
+
# Full Benefit Dual (FBD)
|
|
132
|
+
if is_dur4_9:
|
|
133
|
+
interactions.update({
|
|
134
|
+
'FGC_GE65_DUR4_9_FBD': int(is_aged) * int(not lti),
|
|
135
|
+
'FGC_LT65_DUR4_9_FBD': int(not is_aged) * int(not lti),
|
|
136
|
+
'FGI_GE65_DUR4_9_FBD': int(is_aged) * lti,
|
|
137
|
+
'FGI_LT65_DUR4_9_FBD': int(not is_aged) * lti,
|
|
138
|
+
})
|
|
139
|
+
if is_dur10pl:
|
|
140
|
+
interactions.update({
|
|
141
|
+
'FGC_GE65_DUR10PL_FBD': int(is_aged) * int(not lti),
|
|
142
|
+
'FGC_LT65_DUR10PL_FBD': int(not is_aged) * int(not lti),
|
|
143
|
+
'FGI_GE65_DUR10PL_FBD': int(is_aged) * lti,
|
|
144
|
+
'FGI_LT65_DUR10PL_FBD': int(not is_aged) * lti,
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
# Output only non-zero interactions
|
|
53
148
|
interactions = {k: v for k, v in interactions.items() if v > 0}
|
|
54
149
|
|
|
55
150
|
return interactions
|
|
@@ -214,7 +309,7 @@ def create_disease_interactions(model_name: ModelName,
|
|
|
214
309
|
'HCC85_gRenal_V24': diagnostic_cats['CHF'] * diagnostic_cats['RENAL_V24'],
|
|
215
310
|
'gCopdCF_CARD_RESP_FAIL': diagnostic_cats['gCopdCF'] * diagnostic_cats['CARD_RESP_FAIL'],
|
|
216
311
|
'HCC85_HCC96': int('85' in hcc_set) * int('96' in hcc_set),
|
|
217
|
-
'
|
|
312
|
+
'gSubstanceUseDisorder_gPsych': diagnostic_cats['gSubstanceUseDisorder_V24'] * diagnostic_cats['gPsychiatric_V24'],
|
|
218
313
|
'SEPSIS_PRESSURE_ULCER': diagnostic_cats['SEPSIS'] * diagnostic_cats['PRESSURE_ULCER'],
|
|
219
314
|
'SEPSIS_ARTIF_OPENINGS': diagnostic_cats['SEPSIS'] * int('188' in hcc_set),
|
|
220
315
|
'ART_OPENINGS_PRESS_ULCER': int('188' in hcc_set) * diagnostic_cats['PRESSURE_ULCER'],
|
|
@@ -8,12 +8,12 @@ hccinfhir/extractor_837.py,sha256=fGsvBTWIj9dsHLGGR67AdlYDSsFi5qnSVlTgwkL1f-E,15
|
|
|
8
8
|
hccinfhir/extractor_fhir.py,sha256=wUN3vTm1oTZ-KvfcDebnpQMxAC-7YlRKv12Wrv3p85A,8490
|
|
9
9
|
hccinfhir/filter.py,sha256=j_yD2g6RBXVUV9trKkWzsQ35x3fRvfKUPvEXKUefI64,2007
|
|
10
10
|
hccinfhir/hccinfhir.py,sha256=NydnH3WBvuyskn76hY70LpUS6XuIEoax_kip1mgfpHw,11225
|
|
11
|
-
hccinfhir/model_calculate.py,sha256=
|
|
12
|
-
hccinfhir/model_coefficients.py,sha256=
|
|
11
|
+
hccinfhir/model_calculate.py,sha256=32JOFItbEQ5OAGPrvfLnQSgW2aBiZ-JCS7ixEB6TAZY,8429
|
|
12
|
+
hccinfhir/model_coefficients.py,sha256=PGZDAFRyz7asT0epl4xTatNCsuzYaISdbXEHU2wQ27U,5504
|
|
13
13
|
hccinfhir/model_demographics.py,sha256=nImKtJCq1HkR9w2GU8aikybJFgow71CPufBRV8Jn7fM,8932
|
|
14
14
|
hccinfhir/model_dx_to_cc.py,sha256=Yjc6xKI-jMXsbOzS_chc4NI15Bwagb7BwZZ8cKQaTbk,1540
|
|
15
15
|
hccinfhir/model_hierarchies.py,sha256=cboUnSHZZfOxA8QZKV4QIE-32duElssML32OqYT-65g,1542
|
|
16
|
-
hccinfhir/model_interactions.py,sha256=
|
|
16
|
+
hccinfhir/model_interactions.py,sha256=prguJoOWBIO97UEpD0njXPvYM6-hoNjBIFYxDOxkLt0,25816
|
|
17
17
|
hccinfhir/samples.py,sha256=2VSWS81cv9EnaHqK7sd6CjwG6FUI9E--5wHgD000REI,9952
|
|
18
18
|
hccinfhir/utils.py,sha256=WQ2atW0CrdX7sAz_YRLeY4JD-CuH0o-WRusQ_xVVfgY,12152
|
|
19
19
|
hccinfhir/data/__init__.py,sha256=SGiSkpGrnxbvtEFMMlk82NFHOE50hFXcgKwKUSuVZUg,45
|
|
@@ -29,8 +29,8 @@ hccinfhir/data/ra_eligible_cpt_hcpcs_2024.csv,sha256=CawKImfCb8fFMDbWwqvNLRyRAda
|
|
|
29
29
|
hccinfhir/data/ra_eligible_cpt_hcpcs_2025.csv,sha256=-tMvv2su5tsSbGUh6fZZCMUEkXInBpcTtbUCi2o_UwI,40359
|
|
30
30
|
hccinfhir/data/ra_eligible_cpt_hcpcs_2026.csv,sha256=EYGN7k_rgCpJe59lL_yNInUcCkdETDWGSFTXII3LZ0Y,40497
|
|
31
31
|
hccinfhir/data/ra_hierarchies_2025.csv,sha256=HQSPNloe6mvvwMgv8ZwYAfWKkT2b2eUvm4JQy6S_mVQ,13045
|
|
32
|
-
hccinfhir/data/ra_hierarchies_2026.csv,sha256=
|
|
33
|
-
hccinfhir/data/ra_labels_2026.csv,sha256=
|
|
32
|
+
hccinfhir/data/ra_hierarchies_2026.csv,sha256=pKevSx-dYfLyO-Leruh2AFLn5uO4y49O9EOr-O6-cbY,19595
|
|
33
|
+
hccinfhir/data/ra_labels_2026.csv,sha256=P-Ym0np06E_CxwELdBGZZ7j5NwhXLsHoRPnp3jeYWn4,50248
|
|
34
34
|
hccinfhir/sample_files/__init__.py,sha256=SGiSkpGrnxbvtEFMMlk82NFHOE50hFXcgKwKUSuVZUg,45
|
|
35
35
|
hccinfhir/sample_files/sample_834_01.txt,sha256=J2HMXfY6fAFpV36rvLQ3QymRRS2TPqf3TQY6CNS7TrE,1627
|
|
36
36
|
hccinfhir/sample_files/sample_834_02.txt,sha256=vSvjM69kKfOW9e-8dvlO9zDcRPpOD7LmekLu68z4aB4,926
|
|
@@ -55,7 +55,7 @@ hccinfhir/sample_files/sample_eob_1.json,sha256=_NGSVR2ysFpx-DcTvyga6dFCzhQ8Vi9f
|
|
|
55
55
|
hccinfhir/sample_files/sample_eob_2.json,sha256=FcnJcx0ApOczxjJ_uxVLzCep9THfNf4xs9Yf7hxk8e4,1769
|
|
56
56
|
hccinfhir/sample_files/sample_eob_200.ndjson,sha256=CxpjeQ1DCMUzZILaM68UEhfxO0p45YGhDDoCZeq8PxU,1917986
|
|
57
57
|
hccinfhir/sample_files/sample_eob_3.json,sha256=4BW4wOMBEEU9RDfJR15rBEvk0KNHyuMEh3e055y87Hc,2306
|
|
58
|
-
hccinfhir-0.2.
|
|
59
|
-
hccinfhir-0.2.
|
|
60
|
-
hccinfhir-0.2.
|
|
61
|
-
hccinfhir-0.2.
|
|
58
|
+
hccinfhir-0.2.7.dist-info/METADATA,sha256=d52fnw3hxrWH7BLxEtkB-aefn4K6bo0g6JjLivHTBFM,37381
|
|
59
|
+
hccinfhir-0.2.7.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
60
|
+
hccinfhir-0.2.7.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
61
|
+
hccinfhir-0.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|