hccinfhir 0.1.8__py3-none-any.whl → 0.2.0__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.
@@ -1,782 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: hccinfhir
3
- Version: 0.1.8
4
- Summary: HCC Algorithm for FHIR Resources
5
- Project-URL: Homepage, https://github.com/mimilabs/hccinfhir
6
- Project-URL: Issues, https://github.com/mimilabs/hccinfhir/issues
7
- Author-email: Yubin Park <yubin.park@mimilabs.ai>
8
- Classifier: License :: OSI Approved :: Apache Software License
9
- Classifier: Operating System :: OS Independent
10
- Classifier: Programming Language :: Python :: 3
11
- Requires-Python: >=3.8
12
- Requires-Dist: pydantic>=2.10.3
13
- Description-Content-Type: text/markdown
14
-
15
- # HCCInFHIR
16
-
17
- [![PyPI version](https://badge.fury.io/py/hccinfhir.svg)](https://badge.fury.io/py/hccinfhir)
18
- [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
19
- [![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
20
-
21
- A Python library for calculating HCC (Hierarchical Condition Category) risk adjustment scores from healthcare claims data. Supports multiple data sources including FHIR resources, X12 837 claims, and CMS encounter data.
22
-
23
- ## 🚀 Quick Start
24
-
25
- ```bash
26
- pip install hccinfhir
27
- ```
28
-
29
- ```python
30
- from hccinfhir import HCCInFHIR, Demographics
31
-
32
- # Initialize processor
33
- processor = HCCInFHIR(model_name="CMS-HCC Model V28")
34
-
35
- # Calculate from diagnosis codes
36
- demographics = Demographics(age=67, sex="F")
37
- diagnosis_codes = ["E11.9", "I10", "N18.3"]
38
-
39
- result = processor.calculate_from_diagnosis(diagnosis_codes, demographics)
40
- print(f"Risk Score: {result.risk_score}")
41
- print(f"HCCs: {result.hcc_list}")
42
- ```
43
-
44
- ## 📋 Table of Contents
45
-
46
- - [Data Sources & Use Cases](#data-sources--use-cases)
47
- - [Installation](#installation)
48
- - [How-To Guides](#how-to-guides)
49
- - [Working with CMS Encounter Data (EDRs)](#working-with-cms-encounter-data-edrs)
50
- - [Processing 837 Claims from Clearinghouses](#processing-837-claims-from-clearinghouses)
51
- - [Using CMS BCDA API Data](#using-cms-bcda-api-data)
52
- - [Direct Diagnosis Code Processing](#direct-diagnosis-code-processing)
53
- - [Model Configuration](#model-configuration)
54
- - [API Reference](#api-reference)
55
- - [Sample Data](#sample-data)
56
- - [Advanced Usage](#advanced-usage)
57
-
58
- ## 📊 Data Sources & Use Cases
59
-
60
- HCCInFHIR supports three primary data sources for HCC risk adjustment calculations:
61
-
62
- ### 1. **CMS Encounter Data Records (EDRs)**
63
- - **Input**: X12 837 5010 transaction files (text format) + demographic data from payers
64
- - **Use Case**: Medicare Advantage plans processing encounter data for CMS submissions
65
- - **Output**: Risk scores with detailed HCC mappings and interactions
66
-
67
- ### 2. **Clearinghouse 837 Claims**
68
- - **Input**: X12 837 5010 institutional/professional claim files + patient demographics
69
- - **Use Case**: Health plans and providers calculating risk scores from claims data
70
- - **Output**: Service-level analysis with filtering and risk score calculations
71
-
72
- ### 3. **CMS BCDA API Data**
73
- - **Input**: FHIR ExplanationOfBenefit resources from Blue Button 2.0 API
74
- - **Use Case**: Applications processing Medicare beneficiary data via BCDA
75
- - **Output**: Standardized risk adjustment calculations from FHIR resources
76
-
77
- ### 4. **Direct Diagnosis Processing**
78
- - **Input**: Diagnosis codes + demographics
79
- - **Use Case**: Quick risk score validation or research applications
80
- - **Output**: HCC mappings and risk scores without claims context
81
-
82
- ## 🛠️ Installation
83
-
84
- ### Basic Installation
85
- ```bash
86
- pip install hccinfhir
87
- ```
88
-
89
- ### Development Installation
90
- ```bash
91
- git clone https://github.com/yourusername/hccinfhir.git
92
- cd hccinfhir
93
- pip install -e .
94
- ```
95
-
96
- ### Requirements
97
- - Python 3.9+
98
- - Pydantic >= 2.10.3
99
-
100
- ## 📖 How-To Guides
101
-
102
- ### Working with CMS Encounter Data (EDRs)
103
-
104
- **Scenario**: You're a Medicare Advantage plan processing encounter data for CMS risk adjustment.
105
-
106
- **What you need**:
107
- - X12 837 envelope files from your claims system
108
- - Demographic data (age, sex, eligibility status) for each beneficiary
109
- - Knowledge of your plan's model year and HCC model version
110
-
111
- ```python
112
- from hccinfhir import HCCInFHIR, Demographics, get_837_sample
113
- from hccinfhir.extractor import extract_sld
114
-
115
- # Step 1: Configure processor for your model year and version
116
- processor = HCCInFHIR(
117
- model_name="CMS-HCC Model V28", # CMS model version
118
- filter_claims=True, # Apply CMS filtering rules
119
- dx_cc_mapping_filename="ra_dx_to_cc_2026.csv",
120
- proc_filtering_filename="ra_eligible_cpt_hcpcs_2026.csv"
121
- )
122
-
123
- # Step 2: Load your 837 data
124
- with open("encounter_data.txt", "r") as f:
125
- raw_837_data = f.read()
126
-
127
- # Step 3: Extract service-level data
128
- service_data = extract_sld(raw_837_data, format="837")
129
-
130
- # Step 4: Define beneficiary demographics
131
- demographics = Demographics(
132
- age=72,
133
- sex="M",
134
- dual_elgbl_cd="00", # Dual eligibility status
135
- orig_disabled=False, # Original disability status
136
- new_enrollee=False, # New enrollee flag
137
- esrd=False # ESRD status
138
- )
139
-
140
- # Step 5: Calculate risk score
141
- result = processor.run_from_service_data(service_data, demographics)
142
-
143
- # Step 6: Review results
144
- print(f"Beneficiary Risk Score: {result.risk_score}")
145
- print(f"Active HCCs: {result.hcc_list}")
146
- print(f"Disease Interactions: {result.interactions}")
147
-
148
- # Export results for CMS submission
149
- encounter_summary = {
150
- "beneficiary_id": "example_id",
151
- "risk_score": result.risk_score,
152
- "hcc_list": result.hcc_list,
153
- "model_version": "V28",
154
- "payment_year": 2026
155
- }
156
- ```
157
-
158
- ### Processing 837 Claims from Clearinghouses
159
-
160
- **Scenario**: You're a health plan receiving 837 files from clearinghouses and need to calculate member risk scores.
161
-
162
- ```python
163
- from hccinfhir import HCCInFHIR, Demographics
164
- from hccinfhir.extractor import extract_sld_list
165
-
166
- # Configure for institutional and professional claims
167
- processor = HCCInFHIR(
168
- model_name="CMS-HCC Model V28",
169
- filter_claims=True, # Enable CMS filtering
170
- dx_cc_mapping_filename="ra_dx_to_cc_2026.csv"
171
- )
172
-
173
- # Process multiple 837 files
174
- claim_files = ["inst_claims.txt", "prof_claims.txt"]
175
- all_service_data = []
176
-
177
- for file_path in claim_files:
178
- with open(file_path, "r") as f:
179
- claims_data = f.read()
180
-
181
- # Extract service data from each file
182
- service_data = extract_sld_list([claims_data], format="837")
183
- all_service_data.extend(service_data)
184
-
185
- # Member demographics (typically from your enrollment system)
186
- member_demographics = Demographics(
187
- age=45,
188
- sex="F",
189
- dual_elgbl_cd="02", # Partial dual eligible
190
- orig_disabled=True, # Originally disabled
191
- new_enrollee=False
192
- )
193
-
194
- # Calculate comprehensive risk score
195
- result = processor.run_from_service_data(all_service_data, member_demographics)
196
-
197
- # Analyze by service type
198
- professional_services = [svc for svc in result.service_level_data if svc.claim_type == "71"]
199
- institutional_services = [svc for svc in result.service_level_data if svc.claim_type == "72"]
200
-
201
- print(f"Member Risk Score: {result.risk_score}")
202
- print(f"Professional Claims: {len(professional_services)}")
203
- print(f"Institutional Claims: {len(institutional_services)}")
204
- ```
205
-
206
- ### Using CMS BCDA API Data
207
-
208
- **Scenario**: You're building an application that processes Medicare beneficiary data from the BCDA API.
209
-
210
- ```python
211
- from hccinfhir import HCCInFHIR, Demographics, get_eob_sample_list
212
- from hccinfhir.extractor import extract_sld_list
213
- import requests
214
-
215
- # Configure processor for BCDA data
216
- processor = HCCInFHIR(
217
- model_name="CMS-HCC Model V24", # BCDA typically uses V24
218
- filter_claims=True,
219
- dx_cc_mapping_filename="ra_dx_to_cc_2025.csv"
220
- )
221
-
222
- # Fetch EOB data from BCDA (example using sample data)
223
- eob_resources = get_eob_sample_list(limit=50) # Replace with actual BCDA API call
224
-
225
- # Extract service-level data from FHIR resources
226
- service_data = extract_sld_list(eob_resources, format="fhir")
227
-
228
- # BCDA provides beneficiary demographics in the EOB
229
- # Extract demographics from the first EOB resource
230
- first_eob = eob_resources[0]
231
- beneficiary_ref = first_eob.get("patient", {}).get("reference", "")
232
-
233
- # You would typically look up demographics from your system
234
- demographics = Demographics(
235
- age=68,
236
- sex="M",
237
- dual_elgbl_cd="00",
238
- new_enrollee=False,
239
- esrd=False
240
- )
241
-
242
- # Process FHIR data
243
- result = processor.run(eob_resources, demographics)
244
-
245
- # BCDA-specific analysis
246
- print(f"Beneficiary: {beneficiary_ref}")
247
- print(f"Risk Score: {result.risk_score}")
248
- print(f"Data Source: BCDA API")
249
- print(f"HCC Categories: {', '.join(map(str, result.hcc_list))}")
250
-
251
- # Examine service utilization patterns
252
- service_dates = [svc.service_date for svc in result.service_level_data if svc.service_date]
253
- if service_dates:
254
- print(f"Service Period: {min(service_dates)} to {max(service_dates)}")
255
- ```
256
-
257
- ### Direct Diagnosis Code Processing
258
-
259
- **Scenario**: You need to quickly validate HCC mappings or calculate risk scores for research purposes.
260
-
261
- ```python
262
- from hccinfhir import HCCInFHIR, Demographics
263
-
264
- # Simple setup for diagnosis-only processing
265
- processor = HCCInFHIR(model_name="CMS-HCC Model V28")
266
-
267
- # Define patient population
268
- demographics = Demographics(
269
- age=75,
270
- sex="F",
271
- dual_elgbl_cd="02", # Dual eligible
272
- orig_disabled=False,
273
- new_enrollee=False,
274
- esrd=False
275
- )
276
-
277
- # Diagnosis codes from clinical encounter
278
- diagnosis_codes = [
279
- "E11.9", # Type 2 diabetes without complications
280
- "I10", # Essential hypertension
281
- "N18.3", # Chronic kidney disease, stage 3
282
- "F32.9", # Major depressive disorder
283
- "M79.3" # Panniculitis
284
- ]
285
-
286
- # Calculate risk score
287
- result = processor.calculate_from_diagnosis(diagnosis_codes, demographics)
288
-
289
- # Detailed analysis
290
- print("=== HCC Risk Analysis ===")
291
- print(f"Risk Score: {result.risk_score:.3f}")
292
- print(f"HCC Categories: {result.hcc_list}")
293
-
294
- # Show diagnosis to HCC mappings
295
- print("\nDiagnosis Mappings:")
296
- for cc, dx_list in result.cc_to_dx.items():
297
- print(f" CC {cc}: {', '.join(dx_list)}")
298
-
299
- # Show applied coefficients
300
- print(f"\nApplied Coefficients: {len(result.coefficients)}")
301
- for coeff_name, value in result.coefficients.items():
302
- print(f" {coeff_name}: {value}")
303
-
304
- # Check for interactions
305
- if result.interactions:
306
- print(f"\nDisease Interactions: {len(result.interactions)}")
307
- for interaction, value in result.interactions.items():
308
- print(f" {interaction}: {value}")
309
- ```
310
-
311
- ## ⚙️ Model Configuration
312
-
313
- ### Supported HCC Models
314
-
315
- | Model Name | Model Years | Use Case |
316
- |------------|-------------|----------|
317
- | `"CMS-HCC Model V22"` | 2024-2025 | Community populations |
318
- | `"CMS-HCC Model V24"` | 2024-2026 | Community populations (current) |
319
- | `"CMS-HCC Model V28"` | 2025-2026 | Community populations (latest) |
320
- | `"CMS-HCC ESRD Model V21"` | 2024-2025 | ESRD populations |
321
- | `"CMS-HCC ESRD Model V24"` | 2025-2026 | ESRD populations |
322
- | `"RxHCC Model V08"` | 2024-2026 | Part D prescription drug coverage |
323
-
324
- ### Configuration Parameters
325
-
326
- ```python
327
- processor = HCCInFHIR(
328
- # Core model settings
329
- model_name="CMS-HCC Model V28", # Required: HCC model version
330
-
331
- # Filtering options
332
- filter_claims=True, # Apply CMS filtering rules
333
-
334
- # Custom data files (optional)
335
- dx_cc_mapping_filename="ra_dx_to_cc_2026.csv", # Diagnosis to CC mapping
336
- proc_filtering_filename="ra_eligible_cpt_hcpcs_2026.csv", # Procedure code filtering
337
- )
338
- ```
339
-
340
- ### Demographics Configuration
341
-
342
- ```python
343
- from hccinfhir import Demographics
344
-
345
- demographics = Demographics(
346
- # Required fields
347
- age=67, # Age in years
348
- sex="F", # "M" or "F"
349
-
350
- # CMS-specific fields
351
- dual_elgbl_cd="00", # Dual eligibility: "00"=Non-dual, "01"=Partial, "02"=Full
352
- orig_disabled=False, # Original reason for Medicare entitlement was disability
353
- new_enrollee=False, # New Medicare enrollee (< 12 months)
354
- esrd=False, # End-Stage Renal Disease status
355
-
356
- # Optional fields
357
- snp=False, # Special Needs Plan member
358
- low_income=False, # Low-income subsidy
359
- graft_months=None, # Months since kidney transplant (for ESRD models)
360
- category="CNA" # Beneficiary category (auto-calculated if not provided)
361
- )
362
- ```
363
-
364
- ### Data File Specifications
365
-
366
- The library includes CMS reference data files for 2025 and 2026. You can override with custom files:
367
-
368
- ```python
369
- # Use custom mapping files
370
- processor = HCCInFHIR(
371
- model_name="CMS-HCC Model V28",
372
- dx_cc_mapping_filename="custom_dx_mapping.csv", # Format: diagnosis_code,cc,model_name
373
- proc_filtering_filename="custom_procedures.csv" # Format: cpt_hcpcs_code
374
- )
375
- ```
376
-
377
- ## 📚 API Reference
378
-
379
- ### Main Classes
380
-
381
- #### `HCCInFHIR`
382
- Main processor class for HCC calculations.
383
-
384
- **Methods**:
385
- - `run(eob_list, demographics)` - Process FHIR ExplanationOfBenefit resources
386
- - `run_from_service_data(service_data, demographics)` - Process service-level data
387
- - `calculate_from_diagnosis(diagnosis_codes, demographics)` - Calculate from diagnosis codes only
388
-
389
- #### `Demographics`
390
- Patient demographic information for risk adjustment.
391
-
392
- **Fields**:
393
- - `age: int` - Patient age in years
394
- - `sex: str` - Patient sex ("M" or "F")
395
- - `dual_elgbl_cd: str` - Dual eligibility code
396
- - `orig_disabled: bool` - Original disability status
397
- - `new_enrollee: bool` - New enrollee flag
398
- - `esrd: bool` - ESRD status
399
-
400
- #### `RAFResult`
401
- Risk adjustment calculation results.
402
-
403
- **Fields**:
404
- - `risk_score: float` - Final RAF score
405
- - `risk_score_demographics: float` - Demographics-only risk score
406
- - `risk_score_chronic_only: float` - Chronic conditions risk score
407
- - `risk_score_hcc: float` - HCC conditions risk score
408
- - `hcc_list: List[str]` - List of active HCC categories
409
- - `cc_to_dx: Dict[str, Set[str]]` - Condition categories mapped to diagnosis codes
410
- - `coefficients: Dict[str, float]` - Applied model coefficients
411
- - `interactions: Dict[str, float]` - Disease interaction coefficients
412
- - `demographics: Demographics` - Patient demographics used in calculation
413
- - `model_name: ModelName` - HCC model used for calculation
414
- - `version: str` - Library version
415
- - `diagnosis_codes: List[str]` - Input diagnosis codes
416
- - `service_level_data: Optional[List[ServiceLevelData]]` - Processed service records (when applicable)
417
-
418
- ### Utility Functions
419
-
420
- ```python
421
- from hccinfhir import (
422
- get_eob_sample, # Get sample FHIR EOB data
423
- get_837_sample, # Get sample 837 claim data
424
- list_available_samples, # List all available sample data
425
- extract_sld, # Extract service-level data from single resource
426
- extract_sld_list, # Extract service-level data from multiple resources
427
- apply_filter # Apply CMS filtering rules to service data
428
- )
429
- ```
430
-
431
- ## 📝 Sample Data
432
-
433
- The library includes comprehensive sample data for testing and development:
434
-
435
- ```python
436
- from hccinfhir import get_eob_sample, get_837_sample, list_available_samples
437
-
438
- # FHIR ExplanationOfBenefit samples
439
- eob_data = get_eob_sample(1) # Individual EOB (cases 1, 2, 3)
440
- eob_list = get_eob_sample_list(limit=10) # Up to 200 EOB resources
441
-
442
- # X12 837 claim samples
443
- claim_data = get_837_sample(0) # Individual 837 claim (cases 0-12)
444
- claim_list = get_837_sample_list([0, 1, 2]) # Multiple 837 claims
445
-
446
- # Sample information
447
- sample_info = list_available_samples()
448
- print(f"Available EOB samples: {len(sample_info['eob_case_numbers'])}")
449
- print(f"Available 837 samples: {len(sample_info['837_case_numbers'])}")
450
- ```
451
-
452
- ## 🔧 Advanced Usage
453
-
454
- ### Converting to Dictionary Format
455
-
456
- If you need to work with regular Python dictionaries (e.g., for JSON serialization, database storage, or legacy code compatibility), you can easily convert Pydantic models using built-in methods:
457
-
458
- ```python
459
- from hccinfhir import HCCInFHIR, Demographics
460
-
461
- processor = HCCInFHIR(model_name="CMS-HCC Model V28")
462
- demographics = Demographics(age=67, sex="F")
463
- diagnosis_codes = ["E11.9", "I10"]
464
-
465
- # Get Pydantic model result
466
- result = processor.calculate_from_diagnosis(diagnosis_codes, demographics)
467
- print(f"Risk Score: {result.risk_score}") # Pydantic attribute access
468
-
469
- # Convert to dictionary
470
- result_dict = result.model_dump()
471
- print(f"Risk Score: {result_dict['risk_score']}") # Dictionary access
472
-
473
- # Convert with different modes
474
- result_json_compatible = result.model_dump(mode='json') # JSON-serializable types
475
- result_python_types = result.model_dump(mode='python') # Python native types (default)
476
-
477
- # Convert only specific fields
478
- partial_dict = result.model_dump(include={'risk_score', 'hcc_list', 'demographics'})
479
-
480
- # Convert excluding certain fields
481
- summary_dict = result.model_dump(exclude={'service_level_data', 'interactions'})
482
-
483
- # Convert to JSON string directly
484
- json_string = result.model_dump_json() # Returns JSON string
485
- ```
486
-
487
- #### Working with Nested Models
488
-
489
- ```python
490
- # Demographics also support dictionary conversion
491
- demographics_dict = result.demographics.model_dump()
492
- print(demographics_dict)
493
- # Output: {'age': 67, 'sex': 'F', 'dual_elgbl_cd': '00', ...}
494
-
495
- # Service data conversion (list of Pydantic models)
496
- if result.service_level_data:
497
- service_dicts = [svc.model_dump() for svc in result.service_level_data]
498
- ```
499
-
500
- #### Common Use Cases
501
-
502
- **1. API Responses:**
503
- ```python
504
- # FastAPI automatically handles Pydantic models, but for other frameworks:
505
- @app.route('/calculate')
506
- def calculate_risk():
507
- result = processor.calculate_from_diagnosis(diagnosis_codes, demographics)
508
- return jsonify(result.model_dump(mode='json')) # JSON-safe types
509
- ```
510
-
511
- **2. Database Storage:**
512
- ```python
513
- # Store in database
514
- result_data = result.model_dump(exclude={'service_level_data'}) # Exclude large nested data
515
- db.risks.insert_one(result_data)
516
- ```
517
-
518
- **3. Legacy Code Integration:**
519
- ```python
520
- # Working with existing code that expects dictionaries
521
- def legacy_function(risk_data):
522
- return risk_data['risk_score'] * risk_data['demographics']['age']
523
-
524
- # Easy conversion
525
- result_dict = result.model_dump()
526
- legacy_result = legacy_function(result_dict)
527
- ```
528
-
529
- **4. Custom Serialization:**
530
- ```python
531
- # Custom formatting for specific needs
532
- export_data = result.model_dump(
533
- include={'risk_score', 'hcc_list', 'model_name'},
534
- mode='json'
535
- )
536
- ```
537
-
538
- ### Overriding Demographic Categorization
539
-
540
- **Problem**: Sometimes demographic data has quality issues (e.g., ESRD patients with incorrect `orec`/`crec` codes), leading to wrong risk score calculations.
541
-
542
- **Solution**: Use the `prefix_override` parameter to manually specify the coefficient prefix.
543
-
544
- #### Common Use Case: ESRD Patients with Incorrect OREC/CREC
545
-
546
- ```python
547
- from hccinfhir import HCCInFHIR, Demographics
548
-
549
- # ESRD dialysis patient, but source data has wrong orec/crec codes
550
- processor = HCCInFHIR(model_name="CMS-HCC ESRD Model V24")
551
-
552
- demographics = Demographics(
553
- age=65,
554
- sex="F",
555
- orec="0", # Should be '2' or '3' for ESRD, but data is incorrect
556
- crec="0" # Should be '2' or '3' for ESRD, but data is incorrect
557
- )
558
-
559
- diagnosis_codes = ["N18.6", "E11.22", "I12.0"] # ESRD + diabetes + hypertensive CKD
560
-
561
- # Force ESRD dialysis coefficients despite incorrect orec/crec
562
- result = processor.calculate_from_diagnosis(
563
- diagnosis_codes,
564
- demographics,
565
- prefix_override='DI_' # DI_ = ESRD Dialysis
566
- )
567
-
568
- print(f"Risk Score with override: {result.risk_score}")
569
- ```
570
-
571
- #### Other Common Scenarios
572
-
573
- ```python
574
- # Long-term institutionalized patient not properly flagged
575
- processor = HCCInFHIR(model_name="CMS-HCC Model V28")
576
- demographics = Demographics(age=78, sex="M")
577
- diagnosis_codes = ["F03.90", "I48.91", "N18.4"]
578
-
579
- result = processor.calculate_from_diagnosis(
580
- diagnosis_codes,
581
- demographics,
582
- prefix_override='INS_' # INS_ = Institutionalized
583
- )
584
-
585
- # New enrollee with missing flag
586
- result = processor.calculate_from_diagnosis(
587
- diagnosis_codes,
588
- demographics,
589
- prefix_override='NE_' # NE_ = New Enrollee
590
- )
591
- ```
592
-
593
- #### Common Prefix Values
594
-
595
- **CMS-HCC Models (V22, V24, V28):**
596
- - `CNA_` - Community, Non-Dual, Aged (65+)
597
- - `CND_` - Community, Non-Dual, Disabled (<65)
598
- - `CFA_` - Community, Full Benefit Dual, Aged
599
- - `CFD_` - Community, Full Benefit Dual, Disabled
600
- - `CPA_` - Community, Partial Benefit Dual, Aged
601
- - `CPD_` - Community, Partial Benefit Dual, Disabled
602
- - `INS_` - Long-Term Institutionalized
603
- - `NE_` - New Enrollee
604
- - `SNPNE_` - Special Needs Plan New Enrollee
605
-
606
- **ESRD Models (V21, V24):**
607
- - `DI_` - Dialysis (standard)
608
- - `DNE_` - Dialysis New Enrollee
609
- - `GI_` - Graft, Institutionalized
610
- - `GNE_` - Graft, New Enrollee
611
- - `GFPA_`, `GFPN_`, `GNPA_`, `GNPN_` - Graft with various dual/age combinations
612
-
613
- **RxHCC Model (V08):**
614
- - `Rx_CE_LowAged_` - Community, Low Income, Aged
615
- - `Rx_CE_NoLowAged_` - Community, Not Low Income, Aged
616
- - `Rx_NE_Lo_` - New Enrollee, Low Income
617
- - `Rx_CE_LTI_` - Community, Long-Term Institutionalized
618
-
619
- See [CLAUDE.md](./CLAUDE.md#coefficient-prefix-reference) for complete prefix reference.
620
-
621
- ### Custom Filtering Rules
622
-
623
- ```python
624
- from hccinfhir.filter import apply_filter
625
-
626
- # Apply custom filtering to service data
627
- filtered_data = apply_filter(
628
- service_data,
629
- include_inpatient=True,
630
- include_outpatient=True,
631
- eligible_cpt_hcpcs_file="custom_procedures.csv"
632
- )
633
- ```
634
-
635
- ### Batch Processing
636
-
637
- ```python
638
- # Process multiple beneficiaries efficiently
639
- results = []
640
- for beneficiary_data in beneficiary_list:
641
- demographics = Demographics(**beneficiary_data['demographics'])
642
- service_data = beneficiary_data['service_data']
643
-
644
- result = processor.run_from_service_data(service_data, demographics)
645
- results.append({
646
- 'beneficiary_id': beneficiary_data['id'],
647
- 'risk_score': result.risk_score,
648
- 'hcc_list': result.hcc_list
649
- })
650
- ```
651
-
652
- ### Error Handling
653
-
654
- ```python
655
- from hccinfhir.exceptions import ValidationError, ModelNotFoundError
656
-
657
- try:
658
- result = processor.calculate_from_diagnosis(diagnosis_codes, demographics)
659
- except ValidationError as e:
660
- print(f"Data validation error: {e}")
661
- except ModelNotFoundError as e:
662
- print(f"Model configuration error: {e}")
663
- ```
664
-
665
- ### Custom Valuesets
666
-
667
- Users can generate custom and more specific valuesets using the mimilabs data lakehouse.
668
-
669
- For example, the valuesets in the package are created as follows:
670
-
671
- `ra_dx_to_cc_mapping_2026.csv`
672
- ```sql
673
- WITH latest_years AS (
674
- SELECT
675
- model_name,
676
- MAX(year) as latest_year
677
- FROM mimi_ws_1.cmspayment.ra_dx_to_cc_mapping
678
- WHERE model_type = 'Initial'
679
- AND year <= 2026 -- Don't go beyond 2026
680
- GROUP BY model_name
681
- )
682
- SELECT
683
- r.diagnosis_code,
684
- r.cc,
685
- r.model_name
686
- FROM mimi_ws_1.cmspayment.ra_dx_to_cc_mapping r
687
- INNER JOIN latest_years l
688
- ON r.model_name = l.model_name
689
- AND r.year = l.latest_year
690
- WHERE r.model_type = 'Initial'
691
- ORDER BY r.model_name, r.diagnosis_code;
692
- ```
693
-
694
- `ra_hierarchies_2026.csv`
695
- ```sql
696
- WITH latest_dates AS (
697
- SELECT
698
- model_domain,
699
- model_version,
700
- model_fullname,
701
- MAX(eff_last_date) as latest_eff_last_date
702
- FROM mimi_ws_1.cmspayment.ra_hierarchies
703
- GROUP BY model_domain, model_version, model_fullname
704
- )
705
- SELECT
706
- r.cc_parent,
707
- r.cc_child,
708
- r.model_domain,
709
- r.model_version,
710
- r.model_fullname
711
- FROM mimi_ws_1.cmspayment.ra_hierarchies r
712
- INNER JOIN latest_dates l
713
- ON r.model_domain = l.model_domain
714
- AND r.model_version = l.model_version
715
- AND r.model_fullname = l.model_fullname
716
- AND r.eff_last_date = l.latest_eff_last_date
717
- ORDER BY r.model_domain, r.model_version, r.model_fullname, r.cc_parent, r.cc_child;
718
- ```
719
-
720
-
721
- `ra_coefficients_2026.csv`
722
- ```sql
723
- WITH preferred_records AS (
724
- SELECT
725
- model_domain,
726
- model_version,
727
- MAX(eff_last_date) as latest_eff_last_date
728
- FROM mimi_ws_1.cmspayment.ra_coefficients
729
- GROUP BY model_domain, model_version
730
- )
731
- SELECT
732
- r.coefficient,
733
- r.value,
734
- r.model_domain,
735
- r.model_version
736
- FROM mimi_ws_1.cmspayment.ra_coefficients r
737
- INNER JOIN preferred_records p
738
- ON r.model_domain = p.model_domain
739
- AND r.model_version = p.model_version
740
- AND r.eff_last_date = p.latest_eff_last_date
741
- ORDER BY r.model_domain, r.model_version, r.coefficient;
742
- ```
743
-
744
- `ra_eligible_cpt_hcpcs_2026.csv`
745
- ```sql
746
- SELECT DISTINCT cpt_hcpcs_code
747
- FROM mimi_ws_1.cmspayment.ra_eligible_cpt_hcpcs
748
- WHERE is_included = 'yes' AND YEAR(mimi_src_file_date) = 2025;
749
- ```
750
-
751
- `hcc_is_chronic.csv`
752
- ```sql
753
- SELECT hcc, is_chronic, model_version, model_domain
754
- FROM cmspayment.ra_report_to_congress
755
- WHERE mimi_src_file_name = '2024riskadjustmentinma-rtc.pdf'
756
- ```
757
-
758
- ## 🧪 Testing
759
-
760
- ```bash
761
- $ hatch shell
762
- $ pip install -e .
763
- $ pytest tests/*
764
- ```
765
-
766
- ## 📄 License
767
-
768
- Apache License 2.0. See [LICENSE](LICENSE) for details.
769
-
770
- ## 🤝 Contributing
771
-
772
- We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
773
-
774
- ## 📞 Support
775
-
776
- - **Documentation**: [https://hccinfhir.readthedocs.io](https://hccinfhir.readthedocs.io)
777
- - **Issues**: [GitHub Issues](https://github.com/yourusername/hccinfhir/issues)
778
- - **Discussions**: [GitHub Discussions](https://github.com/yourusername/hccinfhir/discussions)
779
-
780
- ---
781
-
782
- **Made with ❤️ by the HCCInFHIR team**