Vertebro / spine_coder /spine_coder_core.py
Slaiwala's picture
Update spine_coder/spine_coder_core.py
f2e05cd verified
import re, json
from typing import Dict, Any, List, Tuple
# ---------- helpers ----------
def _norm(s: str) -> str:
if not s: return ""
s = s.replace("\u2013","-").replace("\u2014","-").replace("—","-").replace("–","-").replace("\u00A0"," ")
s = re.sub(r"\s+", " ", s.strip().lower())
return s
def _has(text: str, pat: str) -> bool:
return re.search(pat, text, flags=re.I) is not None
def _level_sort_key(lv: str) -> Tuple[int, int]:
band = {"C":100, "T":200, "L":300, "S":400}.get(lv[0], 999)
num = int(re.sub(r"\D", "", lv) or 0)
return (band, num)
def _extract_levels(t: str) -> List[str]:
levels = set()
# Ranges (e.g., L4-5, C4–C7). If prefix changes (C->T), capture both endpoints.
for m in re.finditer(r"\b([CTLS])\s?(\d{1,2})\s*[-–]\s*([CTLS])?\s?(\d{1,2})\b", t, flags=re.I):
pfx1, n1, pfx2, n2 = m.group(1).upper(), int(m.group(2)), (m.group(3) or m.group(1)).upper(), int(m.group(4))
if pfx1 != pfx2:
levels.add(f"{pfx1}{n1}"); levels.add(f"{pfx2}{n2}")
else:
lo, hi = sorted([n1, n2])
for k in range(lo, hi+1): levels.add(f"{pfx1}{k}")
# Singles (e.g., L4, T10)
for m in re.finditer(r"\b([CTLS])\s?(\d{1,2})\b", t, flags=re.I):
levels.add(f"{m.group(1).upper()}{int(m.group(2))}")
return sorted(levels, key=_level_sort_key)
def _count_interspaces(levels: List[str]) -> int:
if not levels: return 0
by_band: Dict[str, List[int]] = {}
for lv in levels:
by_band.setdefault(lv[0], []).append(int(re.sub(r"\D", "", lv)))
for b in list(by_band):
by_band[b] = sorted(set(by_band[b]))
inters = 0
for arr in by_band.values():
if len(arr) >= 2:
inters += sum(1 for i in range(1, len(arr)) if arr[i]-arr[i-1]==1)
# L5–S1 interspace
if "L5" in levels and "S1" in levels: inters += 1
# Conservative fallback for multi-level with gaps
if inters == 0:
for arr in by_band.values():
if len(arr) >= 2:
inters = 1
break
return inters
def _span_segments(levels: List[str]) -> int:
if not levels: return 0
by_band: Dict[str, List[int]] = {}
for lv in levels:
by_band.setdefault(lv[0], []).append(int(re.sub(r"\D", "", lv)))
spans = []
for arr in by_band.values():
arr = sorted(set(arr))
spans.append(arr[-1]-arr[0]+1 if len(arr)>=2 else 1)
# If multiple bands, take max; ensure at least 2 for instrumentation estimation in mixed cases
return (max(spans) if spans else 0) if len(spans)==1 else max(spans + [2])
def _laterality_mods(t: str) -> List[str]:
mods: List[str] = []
if _has(t, r"\bleft\b|left-sided|left side|leftward|hemilam\w* left|foraminotomy left|\blt\b"):
mods.append("LT")
# Avoid bare \brt\b to reduce false matches
if _has(t, r"\bright\b|right-sided|right side|rightward|hemilam\w* right|foraminotomy right"):
mods.append("RT")
return list(sorted(set(mods)))
def _add(suggestions: List[Dict[str, Any]], cpt: str, desc: str, rationale: str,
category: str, primary: bool, confidence: float = 0.8, units: int = 1,
mods: List[str] = None, score: float = None):
suggestions.append({
"cpt": cpt, "desc": desc, "rationale": rationale, "category": category,
"primary": primary, "confidence": confidence, "units": units,
"modifiers": mods or [], "score": score if score is not None else confidence
})
def _inst_code_by_span(span_segments: int, anterior: bool) -> str:
if span_segments <= 1: return ""
if anterior:
return "22845" if span_segments <= 3 else ("22846" if span_segments <= 7 else "22847")
else:
return "22842" if span_segments <= 3 else ("22843" if span_segments <= 7 else "22844")
# ---------- main ----------
def suggest_with_cpt_billing(note: str, payer: str = "Medicare", top_k: int = 10) -> Dict[str, Any]:
t = _norm(note)
suggestions: List[Dict[str, Any]] = []
case_modifiers: List[Dict[str, str]] = []
# --- Early guard: exposure-only / access-only -----------------------------
# Flexible: catches "anterior exposure of L4–S1 performed by vascular surgeon ... No fusion performed"
exposure_only = (
_has(t, r"\bexpos(e|ed|ure)\b|\bapproach\b") and
_has(t, r"\banterior\b|retroperitoneal|vascular (surgeon|exposure)|access\b") and
_has(t, r"\bno (fusion|arthrodesis|interbody|implants?|cage|plate|screw|instrumentation)\b|without (fusion|interbody|instrumentation)") and
not _has(t, r"\bfusion|arthrodesis|discectom\w+|interbody|tlif|plif|alif|acdf|arthroplasty|stimulator|instrument|hardware|screw|rod|plate|cage")
)
if exposure_only:
return {
"payer": payer,
"region": "unknown",
"levels": [],
"interspaces_est": 0,
"span_segments_est": 0,
"suggestions": [{
"cpt": "00000",
"desc": "No recognizable spine CPT pattern found",
"rationale": "Exposure-only access without decompression/fusion/instrumentation.",
"confidence": 0.0, "category": "none", "primary": True, "modifiers": [], "units": 1, "score": 0.0
}],
"case_modifiers": [],
"flags": [],
"flags_map": {},
"laterality": "na",
"build": "FINAL-v2.1",
"mode": "standard",
}
# --- Levels / spans / laterality -----------------------------------------
levels = _extract_levels(t)
inters = _count_interspaces(levels)
span = _span_segments(levels)
lat_mods = _laterality_mods(t)
# ---------- Region ----------
region = "unknown"
if any(l.startswith("C") for l in levels) or _has(t, r"\bcervic"):
region = "cervical"
elif any(l.startswith("T") for l in levels) or _has(t, r"\bthorac"):
region = "thoracic"
elif any(l.startswith(("L","S")) for l in levels) or _has(t, r"\blumbar|sacrum"):
region = "lumbar"
# Transitional cervicothoracic override
has_c7 = any(l.upper() == "C7" for l in levels) or _has(t, r"\bc7\b")
has_t1_3 = any(l.upper() in {"T1","T2","T3"} for l in levels) or _has(t, r"\bt[1-3]\b")
if has_c7 and has_t1_3:
region = "cervicothoracic"
# Helper flags
mentions_plate_ant = _has(t, r"\b(anterior (plate|instrument(ation)?)|plate fixed|plating)\b") or _has(t, r"\bplate\b")
mentions_pedicle = _has(t, r"\bpedicle screw|pedicle-screw|pedicle fixation|s2ai\b")
mentions_rod = _has(t, r"\brod(s)?\b")
mentions_inst_post = mentions_pedicle or mentions_rod or _has(t, r"\binstrument(ation)?\b")
did_corpectomy = False
no_decompression_due_to_revision = False
avoid_decompression_for_stimulator = False
# ---------- (1) Hardware removal (support both word orders) ----------
rem_pat_either = (
r"(?:\b(hardware|instrumentation|implant|plate|rod|screw)\b.{0,40}\b(remov\w+|explant\w+|taken out))"
r"|(?:\bremov\w+\b.{0,40}\b(hardware|instrumentation|implant|plate|rod|screw)\b)"
)
if _has(t, rem_pat_either):
if _has(t, r"\banterior\b|acdf|alif|anterior plate|smith[- ]?robinson"):
_add(suggestions, "22855", "Removal of anterior instrumentation",
"Anterior hardware removal documented.", "hardware_removal", True, 0.85, mods=lat_mods)
elif _has(t, r"non[- ]?segmental|hook|wire") and not _has(t, r"segmental|pedicle"):
_add(suggestions, "22850", "Removal of posterior non-segmental instrumentation",
"Posterior non-segmental removal documented.", "hardware_removal", True, 0.82, mods=lat_mods)
else:
_add(suggestions, "22852", "Removal of posterior segmental instrumentation",
"Posterior segmental hardware removal documented.", "hardware_removal", True, 0.85, mods=lat_mods)
# If remove + replace/reinsert/revision language → add 22849 and avoid decompression auto-fires
if _has(t, r"\b(reinsertion|remove and replace|revision of instrumentation|hardware revision)\b"):
_add(suggestions, "22849", "Reinsertion/revision of spinal instrumentation",
"Revision/reinsertion documented.", "revision", True, 0.85)
no_decompression_due_to_revision = True
# ---------- (2b) New posterior instrumentation WITHOUT explicit fusion ----------
if (
not _has(t, r"\btlif\b|\bplif\b|posterolateral\b.*\bfusion|posterior\b.*\bfusion")
and (mentions_inst_post or _has(t, r"\b(new|placed|inserted|reinserted)\b.{0,20}\b(screw|rod|construct|instrumentation)\b"))
and region in {"cervical","thoracic","lumbar"}
):
est_segments = span or max(2, inters + 1)
code = _inst_code_by_span(est_segments, anterior=False)
if code:
desc = {"22842":"Posterior segmental instrumentation (2–3 segments)",
"22843":"Posterior segmental instrumentation (4–7 segments)",
"22844":"Posterior segmental instrumentation (8+ segments)"}[code]
_add(suggestions, code, desc, "New posterior instrumentation documented.", "instrumentation", False, 0.82)
# ---------- (2) ACDF with guards (history/removal) + broadened trigger ----------
found_removal = _has(t, rem_pat_either)
acdf_history = _has(t, r"\b(prior|previous|history of|s/?p)\s*acdf\b")
acdf_current = (
_has(t, r"\banterior cervical discectomy|anterior cervical fusion|smith[- ]?robinson\b")
or (
(region in {"cervical","cervicothoracic"})
and _has(t, r"\bdiscectom\w+\b")
and (_has(t, r"\b(interbody|cage|arthrodesis|plate)\b") or mentions_plate_ant)
)
or _has(t, r"\bacdf\b")
)
if acdf_current and not (found_removal and not _has(t, r"\bacdf\b")) and not exposure_only:
n = max(1, inters or 1)
_add(suggestions, "22551", "ACDF, first interspace (includes discectomy)",
"Anterior cervical fusion pattern detected.", "ACDF", True, 0.95, mods=lat_mods)
if n > 1:
_add(suggestions, "22552", f"ACDF, each additional interspace ×{n-1}",
"Multi-level ACDF.", "ACDF add-on", False, 0.9, units=(n-1), mods=lat_mods)
# Plate span inference: "spanning C4–C7" or "span C4–C7"
m_span = re.search(r"\bspan\w*\s*(c\d)\s*[-–—]\s*(c\d)\b", t, flags=re.I)
plate_span_est = None
if m_span:
try:
c_lo = int(re.sub(r"\D","", m_span.group(1)))
c_hi = int(re.sub(r"\D","", m_span.group(2)))
if c_hi >= c_lo:
plate_span_est = c_hi - c_lo + 1
except Exception:
plate_span_est = None
if mentions_plate_ant:
est_span = (plate_span_est if plate_span_est and plate_span_est >= 2
else (span if (span and span >= 2) else (n + 1)))
code = _inst_code_by_span(est_span, anterior=True)
if code:
desc = {"22845":"Anterior instrumentation (2–3 segments)",
"22846":"Anterior instrumentation (4–7 segments)",
"22847":"Anterior instrumentation (8+ segments)"}[code]
_add(suggestions, code, desc, "Anterior plate present; span estimated from levels/plate span.", "instrumentation", False, 0.8)
# ---------- (3a) Implicit TLIF when keywords imply the construct ----------
if (
not _has(t, r"\btlif\b|\bplif\b|posterior interbody fusion")
and _has(t, r"\bfacetectom(y|ies)\b|complete facetectomy|hemifacetectomy|transforaminal")
and _has(t, r"\binterbody (cage|device|spacer)\b|peek (cage|spacer)|titanium (cage|spacer)|allograft spacer")
and (mentions_pedicle or _has(t, r"\bpedicle screw(s)?\b"))
and region in {"lumbar", "thoracic"}
):
n = max(1, inters or 1)
_add(suggestions, "22633", "Posterior/posterolateral + posterior interbody, single level",
"Implicit TLIF/PLIF: facetectomy + interbody device + pedicle screws.", "TLIF/PLIF", True, 0.93, mods=lat_mods)
if n > 1:
_add(suggestions, "22634", f"Posterior interbody each additional interspace ×{n-1}",
"Multi-level implicit TLIF/PLIF.", "TLIF/PLIF add-on", False, 0.89, units=(n-1), mods=lat_mods)
code = _inst_code_by_span(span or (n+1), anterior=False)
if code:
desc = {"22842":"Posterior segmental instrumentation (2–3 segments)",
"22843":"Posterior segmental instrumentation (4–7 segments)",
"22844":"Posterior segmental instrumentation (8+ segments)"}[code]
_add(suggestions, code, desc, "Posterior instrumentation detected (implicit TLIF).", "instrumentation", False, 0.83)
# ---------- (3) TLIF / PLIF (beats posterior fusion) ----------
if _has(t, r"\btlif\b|\bplif\b|posterior interbody fusion"):
n = max(1, inters or 1)
_add(suggestions, "22633", "Posterior/posterolateral + posterior interbody, single level",
"TLIF/PLIF pattern: posterior approach + cage + screws.", "TLIF/PLIF", True, 0.92, mods=lat_mods)
if n > 1:
_add(suggestions, "22634", f"Posterior interbody each additional interspace ×{n-1}",
"Multi-level TLIF/PLIF.", "TLIF/PLIF add-on", False, 0.88, units=(n-1), mods=lat_mods)
if mentions_inst_post:
code = _inst_code_by_span(span or (n+1), anterior=False)
if code:
desc = {"22842":"Posterior segmental instrumentation (2–3 segments)",
"22843":"Posterior segmental instrumentation (4–7 segments)",
"22844":"Posterior segmental instrumentation (8+ segments)"}[code]
_add(suggestions, code, desc, "Posterior instrumentation detected.", "instrumentation", False, 0.82)
# ---------- (4) ALIF ----------
if _has(t, r"\balif\b|anterior lumbar interbody fusion"):
n = max(1, inters or 1)
_add(suggestions, "22558", "Anterior lumbar interbody fusion, single interspace",
"ALIF detected.", "ALIF", True, 0.9)
if n > 1:
_add(suggestions, "22585", f"ALIF each additional interspace ×{n-1}",
"Multi-level ALIF.", "ALIF add-on", False, 0.86, units=(n-1))
if mentions_plate_ant:
est_span = span if (span and span >= 2) else (n + 1)
code = _inst_code_by_span(est_span, anterior=True)
if code:
desc = {"22845":"Anterior instrumentation (2–3 segments)",
"22846":"Anterior instrumentation (4–7 segments)",
"22847":"Anterior instrumentation (8+ segments)"}[code]
_add(suggestions, code, desc, "Anterior plate present; span estimated from levels.", "instrumentation", False, 0.8)
# ---------- (5) Posterolateral/posterior fusion WITHOUT interbody ----------
if (_has(t, r"posterolateral\b.*\bfusion|post[- ]?lat\b.*\bfusion|posterior\b.*\bfusion|in situ\b.*\bfusion")
and not _has(t, r"\btlif\b|\bplif\b|posterior interbody")):
base_map = {"cervical":"22600", "thoracic":"22610", "lumbar":"22612"}
base = base_map.get(region, "22612")
_add(suggestions, base, f"Posterolateral/posterior fusion, first level ({region})",
"Posterior fusion without interbody.", "posterior_fusion", True, 0.78, mods=lat_mods)
add_units = max(0, inters)
if add_units:
_add(suggestions, "22614", f"Posterior fusion each additional segment ×{add_units}",
"Multi-level posterior fusion.", "posterior_fusion add-on", False, 0.72, units=add_units, mods=lat_mods)
if mentions_inst_post:
n_seg = span or max(2, (inters + 1))
code = _inst_code_by_span(n_seg, anterior=False)
if code:
desc = {"22842":"Posterior segmental instrumentation (2–3 segments)",
"22843":"Posterior segmental instrumentation (4–7 segments)",
"22844":"Posterior segmental instrumentation (8+ segments)"}[code]
_add(suggestions, code, desc, "Posterior instrumentation detected.", "instrumentation", False, 0.8)
# ---------- (6) Neurostimulator paddle + IPG ----------
if _has(t, r"\bstimulator\b|paddle lead|spinal cord stimulator|scs") and _has(t, r"\blaminectomy\b|laminotomy"):
_add(suggestions, "63655", "Laminectomy for implantation of neurostimulator paddle electrodes",
"Paddle lead placed via laminectomy.", "neurostimulator", True, 0.86)
if _has(t, r"\bpulse generator\b|ipg|implantable pulse generator|battery\b"):
_add(suggestions, "63685", "Insertion or replacement of IPG",
"Pulse generator implanted.", "neurostimulator", False, 0.84)
avoid_decompression_for_stimulator = True
# ---------- (7) Decompression (guarded: no history/corpectomy/revision/stimulator) ----------
if (not no_decompression_due_to_revision) and (not avoid_decompression_for_stimulator):
if _has(t, r"\bdecompression(s)?\b|laminectom(y|ies)|laminotom(y|ies)|foraminotom(y|ies)|foraminal decompression(s)?|neuroforamen|lateral recess|central stenosis") \
and not _has(t, r"\b(prior|previous|history of|s/?p)\s+(decompression|laminectomy|laminotomy|foraminotomy)\b"):
base_map = {"cervical":"63045", "thoracic":"63046", "lumbar":"63047"}
base = base_map.get(region, "63047")
_add(suggestions, base, "Decompression, first level", "Decompression terms detected.", "decompression", True, 0.82, mods=lat_mods)
if _has(t, r"additional level|two levels|three levels|multi|levels|l\d-?l\d|c\d-?c\d|t\d-?t\d"):
extra = max(1, inters)
_add(suggestions, "63048", f"Decompression, each additional level ×{extra}",
"Multi-level decompression inferred.", "decompression add-on", False, 0.78, units=extra, mods=lat_mods)
# ---------- (8) Interspinous/interlaminar device ----------
if _has(t, r"\bcoflex\b|interspinous|interlaminar device|ipd"):
_add(suggestions, "22868", "Insertion of interspinous/interlaminar device",
"Coflex/IPD insertion documented.", "interspinous", True, 0.86, mods=lat_mods)
# ---------- (9) Cervical disc arthroplasty ----------
if _has(t, r"cervical (arthroplasty|artificial disc|disc replacement)|\bcda\b") or (
(region == "cervical") and _has(t, r"\barthroplasty\b|artificial disc|disc replacement")
):
n = max(1, inters or 1)
_add(suggestions, "22856", "Cervical disc arthroplasty, single level",
"Cervical disc arthroplasty documented.", "arthroplasty", True, 0.87, mods=lat_mods)
if n > 1:
_add(suggestions, "22858", f"Cervical disc arthroplasty, each additional level ×{n-1}",
"Multi-level arthroplasty.", "arthroplasty add-on", False, 0.84, units=(n-1), mods=lat_mods)
# ---------- (10) Tumor / corpectomy ----------
# Cervical corpectomy
if _has(t, r"\bcorpectomy\b") and (region == "cervical" or _has(t, r"\bcervic")):
_add(suggestions, "63081", "Cervical corpectomy for decompression, first segment",
"Cervical corpectomy documented.", "tumor/corpectomy", True, 0.86)
if _has(t, r"additional (level|segment)|two levels|three levels|multi|c\d-?c\d"):
extra = max(1, inters or 1)
_add(suggestions, "63082", f"Each additional cervical segment ×{extra}",
"Multi-segment cervical corpectomy.", "tumor/corpectomy add-on", False, 0.82, units=extra)
did_corpectomy = True
# Thoracic/Lumbar corpectomy (non-cervical)
if _has(t, r"\btumou?r\b|metastatic|metastasis|en bloc") or (_has(t, r"\bcorpectomy\b") and region in {"thoracic","lumbar"}):
_add(suggestions, "63085", "Vertebral corpectomy for decompression (thoracic/lumbar), first segment",
"Tumor/corpectomy documented.", "tumor/corpectomy", True, 0.84)
if _has(t, r"additional (level|segment)|two levels|three levels|multi|t\d-?t\d|l\d-?l\d"):
_add(suggestions, "63086", "Each additional segment (thoracic/lumbar) ×1+",
"Multi-segment corpectomy.", "tumor/corpectomy add-on", False, 0.8)
did_corpectomy = True
# If corpectomy present, suppress decompression rows
if did_corpectomy:
suggestions = [r for r in suggestions if r["category"] != "decompression" and r["cpt"] not in {"63045","63046","63047","63048"}]
# ---------- (11) Deformity / Smith-Petersen osteotomy ----------
if _has(t, r"\bspo\b|smith[- ]?petersen|posterior column osteotomy|osteotomy"):
base_map = {"cervical":"22210", "thoracic":"22214", "lumbar":"22206"}
base = base_map.get(region, "22206")
_add(suggestions, base, "Posterior column osteotomy (Smith-Petersen), first level",
"Deformity correction with SPO documented.", "deformity", True, 0.83)
if _has(t, r"additional (level|segment)|two levels|three levels|multi"):
_add(suggestions, str(int(base)+1), "Each additional vertebral segment ×1+",
"Multi-level osteotomy.", "deformity add-on", False, 0.78)
# ---------- (12) Kyphoplasty / vertebral augmentation ----------
if _has(t, r"\bkyphoplasty\b|vertebroplasty|cement (augmentation|injection)"):
base_map = {"cervical":"22510", "thoracic":"22513", "lumbar":"22514"}
base = base_map.get(region, "22514")
_add(suggestions, base, "Percutaneous vertebral augmentation, first level",
"Vertebral augmentation terms present.", "percutaneous", True, 0.82)
if _has(t, r"additional (level|segment)|two levels|three levels|multi"):
_add(suggestions, "22515", "Each additional vertebral body ×1+",
"Multi-level augmentation.", "percutaneous add-on", False, 0.8)
# ---------- (13) Pelvic fixation ----------
if _has(t, r"\bpelvic fixation\b|iliac bolt|iliac screw|s2ai|to pelvis\b"):
_add(suggestions, "22848", "Pelvic fixation (attach instrumentation to pelvis)",
"Iliac/pelvic fixation documented.", "pelvic_fixation", False, 0.84)
# ---------- (14) Bone grafts (prefer structural 20931 over 20930) ----------
structural_like = _has(t, r"\b(structural allograft|fibular strut|strut graft|allograft spacer(s)?|interbody allograft spacer(s)?)\b")
any_allograft = _has(t, r"\ballograft\b|dbm|demineralized|osteo.?promotive|morselized local bone|local autograft")
if _has(t, r"\bautograft\b|iliac crest harvest|icbg|iliac crest bone"):
_add(suggestions, "20937", "Autograft (separate incision)",
"Autograft harvest documented.", "bone_graft", False, 0.8)
if structural_like:
_add(suggestions, "20931", "Structural allograft",
"Structural allograft documented.", "bone_graft", False, 0.8)
elif any_allograft:
_add(suggestions, "20930", "Allograft, morselized / osteopromotive material",
"Allograft/DBM documented.", "bone_graft", False, 0.8)
if _has(t, r"\bbmp\b|biologic|recombinant growth factor|rhbmp"):
_add(suggestions, "20939", "Osteopromotive biologic (e.g., BMP)",
"BMP/biologic documented.", "bone_graft", False, 0.8)
# ---------- Case Modifiers (case-level) ----------
mod_map = {
"22": r"\b(complex|difficult|prolonged|adhesiolysis|severe deformity|morbid obesity)\b",
"50": r"\b(both sides|bilaterally|bilateral(?!\s*(pedicle|screw|screws|rod|rods|instrumentation)))\b",
"52": r"\bpartial|limited|reduced service\b",
"53": r"\baborted|terminated|discontinued\b",
"59": r"\bseparate (site|incision)|distinct|different level\b",
"62": r"\bco[- ]?surgeon|two surgeons|co-surgeons\b",
"78": r"\breturn to or\b|\bunplanned return\b",
"79": r"\bunrelated procedure\b",
"80": r"\bassistant surgeon|assistant present\b",
"82": r"\bresident not available\b"
}
reasons = {
"22": "Increased procedural service (complexity).",
"50": "Bilateral procedure documented.",
"52": "Reduced service (limited portion performed).",
"53": "Procedure discontinued for safety.",
"59": "Distinct procedural service (separate site/level).",
"62": "Two surgeons (co-surgeons) documented.",
"78": "Unplanned return to OR during global period.",
"79": "Unrelated procedure during postoperative period.",
"80": "Assistant surgeon documented.",
"82": "Assistant surgeon; resident not available."
}
for k, pat in mod_map.items():
if _has(t, pat): case_modifiers.append({"modifier": k, "reason": reasons[k]})
# Force -50 if 'bilateral' appears near decompression nouns and not already set
if not any(m["modifier"]=="50" for m in case_modifiers):
if _has(t, r"\bbilateral\b") and _has(t, r"(foraminotom(y|ies)|facetectom(y|ies)|laminectom(y|ies)|laminotom(y|ies))"):
case_modifiers.append({"modifier":"50","reason": reasons["50"]})
# --- Modifier sanity rules ---
if any(m["modifier"]=="82" for m in case_modifiers):
case_modifiers = [m for m in case_modifiers if m["modifier"]!="80"]
if any(m["modifier"]=="53" for m in case_modifiers):
case_modifiers = [m for m in case_modifiers if m["modifier"]!="52"]
# ---------- Default guard ----------
if not suggestions:
suggestions = [{
"cpt": "00000",
"desc": "No recognizable spine CPT pattern found",
"rationale": "No fusion/decompression pattern detected.",
"confidence": 0.0, "category": "none", "primary": True, "modifiers": [], "units": 1, "score": 0.0
}]
# ---------- De-dup ----------
merged: Dict[Tuple[str, str, str, str], Dict[str, Any]] = {}
for r in suggestions:
key = (r["cpt"], r["desc"], r["category"], "|".join(sorted(r.get("modifiers", []))))
if key not in merged:
merged[key] = r.copy()
else:
merged[key]["units"] = merged[key].get("units", 1) + r.get("units", 1)
merged[key]["confidence"] = max(merged[key]["confidence"], r.get("confidence", 0.0))
merged[key]["score"] = max(merged[key]["score"], r.get("score", 0.0))
merged[key]["primary"] = merged[key]["primary"] or r.get("primary", False)
out = list(merged.values())
# --- Propagate case-level -53 (discontinued) onto primary rows only ---
has_53 = any(m["modifier"] == "53" for m in case_modifiers)
if has_53:
for r in out:
if r.get("primary", False):
r.setdefault("modifiers", [])
if "53" not in r["modifiers"]:
r["modifiers"].append("53")
# ensure add-ons don't inherit -53
for r in out:
if not r.get("primary", False) and r.get("modifiers"):
r["modifiers"] = [m for m in r["modifiers"] if m != "53"]
# --- Apply laterality to rows; strip when case-level bilateral (-50) present ---
has_50 = any(m["modifier"] == "50" for m in case_modifiers)
lat_row_mods = [] if has_50 else lat_mods
for row in out:
if row["category"] in {"decompression","decompression add-on","TLIF/PLIF","posterior_fusion","posterior_fusion add-on"}:
if lat_row_mods and not row.get("modifiers"):
row["modifiers"] = lat_row_mods[:]
if has_50:
for row in out:
if row.get("modifiers"):
row["modifiers"] = [m for m in row["modifiers"] if m not in ("LT","RT")]
# ---------- Order ----------
def _cpt_num(x: Dict[str, Any]) -> int:
try: return int(re.sub(r"\D","", x.get("cpt","0")) or 0)
except: return 0
out.sort(key=lambda r: (not r.get("primary", False), -(r.get("score", r.get("confidence",0.0))), _cpt_num(r)))
if isinstance(top_k, int) and top_k > 0:
out = out[:top_k]
# ---------- Tech flags (microscope / navigation / neuromonitoring / fluoro) ----------
flags_map = {
"microscope": _has(t, r"\bmicroscope\b|microdissection"),
"nav": _has(t, r"\bnavigation\b|o-?arm|stealth|mazor|7d|image[- ]?guided"),
"io_monitor": _has(t, r"\bneuromonitor\w*|ssep|tcem|tcme|emg\b|\bintra[- ]?op(erative)? monitoring\b"),
"fluoro": _has(t, r"\bfluoro\w*|c[- ]?arm\b|fluoroscop\w*"),
}
flags_list = [k for k, v in flags_map.items() if v]
# ---------- Case-level laterality (meta) ----------
bilateral_procedure_pat = (
r"\bboth sides\b"
r"|"
r"\bbilateral\b(?!\s*(pedicle|screw|screws|rod|rods|instrument|instrumentation|hardware|construct))"
)
case_laterality = "na"
if _has(t, r"\bleft[- ]sided|\bleft\b"):
case_laterality = "left"
elif _has(t, r"\bright[- ]sided|\bright\b"):
case_laterality = "right"
elif _has(t, bilateral_procedure_pat):
case_laterality = "bilateral"
# ---------- OPTIONAL: surface tech flags in primary rationale ----------
if flags_list:
for r in out:
if r.get("primary", False):
r["rationale"] = (r.get("rationale","") + f" (Tech: {', '.join(flags_list)})").strip()
break
return {
"payer": payer,
"region": region,
"levels": levels,
"interspaces_est": inters,
"span_segments_est": span,
"suggestions": out,
"case_modifiers": case_modifiers,
"flags": flags_list,
"flags_map": flags_map,
"laterality": case_laterality,
"build": "FINAL-v2.1",
"mode": "standard",
}