fix: remove locality-only fallback — mac is always required for payment()
Some checks failed
CI / skinny-install (aco) (pull_request) Successful in 51s
CI / lint-test (pull_request) Successful in 1m17s
CI / skinny-install (api) (pull_request) Successful in 28s
CI / skinny-install (bcda) (pull_request) Successful in 32s
CI / skinny-install (bib) (pull_request) Successful in 31s
CI / skinny-install (bls) (pull_request) Successful in 33s
CI / skinny-install (ccw) (pull_request) Successful in 33s
CI / skinny-install (cli) (pull_request) Successful in 36s
CI / skinny-install (opps) (pull_request) Successful in 34s
CI / skinny-install (conf) (pull_request) Successful in 36s
CI / skinny-install (cms) (pull_request) Successful in 33s
CI / skinny-install (perf) (pull_request) Successful in 26s
CI / skinny-install (pfs) (pull_request) Successful in 35s
CI / skinny-install (aco) (push) Successful in 44s
CI / lint-test (push) Successful in 1m12s
CI / skinny-install (api) (push) Successful in 25s
CI / skinny-install (bib) (push) Successful in 41s
CI / skinny-install (bls) (push) Successful in 32s
CI / skinny-install (ccw) (push) Successful in 30s
CI / skinny-install (perf) (push) Successful in 30s
Infra CI / zotero (pull_request) Successful in 6s
Infra CI / docs (pull_request) Failing after 7s
Infra CI / notebooks (push) Successful in 7s
Infra CI / zotero (push) Successful in 6s
CI / skinny-install (rex) (pull_request) Successful in 32s
CI / skinny-install (bcda) (push) Successful in 31s
CI / skinny-install (cli) (push) Successful in 40s
CI / skinny-install (cms) (push) Successful in 30s
CI / skinny-install (conf) (push) Successful in 27s
CI / skinny-install (opps) (push) Successful in 29s
CI / skinny-install (pfs) (push) Successful in 28s
Infra CI / notebooks (pull_request) Successful in 6s
CI / skinny-install (rex) (push) Successful in 23s
Infra CI / api (pull_request) Successful in 7s
Infra CI / mc (pull_request) Successful in 5s
Infra CI / docs (push) Failing after 8s
Infra CI / api (push) Successful in 8s
Infra CI / mc (push) Successful in 7s
Some checks failed
CI / skinny-install (aco) (pull_request) Successful in 51s
CI / lint-test (pull_request) Successful in 1m17s
CI / skinny-install (api) (pull_request) Successful in 28s
CI / skinny-install (bcda) (pull_request) Successful in 32s
CI / skinny-install (bib) (pull_request) Successful in 31s
CI / skinny-install (bls) (pull_request) Successful in 33s
CI / skinny-install (ccw) (pull_request) Successful in 33s
CI / skinny-install (cli) (pull_request) Successful in 36s
CI / skinny-install (opps) (pull_request) Successful in 34s
CI / skinny-install (conf) (pull_request) Successful in 36s
CI / skinny-install (cms) (pull_request) Successful in 33s
CI / skinny-install (perf) (pull_request) Successful in 26s
CI / skinny-install (pfs) (pull_request) Successful in 35s
CI / skinny-install (aco) (push) Successful in 44s
CI / lint-test (push) Successful in 1m12s
CI / skinny-install (api) (push) Successful in 25s
CI / skinny-install (bib) (push) Successful in 41s
CI / skinny-install (bls) (push) Successful in 32s
CI / skinny-install (ccw) (push) Successful in 30s
CI / skinny-install (perf) (push) Successful in 30s
Infra CI / zotero (pull_request) Successful in 6s
Infra CI / docs (pull_request) Failing after 7s
Infra CI / notebooks (push) Successful in 7s
Infra CI / zotero (push) Successful in 6s
CI / skinny-install (rex) (pull_request) Successful in 32s
CI / skinny-install (bcda) (push) Successful in 31s
CI / skinny-install (cli) (push) Successful in 40s
CI / skinny-install (cms) (push) Successful in 30s
CI / skinny-install (conf) (push) Successful in 27s
CI / skinny-install (opps) (push) Successful in 29s
CI / skinny-install (pfs) (push) Successful in 28s
Infra CI / notebooks (pull_request) Successful in 6s
CI / skinny-install (rex) (push) Successful in 23s
Infra CI / api (pull_request) Successful in 7s
Infra CI / mc (pull_request) Successful in 5s
Infra CI / docs (push) Failing after 8s
Infra CI / api (push) Successful in 8s
Infra CI / mc (push) Successful in 7s
The payment() join on (mac, locality) is the only correct path. Locality alone is not unique in GPCI and produces wrong results. Remove the conditional fallback, require mac in both DataFrames. Update all test fixtures and inline test DataFrames to include mac.
This commit is contained in:
@@ -24,21 +24,21 @@ def payment(
|
|||||||
``Payment = (Work_RVU × Work_GPCI + PE_RVU × PE_GPCI
|
``Payment = (Work_RVU × Work_GPCI + PE_RVU × PE_GPCI
|
||||||
+ MP_RVU × MP_GPCI) × Conversion_Factor``
|
+ MP_RVU × MP_GPCI) × Conversion_Factor``
|
||||||
|
|
||||||
The join uses ``(mac, locality)`` when both DataFrames have a
|
Joins on ``(mac, locality)`` — both columns are required.
|
||||||
``mac`` column, falling back to ``locality`` alone for backward
|
Locality alone is not unique in the GPCI table (109 rows map to
|
||||||
compatibility. Using the MAC-aware join is critical for accuracy —
|
47 locality codes). Different MACs apply different GPCI values
|
||||||
different Medicare Administrative Contractors apply different GPCI
|
to the same locality number, so joining without MAC produces
|
||||||
values to the same locality number.
|
wrong results.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
rvu : DataFrame
|
rvu : DataFrame
|
||||||
RVU data with columns: ``hcpcs``, ``work_rvu``,
|
RVU data with columns: ``hcpcs``, ``work_rvu``,
|
||||||
``non_fac_pe_rvu`` or ``fac_pe_rvu``, ``mp_rvu``,
|
``non_fac_pe_rvu`` or ``fac_pe_rvu``, ``mp_rvu``,
|
||||||
``conv_factor``, ``locality``, and optionally ``mac``.
|
``conv_factor``, ``mac``, ``locality``.
|
||||||
gpci : DataFrame
|
gpci : DataFrame
|
||||||
GPCI data with columns: ``locality``, ``work_gpci``,
|
GPCI data with columns: ``mac``, ``locality``, ``work_gpci``,
|
||||||
``pe_gpci``, ``mp_gpci``, and optionally ``mac``.
|
``pe_gpci``, ``mp_gpci``.
|
||||||
facility : bool
|
facility : bool
|
||||||
If True, use facility PE RVUs; otherwise non-facility.
|
If True, use facility PE RVUs; otherwise non-facility.
|
||||||
|
|
||||||
@@ -49,15 +49,9 @@ def payment(
|
|||||||
"""
|
"""
|
||||||
pe_col = "fac_pe_rvu" if facility else "non_fac_pe_rvu"
|
pe_col = "fac_pe_rvu" if facility else "non_fac_pe_rvu"
|
||||||
|
|
||||||
# MAC-aware join produces exact CMS carrier file parity (0.00 diff
|
# MAC + locality is the correct join — locality alone is not unique
|
||||||
# across 889k rows). Fall back to locality-only for simple usage.
|
# in the GPCI table and produces wrong results.
|
||||||
join_on = (
|
joined = rvu.join(gpci, on=["mac", "locality"], how="left")
|
||||||
["mac", "locality"]
|
|
||||||
if ("mac" in rvu.columns and "mac" in gpci.columns)
|
|
||||||
else ["locality"]
|
|
||||||
)
|
|
||||||
|
|
||||||
joined = rvu.join(gpci, on=join_on, how="left")
|
|
||||||
|
|
||||||
return joined.with_columns(
|
return joined.with_columns(
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -526,6 +526,7 @@ def rvu_df() -> pl.DataFrame:
|
|||||||
"fac_pe_rvu": [0.41, 0.63, 0.95],
|
"fac_pe_rvu": [0.41, 0.63, 0.95],
|
||||||
"mp_rvu": [0.07, 0.11, 0.16],
|
"mp_rvu": [0.07, 0.11, 0.16],
|
||||||
"conv_factor": [32.7442, 32.7442, 32.7442],
|
"conv_factor": [32.7442, 32.7442, 32.7442],
|
||||||
|
"mac": ["10212", "10212", "10212"],
|
||||||
"locality": ["0201", "0201", "0201"],
|
"locality": ["0201", "0201", "0201"],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -536,6 +537,7 @@ def gpci_df() -> pl.DataFrame:
|
|||||||
"""GPCI data for PFS payment calculation tests."""
|
"""GPCI data for PFS payment calculation tests."""
|
||||||
return pl.DataFrame(
|
return pl.DataFrame(
|
||||||
{
|
{
|
||||||
|
"mac": ["10212"],
|
||||||
"locality": ["0201"],
|
"locality": ["0201"],
|
||||||
"work_gpci": [1.0],
|
"work_gpci": [1.0],
|
||||||
"pe_gpci": [0.998],
|
"pe_gpci": [0.998],
|
||||||
|
|||||||
@@ -133,11 +133,13 @@ class TestPayment:
|
|||||||
"fac_pe_rvu": [0.41],
|
"fac_pe_rvu": [0.41],
|
||||||
"mp_rvu": [0.07],
|
"mp_rvu": [0.07],
|
||||||
"conv_factor": [32.7442],
|
"conv_factor": [32.7442],
|
||||||
|
"mac": ["10212"],
|
||||||
"locality": ["9999"], # no match in gpci
|
"locality": ["9999"], # no match in gpci
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
gpci = pl.DataFrame(
|
gpci = pl.DataFrame(
|
||||||
{
|
{
|
||||||
|
"mac": ["10212"],
|
||||||
"locality": ["0201"],
|
"locality": ["0201"],
|
||||||
"work_gpci": [1.0],
|
"work_gpci": [1.0],
|
||||||
"pe_gpci": [0.998],
|
"pe_gpci": [0.998],
|
||||||
@@ -158,11 +160,13 @@ class TestPayment:
|
|||||||
"fac_pe_rvu": [0.41, 0.41],
|
"fac_pe_rvu": [0.41, 0.41],
|
||||||
"mp_rvu": [0.07, 0.07],
|
"mp_rvu": [0.07, 0.07],
|
||||||
"conv_factor": [32.7442, 32.7442],
|
"conv_factor": [32.7442, 32.7442],
|
||||||
|
"mac": ["10212", "10212"],
|
||||||
"locality": ["0201", "0101"],
|
"locality": ["0201", "0101"],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
gpci = pl.DataFrame(
|
gpci = pl.DataFrame(
|
||||||
{
|
{
|
||||||
|
"mac": ["10212", "10212"],
|
||||||
"locality": ["0201", "0101"],
|
"locality": ["0201", "0101"],
|
||||||
"work_gpci": [1.0, 1.05],
|
"work_gpci": [1.0, 1.05],
|
||||||
"pe_gpci": [0.998, 1.10],
|
"pe_gpci": [0.998, 1.10],
|
||||||
@@ -188,12 +192,14 @@ class TestPayment:
|
|||||||
"fac_pe_rvu": [0.41],
|
"fac_pe_rvu": [0.41],
|
||||||
"mp_rvu": [0.07],
|
"mp_rvu": [0.07],
|
||||||
"conv_factor": [32.7442],
|
"conv_factor": [32.7442],
|
||||||
|
"mac": ["10212"],
|
||||||
"locality": ["0201"],
|
"locality": ["0201"],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
rvu_double = rvu_base.with_columns(pl.col("conv_factor") * 2)
|
rvu_double = rvu_base.with_columns(pl.col("conv_factor") * 2)
|
||||||
gpci = pl.DataFrame(
|
gpci = pl.DataFrame(
|
||||||
{
|
{
|
||||||
|
"mac": ["10212"],
|
||||||
"locality": ["0201"],
|
"locality": ["0201"],
|
||||||
"work_gpci": [1.0],
|
"work_gpci": [1.0],
|
||||||
"pe_gpci": [0.998],
|
"pe_gpci": [0.998],
|
||||||
@@ -215,11 +221,13 @@ class TestPayment:
|
|||||||
"fac_pe_rvu": [0.0],
|
"fac_pe_rvu": [0.0],
|
||||||
"mp_rvu": [0.0],
|
"mp_rvu": [0.0],
|
||||||
"conv_factor": [32.7442],
|
"conv_factor": [32.7442],
|
||||||
|
"mac": ["10212"],
|
||||||
"locality": ["0201"],
|
"locality": ["0201"],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
gpci = pl.DataFrame(
|
gpci = pl.DataFrame(
|
||||||
{
|
{
|
||||||
|
"mac": ["10212"],
|
||||||
"locality": ["0201"],
|
"locality": ["0201"],
|
||||||
"work_gpci": [1.0],
|
"work_gpci": [1.0],
|
||||||
"pe_gpci": [0.998],
|
"pe_gpci": [0.998],
|
||||||
@@ -238,11 +246,13 @@ class TestPayment:
|
|||||||
"fac_pe_rvu": pl.Series([], dtype=pl.Float64),
|
"fac_pe_rvu": pl.Series([], dtype=pl.Float64),
|
||||||
"mp_rvu": pl.Series([], dtype=pl.Float64),
|
"mp_rvu": pl.Series([], dtype=pl.Float64),
|
||||||
"conv_factor": pl.Series([], dtype=pl.Float64),
|
"conv_factor": pl.Series([], dtype=pl.Float64),
|
||||||
|
"mac": pl.Series([], dtype=pl.Utf8),
|
||||||
"locality": pl.Series([], dtype=pl.Utf8),
|
"locality": pl.Series([], dtype=pl.Utf8),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
gpci = pl.DataFrame(
|
gpci = pl.DataFrame(
|
||||||
{
|
{
|
||||||
|
"mac": ["10212"],
|
||||||
"locality": ["0201"],
|
"locality": ["0201"],
|
||||||
"work_gpci": [1.0],
|
"work_gpci": [1.0],
|
||||||
"pe_gpci": [0.998],
|
"pe_gpci": [0.998],
|
||||||
|
|||||||
Reference in New Issue
Block a user