hccinfhir 0.2.0__py3-none-any.whl → 0.2.2__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/__init__.py +2 -1
- hccinfhir/constants.py +240 -0
- hccinfhir/data/ra_labels_2026.csv +784 -0
- hccinfhir/datamodels.py +17 -0
- hccinfhir/defaults.py +3 -1
- hccinfhir/extractor_834.py +52 -71
- hccinfhir/extractor_837.py +2 -2
- hccinfhir/hccinfhir.py +10 -10
- hccinfhir/model_calculate.py +18 -2
- hccinfhir/model_coefficients.py +2 -2
- hccinfhir/model_demographics.py +26 -29
- hccinfhir/model_interactions.py +7 -7
- hccinfhir/utils.py +68 -1
- {hccinfhir-0.2.0.dist-info → hccinfhir-0.2.2.dist-info}/METADATA +145 -3
- {hccinfhir-0.2.0.dist-info → hccinfhir-0.2.2.dist-info}/RECORD +17 -15
- {hccinfhir-0.2.0.dist-info → hccinfhir-0.2.2.dist-info}/WHEEL +0 -0
- {hccinfhir-0.2.0.dist-info → hccinfhir-0.2.2.dist-info}/licenses/LICENSE +0 -0
hccinfhir/__init__.py
CHANGED
|
@@ -9,7 +9,7 @@ from .hccinfhir import HCCInFHIR
|
|
|
9
9
|
from .extractor import extract_sld, extract_sld_list
|
|
10
10
|
from .filter import apply_filter
|
|
11
11
|
from .model_calculate import calculate_raf
|
|
12
|
-
from .datamodels import Demographics, ServiceLevelData, RAFResult, ModelName
|
|
12
|
+
from .datamodels import Demographics, ServiceLevelData, RAFResult, ModelName, HCCDetail
|
|
13
13
|
|
|
14
14
|
# Sample data functions
|
|
15
15
|
from .samples import (
|
|
@@ -37,6 +37,7 @@ __all__ = [
|
|
|
37
37
|
"ServiceLevelData",
|
|
38
38
|
"RAFResult",
|
|
39
39
|
"ModelName",
|
|
40
|
+
"HCCDetail",
|
|
40
41
|
|
|
41
42
|
# Sample data
|
|
42
43
|
"SampleData",
|
hccinfhir/constants.py
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CMS Risk Adjustment Domain Constants
|
|
3
|
+
|
|
4
|
+
This module contains constants used across the HCC risk adjustment system,
|
|
5
|
+
including dual eligibility codes, OREC/CREC values, and state-specific mappings.
|
|
6
|
+
|
|
7
|
+
References:
|
|
8
|
+
- CMS Rate Announcement and Call Letter
|
|
9
|
+
- Medicare Advantage Enrollment and Disenrollment Guidance
|
|
10
|
+
- X12 834 Implementation Guides
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Set, Dict
|
|
14
|
+
|
|
15
|
+
# =============================================================================
|
|
16
|
+
# DUAL ELIGIBILITY CODES
|
|
17
|
+
# =============================================================================
|
|
18
|
+
# CMS Dual Eligibility Status Codes (Medicare + Medicaid)
|
|
19
|
+
# Used in coefficient prefix selection (CNA_, CFA_, CPA_, etc.)
|
|
20
|
+
|
|
21
|
+
VALID_DUAL_CODES: Set[str] = {'00', '01', '02', '03', '04', '05', '06', '08'}
|
|
22
|
+
|
|
23
|
+
# Non-Dual Eligible
|
|
24
|
+
NON_DUAL_CODE: str = '00'
|
|
25
|
+
|
|
26
|
+
# Full Benefit Dual Eligible (receive both Medicare and full Medicaid benefits)
|
|
27
|
+
# Uses CFA_ (Community, Full Benefit Dual, Aged) or CFD_ (Disabled) prefixes
|
|
28
|
+
FULL_BENEFIT_DUAL_CODES: Set[str] = {
|
|
29
|
+
'02', # QMB Plus (Qualified Medicare Beneficiary Plus)
|
|
30
|
+
'04', # SLMB Plus (Specified Low-Income Medicare Beneficiary Plus)
|
|
31
|
+
'08', # Other Full Benefit Dual Eligible
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Partial Benefit Dual Eligible (Medicare + limited Medicaid)
|
|
35
|
+
# Uses CPA_ (Community, Partial Benefit Dual, Aged) or CPD_ (Disabled) prefixes
|
|
36
|
+
PARTIAL_BENEFIT_DUAL_CODES: Set[str] = {
|
|
37
|
+
'01', # QMB Only
|
|
38
|
+
'03', # SLMB Only
|
|
39
|
+
'05', # QDWI (Qualified Disabled and Working Individual)
|
|
40
|
+
'06', # QI (Qualifying Individual)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# =============================================================================
|
|
44
|
+
# OREC - Original Reason for Entitlement Code
|
|
45
|
+
# =============================================================================
|
|
46
|
+
# Determines if beneficiary has ESRD and affects coefficient prefix selection
|
|
47
|
+
|
|
48
|
+
VALID_OREC_VALUES: Set[str] = {'0', '1', '2', '3'}
|
|
49
|
+
|
|
50
|
+
OREC_DESCRIPTIONS: Dict[str, str] = {
|
|
51
|
+
'0': 'Old Age and Survivors Insurance (OASI)',
|
|
52
|
+
'1': 'Disability Insurance Benefits (DIB)',
|
|
53
|
+
'2': 'ESRD - End-Stage Renal Disease',
|
|
54
|
+
'3': 'DIB and ESRD',
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
# OREC codes indicating ESRD status (per CMS documentation)
|
|
58
|
+
OREC_ESRD_CODES: Set[str] = {'2', '3'}
|
|
59
|
+
|
|
60
|
+
# =============================================================================
|
|
61
|
+
# CREC - Current Reason for Entitlement Code
|
|
62
|
+
# =============================================================================
|
|
63
|
+
# Current entitlement status (may differ from OREC)
|
|
64
|
+
|
|
65
|
+
VALID_CREC_VALUES: Set[str] = {'0', '1', '2', '3'}
|
|
66
|
+
|
|
67
|
+
CREC_DESCRIPTIONS: Dict[str, str] = {
|
|
68
|
+
'0': 'Old Age and Survivors Insurance (OASI)',
|
|
69
|
+
'1': 'Disability Insurance Benefits (DIB)',
|
|
70
|
+
'2': 'ESRD - End-Stage Renal Disease',
|
|
71
|
+
'3': 'DIB and ESRD',
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# CREC codes indicating ESRD status
|
|
75
|
+
CREC_ESRD_CODES: Set[str] = {'2', '3'}
|
|
76
|
+
|
|
77
|
+
# =============================================================================
|
|
78
|
+
# COEFFICIENT PREFIX GROUPS
|
|
79
|
+
# =============================================================================
|
|
80
|
+
# Used for prefix_override logic in model_demographics.py
|
|
81
|
+
|
|
82
|
+
# ESRD model prefixes
|
|
83
|
+
ESRD_PREFIXES: Set[str] = {'DI_', 'DNE_', 'GI_', 'GNE_', 'GFPA_', 'GFPN_', 'GNPA_', 'GNPN_'}
|
|
84
|
+
|
|
85
|
+
# CMS-HCC new enrollee prefixes
|
|
86
|
+
NEW_ENROLLEE_PREFIXES: Set[str] = {'NE_', 'SNPNE_', 'DNE_', 'GNE_'}
|
|
87
|
+
|
|
88
|
+
# CMS-HCC community prefixes
|
|
89
|
+
COMMUNITY_PREFIXES: Set[str] = {'CNA_', 'CND_', 'CFA_', 'CFD_', 'CPA_', 'CPD_'}
|
|
90
|
+
|
|
91
|
+
# Institutionalized prefixes
|
|
92
|
+
INSTITUTIONAL_PREFIXES: Set[str] = {'INS_', 'GI_'}
|
|
93
|
+
|
|
94
|
+
# Full Benefit Dual prefixes
|
|
95
|
+
FULL_BENEFIT_DUAL_PREFIXES: Set[str] = {'CFA_', 'CFD_', 'GFPA_', 'GFPN_'}
|
|
96
|
+
|
|
97
|
+
# Partial Benefit Dual prefixes
|
|
98
|
+
PARTIAL_BENEFIT_DUAL_PREFIXES: Set[str] = {'CPA_', 'CPD_'}
|
|
99
|
+
|
|
100
|
+
# Non-Dual prefixes
|
|
101
|
+
NON_DUAL_PREFIXES: Set[str] = {'CNA_', 'CND_', 'GNPA_', 'GNPN_'}
|
|
102
|
+
|
|
103
|
+
# =============================================================================
|
|
104
|
+
# DEMOGRAPHIC CODES
|
|
105
|
+
# =============================================================================
|
|
106
|
+
|
|
107
|
+
VALID_SEX_CODES: Set[str] = {'M', 'F'}
|
|
108
|
+
|
|
109
|
+
# X12 834 Gender Code mappings
|
|
110
|
+
X12_SEX_CODE_MAPPING: Dict[str, str] = {
|
|
111
|
+
'M': 'M',
|
|
112
|
+
'F': 'F',
|
|
113
|
+
'1': 'M', # X12 numeric code
|
|
114
|
+
'2': 'F', # X12 numeric code
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
# =============================================================================
|
|
118
|
+
# X12 834 MAINTENANCE TYPE CODES
|
|
119
|
+
# =============================================================================
|
|
120
|
+
# INS03 - Maintenance Type Code
|
|
121
|
+
|
|
122
|
+
MAINTENANCE_TYPE_CHANGE: str = '001'
|
|
123
|
+
MAINTENANCE_TYPE_ADD: str = '021'
|
|
124
|
+
MAINTENANCE_TYPE_CANCEL: str = '024'
|
|
125
|
+
MAINTENANCE_TYPE_REINSTATE: str = '025'
|
|
126
|
+
|
|
127
|
+
MAINTENANCE_TYPE_DESCRIPTIONS: Dict[str, str] = {
|
|
128
|
+
'001': 'Change',
|
|
129
|
+
'021': 'Addition',
|
|
130
|
+
'024': 'Cancellation/Termination',
|
|
131
|
+
'025': 'Reinstatement',
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# =============================================================================
|
|
135
|
+
# STATE-SPECIFIC MAPPINGS
|
|
136
|
+
# =============================================================================
|
|
137
|
+
|
|
138
|
+
# -----------------------------------------------------------------------------
|
|
139
|
+
# California DHCS Medi-Cal Aid Codes
|
|
140
|
+
# -----------------------------------------------------------------------------
|
|
141
|
+
# Maps California-specific aid codes to CMS dual eligibility codes
|
|
142
|
+
# Source: California DHCS 834 Implementation Guide
|
|
143
|
+
|
|
144
|
+
MEDI_CAL_AID_CODES: Dict[str, str] = {
|
|
145
|
+
# Full Benefit Dual (QMB Plus, SLMB Plus)
|
|
146
|
+
'4N': '02', # QMB Plus - Aged
|
|
147
|
+
'4P': '02', # QMB Plus - Disabled
|
|
148
|
+
'5B': '04', # SLMB Plus - Aged
|
|
149
|
+
'5D': '04', # SLMB Plus - Disabled
|
|
150
|
+
|
|
151
|
+
# Partial Benefit Dual (QMB Only, SLMB Only, QI)
|
|
152
|
+
'4M': '01', # QMB Only - Aged
|
|
153
|
+
'4O': '01', # QMB Only - Disabled
|
|
154
|
+
'5A': '03', # SLMB Only - Aged
|
|
155
|
+
'5C': '03', # SLMB Only - Disabled
|
|
156
|
+
'5E': '06', # QI - Aged
|
|
157
|
+
'5F': '06', # QI - Disabled
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
# -----------------------------------------------------------------------------
|
|
161
|
+
# Medicare Status Code Mappings
|
|
162
|
+
# -----------------------------------------------------------------------------
|
|
163
|
+
# Maps Medicare status codes (from various sources) to CMS dual eligibility codes
|
|
164
|
+
# Used in X12 834 REF*ABB segment and other payer files
|
|
165
|
+
|
|
166
|
+
MEDICARE_STATUS_CODE_MAPPING: Dict[str, str] = {
|
|
167
|
+
# QMB - Qualified Medicare Beneficiary
|
|
168
|
+
'QMB': '01', # QMB Only (Partial)
|
|
169
|
+
'QMBONLY': '01',
|
|
170
|
+
'QMBPLUS': '02', # QMB Plus (Full Benefit)
|
|
171
|
+
'QMB+': '02',
|
|
172
|
+
|
|
173
|
+
# SLMB - Specified Low-Income Medicare Beneficiary
|
|
174
|
+
'SLMB': '03', # SLMB Only (Partial)
|
|
175
|
+
'SLMBONLY': '03',
|
|
176
|
+
'SLMBPLUS': '04', # SLMB Plus (Full Benefit)
|
|
177
|
+
'SLMB+': '04',
|
|
178
|
+
|
|
179
|
+
# Other dual eligibility programs
|
|
180
|
+
'QDWI': '05', # Qualified Disabled and Working Individual
|
|
181
|
+
'QI': '06', # Qualifying Individual
|
|
182
|
+
'QI1': '06',
|
|
183
|
+
'FBDE': '08', # Full Benefit Dual Eligible (Other)
|
|
184
|
+
'OTHERFULL': '08',
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# =============================================================================
|
|
188
|
+
# HELPER FUNCTIONS
|
|
189
|
+
# =============================================================================
|
|
190
|
+
|
|
191
|
+
def is_full_benefit_dual(dual_code: str) -> bool:
|
|
192
|
+
"""Check if dual eligibility code is Full Benefit Dual"""
|
|
193
|
+
return dual_code in FULL_BENEFIT_DUAL_CODES
|
|
194
|
+
|
|
195
|
+
def is_partial_benefit_dual(dual_code: str) -> bool:
|
|
196
|
+
"""Check if dual eligibility code is Partial Benefit Dual"""
|
|
197
|
+
return dual_code in PARTIAL_BENEFIT_DUAL_CODES
|
|
198
|
+
|
|
199
|
+
def is_esrd_by_orec(orec: str) -> bool:
|
|
200
|
+
"""Check if OREC indicates ESRD status"""
|
|
201
|
+
return orec in OREC_ESRD_CODES
|
|
202
|
+
|
|
203
|
+
def is_esrd_by_crec(crec: str) -> bool:
|
|
204
|
+
"""Check if CREC indicates ESRD status"""
|
|
205
|
+
return crec in CREC_ESRD_CODES
|
|
206
|
+
|
|
207
|
+
def normalize_medicare_status_code(status: str) -> str:
|
|
208
|
+
"""Normalize Medicare status code (uppercase, no spaces/hyphens)"""
|
|
209
|
+
if not status:
|
|
210
|
+
return ''
|
|
211
|
+
return status.upper().replace(' ', '').replace('-', '')
|
|
212
|
+
|
|
213
|
+
def map_medicare_status_to_dual_code(status: str) -> str:
|
|
214
|
+
"""Map Medicare status code to dual eligibility code
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
status: Medicare status code (e.g., 'QMB Plus', 'SLMB', 'QI')
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
Dual eligibility code ('01'-'08') or '00' if not found
|
|
221
|
+
"""
|
|
222
|
+
if not status:
|
|
223
|
+
return NON_DUAL_CODE
|
|
224
|
+
|
|
225
|
+
normalized = normalize_medicare_status_code(status)
|
|
226
|
+
return MEDICARE_STATUS_CODE_MAPPING.get(normalized, NON_DUAL_CODE)
|
|
227
|
+
|
|
228
|
+
def map_aid_code_to_dual_status(aid_code: str) -> str:
|
|
229
|
+
"""Map California Medi-Cal aid code to dual eligibility code
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
aid_code: California aid code (e.g., '4N', '5B')
|
|
233
|
+
|
|
234
|
+
Returns:
|
|
235
|
+
Dual eligibility code ('01'-'08') or '00' if not found
|
|
236
|
+
"""
|
|
237
|
+
if not aid_code:
|
|
238
|
+
return NON_DUAL_CODE
|
|
239
|
+
|
|
240
|
+
return MEDI_CAL_AID_CODES.get(aid_code, NON_DUAL_CODE)
|