feat(notebooks): CY2027 NPRM — GPCI & locality section + primary-care (ACO attribution) per-service analysis (closes #631, closes #632)
This commit is contained in:
@@ -29,11 +29,12 @@ def _(mo):
|
|||||||
and `qpp.QPP` (the repo's rule registries) and the `pfs`/`cms`
|
and `qpp.QPP` (the repo's rule registries) and the `pfs`/`cms`
|
||||||
DuckLake schemas — nothing here is a hard-coded figure. Columns are
|
DuckLake schemas — nothing here is a hard-coded figure. Columns are
|
||||||
explicitly labeled **"final rule pending"** rather than fabricating
|
explicitly labeled **"final rule pending"** rather than fabricating
|
||||||
a CY2027-final column that does not exist yet. All dollar figures
|
a CY2027-final column that does not exist yet. Dollar figures in
|
||||||
use **national, GPCI-unadjusted RVUs (GPCI = 1.0)** — a deliberate
|
Sections 1-2 and 4 are **national, GPCI-unadjusted (GPCI = 1.0)**
|
||||||
scope simplification, disclosed once here rather than on every
|
unless a figure says otherwise; **Section 3** carries the locality
|
||||||
figure; real payment varies by locality via `pfs.gpci`, which this
|
story — the CY2027 NPRM's proposed GPCIs (`pfs.gpci_proposed`,
|
||||||
notebook does not join.
|
Addendum E) against the final-rule history in `pfs.gpci`, with
|
||||||
|
locality-adjusted payment examples.
|
||||||
""")
|
""")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -50,9 +51,13 @@ def _():
|
|||||||
connect.theme()
|
connect.theme()
|
||||||
|
|
||||||
# connect.theme() puts assets/ on sys.path — reuse the HTI-5 design
|
# connect.theme() puts assets/ on sys.path — reuse the HTI-5 design
|
||||||
# tokens directly instead of re-typing hex literals for the gain/loss
|
# tokens directly instead of re-typing hex literals: AMBER/TEAL are
|
||||||
# diverging pair used in Section 2.
|
# the gain/loss diverging pair (Sections 2-4), INDIGO_MED the
|
||||||
from fhirworx import AMBER, TEAL
|
# default series, PLUM/GRAY the fixed categorical follow-ons for
|
||||||
|
# the GPCI locality lines (Section 3).
|
||||||
|
from fhirworx import AMBER, GRAY, INDIGO_MED, PLUM, TEAL
|
||||||
|
|
||||||
|
from pfs.calcs.payment import payment as pfs_payment
|
||||||
|
|
||||||
# PFS reference data lives in the DuckLake lakehouse (M5, #514) —
|
# PFS reference data lives in the DuckLake lakehouse (M5, #514) —
|
||||||
# notebooks connect read-only.
|
# notebooks connect read-only.
|
||||||
@@ -61,7 +66,22 @@ def _():
|
|||||||
def q(sql):
|
def q(sql):
|
||||||
return con.execute(sql).pl()
|
return con.execute(sql).pl()
|
||||||
|
|
||||||
return AMBER, QPP, RULES, TEAL, alt, con, for_payment_year, pl, proposed_for, q
|
return (
|
||||||
|
AMBER,
|
||||||
|
GRAY,
|
||||||
|
INDIGO_MED,
|
||||||
|
PLUM,
|
||||||
|
QPP,
|
||||||
|
RULES,
|
||||||
|
TEAL,
|
||||||
|
alt,
|
||||||
|
con,
|
||||||
|
for_payment_year,
|
||||||
|
pfs_payment,
|
||||||
|
pl,
|
||||||
|
proposed_for,
|
||||||
|
q,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ── 1. The conversion-factor walk ─────────────────────────────────────
|
# ── 1. The conversion-factor walk ─────────────────────────────────────
|
||||||
@@ -493,13 +513,777 @@ def _(cross_nprm, mo):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# ── 3. Advanced APM ─────────────────────────────────────────────────────
|
# ── 3. GPCI & Locality ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(mo):
|
def _(mo):
|
||||||
mo.md("""
|
mo.md("""
|
||||||
## 3. Advanced APM (QP) Requirements
|
## 3. GPCI & Locality — Proposed CY2027 Geographic Indices
|
||||||
|
|
||||||
|
Geographic Practice Cost Indices scale each RVU component to local
|
||||||
|
input costs: `payment = (work_rvu x work_gpci + pe_rvu x pe_gpci +
|
||||||
|
mp_rvu x mp_gpci) x CF`. Every dollar figure in Sections 1-2 is
|
||||||
|
national/unadjusted (all GPCIs = 1.0); this section is where
|
||||||
|
locality enters, from `pfs.gpci_proposed` — the NPRM **Addendum E**
|
||||||
|
workbooks, ingested per rule partition exactly like
|
||||||
|
`pfs.rvu_proposed`.
|
||||||
|
|
||||||
|
GPCIs update on a **biennial** cycle, so the table holds three
|
||||||
|
partition-years: the CY2026 NPRM (`CMS-1832-P`) proposed CY2026
|
||||||
|
values *and* CY2027 phase-in values, and the CY2027 NPRM
|
||||||
|
(`CMS-1848-P`) re-proposes CY2027. That makes "did CMS change its
|
||||||
|
mind about 2027?" a plain self-join, done below.
|
||||||
|
|
||||||
|
> **Work-floor caveat:** the proposed work GPCIs are published
|
||||||
|
> **without** the statutory 1.0 work floor — that is the Addendum E
|
||||||
|
> column heading's own wording, while the CY2025 baseline column in
|
||||||
|
> the CY2026-NPRM workbook was published *with* the floor. Values
|
||||||
|
> here are shown exactly as published; whether a floor applies to
|
||||||
|
> actual CY2027 payment depends on legislation not adjudicated in
|
||||||
|
> this notebook.
|
||||||
|
""")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(q):
|
||||||
|
gpci_2027p = q("""
|
||||||
|
WITH prop AS (
|
||||||
|
SELECT mac, state, locality, locality_name,
|
||||||
|
work_gpci, pe_gpci, mp_gpci
|
||||||
|
FROM pfs.gpci_proposed
|
||||||
|
WHERE cms_rule_id = 'CMS-1848-P' AND gpci_year = 2027
|
||||||
|
),
|
||||||
|
fin AS (
|
||||||
|
SELECT mac, locality,
|
||||||
|
work_gpci AS work_gpci_2026f,
|
||||||
|
pe_gpci AS pe_gpci_2026f,
|
||||||
|
mp_gpci AS mp_gpci_2026f
|
||||||
|
FROM pfs.gpci WHERE year = 2026
|
||||||
|
)
|
||||||
|
SELECT p.*,
|
||||||
|
f.work_gpci_2026f, f.pe_gpci_2026f, f.mp_gpci_2026f,
|
||||||
|
round(p.work_gpci - f.work_gpci_2026f, 4) AS d_work,
|
||||||
|
round(p.pe_gpci - f.pe_gpci_2026f, 4) AS d_pe,
|
||||||
|
round(p.mp_gpci - f.mp_gpci_2026f, 4) AS d_mp,
|
||||||
|
round((p.work_gpci + p.pe_gpci + p.mp_gpci) / 3
|
||||||
|
- (f.work_gpci_2026f + f.pe_gpci_2026f + f.mp_gpci_2026f) / 3,
|
||||||
|
4) AS d_mean
|
||||||
|
FROM prop p
|
||||||
|
JOIN fin f USING (mac, locality)
|
||||||
|
""")
|
||||||
|
gpci_2027p
|
||||||
|
return (gpci_2027p,)
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(AMBER, TEAL, alt, gpci_2027p, mo, pl, proposed_for):
|
||||||
|
_n = 15
|
||||||
|
_up = (gpci_2027p["d_mean"] > 0).sum()
|
||||||
|
_down = (gpci_2027p["d_mean"] < 0).sum()
|
||||||
|
_flat = (gpci_2027p["d_mean"] == 0).sum()
|
||||||
|
|
||||||
|
_movers = (
|
||||||
|
gpci_2027p.sort("d_mean", descending=True)
|
||||||
|
.head(_n)
|
||||||
|
.vstack(gpci_2027p.sort("d_mean").head(_n).sort("d_mean", descending=True))
|
||||||
|
.with_columns(
|
||||||
|
(pl.col("locality_name") + " (" + pl.col("state") + ")").alias("label"),
|
||||||
|
pl.when(pl.col("d_mean") >= 0)
|
||||||
|
.then(pl.lit("Gain"))
|
||||||
|
.otherwise(pl.lit("Loss"))
|
||||||
|
.alias("sign"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
gpci_movers_chart = (
|
||||||
|
alt.Chart(_movers.to_pandas())
|
||||||
|
.mark_bar()
|
||||||
|
.encode(
|
||||||
|
x=alt.X("d_mean:Q", title="Mean GPCI change (unweighted mean of work/PE/MP)"),
|
||||||
|
y=alt.Y("label:N", title=None, sort=alt.SortField(field="d_mean", order="descending")),
|
||||||
|
color=alt.Color(
|
||||||
|
"sign:N",
|
||||||
|
title=None,
|
||||||
|
scale=alt.Scale(domain=["Gain", "Loss"], range=[TEAL, AMBER]),
|
||||||
|
legend=alt.Legend(orient="top"),
|
||||||
|
),
|
||||||
|
tooltip=[
|
||||||
|
"locality_name", "state", "mac", "locality",
|
||||||
|
alt.Tooltip("d_work:Q", format="+.4f"),
|
||||||
|
alt.Tooltip("d_pe:Q", format="+.4f"),
|
||||||
|
alt.Tooltip("d_mp:Q", format="+.4f"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.properties(
|
||||||
|
title="GPCI Movers — CY2027 Proposed vs. CY2026 Final, Top ±15 Localities",
|
||||||
|
width=640,
|
||||||
|
height=520,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
mo.vstack(
|
||||||
|
[
|
||||||
|
gpci_movers_chart,
|
||||||
|
mo.md(f"""
|
||||||
|
Across the {gpci_2027p.height} payment localities matched to
|
||||||
|
the CY2026-final GPCI table: **{_up} rise, {_down} fall,
|
||||||
|
{_flat} unchanged** on the unweighted mean of the three
|
||||||
|
components (a GAF proxy — CMS's official GAFs in Addendum D
|
||||||
|
are utilization-weighted and not loaded here).
|
||||||
|
|
||||||
|
**Sources:** `pfs.gpci_proposed` (`CMS-1848-P`, gpci_year
|
||||||
|
2027) — CY2027 NPRM Addendum E,
|
||||||
|
{proposed_for(2027).federal_register_citation}. Baseline —
|
||||||
|
`pfs.gpci` year 2026 (CY2026 Final).
|
||||||
|
"""),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(mo, q):
|
||||||
|
_drift = q("""
|
||||||
|
WITH projected AS (
|
||||||
|
SELECT mac, locality, locality_name, state,
|
||||||
|
work_gpci AS w_1832, pe_gpci AS p_1832, mp_gpci AS m_1832
|
||||||
|
FROM pfs.gpci_proposed
|
||||||
|
WHERE cms_rule_id = 'CMS-1832-P' AND gpci_year = 2027
|
||||||
|
),
|
||||||
|
reproposed AS (
|
||||||
|
SELECT mac, locality,
|
||||||
|
work_gpci AS w_1848, pe_gpci AS p_1848, mp_gpci AS m_1848
|
||||||
|
FROM pfs.gpci_proposed
|
||||||
|
WHERE cms_rule_id = 'CMS-1848-P' AND gpci_year = 2027
|
||||||
|
)
|
||||||
|
SELECT a.locality_name, a.state,
|
||||||
|
a.w_1832, b.w_1848, a.p_1832, b.p_1848, a.m_1832, b.m_1848,
|
||||||
|
round(abs(b.w_1848 - a.w_1832) + abs(b.p_1848 - a.p_1832)
|
||||||
|
+ abs(b.m_1848 - a.m_1832), 4) AS total_abs_drift
|
||||||
|
FROM projected a
|
||||||
|
JOIN reproposed b USING (mac, locality)
|
||||||
|
ORDER BY total_abs_drift DESC
|
||||||
|
""")
|
||||||
|
_changed = _drift.filter(_drift["total_abs_drift"] > 0)
|
||||||
|
if _changed.height == 0:
|
||||||
|
_msg = (
|
||||||
|
f"**All {_drift.height} localities carry identical CY2027 GPCIs in "
|
||||||
|
"both rulemakings** — the CY2027 NPRM re-proposes the CY2026 "
|
||||||
|
"NPRM's phase-in values unchanged."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_msg = (
|
||||||
|
f"**{_changed.height} of {_drift.height} localities moved** between "
|
||||||
|
"the CY2026 NPRM's projected 2027 values and the CY2027 NPRM's "
|
||||||
|
"re-proposed values (largest movers below)."
|
||||||
|
)
|
||||||
|
_parts = [
|
||||||
|
mo.md(f"""
|
||||||
|
### Did CMS change its 2027 mind? — CMS-1832-P projection vs. CMS-1848-P proposal
|
||||||
|
|
||||||
|
{_msg}
|
||||||
|
""")
|
||||||
|
]
|
||||||
|
if _changed.height > 0:
|
||||||
|
_parts.append(
|
||||||
|
mo.ui.table(
|
||||||
|
_changed.head(15).to_pandas(),
|
||||||
|
label="Largest 1832-P → 1848-P CY2027 GPCI revisions",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
mo.vstack(_parts)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(GRAY, INDIGO_MED, PLUM, alt, mo, pl, q):
|
||||||
|
# Long-term: highest- and lowest-cost localities (by CY2026-final mean
|
||||||
|
# GPCI) against the all-locality median, 2016-2026 final + 2027
|
||||||
|
# proposed (flagged).
|
||||||
|
_extremes = q("""
|
||||||
|
SELECT mac, locality, locality_name, state,
|
||||||
|
(work_gpci + pe_gpci + mp_gpci) / 3 AS mean_gpci
|
||||||
|
FROM pfs.gpci WHERE year = 2026
|
||||||
|
ORDER BY mean_gpci DESC
|
||||||
|
""")
|
||||||
|
_hi = _extremes.row(0, named=True)
|
||||||
|
_lo = _extremes.row(-1, named=True)
|
||||||
|
|
||||||
|
_hist = q(f"""
|
||||||
|
WITH sel AS (
|
||||||
|
SELECT year, locality_name, work_gpci, pe_gpci, mp_gpci
|
||||||
|
FROM pfs.gpci
|
||||||
|
WHERE (mac = '{_hi["mac"]}' AND locality = '{_hi["locality"]}')
|
||||||
|
OR (mac = '{_lo["mac"]}' AND locality = '{_lo["locality"]}')
|
||||||
|
),
|
||||||
|
med AS (
|
||||||
|
SELECT year, 'All-locality median' AS locality_name,
|
||||||
|
median(work_gpci) AS work_gpci,
|
||||||
|
median(pe_gpci) AS pe_gpci,
|
||||||
|
median(mp_gpci) AS mp_gpci
|
||||||
|
FROM pfs.gpci GROUP BY year
|
||||||
|
),
|
||||||
|
prop AS (
|
||||||
|
SELECT gpci_year AS year, locality_name, work_gpci, pe_gpci, mp_gpci
|
||||||
|
FROM pfs.gpci_proposed
|
||||||
|
WHERE cms_rule_id = 'CMS-1848-P' AND gpci_year = 2027
|
||||||
|
AND ((mac = '{_hi["mac"]}' AND locality = '{_hi["locality"]}')
|
||||||
|
OR (mac = '{_lo["mac"]}' AND locality = '{_lo["locality"]}'))
|
||||||
|
),
|
||||||
|
propmed AS (
|
||||||
|
SELECT gpci_year AS year, 'All-locality median' AS locality_name,
|
||||||
|
median(work_gpci) AS work_gpci,
|
||||||
|
median(pe_gpci) AS pe_gpci,
|
||||||
|
median(mp_gpci) AS mp_gpci
|
||||||
|
FROM pfs.gpci_proposed
|
||||||
|
WHERE cms_rule_id = 'CMS-1848-P' AND gpci_year = 2027
|
||||||
|
GROUP BY gpci_year
|
||||||
|
)
|
||||||
|
SELECT *, false AS proposed FROM sel
|
||||||
|
UNION ALL SELECT *, false FROM med
|
||||||
|
UNION ALL SELECT *, true FROM prop
|
||||||
|
UNION ALL SELECT *, true FROM propmed
|
||||||
|
ORDER BY year, locality_name
|
||||||
|
""")
|
||||||
|
|
||||||
|
_long = _hist.unpivot(
|
||||||
|
index=["year", "locality_name", "proposed"],
|
||||||
|
on=["work_gpci", "pe_gpci", "mp_gpci"],
|
||||||
|
variable_name="component",
|
||||||
|
value_name="gpci",
|
||||||
|
).with_columns(
|
||||||
|
pl.col("component").replace(
|
||||||
|
{"work_gpci": "Work", "pe_gpci": "PE", "mp_gpci": "MP"}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
_domain = [_hi["locality_name"], _lo["locality_name"], "All-locality median"]
|
||||||
|
_range = [INDIGO_MED, PLUM, GRAY]
|
||||||
|
|
||||||
|
_charts = []
|
||||||
|
for _comp in ("Work", "PE", "MP"):
|
||||||
|
_cdf = _long.filter(pl.col("component") == _comp).to_pandas()
|
||||||
|
_line = (
|
||||||
|
alt.Chart(_cdf[~_cdf["proposed"]])
|
||||||
|
.mark_line(point=True)
|
||||||
|
.encode(
|
||||||
|
x=alt.X("year:O", title="Year"),
|
||||||
|
y=alt.Y("gpci:Q", title="GPCI", scale=alt.Scale(zero=False)),
|
||||||
|
color=alt.Color(
|
||||||
|
"locality_name:N",
|
||||||
|
title=None,
|
||||||
|
scale=alt.Scale(domain=_domain, range=_range),
|
||||||
|
legend=alt.Legend(orient="bottom") if _comp == "PE" else None,
|
||||||
|
),
|
||||||
|
tooltip=["locality_name", "year:O", alt.Tooltip("gpci:Q", format=".4f")],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_prop_pts = (
|
||||||
|
alt.Chart(_cdf[_cdf["proposed"]])
|
||||||
|
.mark_point(shape="diamond", size=90, filled=True)
|
||||||
|
.encode(
|
||||||
|
x="year:O",
|
||||||
|
y="gpci:Q",
|
||||||
|
color=alt.Color(
|
||||||
|
"locality_name:N",
|
||||||
|
scale=alt.Scale(domain=_domain, range=_range),
|
||||||
|
legend=None,
|
||||||
|
),
|
||||||
|
tooltip=["locality_name", "year:O", alt.Tooltip("gpci:Q", format=".4f")],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_charts.append(
|
||||||
|
(_line + _prop_pts).properties(title=f"{_comp} GPCI", width=240, height=220)
|
||||||
|
)
|
||||||
|
gpci_longterm_chart = alt.hconcat(*_charts)
|
||||||
|
|
||||||
|
mo.vstack(
|
||||||
|
[
|
||||||
|
gpci_longterm_chart,
|
||||||
|
mo.md(f"""
|
||||||
|
Final-rule GPCIs 2016-2026 (`pfs.gpci`) for the
|
||||||
|
highest-cost locality (**{_hi["locality_name"]}**,
|
||||||
|
{_hi["state"]}) and lowest-cost locality
|
||||||
|
(**{_lo["locality_name"]}**, {_lo["state"]}) by CY2026 mean
|
||||||
|
GPCI, against the all-locality median. Diamond markers at
|
||||||
|
2027 are the **CY2027 NPRM proposal — final rule pending**,
|
||||||
|
with the work-floor caveat above applying to the Work
|
||||||
|
panel.
|
||||||
|
"""),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(gpci_2027p, mo, pfs_payment, pl, proposed_for, q):
|
||||||
|
# Locality-adjusted payment for the Section-1 example trio at the
|
||||||
|
# best/worst CY2027-proposed localities vs the national (GPCI=1.0)
|
||||||
|
# rate, all priced at the CY2027 proposed non-QP CF.
|
||||||
|
_best = gpci_2027p.sort("d_mean", descending=True).row(0, named=True)
|
||||||
|
_worst = gpci_2027p.sort("d_mean").row(0, named=True)
|
||||||
|
|
||||||
|
_rvu = q("""
|
||||||
|
SELECT hcpcs, description, work_rvu, non_fac_pe_rvu, mp_rvu
|
||||||
|
FROM pfs.rvu
|
||||||
|
WHERE year = 2026 AND (mod IS NULL OR mod = '')
|
||||||
|
AND hcpcs IN ('99213', '27447', '70553')
|
||||||
|
QUALIFY row_number() OVER (PARTITION BY hcpcs ORDER BY hcpcs) = 1
|
||||||
|
""")
|
||||||
|
|
||||||
|
_localities = pl.DataFrame(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"mac": r["mac"],
|
||||||
|
"locality": r["locality"],
|
||||||
|
"where": f"{r['locality_name']} ({r['state']})",
|
||||||
|
"work_gpci": r["work_gpci"],
|
||||||
|
"pe_gpci": r["pe_gpci"],
|
||||||
|
"mp_gpci": r["mp_gpci"],
|
||||||
|
}
|
||||||
|
for r in (_best, _worst)
|
||||||
|
]
|
||||||
|
+ [
|
||||||
|
{
|
||||||
|
"mac": "NATL",
|
||||||
|
"locality": "00",
|
||||||
|
"where": "National (GPCI = 1.0)",
|
||||||
|
"work_gpci": 1.0,
|
||||||
|
"pe_gpci": 1.0,
|
||||||
|
"mp_gpci": 1.0,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
_rvu_x_loc = _rvu.join(_localities.select("mac", "locality"), how="cross")
|
||||||
|
_priced = pfs_payment(
|
||||||
|
_rvu_x_loc,
|
||||||
|
_localities.select("mac", "locality", "work_gpci", "pe_gpci", "mp_gpci"),
|
||||||
|
cf=proposed_for(2027).conversion_factor,
|
||||||
|
)
|
||||||
|
gpci_payment_table = (
|
||||||
|
_priced.join(_localities.select("mac", "locality", "where"), on=["mac", "locality"])
|
||||||
|
.with_columns(pl.col("payment_amount").round(2))
|
||||||
|
.pivot(on="where", index=["hcpcs", "description"], values="payment_amount")
|
||||||
|
)
|
||||||
|
|
||||||
|
mo.vstack(
|
||||||
|
[
|
||||||
|
mo.ui.table(gpci_payment_table.to_pandas(), label="Locality-adjusted payment — CY2027 proposed non-QP CF"),
|
||||||
|
mo.md(f"""
|
||||||
|
`pfs.calcs.payment.payment` (the module's locality formula)
|
||||||
|
applied to CY2026-final RVUs at the CY2027 **proposed**
|
||||||
|
non-QP CF ({proposed_for(2027).conversion_factor}) — final
|
||||||
|
rule pending. Localities shown are the CY2027 proposal's
|
||||||
|
biggest mean-GPCI gainer (**{_best["locality_name"]}**) and
|
||||||
|
decliner (**{_worst["locality_name"]}**), with the
|
||||||
|
national GPCI = 1.0 rate for reference.
|
||||||
|
"""),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# ── 4. Primary Care Services (ACO attribution set) ──────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(mo, q):
|
||||||
|
pcs_codes = q("""
|
||||||
|
SELECT hcpcs_code AS hcpcs, trim(description) AS pcs_description
|
||||||
|
FROM cms.primary_care_service_code
|
||||||
|
ORDER BY hcpcs
|
||||||
|
""")
|
||||||
|
assert pcs_codes.height == 109, (
|
||||||
|
f"expected 109 designated primary care service codes, got {pcs_codes.height}"
|
||||||
|
)
|
||||||
|
mo.md(f"""
|
||||||
|
## 4. Primary Care Services — the ACO Attribution Set
|
||||||
|
|
||||||
|
The **{pcs_codes.height} designated primary care service codes**
|
||||||
|
used for Medicare Shared Savings Program beneficiary assignment (42
|
||||||
|
CFR § 425.400(c)), read live from
|
||||||
|
`cms.primary_care_service_code` — the attribution reference list
|
||||||
|
published to the lake from the aco module. These are the services
|
||||||
|
whose billing patterns decide which ACO a beneficiary is attributed
|
||||||
|
to, so their PFS valuation moves both clinician revenue **and** the
|
||||||
|
attribution denominators every MSSP financial calculation stands
|
||||||
|
on.
|
||||||
|
|
||||||
|
Two disclosures, once: (1) this is the **current-law list applied
|
||||||
|
retrospectively** — the designation set itself changes across
|
||||||
|
rulemakings and is not versioned by year in this repo; (2) all
|
||||||
|
aggregate statements are **unweighted by utilization** (the lake
|
||||||
|
carries no claims-volume reference), so each code counts equally.
|
||||||
|
""")
|
||||||
|
return (pcs_codes,)
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(RULES, pl, proposed_for, q):
|
||||||
|
_pqm_raw = q("""
|
||||||
|
WITH pcs AS (
|
||||||
|
SELECT hcpcs_code AS hcpcs, trim(description) AS pcs_description
|
||||||
|
FROM cms.primary_care_service_code
|
||||||
|
),
|
||||||
|
prop AS (
|
||||||
|
SELECT hcpcs, status_code AS status_2027p,
|
||||||
|
work_rvu AS work_2027p,
|
||||||
|
work_rvu + coalesce(non_fac_pe_rvu, fac_pe_rvu) + mp_rvu
|
||||||
|
AS total_2027p
|
||||||
|
FROM pfs.rvu_proposed
|
||||||
|
WHERE cms_rule_id = 'CMS-1848-P' AND (mod IS NULL OR mod = '')
|
||||||
|
QUALIFY row_number() OVER (PARTITION BY hcpcs ORDER BY hcpcs) = 1
|
||||||
|
),
|
||||||
|
fin AS (
|
||||||
|
SELECT hcpcs, status_code AS status_2026f,
|
||||||
|
work_rvu AS work_2026f,
|
||||||
|
work_rvu + coalesce(non_fac_pe_rvu, fac_pe_rvu) + mp_rvu
|
||||||
|
AS total_2026f
|
||||||
|
FROM pfs.rvu
|
||||||
|
WHERE year = 2026 AND (mod IS NULL OR mod = '')
|
||||||
|
QUALIFY row_number() OVER (PARTITION BY hcpcs ORDER BY hcpcs) = 1
|
||||||
|
)
|
||||||
|
SELECT pcs.hcpcs, pcs.pcs_description,
|
||||||
|
fin.status_2026f, fin.work_2026f, fin.total_2026f,
|
||||||
|
prop.status_2027p, prop.work_2027p, prop.total_2027p
|
||||||
|
FROM pcs
|
||||||
|
LEFT JOIN fin USING (hcpcs)
|
||||||
|
LEFT JOIN prop USING (hcpcs)
|
||||||
|
ORDER BY pcs.hcpcs
|
||||||
|
""")
|
||||||
|
|
||||||
|
_cf26 = RULES[2026].conversion_factor
|
||||||
|
_cf27p = proposed_for(2027).conversion_factor
|
||||||
|
pqm_near = _pqm_raw.with_columns(
|
||||||
|
(pl.col("total_2026f") * _cf26).round(2).alias("dollar_2026final"),
|
||||||
|
(pl.col("total_2027p") * _cf27p).round(2).alias("dollar_2027proposed"),
|
||||||
|
).with_columns(
|
||||||
|
(pl.col("dollar_2027proposed") - pl.col("dollar_2026final"))
|
||||||
|
.round(2)
|
||||||
|
.alias("dollar_delta"),
|
||||||
|
pl.when(pl.col("total_2026f").is_not_null() & pl.col("total_2027p").is_not_null())
|
||||||
|
.then(
|
||||||
|
(100 * (pl.col("dollar_2027proposed") - pl.col("dollar_2026final"))
|
||||||
|
/ pl.col("dollar_2026final")).round(2)
|
||||||
|
)
|
||||||
|
.alias("pct_change"),
|
||||||
|
pl.when(pl.col("total_2026f").is_not_null() & pl.col("total_2027p").is_not_null())
|
||||||
|
.then(pl.lit("both"))
|
||||||
|
.when(pl.col("total_2027p").is_not_null())
|
||||||
|
.then(pl.lit("new_in_2027"))
|
||||||
|
.when(pl.col("total_2026f").is_not_null())
|
||||||
|
.then(pl.lit("missing_from_2027"))
|
||||||
|
.otherwise(pl.lit("absent_both"))
|
||||||
|
.alias("coverage"),
|
||||||
|
)
|
||||||
|
assert pqm_near.height == 109, pqm_near.height
|
||||||
|
return (pqm_near,)
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(RULES, mo, pqm_near, proposed_for):
|
||||||
|
mo.vstack(
|
||||||
|
[
|
||||||
|
mo.md(f"""
|
||||||
|
### Near-term — every designated code, CY2026 final vs. CY2027 proposed
|
||||||
|
|
||||||
|
One row per designated code: CY2026-final and
|
||||||
|
CY2027-proposed work/total RVUs (non-facility PE where
|
||||||
|
priced, facility otherwise), dollars at each vintage's own
|
||||||
|
standard CF (CY2026 final {RULES[2026].conversion_factor};
|
||||||
|
CY2027 proposed non-QP
|
||||||
|
{proposed_for(2027).conversion_factor} — **final rule
|
||||||
|
pending**), national unadjusted; Section 3 carries the
|
||||||
|
locality adjustment.
|
||||||
|
"""),
|
||||||
|
mo.ui.table(
|
||||||
|
pqm_near.sort("pct_change", nulls_last=True).to_pandas(),
|
||||||
|
page_size=25,
|
||||||
|
label="All 109 designated primary care services — near-term comparison",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(AMBER, TEAL, alt, mo, pl, pqm_near):
|
||||||
|
_both = pqm_near.filter(pl.col("coverage") == "both").with_columns(
|
||||||
|
pl.when(pl.col("pct_change") >= 0)
|
||||||
|
.then(pl.lit("Gain"))
|
||||||
|
.otherwise(pl.lit("Loss"))
|
||||||
|
.alias("sign")
|
||||||
|
)
|
||||||
|
_one_sided = pqm_near.filter(pl.col("coverage") != "both")
|
||||||
|
|
||||||
|
pqm_near_chart = (
|
||||||
|
alt.Chart(_both.to_pandas())
|
||||||
|
.mark_bar()
|
||||||
|
.encode(
|
||||||
|
x=alt.X("pct_change:Q", title="% change in national payment, CY2026 final → CY2027 proposed"),
|
||||||
|
y=alt.Y("hcpcs:N", title=None, sort=alt.SortField(field="pct_change", order="descending")),
|
||||||
|
color=alt.Color(
|
||||||
|
"sign:N",
|
||||||
|
title=None,
|
||||||
|
scale=alt.Scale(domain=["Gain", "Loss"], range=[TEAL, AMBER]),
|
||||||
|
legend=alt.Legend(orient="top"),
|
||||||
|
),
|
||||||
|
tooltip=[
|
||||||
|
"hcpcs", "pcs_description",
|
||||||
|
alt.Tooltip("dollar_2026final:Q", format="$.2f"),
|
||||||
|
alt.Tooltip("dollar_2027proposed:Q", format="$.2f"),
|
||||||
|
alt.Tooltip("pct_change:Q", format="+.2f"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.properties(
|
||||||
|
title="Designated Primary Care Services — % Payment Change (every matched code)",
|
||||||
|
width=640,
|
||||||
|
height=max(300, 11 * _both.height),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
_sided_lines = "\n".join(
|
||||||
|
f" - `{r['hcpcs']}` — {r['pcs_description']} (*{r['coverage'].replace('_', ' ')}*)"
|
||||||
|
for r in _one_sided.iter_rows(named=True)
|
||||||
|
)
|
||||||
|
mo.vstack(
|
||||||
|
[
|
||||||
|
pqm_near_chart,
|
||||||
|
mo.md(f"""
|
||||||
|
**{_both.height} of 109** designated codes price in both
|
||||||
|
tables and appear above. The remaining
|
||||||
|
**{_one_sided.height}** are one-sided or unpriced and are
|
||||||
|
listed explicitly rather than plotted with a fabricated
|
||||||
|
baseline:
|
||||||
|
|
||||||
|
{_sided_lines}
|
||||||
|
|
||||||
|
The one-sided groups are computed live, so their
|
||||||
|
composition tracks the data: as of this ingest every
|
||||||
|
designated code that prices anywhere prices in **both**
|
||||||
|
tables (the APCM G-codes already carry CY2026-final RVUs),
|
||||||
|
and the unmatched remainder is entirely `absent_both` —
|
||||||
|
deleted or replaced legacy codes (telephone E/M 99441-3,
|
||||||
|
prolonged 99354-5, consult-era visits, pre-APCM
|
||||||
|
check-in/CCM G-codes) that stay on the attribution
|
||||||
|
designation list without a current PFS price.
|
||||||
|
"""),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(RULES, pl, proposed_for, q):
|
||||||
|
_hist = q("""
|
||||||
|
WITH pcs AS (
|
||||||
|
SELECT hcpcs_code AS hcpcs, trim(description) AS pcs_description
|
||||||
|
FROM cms.primary_care_service_code
|
||||||
|
),
|
||||||
|
fin AS (
|
||||||
|
SELECT year, hcpcs,
|
||||||
|
work_rvu + coalesce(non_fac_pe_rvu, fac_pe_rvu) + mp_rvu
|
||||||
|
AS total_rvu
|
||||||
|
FROM pfs.rvu
|
||||||
|
WHERE (mod IS NULL OR mod = '')
|
||||||
|
QUALIFY row_number() OVER (PARTITION BY hcpcs, year ORDER BY hcpcs) = 1
|
||||||
|
),
|
||||||
|
prop AS (
|
||||||
|
SELECT 2027 AS year, hcpcs,
|
||||||
|
work_rvu + coalesce(non_fac_pe_rvu, fac_pe_rvu) + mp_rvu
|
||||||
|
AS total_rvu
|
||||||
|
FROM pfs.rvu_proposed
|
||||||
|
WHERE cms_rule_id = 'CMS-1848-P' AND (mod IS NULL OR mod = '')
|
||||||
|
QUALIFY row_number() OVER (PARTITION BY hcpcs ORDER BY hcpcs) = 1
|
||||||
|
)
|
||||||
|
SELECT pcs.hcpcs, pcs.pcs_description, u.year, u.total_rvu,
|
||||||
|
u.year = 2027 AS proposed
|
||||||
|
FROM pcs
|
||||||
|
JOIN (SELECT * FROM fin UNION ALL SELECT * FROM prop) u USING (hcpcs)
|
||||||
|
WHERE u.total_rvu IS NOT NULL
|
||||||
|
ORDER BY pcs.hcpcs, u.year
|
||||||
|
""")
|
||||||
|
|
||||||
|
_cf = pl.DataFrame(
|
||||||
|
{
|
||||||
|
"year": [y for y in sorted(RULES) if y >= 2015] + [2027],
|
||||||
|
"cf": [RULES[y].conversion_factor for y in sorted(RULES) if y >= 2015]
|
||||||
|
+ [proposed_for(2027).conversion_factor],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
pqm_long = (
|
||||||
|
_hist.join(_cf, on="year")
|
||||||
|
.with_columns((pl.col("total_rvu") * pl.col("cf")).round(2).alias("dollar"))
|
||||||
|
.with_columns(
|
||||||
|
(
|
||||||
|
100
|
||||||
|
* (pl.col("total_rvu") / pl.col("total_rvu").shift(1).over("hcpcs") - 1)
|
||||||
|
)
|
||||||
|
.round(2)
|
||||||
|
.alias("rvu_yoy_pct")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return (pqm_long,)
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(AMBER, TEAL, alt, mo, pqm_long):
|
||||||
|
_hm = pqm_long.to_pandas()
|
||||||
|
pqm_heatmap = (
|
||||||
|
alt.Chart(_hm)
|
||||||
|
.mark_rect(stroke="#F7F5F0", strokeWidth=1)
|
||||||
|
.encode(
|
||||||
|
x=alt.X("year:O", title="Year (2027 = proposed)"),
|
||||||
|
y=alt.Y("hcpcs:N", title=None),
|
||||||
|
color=alt.Color(
|
||||||
|
"rvu_yoy_pct:Q",
|
||||||
|
title="RVU YoY %",
|
||||||
|
scale=alt.Scale(domainMid=0, range=[AMBER, "#EDEBE6", TEAL]),
|
||||||
|
),
|
||||||
|
tooltip=[
|
||||||
|
"hcpcs", "pcs_description", "year:O",
|
||||||
|
alt.Tooltip("total_rvu:Q", format=".2f"),
|
||||||
|
alt.Tooltip("dollar:Q", format="$.2f"),
|
||||||
|
alt.Tooltip("rvu_yoy_pct:Q", format="+.2f"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.properties(
|
||||||
|
title="Total-RVU Year-over-Year % Change — Every Designated Code, 2015-2027p",
|
||||||
|
width=560,
|
||||||
|
height=11 * _hm["hcpcs"].nunique(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
mo.vstack(
|
||||||
|
[
|
||||||
|
pqm_heatmap,
|
||||||
|
mo.md("""
|
||||||
|
Long-term valuation of **each individual designated code**:
|
||||||
|
cells are year-over-year % change in total RVUs (first
|
||||||
|
available year blank). Sustained white rows are codes CMS
|
||||||
|
has left untouched for a decade; the visible vertical band
|
||||||
|
at 2021 is the office/outpatient E/M revaluation. Hover any
|
||||||
|
cell for that code-year's RVUs and dollars.
|
||||||
|
"""),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(INDIGO_MED, alt, mo, pl, pqm_long):
|
||||||
|
_span = (
|
||||||
|
pqm_long.sort("hcpcs", "year")
|
||||||
|
.group_by("hcpcs", "pcs_description")
|
||||||
|
.agg(
|
||||||
|
pl.col("dollar").first().alias("dollar_first"),
|
||||||
|
pl.col("dollar").last().alias("dollar_last"),
|
||||||
|
pl.len().alias("n_years"),
|
||||||
|
)
|
||||||
|
.filter(pl.col("n_years") >= 5)
|
||||||
|
.with_columns((pl.col("dollar_last") - pl.col("dollar_first")).abs().alias("abs_move"))
|
||||||
|
.sort("abs_move", descending=True)
|
||||||
|
.head(12)
|
||||||
|
)
|
||||||
|
_sel = pqm_long.filter(pl.col("hcpcs").is_in(_span["hcpcs"]))
|
||||||
|
|
||||||
|
_rows = []
|
||||||
|
_codes = _span["hcpcs"].to_list()
|
||||||
|
for _i in range(0, len(_codes), 4):
|
||||||
|
_row_charts = []
|
||||||
|
for _code in _codes[_i : _i + 4]:
|
||||||
|
_cdf = _sel.filter(pl.col("hcpcs") == _code).to_pandas()
|
||||||
|
_solid = (
|
||||||
|
alt.Chart(_cdf[~_cdf["proposed"]])
|
||||||
|
.mark_line(point=True, color=INDIGO_MED)
|
||||||
|
.encode(
|
||||||
|
x=alt.X("year:O", title=None, axis=alt.Axis(values=[2015, 2020, 2026])),
|
||||||
|
y=alt.Y("dollar:Q", title=None, scale=alt.Scale(zero=False)),
|
||||||
|
tooltip=["hcpcs", "year:O", alt.Tooltip("dollar:Q", format="$.2f")],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_prop = (
|
||||||
|
alt.Chart(_cdf[_cdf["year"] >= 2026])
|
||||||
|
.mark_line(point=alt.OverlayMarkDef(shape="diamond", size=70), color=INDIGO_MED, strokeDash=[4, 3])
|
||||||
|
.encode(
|
||||||
|
x="year:O",
|
||||||
|
y="dollar:Q",
|
||||||
|
tooltip=["hcpcs", "year:O", alt.Tooltip("dollar:Q", format="$.2f")],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
_row_charts.append(
|
||||||
|
(_solid + _prop).properties(title=str(_code), width=150, height=120)
|
||||||
|
)
|
||||||
|
_rows.append(alt.hconcat(*_row_charts))
|
||||||
|
pqm_multiples = alt.vconcat(*_rows)
|
||||||
|
|
||||||
|
mo.vstack(
|
||||||
|
[
|
||||||
|
pqm_multiples,
|
||||||
|
mo.md("""
|
||||||
|
The 12 designated codes with the largest absolute national
|
||||||
|
dollar move across their observed span (min. 5 priced
|
||||||
|
years). Solid line = final rules at each year's own final
|
||||||
|
CF; dashed segment to the diamond = **CY2027 proposed, at
|
||||||
|
the proposed non-QP CF — final rule pending**. Dollar
|
||||||
|
trajectories mix RVU changes with CF changes deliberately —
|
||||||
|
this is realized-price history, not resource-weight
|
||||||
|
history (the heatmap above isolates RVUs).
|
||||||
|
"""),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(gpci_2027p, mo, pl, pqm_near, proposed_for):
|
||||||
|
# Cross-cut: what the GPCI proposal does to one bread-and-butter
|
||||||
|
# attribution code (99213) at the Section-3 extreme localities.
|
||||||
|
_r = pqm_near.filter(pl.col("hcpcs") == "99213").row(0, named=True)
|
||||||
|
_best = gpci_2027p.sort("d_mean", descending=True).row(0, named=True)
|
||||||
|
_worst = gpci_2027p.sort("d_mean").row(0, named=True)
|
||||||
|
_natl = _r["dollar_2027proposed"]
|
||||||
|
|
||||||
|
_rows = pl.DataFrame(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"where": f"{loc['locality_name']} ({loc['state']})",
|
||||||
|
"work_gpci": loc["work_gpci"],
|
||||||
|
"pe_gpci": loc["pe_gpci"],
|
||||||
|
"mp_gpci": loc["mp_gpci"],
|
||||||
|
"mean_gpci_delta_vs_2026f": loc["d_mean"],
|
||||||
|
}
|
||||||
|
for loc in (_best, _worst)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
mo.vstack(
|
||||||
|
[
|
||||||
|
mo.md(f"""
|
||||||
|
### GPCI × attribution cross-cut — 99213 under the CY2027 proposal
|
||||||
|
|
||||||
|
`99213` (established-patient office visit — the single most
|
||||||
|
attribution-relevant E/M code) prices at
|
||||||
|
**${_natl:.2f}** nationally under the CY2027 proposed
|
||||||
|
non-QP CF. At the proposal's extreme localities that
|
||||||
|
becomes a spread of locality-adjusted rates (Section 3's
|
||||||
|
payment table carries the exact figures for the example
|
||||||
|
trio); the GPCI movement below is what drives it.
|
||||||
|
"""),
|
||||||
|
mo.ui.table(_rows.to_pandas(), label="Extreme localities — proposed CY2027 GPCIs (vs CY2026-final mean)"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# ── 5. Advanced APM ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
@app.cell(hide_code=True)
|
||||||
|
def _(mo):
|
||||||
|
mo.md("""
|
||||||
|
## 5. Advanced APM (QP) Requirements
|
||||||
|
|
||||||
Under MACRA 2015, clinicians who participate heavily enough in an
|
Under MACRA 2015, clinicians who participate heavily enough in an
|
||||||
Advanced Alternative Payment Model (Advanced APM) during a "QP
|
Advanced Alternative Payment Model (Advanced APM) during a "QP
|
||||||
@@ -722,20 +1506,23 @@ def _(alt, mo, proposed_for, qp_differential):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# ── 4. Provenance ───────────────────────────────────────────────────────
|
# ── 6. Provenance ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
@app.cell(hide_code=True)
|
@app.cell(hide_code=True)
|
||||||
def _(mo):
|
def _(mo):
|
||||||
mo.md("""
|
mo.md("""
|
||||||
## 4. Provenance & Comment-Period Status
|
## 6. Provenance & Comment-Period Status
|
||||||
|
|
||||||
Ingest-log entries (`cms.ingest_log`) for every table this notebook
|
Ingest-log entries (`cms.ingest_log`) for every FR-ingested table
|
||||||
reads from — `pfs.rvu` and `pfs.rvu_proposed` — so every figure
|
this notebook reads — `pfs.rvu`, `pfs.rvu_proposed`, `pfs.gpci`,
|
||||||
above can be traced back to a specific ingest run, source file, and
|
and `pfs.gpci_proposed` — so every figure above can be traced back
|
||||||
Federal Register citation. (`pfs.gpci` is not queried anywhere in
|
to a specific ingest run, source file, and Federal Register
|
||||||
this notebook — see the intro's GPCI = 1.0 scope note — so it is
|
citation. `cms.primary_care_service_code` (Section 4's 109-code
|
||||||
deliberately excluded here rather than claimed as a source.)
|
attribution list) is a reference table published from the aco
|
||||||
|
module's CCLF/attribution data, not an FR ingest, so it carries no
|
||||||
|
ingest-log row; its provenance is the MSSP assignment
|
||||||
|
specification (42 CFR § 425.400(c)).
|
||||||
""")
|
""")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -768,7 +1555,8 @@ def _(mo, q):
|
|||||||
SELECT run_id, ingested_at, module, table_name, rule_id,
|
SELECT run_id, ingested_at, module, table_name, rule_id,
|
||||||
source_file, sha256, rows, fr_citation, pincite_key
|
source_file, sha256, rows, fr_citation, pincite_key
|
||||||
FROM cms.ingest_log
|
FROM cms.ingest_log
|
||||||
WHERE table_name IN ('pfs.rvu', 'pfs.rvu_proposed')
|
WHERE table_name IN ('pfs.rvu', 'pfs.rvu_proposed',
|
||||||
|
'pfs.gpci', 'pfs.gpci_proposed')
|
||||||
ORDER BY ingested_at DESC
|
ORDER BY ingested_at DESC
|
||||||
""")
|
""")
|
||||||
mo.ui.table(provenance.to_pandas(), label="Ingest Log — Tables Used in This Notebook")
|
mo.ui.table(provenance.to_pandas(), label="Ingest Log — Tables Used in This Notebook")
|
||||||
|
|||||||
Reference in New Issue
Block a user