{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.12.13"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":154281},{"sourceType":"datasetVersion","sourceId":18229736},{"sourceType":"datasetVersion","sourceId":18673450},{"sourceType":"datasetVersion","sourceId":18673646},{"sourceType":"datasetVersion","sourceId":18706996},{"sourceType":"datasetVersion","sourceId":18715672},{"sourceType":"datasetVersion","sourceId":18716507},{"sourceType":"datasetVersion","sourceId":18757740},{"sourceType":"datasetVersion","sourceId":18839182},{"sourceType":"datasetVersion","sourceId":18842180},{"sourceType":"datasetVersion","sourceId":18875869},{"sourceType":"datasetVersion","sourceId":18956429},{"sourceType":"datasetVersion","sourceId":19003959},{"sourceType":"kernelVersion","sourceId":342671664},{"sourceType":"kernelVersion","sourceId":342849430},{"sourceType":"modelInstanceVersion","sourceId":4533},{"sourceType":"modelInstanceVersion","sourceId":4534},{"sourceType":"datasetVersion","sourceId":18843521}],"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true},"dinosaurs":{"name":"RSNA Knee | DINOsaur V13","default_submission":"submission.csv","strategy":"V11 measured anchor + nested-fold DINO/radiomics specialists for LM, Lateral OA and Synovitis"}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"e4045692-03ac-4819-8296-88fc1cc39199","cell_type":"markdown","source":"# RSNA Knee | DINOsaur V3 🦖\n","metadata":{}},{"id":"75a2f4e3-cab0-438c-890f-c75aa989edf7","cell_type":"code","source":"from __future__ import annotations\nimport os\nimport gc\nimport hashlib\nimport json\nimport re\nimport time\nimport traceback\nimport threading\nfrom concurrent.futures import ThreadPoolExecutor\nfrom pathlib import Path\nimport numpy as np\nimport pandas as pd\nimport pydicom\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nASSET = Path('/kaggle/input/datasets/tonylica/rsna-knee-bend-dinov3-0917-repro-assets')\nROOT = Path('/kaggle/input/competitions/rsna-knee-abnormality-detection')\nDINO = Path('/kaggle/input/models/metaresearch/dinov2/pytorch/small/1')\nT0 = time.time()\nDEVS = [torch.device(f'cuda:{i}') for i in range(torch.cuda.device_count())]\nSEED = 2026\nTARGETS = ['ACL', 'MCL', 'Medial Meniscus', 'Lateral Meniscus', 'Medial OA', 'Lateral OA', 'PF OA', 'Effusion', 'Synovitis', \"Baker's\", 'Contusion', 'Fracture']\nCROP_MM = 130.0\nCACHE_IMG = 336\nGROUP = 3\nN_GROUP_MAX = 1\nCACHE_FRACTION = 0.45\nCACHE_BUDGET_MAX_GB = 24.0\nCACHE_BUDGET_GB = 12.0\nTEST_SHARE = 0.3\nHDR_THREADS = 16\nPIX_THREADS = 12\nORDER_THREADS = 32\nORDER_BUDGET_S = 5400\nAUG_ROT_DEG = 8.0\nAUG_SCALE = 0.08\nAUG_SHIFT = 0.05\nAUG_INTENSITY = 0.1\nLAT_MIN_OFFSET_MM = 20.0\nSLICE_BAND = (0.2, 0.8)\nRULES_NATIVE = {'order': 'normal', 'lat': 'centre', 'slot_fallback': False, 'decode_fill': 'nearest'}\nRULES_LEGACY = {'order': 'dominant_axis', 'lat': 'corner_x', 'slot_fallback': True, 'decode_fill': 'zero'}\nRULES = dict(RULES_NATIVE)\nLEGACY_LAT_OFFSET_MM = 5.0\nEVAL_BATCH = 8\nTIME_BUDGET = 8.0 * 3600\nSLOTS_RECOVERED = [('SAG_FLUID_FS', 'Sagittal', True, True), ('COR_FLUID_FS', 'Coronal', True, True), ('AX_FLUID_FS', 'Axial', True, True), ('SAG_FLUID_NOFS', 'Sagittal', True, False), ('COR_T1', 'Coronal', False, False), ('SAG_T1', 'Sagittal', False, False)]\nSLOTS_PUBLIC = [('SAG_FLUID', 'Sagittal', None, True), ('COR_FLUID', 'Coronal', None, True), ('AX_FLUID', 'Axial', None, True), ('SAG_STRUCT', 'Sagittal', None, False), ('COR_STRUCT', 'Coronal', None, False), ('AX_STRUCT', 'Axial', None, False)]\nSLOT_SCHEME = os.environ.get('SLOT_SCHEME', 'recovered')\nSLOTS = SLOTS_PUBLIC if SLOT_SCHEME == 'public' else SLOTS_RECOVERED\nN_SLOT = len(SLOTS)\nPOOL_PARTS = {'cls_mean': 2, 'cls_mean_focal': 3}\nSLOT_PRIOR_TABLE = {'ACL': (0, 3, 5), 'MCL': (1, 4), 'Medial Meniscus': (0, 1, 3, 4), 'Lateral Meniscus': (0, 1, 3, 4), 'Medial OA': (1, 4, 5), 'Lateral OA': (1, 4, 5), 'PF OA': (0, 2, 5), 'Effusion': (0, 2), 'Synovitis': (0, 2), \"Baker's\": (0,), 'Contusion': (0, 1, 2), 'Fracture': (0, 1, 2, 4, 5)}\nSLOT_PRIOR_STRENGTH = 0.55\nFATSAT_OPTS = {'FS', 'FATSAT', 'FAT_SAT', 'FSAT'}\n_SEP = re.compile('[_\\\\-.]')\n_FATSAT_RX = re.compile('\\\\bfs\\\\b|fatsat|fat sat|\\\\bstir\\\\b|\\\\bspair\\\\b|\\\\bspir\\\\b|\\\\bwe\\\\b|water excit|\\\\btirm\\\\b|\\\\bsting\\\\b|\\\\bfatsup\\\\b')\n_T1_RX = re.compile('\\\\bt1\\\\b|\\\\bt1w\\\\b')\n_T2_RX = re.compile('\\\\bt2\\\\b|\\\\bt2w\\\\b')\n_PD_RX = re.compile('\\\\bpd\\\\b|\\\\bpdw\\\\b|proton|\\\\bdp\\\\b|dens')\n\ndef log(msg):\n    print(f'[{time.time() - T0:7.1f}s] {msg}', flush=True)\nIMG = CACHE_IMG\n\ndef available_gb():\n    try:\n        with open('/proc/meminfo') as fh:\n            info = {k.strip(): v for k, v in (l.split(':', 1) for l in fh if ':' in l)}\n        return int(info['MemAvailable'].split()[0]) / 1024 ** 2\n    except Exception:\n        return CACHE_BUDGET_GB / CACHE_FRACTION\n\ndef plan_cache(n_study, n_test=0):\n    avail = available_gb()\n    budget = min(avail * CACHE_FRACTION, CACHE_BUDGET_MAX_GB)\n    n_total = n_study + max(n_test, int(TEST_SHARE * n_study))\n    per_slice = n_total * N_SLOT * IMG * IMG\n    afford = int(budget * 1024 ** 3 // max(per_slice, 1))\n    groups = max(1, min(N_GROUP_MAX, afford // GROUP))\n    log(f'memory: {avail:.1f} GB available, {budget:.1f} GB to the cache; sizing for {n_study} train + {n_total - n_study} test studies -> {groups} group(s) of {GROUP} = {groups * GROUP} slices per slot' + (f' (wanted {N_GROUP_MAX})' if groups < N_GROUP_MAX else ''))\n    return groups\nN_GROUP = plan_cache(len(pd.read_csv(ROOT / 'train.csv')), len(pd.read_csv(ROOT / 'test.csv')))\nCACHE_SLICES = GROUP * N_GROUP\nHDR_TAGS = ['SeriesDescription', 'SequenceName', 'ScanOptions', 'ScanningSequence', 'RepetitionTime', 'EchoTime', 'Laterality', 'PixelSpacing', 'Rows', 'Columns', 'RescaleSlope', 'RescaleIntercept', 'ImagePositionPatient', 'ImageOrientationPatient']\n\ndef _hdr_vec(s, n):\n    if not isinstance(s, str):\n        return None\n    try:\n        v = [float(x) for x in s.split('|')]\n    except ValueError:\n        return None\n    return np.array(v) if len(v) >= n else None\n\ndef side_from_geometry(h):\n    cx = {}\n    for r in h.itertuples(index=False):\n        ipp = _hdr_vec(getattr(r, 'ImagePositionPatient', None), 3)\n        iop = _hdr_vec(getattr(r, 'ImageOrientationPatient', None), 6)\n        ps = _hdr_vec(getattr(r, 'PixelSpacing', None), 2)\n        rows, cols = (getattr(r, 'Rows', None), getattr(r, 'Columns', None))\n        if ipp is None or iop is None or ps is None or (not rows) or (not cols):\n            continue\n        try:\n            c = ipp[:3] + iop[:3] * ps[1] * float(cols) / 2 + iop[3:6] * ps[0] * float(rows) / 2\n        except (TypeError, ValueError):\n            continue\n        cx.setdefault(r.StudyInstanceUID, []).append(float(c[0]))\n    out = {}\n    for st, xs in cx.items():\n        m = float(np.median(xs))\n        out[st] = None if abs(m) < LAT_MIN_OFFSET_MM else 'R' if m < 0 else 'L'\n    return out\n\ndef side_from_corner_x(h):\n    out = {}\n    for st, g in h.groupby('StudyInstanceUID'):\n        xs = []\n        for r in g.itertuples(index=False):\n            ipp = _hdr_vec(getattr(r, 'ImagePositionPatient', None), 3)\n            if ipp is not None and np.isfinite(ipp).all():\n                xs.append(float(ipp[0]))\n        if not xs:\n            out[st] = None\n            continue\n        x = float(np.median(xs))\n        out[st] = None if abs(x) < LEGACY_LAT_OFFSET_MM else 'R' if x < 0 else 'L'\n    return out\n\ndef lat_of(h, tag=''):\n    geo = side_from_corner_x(h) if RULES['lat'] == 'corner_x' else side_from_geometry(h)\n    d, n_tag, n_geo, n_none, n_disagree = ({}, 0, 0, 0, 0)\n    for st, g in h.groupby('StudyInstanceUID'):\n        v = [str(x).strip().upper() for x in g['Laterality'].dropna()]\n        if RULES['lat'] == 'corner_x' and 'ImageLaterality' in g.columns:\n            v += [str(x).strip().upper() for x in g['ImageLaterality'].dropna()]\n        v = [x[0] for x in v if x and x[0] in ('L', 'R')]\n        side = v[0] if v else None\n        if side is not None:\n            n_tag += 1\n            if geo.get(st) is not None and geo[st] != side:\n                n_disagree += 1\n        else:\n            side = geo.get(st)\n            n_geo += side is not None\n            n_none += side is None\n        d[st] = side\n    log(f'{tag}laterality: {n_tag} from the tag, {n_geo} from geometry, {n_none} unresolved; tag and geometry disagree on {n_disagree} ({n_disagree / max(n_tag, 1):.1%} of the tagged)')\n    return d\n\ndef probe(item):\n    split, study, series, path = item\n    row = {'split': split, 'StudyInstanceUID': study, 'SeriesInstanceUID': series, 'dir': path}\n    try:\n        files = sorted((e.name for e in os.scandir(path) if e.name.endswith('.dcm')))\n        row['files'] = files\n        row['n_slices'] = len(files)\n        if not files:\n            return row\n        ds = pydicom.dcmread(os.path.join(path, files[len(files) // 2]), stop_before_pixels=True, force=True)\n        for t in HDR_TAGS:\n            v = getattr(ds, t, None)\n            if v is None:\n                row[t] = None\n            elif isinstance(v, (list, tuple)) or type(v).__name__ == 'MultiValue':\n                row[t] = '|'.join((str(x) for x in v))\n            else:\n                row[t] = str(v)\n    except Exception as exc:\n        row['err'] = str(exc)[:120]\n    return row\n\ndef walk(split):\n    base = ROOT / split\n    items = []\n    if not base.is_dir():\n        return pd.DataFrame(columns=['split', 'StudyInstanceUID', 'SeriesInstanceUID', 'dir', 'files', 'n_slices'] + HDR_TAGS)\n    for study in os.scandir(base):\n        if study.is_dir():\n            for series in os.scandir(study.path):\n                if series.is_dir():\n                    items.append((split, study.name, series.name, series.path))\n    with ThreadPoolExecutor(max_workers=HDR_THREADS) as pool:\n        rows = list(pool.map(probe, items))\n    return pd.DataFrame(rows)\n\ndef annotate(df):\n    desc = df['SeriesDescription'].fillna('') + ' ' + df['SequenceName'].fillna('')\n    desc = desc.str.lower().str.replace(_SEP, ' ', regex=True)\n    opts = df['ScanOptions'].fillna('').str.upper().str.split('|')\n    opts_fs = opts.apply(lambda ts: any((t.strip() in FATSAT_OPTS for t in ts)))\n    df['fatsat'] = desc.str.contains(_FATSAT_RX) | opts_fs\n    tr = pd.to_numeric(df['RepetitionTime'], errors='coerce')\n    te = pd.to_numeric(df['EchoTime'], errors='coerce')\n    gre = df['ScanningSequence'].fillna('').str.upper().str.contains('GR')\n    t1, t2, pdw = (desc.str.contains(_T1_RX), desc.str.contains(_T2_RX), desc.str.contains(_PD_RX))\n    df['weight'] = np.where(t1 & ~t2 & ~pdw, 'T1', np.where(t2 & ~pdw, 'T2', np.where(pdw, 'PD', np.where(gre, 'GRE', np.where(tr < 800, 'T1', np.where(te > 60, 'T2', np.where(tr >= 800, 'PD', 'UNK')))))))\n    df['fluid'] = np.isin(df['weight'], ['PD', 'T2'])\n    df['px'] = pd.to_numeric(df['PixelSpacing'].fillna('').str.split('|').str[0].replace('', np.nan), errors='coerce')\n    return df\n\ndef pick_slots(series_df, plane_map):\n    series_df = series_df.copy()\n    series_df['plane'] = series_df['SeriesInstanceUID'].map(plane_map)\n    out = {}\n    for study, g in series_df.groupby('StudyInstanceUID'):\n        chosen = {}\n        for name, plane, fluid, fs in SLOTS:\n            sel = (g['plane'] == plane) & (g['fatsat'] == fs)\n            if fluid is not None:\n                sel &= g['fluid'] == fluid\n            cand = g[sel]\n            if len(cand) == 0 and RULES['slot_fallback'] and (fluid is False):\n                cand = g[(g['plane'] == plane) & ~g['fatsat']]\n            if len(cand):\n                chosen[name] = cand.sort_values('n_slices', ascending=False).iloc[0]\n        out[study] = chosen\n    return out\nORDER_TAGS = [(32, 50), (32, 55), (32, 19)]\nDECODE_FAILED = []\n\ndef _natural_key(name):\n    return tuple((int(x) if x.isdigit() else x.lower() for x in re.split('(\\\\d+)', str(name))))\n\ndef _order_dominant_axis(rec):\n    files, d = (rec['files'], rec['dir'])\n    rows = []\n    for pos, f in enumerate(files):\n        ipp = inst = None\n        try:\n            ds = pydicom.dcmread(os.path.join(d, f), force=True, stop_before_pixels=True, specific_tags=['ImagePositionPatient', 'InstanceNumber'])\n            raw = getattr(ds, 'ImagePositionPatient', None)\n            if raw is not None and len(raw) >= 3:\n                c = np.asarray(raw[:3], dtype=np.float64)\n                if np.isfinite(c).all():\n                    ipp = c\n            n = getattr(ds, 'InstanceNumber', None)\n            if n is not None:\n                inst = float(n)\n        except Exception:\n            pass\n        rows.append((f, ipp, inst, pos))\n    placed = [r for r in rows if r[1] is not None]\n    need = max(2, int(0.8 * len(rows)))\n    if len(placed) >= need:\n        xyz = np.stack([r[1] for r in placed])\n        axis = int(np.argmax(np.ptp(xyz, axis=0)))\n        spare = float(np.nanmedian(xyz[:, axis]))\n        rows.sort(key=lambda r: (float(r[1][axis]) if r[1] is not None else spare, r[2] if r[2] is not None else float('inf'), r[3]))\n    elif sum((r[2] is not None for r in rows)) >= need:\n        rows.sort(key=lambda r: (r[2] if r[2] is not None else float('inf'), r[3]))\n    else:\n        rows.sort(key=lambda r: _natural_key(r[0]))\n    return ([r[0] for r in rows], True)\n\ndef order_slices(rec):\n    if RULES['order'] == 'dominant_axis':\n        return _order_dominant_axis(rec)\n    files, d = (rec['files'], rec['dir'])\n    keyed = []\n    for f in files:\n        k = None\n        try:\n            ds = pydicom.dcmread(os.path.join(d, f), force=True, stop_before_pixels=True, specific_tags=ORDER_TAGS)\n            iop = np.asarray(ds.ImageOrientationPatient, dtype=float)\n            ipp = np.asarray(ds.ImagePositionPatient, dtype=float)\n            k = float(np.dot(ipp, np.cross(iop[:3], iop[3:])))\n        except Exception:\n            try:\n                k = float(ds.InstanceNumber)\n            except Exception:\n                k = None\n        keyed.append((k, f))\n    if any((k is None for k, _ in keyed)):\n        return (files, False)\n    return ([f for _, f in sorted(keyed, key=lambda t: t[0])], True)\n\ndef read_slot(rec, n_slice=None, out_size=None):\n    n_slice = GROUP if n_slice is None else n_slice\n    out_size = IMG if out_size is None else out_size\n    files, d, px = (rec.get('ordered') or rec['files'], rec['dir'], rec['px'])\n    n = len(files)\n    if n == 0:\n        return None\n    lo, hi = (int(SLICE_BAND[0] * (n - 1)), int(SLICE_BAND[1] * (n - 1)))\n    idx = np.unique(np.linspace(lo, hi, n_slice).astype(int)) if hi > lo else np.array([n // 2])\n    while len(idx) < n_slice:\n        idx = np.append(idx, idx[-1])\n    planes = []\n    for i in idx[:n_slice]:\n        try:\n            ds = pydicom.dcmread(os.path.join(d, files[int(i)]), force=True)\n            a = ds.pixel_array.astype(np.float32)\n            sl = float(getattr(ds, 'RescaleSlope', 1) or 1)\n            ic = float(getattr(ds, 'RescaleIntercept', 0) or 0)\n            a = a * sl + ic\n        except Exception:\n            a = None\n        planes.append(a)\n    got = [k for k, p in enumerate(planes) if p is not None]\n    if RULES['decode_fill'] == 'zero':\n        if not got:\n            DECODE_FAILED.append(rec.get('SeriesInstanceUID', d))\n        planes = [np.zeros((out_size, out_size), np.float32) if p is None else p for p in planes]\n        got = list(range(len(planes)))\n    if not got:\n        DECODE_FAILED.append(rec.get('SeriesInstanceUID', d))\n        return None\n    if len(got) < len(planes):\n        DECODE_FAILED.append(rec.get('SeriesInstanceUID', d))\n        for k, p in enumerate(planes):\n            if p is None:\n                planes[k] = planes[min(got, key=lambda j: abs(j - k))]\n    shp = planes[0].shape\n    planes = [p if p.shape == shp else np.zeros(shp, np.float32) for p in planes]\n    vol = np.stack(planes)\n    if px and np.isfinite(px) and (px > 0):\n        want = int(round(CROP_MM / px))\n        h, w = shp\n        if 16 < want < min(h, w):\n            cy, cx = (h // 2, w // 2)\n            half = want // 2\n            vol = vol[:, max(0, cy - half):cy + half, max(0, cx - half):cx + half]\n    lo_v, hi_v = np.percentile(vol, [1, 99])\n    vol = np.clip((vol - lo_v) / max(hi_v - lo_v, 1e-06), 0, 1)\n    t = torch.from_numpy(np.ascontiguousarray(vol)).unsqueeze(0)\n    t = F.interpolate(t, size=(out_size, out_size), mode='bilinear', align_corners=False)\n    return (t.squeeze(0) * 255).round().clamp(0, 255).to(torch.uint8)\n\ndef normalise_laterality(img, plane, lat):\n    if lat != 'R':\n        return img\n    if plane in ('Coronal', 'Axial'):\n        return torch.flip(img, dims=[-1])\n    return torch.flip(img, dims=[0])\nORDER_CACHE = os.environ.get('RSNA_ORDER_CACHE') or None\n\ndef build_cache(slot_map, plane_map, lat_map, tag):\n    studies = sorted(slot_map)\n    sidx = {s: i for i, s in enumerate(studies)}\n    cache = np.zeros((len(studies), N_SLOT, CACHE_SLICES, IMG, IMG), np.uint8)\n    mask = np.zeros((len(studies), N_SLOT), np.float32)\n    log(f'{tag}: cache {cache.shape} = {cache.nbytes / 1024 ** 3:.1f} GB')\n    jobs = [(st, k, plane, slot_map[st][name]) for st in studies for k, (name, plane, _, _) in enumerate(SLOTS) if name in slot_map[st]]\n    n_job = len(jobs)\n    t_ord = time.time()\n    n_slice_total = sum((len(j[3]['files']) for j in jobs))\n    log(f'{tag}: ordering {len(jobs)} slot-series ({n_slice_total} slice headers)')\n    ok = done = 0\n    CHUNK_O = 1024\n    seen = {}\n    if ORDER_CACHE and Path(ORDER_CACHE).is_file():\n        try:\n            import json as _json\n            seen = _json.loads(Path(ORDER_CACHE).read_text())\n        except (OSError, ValueError):\n            seen = {}\n        hit = 0\n        for _, _, _, rec in jobs:\n            e = seen.get(rec['SeriesInstanceUID'])\n            if e and len(e['files']) == len(rec['files']):\n                rec['ordered'] = e['files']\n                ok += int(e['good'])\n                hit += 1\n        jobs = [j for j in jobs if 'ordered' not in j[3]]\n        log(f'{tag}: {hit} slot-series ordered from {ORDER_CACHE}, {len(jobs)} to read')\n    with ThreadPoolExecutor(max_workers=ORDER_THREADS) as pool:\n        for c0 in range(0, len(jobs), CHUNK_O):\n            block = jobs[c0:c0 + CHUNK_O]\n            for (_, _, _, rec), (files, good) in zip(block, pool.map(lambda j: order_slices(j[3]), block)):\n                rec['ordered'] = files\n                ok += int(good)\n                done += 1\n                if ORDER_CACHE:\n                    seen[rec['SeriesInstanceUID']] = {'files': files, 'good': bool(good)}\n            budget = min(ORDER_BUDGET_S, max(60.0, (TIME_BUDGET - (time.time() - T0)) * 0.35))\n            if time.time() - t_ord > budget:\n                log(f'{tag}: ordering budget spent at {done}/{len(jobs)}; the rest keep file order')\n                break\n    if ORDER_CACHE and done:\n        import json as _json\n        _t = Path(ORDER_CACHE).with_suffix('.tmp')\n        _t.write_text(_json.dumps(seen))\n        _t.replace(Path(ORDER_CACHE))\n    log(f'{tag}: ordered {ok}/{n_job} by geometry ({n_job - ok} kept arbitrary) in {time.time() - t_ord:.0f}s')\n    jobs = [(st, k, plane, slot_map[st][name]) for st in studies for k, (name, plane, _, _) in enumerate(SLOTS) if name in slot_map[st]]\n    log(f'{tag}: decoding {len(jobs)} slot-series')\n    n_failed_before = len(DECODE_FAILED)\n    CHUNK = 512\n    done = 0\n    with ThreadPoolExecutor(max_workers=PIX_THREADS) as pool:\n        for c0 in range(0, len(jobs), CHUNK):\n            block = jobs[c0:c0 + CHUNK]\n            for (st, k, plane, _), img in zip(block, pool.map(lambda j: read_slot(j[3], CACHE_SLICES, IMG), block)):\n                done += 1\n                if img is None:\n                    continue\n                cache[sidx[st], k] = normalise_laterality(img, plane, lat_map.get(st)).numpy()\n                mask[sidx[st], k] = 1.0\n            if done % 4096 < CHUNK:\n                log(f'  {tag} {done}/{len(jobs)}')\n            if time.time() - T0 > TIME_BUDGET:\n                log(f'  {tag}: time budget reached during decode')\n                break\n    n_failed = len(DECODE_FAILED) - n_failed_before\n    log(f'{tag}: {int(mask.sum())}/{len(jobs)} slots filled' + (f'; {n_failed} series had a slice that would not decode' if n_failed else ''))\n    gc.collect()\n    return (studies, cache, mask)\n\nclass SlotHead(nn.Module):\n\n    def __init__(self, dim, n_slot, n_out, hidden=256, p=0.2, prior=False):\n        super().__init__()\n        self.proj = nn.Sequential(nn.LayerNorm(dim), nn.Linear(dim, hidden), nn.GELU())\n        self.slot_emb = nn.Parameter(torch.randn(n_slot, hidden) * 0.02)\n        self.query = nn.Parameter(torch.randn(n_out, hidden) * 0.02)\n        self.drop = nn.Dropout(p)\n        self.out = nn.Linear(hidden, n_out)\n        self.hidden = hidden\n        p_ = torch.zeros(n_out, n_slot)\n        if prior and n_slot == len(SLOTS) and (n_out == len(TARGETS)):\n            for t, slots in SLOT_PRIOR_TABLE.items():\n                if t in TARGETS:\n                    p_[TARGETS.index(t), list(slots)] = SLOT_PRIOR_STRENGTH\n        self.prior = prior\n        if prior:\n            self.register_buffer('slot_prior', p_)\n\n    def forward(self, x, mask):\n        h = self.proj(x) + self.slot_emb\n        att = torch.einsum('bsh,oh->bos', h, self.query) / self.hidden ** 0.5\n        if self.prior:\n            att = att + self.slot_prior.unsqueeze(0)\n        att = att.masked_fill(mask.unsqueeze(1) < 0.5, -10000.0).softmax(-1)\n        ctx = self.drop(torch.einsum('bos,bsh->boh', att, h))\n        return (ctx * self.out.weight.unsqueeze(0)).sum(-1) + self.out.bias\n\nclass Model(nn.Module):\n\n    def __init__(self, backbone, dim, pool='cls_mean', prior=False):\n        super().__init__()\n        self.backbone = backbone\n        self.pool = pool\n        self.head = SlotHead(dim * POOL_PARTS[pool], N_SLOT, len(TARGETS), prior=prior)\n        self.register_buffer('mean', torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1))\n        self.register_buffer('std', torch.tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1))\n\n    def forward(self, imgs, mask, img_size=None):\n        B, S = imgs.shape[:2]\n        x = imgs.reshape(B * S, *imgs.shape[2:]).float().div_(255.0)\n        if img_size is not None and img_size != x.shape[-1]:\n            x = F.interpolate(x, size=(img_size, img_size), mode='bilinear', align_corners=False)\n        x = (x - self.mean) / self.std\n        out = self.backbone(pixel_values=x).last_hidden_state\n        patch = out[:, 1:]\n        parts = [out[:, 0], patch.mean(1)]\n        if self.pool == 'cls_mean_focal':\n            k = max(1, patch.shape[1] // 8)\n            parts.append(patch.topk(k, dim=1).values.mean(1))\n        feat = torch.cat(parts, dim=1).reshape(B, S, -1)\n        return self.head(feat, mask)\n\ndef build_model(unfreeze_last, source=None, variant='small', pool='cls_mean', prior=False):\n    from transformers import AutoModel\n    p = source if source is not None else find_dinov2(variant)\n    if p is None:\n        raise FileNotFoundError('DINOv2 weights not attached')\n    bb = AutoModel.from_pretrained(str(p))\n    n_layer = len(bb.encoder.layer)\n    for prm in bb.parameters():\n        prm.requires_grad = False\n    for blk in bb.encoder.layer[max(0, n_layer - unfreeze_last):]:\n        for prm in blk.parameters():\n            prm.requires_grad = True\n    for prm in bb.layernorm.parameters():\n        prm.requires_grad = True\n    dim = bb.config.hidden_size\n    trainable = sum((p.numel() for p in bb.parameters() if p.requires_grad))\n    log(f'backbone: {n_layer} blocks, last {unfreeze_last} trainable ({trainable / 1000000.0:.1f}M params), feature dim {dim * POOL_PARTS[pool]}')\n    return Model(bb, dim, pool=pool, prior=prior)\nFINGERPRINT_TOL = 0.002\n\ndef fingerprint(model, dev, img_size, n_slot=None, group=None, seed=None):\n    n_slot = N_SLOT if n_slot is None else n_slot\n    group = GROUP if group is None else group\n    seed = SEED if seed is None else seed\n    g = torch.Generator().manual_seed(seed)\n    imgs = torch.randint(0, 256, (2, n_slot, group, img_size, img_size), generator=g, dtype=torch.uint8).to(dev)\n    mask = torch.ones(2, n_slot, device=dev)\n    mask[1, -1] = 0.0\n    was_training = model.training\n    model.eval()\n    with torch.no_grad():\n        out = model(imgs, mask, img_size).float().cpu().numpy()\n    if was_training:\n        model.train()\n    return out\n\ndef check_fingerprint(model, dev, img_size, expected, tol=FINGERPRINT_TOL, tag=''):\n    got = fingerprint(model, dev, img_size)\n    exp = np.asarray(expected, np.float32)\n    if got.shape != exp.shape:\n        raise WeightsError(f'{tag}fingerprint shape {got.shape} != stored {exp.shape}: the architecture is not the one these weights were fitted to')\n    d = float(np.abs(got - exp).max())\n    if d > tol:\n        raise WeightsError(f'{tag}fingerprint differs by {d:.4g} (tolerance {tol:g}). The weights load but do not compute what they computed when fitted - preprocessing, resolution or architecture has moved between the two runs.')\n    log(f'{tag}fingerprint matches within {d:.2g}')\n    return d\n\nclass WeightsError(RuntimeError):\n    pass\nTTA_OVERLAP = True\nTTA_POOL = 'prob'\nPUBLIC_FRONTIER_TARGET_POOL = {'Fracture': 'max', 'Contusion': 'max', 'Medial Meniscus': 'max', 'Lateral Meniscus': 'max', 'ACL': 'top2', 'MCL': 'top2', \"Baker's\": 'max'}\nTTA_TARGET_POOL = {**PUBLIC_FRONTIER_TARGET_POOL, 'Synovitis': 'original_mean'}\nLEGACY_FOLD_SOFTPOOL_BETA = {'ACL': 6.0, 'MCL': 6.0, 'Medial Meniscus': 8.0, 'Lateral Meniscus': 8.0, \"Baker's\": 8.0, 'Contusion': 8.0, 'Fracture': 10.0}\nLEGACY_FOLD_SOFTPOOL_ALPHA = {'ACL': 0.2, 'MCL': 0.2, 'Medial Meniscus': 0.25, 'Lateral Meniscus': 0.25, \"Baker's\": 0.2, 'Contusion': 0.2, 'Fracture': 0.15}\n\ndef window_starts(n_slice, group, overlap=None):\n    overlap = TTA_OVERLAP if overlap is None else overlap\n    if overlap and n_slice >= group:\n        return list(range(n_slice - group + 1))\n    return [g * group for g in range(max(n_slice // group, 1))]\n\ndef apply_target_window_pool(values, probs, logits, original_probs, mapping, target_idx):\n    for target, mode in mapping.items():\n        j = target_idx[target]\n        if mode == 'max':\n            values[:, j] = probs[:, :, j].max(0).values\n        elif mode == 'mean':\n            values[:, j] = probs[:, :, j].mean(0)\n        elif mode == 'logit_mean':\n            values[:, j] = torch.sigmoid(logits[:, :, j].mean(0))\n        elif mode == 'original_mean':\n            values[:, j] = original_probs[:, :, j].mean(0)\n        elif mode in ('top2', 'top3'):\n            k = min(int(mode[3:]), probs.shape[0])\n            values[:, j] = probs[:, :, j].topk(k, dim=0).values.mean(0)\n        else:\n            raise ValueError(f'unknown TTA pooling mode for {target}: {mode}')\n    return values\n\ndef legacy_fold_soft_window_pool(original_probs, target_idx):\n    values = original_probs.mean(0).clone()\n    for target, beta in LEGACY_FOLD_SOFTPOOL_BETA.items():\n        j = target_idx[target]\n        x = original_probs[:, :, j]\n        weight = torch.softmax(float(beta) * x, dim=0)\n        values[:, j] = (weight * x).sum(0)\n    return values\n\n@torch.no_grad()\ndef predict_member(model, cache, mask, idx, dev, img_size, group=None, pool=None, starts=None, jitter=False, jitter_seed=SEED, return_public_frontier=False):\n    group = GROUP if group is None else group\n    pool = TTA_POOL if pool is None else pool\n    starts = window_starts(cache.shape[2], group) if starts is None else list(starts)\n    if not starts:\n        raise ValueError('predict_member was given no windows to average over')\n    target_idx = {t: j for j, t in enumerate(TARGETS)}\n    unknown = (set(TTA_TARGET_POOL) | set(PUBLIC_FRONTIER_TARGET_POOL)) - set(target_idx)\n    if unknown:\n        raise ValueError(f'unknown target(s) in TTA_TARGET_POOL: {unknown}')\n    jitter_gen = torch.Generator(device=dev)\n    jitter_gen.manual_seed(int(jitter_seed) % (2 ** 63 - 1))\n    model.eval()\n    out, public_frontier_out, public_soft_out = ([], [], [])\n    for b in range(0, len(idx), EVAL_BATCH):\n        sel = idx[b:b + EVAL_BATCH]\n        m = torch.from_numpy(mask[sel]).to(dev)\n        win_probs, win_logits, win_original_probs = ([], [], [])\n        for st in starts:\n            rows = torch.from_numpy(np.ascontiguousarray(cache[sel, :, st:st + group])).to(dev)\n            views = [rows] + ([augment(rows, generator=jitter_gen)] if jitter else [])\n            view_probs, view_logits = ([], [])\n            for view in views:\n                with torch.autocast('cuda', enabled=dev.type == 'cuda'):\n                    z = model(view, m, img_size).float()\n                view_logits.append(z)\n                view_probs.append(torch.sigmoid(z))\n            win_logits.append(torch.stack(view_logits).mean(0))\n            win_probs.append(torch.stack(view_probs).mean(0))\n            win_original_probs.append(view_probs[0])\n        probs = torch.stack(win_probs)\n        logits = torch.stack(win_logits)\n        original_probs = torch.stack(win_original_probs)\n        v = torch.sigmoid(logits.mean(0)) if pool == 'logit' else probs.mean(0)\n        v = apply_target_window_pool(v, probs, logits, original_probs, TTA_TARGET_POOL, target_idx)\n        out.append(v.cpu().numpy())\n        if return_public_frontier:\n            public_v = apply_target_window_pool(original_probs.mean(0), original_probs, logits, original_probs, PUBLIC_FRONTIER_TARGET_POOL, target_idx)\n            public_frontier_out.append(public_v.cpu().numpy())\n            public_soft = legacy_fold_soft_window_pool(original_probs, target_idx)\n            public_soft_out.append(public_soft.cpu().numpy())\n    primary = np.concatenate(out) if out else np.zeros((0, len(TARGETS)), np.float32)\n    if not return_public_frontier:\n        return primary\n    public_frontier = np.concatenate(public_frontier_out) if public_frontier_out else np.zeros((0, len(TARGETS)), np.float32)\n    public_soft = np.concatenate(public_soft_out) if public_soft_out else np.zeros((0, len(TARGETS)), np.float32)\n    return (primary, public_frontier, public_soft)\nBUILD_LOCK = threading.Lock()\nSTATE_LOCK = threading.Lock()\n\ndef _run_member(path, m, dev, Cte, Mte, idx, starts, jitter):\n    t0 = time.time()\n    with BUILD_LOCK:\n        if 'state' in m:\n            state, fp = (m['state'], None)\n        else:\n            ck = torch.load(Path(path) / m['file'], map_location='cpu', weights_only=False)\n            state, fp = (ck['model'], ck.get('fingerprint'))\n        model = build_model(int(m['config']['unfreeze_last']), variant=m['config']['variant'], pool=m['config'].get('pool', 'cls_mean'), prior=bool(m['config'].get('prior', False))).to(dev)\n        model.load_state_dict(state)\n        if fp is not None:\n            check_fingerprint(model, dev, IMG, fp, tag=f\"{m['id']}: \")\n        else:\n            log(f\"  {m['id']}: no stored fingerprint (legacy bundle) -- accepted at reduced weight\")\n    t_ready = time.time()\n    jitter_seed = SEED + int(hashlib.sha256(str(m['id']).encode()).hexdigest()[:8], 16)\n    public_member = 'state' not in m\n    predicted = predict_member(model, Cte, Mte, idx, dev, IMG, starts=starts, jitter=jitter, jitter_seed=jitter_seed, return_public_frontier=public_member)\n    if public_member:\n        p, public_p, public_soft = predicted\n    else:\n        p, public_p, public_soft = (predicted, None, None)\n    t_done = time.time()\n    del model, state\n    gc.collect()\n    if dev.type == 'cuda':\n        with torch.cuda.device(dev):\n            torch.cuda.empty_cache()\n    passes = len(starts) * (2 if jitter else 1)\n    return (p, public_p, public_soft, (t_ready - t0, (t_done - t_ready) / max(passes, 1)))\n\ndef _combine(per_member):\n    all_ids = sorted({s for m in per_member for s in m['ids']})\n    pos = {s: i for i, s in enumerate(all_ids)}\n    acc = np.zeros((len(all_ids), len(TARGETS)), np.float64)\n    tot = np.zeros(len(TARGETS), np.float64)\n    for m in per_member:\n        target_weight = m.get('target_weight')\n        w = np.asarray(target_weight if target_weight is not None else [float(m.get('weight', 1.0))] * len(TARGETS), dtype=np.float64)\n        if w.shape != (len(TARGETS),) or np.any(w < 0):\n            raise ValueError(f\"invalid target weights for {m.get('id')}: {w}\")\n        r = pd.DataFrame(m['pred']).rank(pct=True).to_numpy()\n        acc[[pos[s] for s in m['ids']]] += r * w[None, :]\n        tot += w\n    if np.any(tot <= 0):\n        raise ValueError(f'at least one target has no ensemble vote: {tot}')\n    return (all_ids, acc / tot[None, :])\n\ndef combine_public_members_by_fold(per_member, pred_key='pred'):\n    all_ids = sorted({study for member in per_member for study in member['ids']})\n    position = {study: i for i, study in enumerate(all_ids)}\n    groups = {}\n    for i, member in enumerate(per_member):\n        fold = member.get('fold')\n        key = f'fold_{fold}' if fold is not None else f'member_{i}'\n        groups.setdefault(key, []).append(member)\n    fold_ranks, diagnostics = ([], [])\n    for key, members_in_fold in sorted(groups.items()):\n        matrices = []\n        for member in members_in_fold:\n            values = np.full((len(all_ids), len(TARGETS)), np.nan, np.float64)\n            values[[position[study] for study in member['ids']]] = np.asarray(member[pred_key], np.float64)\n            if np.isnan(values).any():\n                raise WeightsError(f\"{member.get('id')}: incomplete {pred_key} coverage\")\n            matrices.append(values)\n        raw_fold_mean = np.mean(matrices, axis=0)\n        fold_ranks.append(pd.DataFrame(raw_fold_mean).rank(method='average', pct=True).to_numpy(np.float64))\n        diagnostics.append({'ensemble_group': key, 'members': len(members_in_fold)})\n    if len(fold_ranks) != 5:\n        raise WeightsError(f'legacy branch requires five folds, found {len(fold_ranks)}')\n    return (all_ids, np.mean(fold_ranks, axis=0), pd.DataFrame(diagnostics))\n\ndef blend_legacy_frontier_and_soft(frontier_rank, soft_rank):\n    output = np.asarray(frontier_rank, np.float64).copy()\n    for j, target in enumerate(TARGETS):\n        alpha = float(LEGACY_FOLD_SOFTPOOL_ALPHA.get(target, 0.0))\n        if alpha:\n            output[:, j] = (1.0 - alpha) * frontier_rank[:, j] + alpha * soft_rank[:, j]\n    return output\n\ndef infer_from_package(path, dev=None):\n    man = json.loads((Path(path) / 'manifest.json').read_text())\n    members = man['members']\n    log(f'weights package: {len(members)} member(s) from {path}; {len(DEVS)} device(s)')\n    test_df = pd.read_csv(ROOT / 'test.csv')\n    test_series = pd.read_csv(ROOT / 'test_series.csv')\n    plane_map = dict(zip(test_series['SeriesInstanceUID'], test_series['Anatomical_Plane']))\n    hte = annotate(walk('test_series'))\n    log(f'test header pass: {len(hte)} series')\n    groups = {}\n    for m in members:\n        groups.setdefault(m['pixel_group'], []).append(m)\n    groups.update(legacy_group_members())\n    per_member, public_frontier_members = ([], [])\n    est = {'fixed': None, 'win': None}\n\n    def bank(m, ids, pred, starts, jitter, public_pred=None, public_soft=None):\n        if float(np.std(pred)) < 1e-09:\n            log(f\"  {m['id']}: degenerate predictions; not banked\")\n            return\n        with STATE_LOCK:\n            per_member.append({'id': m['id'], 'fold': m.get('fold'), 'ids': ids, 'pred': pred, 'weight': m.get('weight', 1.0), 'target_weight': m.get('target_weight'), 'holdout': m.get('holdout')})\n            if public_pred is not None and len(starts) == len(starts_full):\n                if float(np.std(public_pred)) < 1e-09:\n                    raise WeightsError(f\"{m['id']}: degenerate public-frontier prediction\")\n                public_frontier_members.append({'id': m['id'], 'fold': m.get('fold'), 'ids': ids, 'pred': public_pred, 'soft_pred': public_soft})\n            elif public_pred is not None:\n                log(f\"  {m['id']}: public-frontier vote omitted because only {len(starts)} / {len(starts_full)} windows completed\")\n            all_ids, acc = _combine(per_member)\n            write_submission(acc, all_ids, test_df, 'submission.csv')\n            log(f\"  banked {m['id']} fold {m.get('fold', '?')} ({len(starts)} window(s){(', jitter' if jitter else '')}); submission.csv = weighted rank mean of {len(per_member)} member(s)\")\n    for gi, (key, gm) in enumerate(groups.items(), 1):\n        cfg = json.loads(key)\n        adopt_config_globals(cfg)\n        log(f\"decode group {gi}/{len(groups)}: {cfg['img']}px x {cfg['slices']} slices, crop {cfg['crop_mm']} mm -> {len(gm)} member(s)\")\n        st_te, Cte, Mte = build_cache(pick_slots(hte, plane_map), plane_map, lat_of(hte, 'test '), f'test g{gi}')\n        idx = np.arange(len(st_te))\n        starts_full = window_starts(Cte.shape[2], GROUP)\n        pending = sorted(gm, key=lambda m: -(m.get('holdout') or 0))\n        left_after = sum((len(g) for j, (_, g) in enumerate(groups.items(), 1) if j > gi))\n\n        def pop_next():\n            with STATE_LOCK:\n                if not pending:\n                    return (None, None, False)\n                left = TIME_BUDGET - (time.time() - T0)\n                remaining = len(pending) + left_after\n                slots_left = -(-remaining // len(DEVS))\n                starts, jit = (starts_full, False)\n                if est['fixed'] is not None and est['win'] is not None:\n                    afford = max(left * 0.9, 0.0)\n                    room = afford / max(slots_left, 1)\n                    if est['fixed'] + est['win'] > room:\n                        log(f'  {left / 60:.0f} min left: surrendering {len(pending)} member(s); not one more fits')\n                        pending.clear()\n                        return (None, None, False)\n                    jit = est['fixed'] + 2 * len(starts_full) * est['win'] <= room * 0.6\n                    per_win = est['win'] * (2 if jit else 1)\n                    n_win = int((room - est['fixed']) / per_win) if per_win > 0 else len(starts_full)\n                    n_win = max(1, min(len(starts_full), n_win))\n                    if n_win < len(starts_full):\n                        mid = (len(starts_full) - n_win) // 2\n                        starts = starts_full[mid:mid + n_win]\n                return (pending.pop(0), starts, jit)\n\n        def worker(dev):\n            others = [d for d in DEVS if d is not dev]\n            while True:\n                m, starts, jit = pop_next()\n                if m is None:\n                    return\n                for attempt, d in enumerate([dev] + others[:1]):\n                    try:\n                        p, public_p, public_soft, (fs, ws) = _run_member(path, m, d, Cte, Mte, idx, starts, jit)\n                        with STATE_LOCK:\n                            est['fixed'], est['win'] = (fs, ws)\n                        bank(m, st_te, p, starts, jit, public_p, public_soft)\n                        break\n                    except Exception as exc:\n                        log(f\"  MEMBER {m['id']} failed on {d} ({type(exc).__name__}: {exc}); \" + ('retrying on peer device' if attempt == 0 and others else 'dropped -- costs one vote, not the run'))\n                        if d.type == 'cuda':\n                            with torch.cuda.device(d):\n                                torch.cuda.empty_cache()\n        threads = [threading.Thread(target=worker, args=(d,)) for d in DEVS]\n        for t in threads:\n            t.start()\n        for t in threads:\n            t.join()\n        del Cte, Mte\n        gc.collect()\n    if not per_member:\n        raise WeightsError('no member produced predictions; submission stays at 0.5')\n    all_ids, acc = _combine(per_member)\n    sub = write_submission(acc, all_ids, test_df, 'submission.csv')\n    log(f'final submission.csv = weighted rank mean of {len(per_member)} member(s); {sub.shape}; nulls {int(sub[TARGETS].isna().sum().sum())}')\n    if len(public_frontier_members) == len(members):\n        frontier_ids, frontier_acc = _combine(public_frontier_members)\n        frontier_sub = write_submission(frontier_acc, frontier_ids, test_df, 'submission_public_0899.csv')\n        log(f'submission_public_0899.csv = exact no-jitter public-frontier rank mean of {len(public_frontier_members)} member(s); {frontier_sub.shape}; nulls {int(frontier_sub[TARGETS].isna().sum().sum())}')\n        fold_ids, fold_frontier, fold_diagnostics = combine_public_members_by_fold(public_frontier_members, 'pred')\n        soft_ids, fold_soft, _ = combine_public_members_by_fold(public_frontier_members, 'soft_pred')\n        if fold_ids != soft_ids:\n            raise WeightsError('legacy hard/soft study order mismatch')\n        legacy_prediction = blend_legacy_frontier_and_soft(fold_frontier, fold_soft)\n        legacy_sub = write_submission(legacy_prediction, fold_ids, test_df, 'submission_legacy_fold_blend.csv')\n        fold_diagnostics.to_csv('legacy_fold_diagnostics.csv', index=False)\n        log(f'legacy DINO aggregation written from five folds; {legacy_sub.shape}')\n    else:\n        log(f'public-frontier fallback not emitted: {len(public_frontier_members)} / {len(members)} required public members completed')\n    return sub\n\ndef adopt_config_globals(cfg):\n    global IMG, CACHE_IMG, GROUP, CACHE_SLICES, N_GROUP, CROP_MM, SLICE_BAND, RULES\n    CACHE_IMG = IMG = int(cfg['img'])\n    GROUP = int(cfg['group'])\n    CACHE_SLICES = int(cfg['slices'])\n    N_GROUP = max(CACHE_SLICES // GROUP, 1)\n    CROP_MM = float(cfg['crop_mm'])\n    SLICE_BAND = tuple((float(x) for x in cfg['band']))\n    rules = cfg.get('rules') or RULES_NATIVE\n    unknown = {k: v for k, v in rules.items() if k not in RULES_NATIVE or v not in (RULES_NATIVE[k], RULES_LEGACY[k])}\n    if unknown:\n        raise WeightsError(f'the members record pixel rules this pipeline cannot reproduce: {unknown}')\n    RULES = {**RULES_NATIVE, **rules}\n    if [s[0] for s in SLOTS] != list(cfg['slots']):\n        raise WeightsError(f\"the members were fitted on slots {cfg['slots']} and this pipeline defines {[s[0] for s in SLOTS]}; a weight would be read against the wrong slot\")\n\ndef augment(imgs, generator=None):\n    lead = imgs.shape[:-3]\n    x = imgs.reshape(-1, *imgs.shape[-3:]).float()\n    n, dev = (x.shape[0], x.device)\n    rot = (torch.rand(n, device=dev, generator=generator) - 0.5) * 2 * (AUG_ROT_DEG * np.pi / 180)\n    sc = 1.0 + torch.rand(n, device=dev, generator=generator) * AUG_SCALE\n    tx = (torch.rand(n, device=dev, generator=generator) - 0.5) * 2 * AUG_SHIFT\n    ty = (torch.rand(n, device=dev, generator=generator) - 0.5) * 2 * AUG_SHIFT\n    cos, sin = (torch.cos(rot) / sc, torch.sin(rot) / sc)\n    theta = torch.zeros(n, 2, 3, device=dev, dtype=torch.float32)\n    theta[:, 0, 0], theta[:, 0, 1], theta[:, 0, 2] = (cos, -sin, tx)\n    theta[:, 1, 0], theta[:, 1, 1], theta[:, 1, 2] = (sin, cos, ty)\n    grid = F.affine_grid(theta, x.shape, align_corners=False)\n    x = F.grid_sample(x, grid, mode='bilinear', padding_mode='border', align_corners=False)\n    scale = 1.0 + (torch.rand(n, 1, 1, 1, device=dev, generator=generator) - 0.5) * 2 * AUG_INTENSITY\n    x = (x * scale).clamp(0, 255)\n    return x.reshape(*lead, *x.shape[-3:]).to(imgs.dtype)\n\ndef write_submission(pred, studies, test_df, path):\n    sub = pd.DataFrame(pd.DataFrame(pred).rank(pct=True).values, columns=TARGETS)\n    sub.insert(0, 'StudyInstanceUID', studies)\n    sub = test_df[['StudyInstanceUID']].merge(sub, on='StudyInstanceUID', how='left')\n    sub[TARGETS] = sub[TARGETS].fillna(0.5)\n    sub.to_csv(path, index=False)\n    return sub\n\ndef find_dinov2(variant='small'):\n    if not (DINO / 'config.json').is_file():\n        raise FileNotFoundError(DINO)\n    return DINO\n\ndef legacy_group_members():\n    return {}\n\ndef run_dinov2():\n    global V8_D2_WEIGHTED_FRAME, V8_D2_SOFT_FRAME, V8_D2_PUBLIC_FRAME\n\n    path = ASSET / 'rsna-knee-weights'\n    infer_from_package(path, DEVS[0])\n\n    work = Path('/kaggle/working')\n    weighted_path = work / 'submission.csv'\n    public_path = work / 'submission_public_0899.csv'\n    soft_path = work / 'submission_legacy_fold_blend.csv'\n\n    if not public_path.is_file():\n        raise RuntimeError('public DINOv2 frontier was not produced')\n\n    V8_D2_WEIGHTED_FRAME = pd.read_csv(\n        weighted_path,\n        dtype={'StudyInstanceUID': str},\n    )\n    V8_D2_PUBLIC_FRAME = pd.read_csv(\n        public_path,\n        dtype={'StudyInstanceUID': str},\n    )\n\n    if soft_path.is_file():\n        V8_D2_SOFT_FRAME = pd.read_csv(\n            soft_path,\n            dtype={'StudyInstanceUID': str},\n        )\n    else:\n        V8_D2_SOFT_FRAME = V8_D2_PUBLIC_FRAME.copy()\n\n    public_path.replace(weighted_path)\n\n    for name in (\n        'submission_legacy_fold_blend.csv',\n        'legacy_fold_diagnostics.csv',\n    ):\n        candidate = work / name\n        if candidate.is_file():\n            candidate.unlink()\n\nrun_dinov2()\n","metadata":{},"outputs":[],"execution_count":null},{"id":"cdb3888c-0fb1-47ea-af36-c760c7619474","cell_type":"code","source":"_A5_SAVED = dict(globals())\nimport gc, os, time, warnings\nfrom concurrent.futures import ProcessPoolExecutor, as_completed\nfrom pathlib import Path\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport pydicom\nimport timm\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nwarnings.filterwarnings('ignore')\ncv2.setNumThreads(1)\nCROP_MM = 130.0\nSIZE = 336\nSLICE_BAND = (0.12, 0.88)\nN_SLICE = 16\nINTENSITY = 'slice'\nSLOTS = [('Sagittal', 1), ('Sagittal', 0), ('Coronal', 1), ('Coronal', 0), ('Axial', 1), ('Axial', 0)]\nN_SLOT = len(SLOTS)\nLABELS = ['ACL', 'MCL', 'Medial Meniscus', 'Lateral Meniscus', 'Medial OA', 'Lateral OA', 'PF OA', 'Effusion', 'Synovitis', \"Baker's\", 'Contusion', 'Fracture']\nCOMP = Path('/kaggle/input/competitions/rsna-knee-abnormality-detection')\nCKPT = ASSET / 'knee-mri-fold-weights'\nDEV = 'cuda' if torch.cuda.is_available() else 'cpu'\nprint(f'competition : {COMP}')\nprint(f'checkpoints : {CKPT}')\nprint(f'device      : {DEV}')\nfor i in range(torch.cuda.device_count() if DEV == 'cuda' else 0):\n    cc = torch.cuda.get_device_capability(i)\n    print(f'  gpu{i}       : {torch.cuda.get_device_name(i)} sm_{cc[0]}{cc[1]}, {torch.cuda.get_device_properties(i).total_memory / 2 ** 30:.0f} GiB, native bf16={cc >= (8, 0)}')\nSERIES_ROOT = COMP / 'test_series'\nif not SERIES_ROOT.exists():\n    SERIES_ROOT = COMP / 'train_series'\nprint('series root:', SERIES_ROOT)\n\ndef ordered_files(sdir, cap=64):\n    keyed = []\n    for f in sdir.glob('*.dcm'):\n        try:\n            ds = pydicom.dcmread(str(f), stop_before_pixels=True)\n            keyed.append((int(ds.InstanceNumber), str(f)))\n        except Exception:\n            continue\n        if len(keyed) >= cap * 4:\n            break\n    return [f for _, f in sorted(keyed)]\n\ndef series_side(path):\n    try:\n        return float(pydicom.dcmread(path, stop_before_pixels=True).ImagePositionPatient[0])\n    except Exception:\n        return 0.0\n\ndef read_crop(path):\n    try:\n        ds = pydicom.dcmread(path)\n        arr = ds.pixel_array.astype(np.float32)\n    except Exception:\n        return None\n    try:\n        ps = float(ds.PixelSpacing[0])\n    except Exception:\n        ps = CROP_MM / max(arr.shape)\n    half = int(round(CROP_MM / ps / 2))\n    cy, cx = (arr.shape[0] // 2, arr.shape[1] // 2)\n    y0, y1 = (max(0, cy - half), min(arr.shape[0], cy + half))\n    x0, x1 = (max(0, cx - half), min(arr.shape[1], cx + half))\n    crop = arr[y0:y1, x0:x1]\n    return None if crop.size == 0 else crop\n\ndef window(crop, lo, hi, flip):\n    c = np.clip((crop - lo) / max(hi - lo, 1e-06), 0, 1)\n    img = cv2.resize(c, (SIZE, SIZE), interpolation=cv2.INTER_AREA)\n    return img[:, ::-1].copy() if flip else img\n\ndef render(path, flip):\n    crop = read_crop(path)\n    if crop is None:\n        return None\n    lo, hi = np.percentile(crop[::4, ::4], [1, 99])\n    return window(crop, lo, hi, flip)\n\ndef build_study(args):\n    idx, study, recs = args\n    out = np.zeros((N_SLOT, N_SLICE, SIZE, SIZE), np.uint8)\n    mask = np.zeros(N_SLOT, np.uint8)\n    rows = pd.DataFrame(recs)\n    if len(rows):\n        for s_i, (plane, fs) in enumerate(SLOTS):\n            sub = rows[(rows.Anatomical_Plane == plane) & (rows.Fat_Suppression == fs)]\n            if sub.empty:\n                continue\n            files = ordered_files(SERIES_ROOT / study / sub.iloc[0].SeriesInstanceUID)\n            if not files:\n                continue\n            flip = plane != 'Sagittal' and series_side(files[0]) < 0\n            lo, hi = SLICE_BAND\n            i0 = int(round(lo * (len(files) - 1)))\n            i1 = int(round(hi * (len(files) - 1)))\n            avail = list(range(i0, i1 + 1))\n            if len(avail) >= N_SLICE:\n                picks = [avail[int(round(t))] for t in np.linspace(0, len(avail) - 1, N_SLICE)]\n                off = 0\n            else:\n                picks, off = (avail, (N_SLICE - len(avail)) // 2)\n            if INTENSITY == 'series':\n                crops = [read_crop(files[p]) for p in picks]\n                got = [x for x in crops if x is not None]\n                if got:\n                    samp = np.concatenate([x[::4, ::4].ravel() for x in got])\n                    lo_, hi_ = np.percentile(samp, [1, 99])\n                    for c, x in enumerate(crops):\n                        if x is None:\n                            x = read_crop(files[min(len(files) - 1, picks[c] + 1)])\n                        if x is not None:\n                            out[s_i, off + c] = (window(x, lo_, hi_, flip) * 255).astype(np.uint8)\n            else:\n                for c, p in enumerate(picks):\n                    img = render(files[p], flip)\n                    if img is None:\n                        img = render(files[min(len(files) - 1, p + 1)], flip)\n                    if img is not None:\n                        out[s_i, off + c] = (img * 255).astype(np.uint8)\n            mask[s_i] = len(picks)\n    return (idx, out, mask)\nsub_df = pd.read_csv(COMP / 'sample_submission.csv')\nser_csv = pd.read_csv(COMP / 'test_series.csv')\nif not (COMP / 'test_series').exists():\n    ser_csv = pd.read_csv(COMP / 'train_series.csv')\nser_csv = ser_csv.loc[:, ~ser_csv.columns.duplicated()]\nstudies = sub_df.StudyInstanceUID.tolist()\nby = {s: g.to_dict('records') for s, g in ser_csv[ser_csv.StudyInstanceUID.isin(set(studies))].groupby('StudyInstanceUID')}\nprint(f'{len(studies):,} test studies, {len(by):,} with series metadata')\nN_SLOT_TYPES, MASK_IDX = (6, 0)\n\ndef segment_softmax(scores, sidx, B):\n    T, K = scores.shape\n    idx = sidx.unsqueeze(1).expand(-1, K)\n    m = torch.full((B, K), float('-inf'), device=scores.device, dtype=scores.dtype)\n    m = m.scatter_reduce(0, idx, scores, reduce='amax', include_self=True)\n    e = (scores - m[sidx]).exp()\n    s = torch.zeros(B, K, device=scores.device, dtype=scores.dtype).index_add_(0, sidx, e)\n    return e / s[sidx].clamp(min=1e-06)\n\nclass MeanMaxPool(nn.Module):\n\n    def forward(self, f, sidx, B, slot=None, return_attn=False):\n        D = f.shape[1]\n        cnt = torch.zeros(B, device=f.device, dtype=f.dtype).index_add_(0, sidx, torch.ones(f.shape[0], device=f.device, dtype=f.dtype))\n        mean = torch.zeros(B, D, device=f.device, dtype=f.dtype).index_add_(0, sidx, f)\n        mean = mean / cnt.clamp(min=1).unsqueeze(1)\n        mx = torch.full((B, D), -10000.0, device=f.device, dtype=f.dtype)\n        mx = mx.scatter_reduce(0, sidx.unsqueeze(1).expand(-1, D), f, reduce='amax', include_self=True)\n        return (torch.cat([mean, mx], 1), None)\n\nclass LabelAttentionPool(nn.Module):\n\n    def __init__(self, d, n_labels=12, n_heads=4, slot_bias=True):\n        super().__init__()\n        self.d, self.k, self.h = (d, n_labels, n_heads)\n        self.q = nn.Parameter(torch.randn(n_labels, d) * 0.02)\n        self.key, self.val = (nn.Linear(d, d), nn.Linear(d, d))\n        self.slot_bias = nn.Parameter(torch.zeros(n_labels, N_SLOT_TYPES + 1)) if slot_bias else None\n\n    def forward(self, f, sidx, B, slot=None, return_attn=False):\n        scores = self.key(f) @ self.q.t() / self.d ** 0.5\n        if self.slot_bias is not None and slot is not None:\n            scores = scores + self.slot_bias.t()[slot]\n        a = segment_softmax(scores, sidx, B)\n        out = torch.zeros(B, self.k, self.d, device=f.device, dtype=f.dtype)\n        out = out.index_add_(0, sidx, a.unsqueeze(-1) * self.val(f).unsqueeze(1))\n        return (out, a)\n\nclass TokenXAttnPool(nn.Module):\n\n    def __init__(self, d, n_labels=12, n_heads=6, dropout=0.2):\n        super().__init__()\n        self.d, self.k = (d, n_labels)\n        self.q = nn.Parameter(torch.randn(n_labels, d) * 0.02)\n        self.slot_emb = nn.Embedding(N_SLOT_TYPES + 1, d, padding_idx=0)\n        self.kv_norm = nn.LayerNorm(d)\n        self.attn = nn.MultiheadAttention(d, n_heads, dropout=dropout, batch_first=True)\n\n    def forward(self, tok, sidx, B, slot=None, return_attn=False):\n        T, N, D = tok.shape\n        cnt = torch.bincount(sidx, minlength=B)\n        S = int(cnt.max().item())\n        starts = torch.cumsum(cnt, 0) - cnt\n        pos = torch.arange(T, device=tok.device) - starts[sidx]\n        kv = tok + self.slot_emb(slot).unsqueeze(1)\n        pad = tok.new_zeros(B, S, N, D)\n        pad[sidx, pos] = kv\n        keep = torch.zeros(B, S, dtype=torch.bool, device=tok.device)\n        keep[sidx, pos] = True\n        kpm = ~keep.repeat_interleave(N, dim=1)\n        pad = self.kv_norm(pad.reshape(B, S * N, D))\n        q = self.q.unsqueeze(0).expand(B, -1, -1)\n        att, w = self.attn(q, pad, pad, key_padding_mask=kpm, need_weights=return_attn, average_attn_weights=True)\n        cls = tok[:, 0]\n        mean = torch.zeros(B, D, device=tok.device, dtype=tok.dtype).index_add_(0, sidx, cls) / cnt.clamp(min=1).unsqueeze(1)\n        mx = torch.full((B, D), -10000.0, device=tok.device, dtype=tok.dtype)\n        mx = mx.scatter_reduce(0, sidx.unsqueeze(1).expand(-1, D), cls, reduce='amax', include_self=True)\n        base = torch.cat([mean, mx], 1).unsqueeze(1).expand(-1, self.k, -1)\n        return (torch.cat([att, base], -1), w)\n\nclass ViTSlotToken(nn.Module):\n\n    def __init__(self, vit, n_cat, dim=None):\n        super().__init__()\n        self.vit = vit\n        d = dim or vit.embed_dim\n        self.tok = nn.Embedding(n_cat + 1, d, padding_idx=MASK_IDX)\n        self.num_features = vit.num_features\n        self._orig_prefix = getattr(vit, 'num_prefix_tokens', 1)\n        vit.num_prefix_tokens = self._orig_prefix + 1\n        for blk in vit.blocks:\n            a = getattr(blk, 'attn', None)\n            if a is not None and hasattr(a, 'num_prefix_tokens'):\n                a.num_prefix_tokens = a.num_prefix_tokens + 1\n\n    @staticmethod\n    def _maybe(mod, x):\n        return x if mod is None else mod(x)\n\n    def forward_features(self, x, cat):\n        v = self.vit\n        x = v.patch_embed(x)\n        pos = v._pos_embed(x)\n        rope = None\n        if isinstance(pos, tuple):\n            x, rope = pos\n        else:\n            x = pos\n        x = self._maybe(getattr(v, 'patch_drop', None), x)\n        x = self._maybe(getattr(v, 'norm_pre', None), x)\n        npt = self._orig_prefix\n        tok = self.tok(cat).unsqueeze(1)\n        x = torch.cat([x[:, :npt], tok, x[:, npt:]], dim=1)\n        if rope is not None:\n            if getattr(v, 'rope_mixed', False):\n                for i, blk in enumerate(v.blocks):\n                    x = blk(x, rope=rope[i])\n            else:\n                for blk in v.blocks:\n                    x = blk(x, rope=rope)\n        else:\n            x = v.blocks(x)\n        return v.norm(x)\n\n    def forward_head(self, x, pre_logits=True):\n        return self.vit.forward_head(x, pre_logits=pre_logits)\nIMAGENET_MEAN = (0.485, 0.456, 0.406)\nIMAGENET_STD = (0.229, 0.224, 0.225)\n\nclass _GatedDepthBlock(nn.Module):\n\n    def __init__(self, n_slice, dropout=0.0, ls_init=0.1):\n        super().__init__()\n        self.norm = nn.GroupNorm(1, n_slice)\n        self.v = nn.Conv2d(n_slice, n_slice, 1)\n        self.g = nn.Conv2d(n_slice, n_slice, 1)\n        self.out = nn.Conv2d(n_slice, n_slice, 1)\n        self.gamma = nn.Parameter(torch.full((n_slice, 1, 1), ls_init))\n        self.drop = nn.Dropout2d(dropout) if dropout else nn.Identity()\n\n    def forward(self, x):\n        z = self.norm(x)\n        return x + self.gamma * self.drop(self.out(self.v(z) * F.silu(self.g(z))))\n\nclass DepthCompress(nn.Module):\n\n    def __init__(self, n_slice=16, out_ch=3, depth=1, dropout=0.0, ls_init=0.1, imagenet=True, proj_noise=0.25):\n        super().__init__()\n        self.imagenet = imagenet\n        self.blocks = nn.ModuleList([_GatedDepthBlock(n_slice, dropout, ls_init) for _ in range(depth)])\n        self.proj = nn.Conv2d(n_slice, out_ch, 1, bias=True)\n        if imagenet:\n            self.register_buffer('mu', torch.tensor(IMAGENET_MEAN).view(1, -1, 1, 1))\n            self.register_buffer('sd', torch.tensor(IMAGENET_STD).view(1, -1, 1, 1))\n\n    def forward(self, x):\n        keep = (x.amax(dim=1, keepdim=True) > 0).to(x.dtype)\n        z = x\n        for b in self.blocks:\n            z = b(z)\n        z = self.proj(z)\n        if self.imagenet:\n            z = (z - self.mu.to(z.dtype)) / self.sd.to(z.dtype)\n        return z * keep\nN_PLANE, N_CONTRAST = (3, 2)\n_PLANE_OF = lambda s: torch.clamp(s - 1, 0, 5) // 2\n_CONTRAST_OF = lambda s: torch.clamp(s - 1, 0, 5) % 2\n\nclass SlotDepthMixer(nn.Module):\n\n    def __init__(self, n_slice=16, ksize=5, alpha_max=0.25):\n        super().__init__()\n        self.n_slice, self.ksize, self.r = (n_slice, ksize, ksize // 2)\n        self.alpha_max = alpha_max\n        b = torch.tensor([1.0, 4.0, 6.0, 4.0, 1.0])\n        self.register_buffer('base', b.log()[self.r:])\n        n_u = self.r + 1\n        self.shared = nn.Parameter(torch.zeros(n_u))\n        self.plane_k = nn.Parameter(torch.zeros(N_PLANE, n_u))\n        self.contrast_k = nn.Parameter(torch.zeros(N_CONTRAST, n_u))\n        self.g0 = nn.Parameter(torch.zeros(()))\n        self.gate_p = nn.Parameter(torch.zeros(N_PLANE))\n        self.gate_c = nn.Parameter(torch.zeros(N_CONTRAST))\n        idx = torch.arange(n_slice)\n        self.register_buffer('off', idx[None, :] - idx[:, None])\n\n    def kernel(self, slot):\n        p, c = (_PLANE_OF(slot), _CONTRAST_OF(slot))\n        half = self.base + self.shared + self.plane_k[p] + self.contrast_k[c]\n        full = torch.cat([half.flip(-1)[..., :self.r], half], dim=-1)\n        return F.softmax(full, dim=-1)\n\n    def alpha(self, slot):\n        p, c = (_PLANE_OF(slot), _CONTRAST_OF(slot))\n        return self.alpha_max * torch.tanh(self.g0 + self.gate_p[p] + self.gate_c[c])\n\n    def forward(self, x, slot, vmask):\n        T, S, H, W = x.shape\n        if vmask is None:\n            raise ValueError('stem=mixer requires the padding mask')\n        k = self.kernel(slot)\n        v = vmask.to(k.dtype)\n        d = self.off + self.r\n        inb = (d >= 0) & (d < self.ksize)\n        kk = k[:, d.clamp(0, self.ksize - 1)] * inb\n        M = kk * v[:, None, :]\n        den = M.sum(-1, keepdim=True)\n        eye = torch.eye(S, device=x.device, dtype=M.dtype).expand(T, S, S)\n        ok = (den > 1e-06) & v[:, :, None].bool()\n        M = torch.where(ok, M / den.clamp(min=1e-06), eye)\n        a = self.alpha(slot)[:, None, None]\n        Aop = ((1.0 - a) * eye + a * M).to(x.dtype)\n        if x.is_contiguous(memory_format=torch.channels_last) and (not x.is_contiguous()):\n            y = torch.bmm(x.permute(0, 2, 3, 1).reshape(T, H * W, S), Aop.transpose(1, 2))\n            return y.reshape(T, H, W, S).permute(0, 3, 1, 2)\n        return torch.bmm(Aop, x.reshape(T, S, H * W)).reshape(T, S, H, W)\n\ndef _seg_mean_max(v, sidx, B):\n    D = v.shape[1]\n    cnt = torch.zeros(B, device=v.device, dtype=v.dtype).index_add_(0, sidx, torch.ones(v.shape[0], device=v.device, dtype=v.dtype))\n    mean = torch.zeros(B, D, device=v.device, dtype=v.dtype).index_add_(0, sidx, v)\n    mean = mean / cnt.clamp(min=1).unsqueeze(1)\n    mx = torch.full((B, D), -10000.0, device=v.device, dtype=v.dtype)\n    mx = mx.scatter_reduce(0, sidx.unsqueeze(1).expand(-1, D), v, reduce='amax', include_self=True)\n    return torch.cat([mean, mx], 1)\n\ndef _pad_kv(x, sidx, B, norm):\n    T, P, D = x.shape\n    cnt = torch.bincount(sidx, minlength=B)\n    S = int(cnt.max().item())\n    starts = torch.cumsum(cnt, 0) - cnt\n    pos = torch.arange(T, device=x.device) - starts[sidx]\n    pad = x.new_zeros(B, S, P, D)\n    pad[sidx, pos] = x\n    keep = torch.zeros(B, S, dtype=torch.bool, device=x.device)\n    keep[sidx, pos] = True\n    return (norm(pad.reshape(B, S * P, D)), ~keep.repeat_interleave(P, dim=1))\n\nclass _GatedDelta(nn.Module):\n\n    def __init__(self, d, n_labels, n_heads, dropout):\n        super().__init__()\n        self.q = nn.Parameter(torch.randn(n_labels, d) * 0.02)\n        self.kv_norm = nn.LayerNorm(d)\n        self.attn = nn.MultiheadAttention(d, n_heads, dropout=dropout, batch_first=True)\n        self.d_norm = nn.LayerNorm(d)\n        self.dw = nn.Parameter(torch.randn(n_labels, d) * (1.0 / d ** 0.5))\n        self.db = nn.Parameter(torch.zeros(n_labels))\n        self.gate = nn.Parameter(torch.zeros(n_labels))\n\n    def delta(self, pat, sidx, B, return_attn):\n        kv, kpm = _pad_kv(pat, sidx, B, self.kv_norm)\n        q = self.q.unsqueeze(0).expand(B, -1, -1)\n        att, w = self.attn(q, kv, kv, key_padding_mask=kpm, need_weights=return_attn, average_attn_weights=True)\n        return ((self.d_norm(att) * self.dw).sum(-1) + self.db, w)\n\nclass TokenResidualPool(_GatedDelta):\n\n    def __init__(self, d, n_labels=12, n_heads=6, pe=64, dropout=0.2):\n        super().__init__(d, n_labels, n_heads, dropout)\n        self.base = nn.Sequential(nn.LayerNorm(2 * d + pe), nn.Dropout(dropout), nn.Linear(2 * d + pe, n_labels))\n\n    def forward(self, tok, slot, sidx, B, pres, return_attn=False):\n        base = self.base(torch.cat([_seg_mean_max(tok[:, 1:].mean(1), sidx, B), pres], 1))\n        d_, w = self.delta(tok[:, 1:], sidx, B, return_attn)\n        return (base + self.gate * d_, w)\n\nclass CodexResidualPool(_GatedDelta):\n\n    def __init__(self, d, n_labels=12, n_heads=6, pe=64, dropout=0.2):\n        super().__init__(d, n_labels, n_heads, dropout)\n        self.base = nn.Sequential(nn.LayerNorm(2 * d + pe), nn.Dropout(dropout), nn.Linear(2 * d + pe, n_labels))\n\n    def forward(self, tok, slot, sidx, B, pres, return_attn=False):\n        base = self.base(torch.cat([_seg_mean_max(tok[:, 0], sidx, B), pres], 1))\n        d_, w = self.delta(tok[:, 1:], sidx, B, return_attn)\n        return (base + self.gate * d_, w)\n\nclass ClsAddPool(nn.Module):\n\n    def __init__(self, d, n_labels=12, pe=64, dropout=0.2):\n        super().__init__()\n        self.net = nn.Sequential(nn.LayerNorm(4 * d + pe), nn.Dropout(dropout), nn.Linear(4 * d + pe, n_labels))\n\n    def forward(self, tok, slot, sidx, B, pres, return_attn=False):\n        return (self.net(torch.cat([_seg_mean_max(tok[:, 1:].mean(1), sidx, B), _seg_mean_max(tok[:, 0], sidx, B), pres], 1)), None)\n\nclass Readout(nn.Module):\n\n    def __init__(self, pool, d, n_labels=12, pe=64):\n        super().__init__()\n        self.pool_kind, self.k = (pool, n_labels)\n        self.pres_emb = nn.Embedding(N_SLOT_TYPES + 1, pe, padding_idx=0)\n        if pool in ('xres', 'clsadd', 'xcodex'):\n            self.pool = {'xres': TokenResidualPool, 'clsadd': ClsAddPool, 'xcodex': CodexResidualPool}[pool](d, n_labels, pe=pe)\n        elif pool in ('attn', 'xattn'):\n            if pool == 'xattn':\n                self.pool = TokenXAttnPool(d, n_labels)\n                wd = 3 * d + pe\n            else:\n                self.pool = LabelAttentionPool(d, n_labels)\n                wd = d + pe\n            self.norm = nn.LayerNorm(wd)\n            self.w = nn.Parameter(torch.randn(n_labels, wd) * (1.0 / wd ** 0.5))\n            self.b = nn.Parameter(torch.zeros(n_labels))\n        else:\n            self.pool = MeanMaxPool()\n            self.net = nn.Sequential(nn.LayerNorm(2 * d + pe), nn.Dropout(0.2), nn.Linear(2 * d + pe, n_labels))\n        self.drop = nn.Dropout(0.2)\n\n    def forward(self, f, slot, sidx, B, return_attn=False):\n        pe = self.pres_emb(slot)\n        pres = torch.zeros(B, pe.shape[1], device=f.device, dtype=f.dtype).index_add_(0, sidx, pe)\n        if self.pool_kind in ('xres', 'clsadd', 'xcodex'):\n            return self.pool(f, slot, sidx, B, pres)[0]\n        pooled, attn = self.pool(f, sidx, B, slot=slot, return_attn=return_attn)\n        if self.pool_kind in ('attn', 'xattn'):\n            x = torch.cat([pooled, pres.unsqueeze(1).expand(-1, self.k, -1)], -1)\n            x = self.drop(self.norm(x))\n            return (x * self.w).sum(-1) + self.b\n        return self.net(torch.cat([pooled, pres], 1))\n\nclass Net(nn.Module):\n\n    def __init__(self, enc, cond, n_meta=0, pool='mean_max', stem='native', n_slice=16):\n        super().__init__()\n        self.enc, self.cond = (enc, cond)\n        self.compress = DepthCompress(n_slice, 3) if stem == 'compress' else None\n        self.mixer = SlotDepthMixer(n_slice) if stem == 'mixer' else None\n        self.tokens = pool in ('xattn', 'xres', 'clsadd', 'xcodex')\n        D = enc.num_features\n        self.meta_mlp = nn.Sequential(nn.LayerNorm(n_meta), nn.Linear(n_meta, 128), nn.GELU(), nn.Linear(128, D)) if n_meta > 0 else None\n        self.readout = Readout(pool, D)\n        if cond == 'post':\n            self.slot_emb = nn.Embedding(N_SLOT_TYPES + 1, D, padding_idx=MASK_IDX)\n\n    def forward(self, im, slot, smeta, sidx, B, vm=None):\n        if self.mixer is not None:\n            im = self.mixer(im, slot, vm)\n        if self.compress is not None:\n            im = self.compress(im)\n        f = self.enc.forward_features(im, slot) if self.cond == 'token' else self.enc.forward_features(im)\n        if self.tokens:\n            inner = getattr(self.enc, 'vit', self.enc)\n            orig = getattr(self.enc, '_orig_prefix', getattr(inner, 'num_prefix_tokens', 1))\n            f = torch.cat([f[:, :1], f[:, orig:]], 1)\n        else:\n            f = self.enc.forward_head(f, pre_logits=True)\n            if f.dim() > 2:\n                f = f.flatten(1)\n        ex = (lambda v: v.unsqueeze(1)) if self.tokens else lambda v: v\n        if self.cond == 'post':\n            f = f + ex(self.slot_emb(slot))\n        if self.meta_mlp is not None and smeta.shape[1] > 0:\n            mt = self.meta_mlp(smeta)\n            f = torch.cat([f, mt.unsqueeze(1)], 1) if self.tokens else f + mt\n        return self.readout(f, slot, sidx, B)\nmodels = []\nfor ckpt_path in sorted(CKPT.glob('*_f*.pt')):\n    z = torch.load(ckpt_path, map_location='cpu', weights_only=False)\n    cfg = z['cfg']\n    _stem = cfg.get('stem', 'native')\n    _in = 3 if _stem == 'compress' else cfg.get('n_slice', 16)\n    enc = timm.create_model(cfg['backbone'], pretrained=False, num_classes=0, in_chans=_in, **{'img_size': cfg['img']} if 'vit_' in cfg['backbone'] else {})\n    if cfg['cond'] == 'token':\n        enc = ViTSlotToken(enc, N_SLOT_TYPES)\n    m = Net(enc, cfg['cond'], cfg.get('n_meta', 0), cfg['pool'], stem=_stem, n_slice=cfg.get('n_slice', 16))\n    missing, unexpected = m.load_state_dict(z['state_dict'], strict=False)\n    assert not missing, f'missing {missing[:5]}'\n    assert not unexpected, f'unexpected {unexpected[:5]}'\n    models.append(m.eval())\n    print(f\"loaded {ckpt_path.name}  fold {z['fold']}  {cfg['backbone']} pool={cfg['pool']} meta={cfg['meta']}\")\nCFG = cfg\nassert CFG.get('n_meta', 0) == 0, f\"checkpoint expects {CFG['n_meta']} metadata features -- build slot_meta for the TEST studies and pass it to predict() before submitting\"\nprint(f\"\\n{len(models)} fold models ready | input norm: {CFG.get('norm', 'none')}\")\nAMP_PREF = 'bf16'\n\ndef amp_for(dev):\n    if not str(dev).startswith('cuda'):\n        return (torch.float32, False)\n    cc = torch.cuda.get_device_capability(dev)\n    if AMP_PREF == 'bf16':\n        return (torch.bfloat16, True)\n    if AMP_PREF == 'fp16':\n        return (torch.float16, True)\n    if AMP_PREF == 'fp32':\n        return (torch.float32, False)\n    return (torch.bfloat16 if cc >= (8, 0) else torch.float16, True)\nAMP_DT, AMP_ON = amp_for(DEV)\nWORKERS = max(1, min(4, os.cpu_count() or 4))\nCHUNK = 48\nMICRO = 8\nmodels = [m.to(DEV).eval() for m in models]\nprint(f\"device {DEV} | amp {str(AMP_DT).split('.')[-1]} (on={AMP_ON}) | workers {WORKERS} | chunk {CHUNK} | micro {MICRO}\")\n\ndef _norm_(im):\n    k = CFG.get('norm', 'none')\n    if k == 'zscore':\n        m = (im > 0).float()\n        n = m.sum(dim=(1, 2, 3), keepdim=True).clamp(min=1.0)\n        mu = (im * m).sum(dim=(1, 2, 3), keepdim=True) / n\n        var = (((im - mu) * m) ** 2).sum(dim=(1, 2, 3), keepdim=True) / n\n        return (im - mu) / (var.sqrt() + 1e-06) * m\n    if k == 'imagenet':\n        m = (im > 0).float()\n        return (im - 0.485) / 0.229 * m\n    return im\n\n@torch.no_grad()\ndef _micro(images, masks):\n    dev = DEV\n    ims, slots, sidx, vms = ([], [], [], [])\n    for b in range(len(masks)):\n        present = np.nonzero(masks[b] > 0)[0]\n        if len(present) == 0:\n            continue\n        blk = images[b][present]\n        ims.append(torch.from_numpy(blk))\n        vms.append(torch.from_numpy(blk.reshape(blk.shape[0], blk.shape[1], -1).max(2) > 0))\n        slots.append(torch.from_numpy(present + 1).long())\n        sidx.append(torch.full((len(present),), b, dtype=torch.long))\n    out = np.full((len(models), len(masks), len(LABELS)), np.nan, np.float32)\n    if not ims:\n        return out\n    im = _norm_(torch.cat(ims).to(dev, non_blocking=True).float().div_(255.0))\n    sl = torch.cat(slots).to(dev)\n    si = torch.cat(sidx).to(dev)\n    vm = torch.cat(vms).to(dev)\n    sm = torch.zeros(len(sl), CFG.get('n_meta', 0), device=dev)\n    per = torch.zeros(len(models), len(masks), len(LABELS), device=dev, dtype=torch.float32)\n    with torch.autocast('cuda' if str(dev).startswith('cuda') else 'cpu', dtype=AMP_DT, enabled=AMP_ON):\n        for fold_index, model in enumerate(models):\n            per[fold_index] = torch.sigmoid(model(im, sl, sm, si, len(masks), vm=vm).float())\n    got = per.cpu().numpy()\n    keep = np.array([(masks[b] > 0).any() for b in range(len(masks))])\n    out[:, keep] = got[:, keep]\n    return out\n\ndef predict(images, masks):\n    out = np.full((len(models), len(masks), len(LABELS)), np.nan, np.float32)\n    for a in range(0, len(masks), MICRO):\n        b = min(a + MICRO, len(masks))\n        out[:, a:b] = _micro(images[a:b], masks[a:b])\n    return out\npreds = np.full((len(models), len(studies), len(LABELS)), np.nan, np.float32)\nt0, done = (time.time(), 0)\nwith ProcessPoolExecutor(max_workers=WORKERS) as ex:\n    for c0 in range(0, len(studies), CHUNK):\n        block = studies[c0:c0 + CHUNK]\n        imgs = np.zeros((len(block), N_SLOT, N_SLICE, SIZE, SIZE), np.uint8)\n        msks = np.zeros((len(block), N_SLOT), np.uint8)\n        futs = [ex.submit(build_study, (i, s, by.get(s, []))) for i, s in enumerate(block)]\n        for f in as_completed(futs):\n            try:\n                i, a, k = f.result()\n                imgs[i], msks[i] = (a, k)\n            except Exception as e:\n                print(f'  study failed: {type(e).__name__}: {e}')\n        preds[:, c0:c0 + len(block)] = predict(imgs, msks)\n        done += len(block)\n        el = time.time() - t0\n        print(f'  {done:,}/{len(studies):,}  {el / 60:.1f}m  eta {el / done * (len(studies) - done) / 60:.1f}m', flush=True)\n        del imgs, msks\n        gc.collect()\nprint(f'\\ninference done in {(time.time() - t0) / 60:.1f} min')\nA5_W = 0.45\nA5_LABELS = list(LABELS)\n_a5_ok = np.isfinite(preds).all(axis=(0, 2))\n\n_a5_rank_mean = np.zeros((len(studies), len(LABELS)), np.float64)\n_v8_fold_ranks = []\n\nfor fold_index in range(preds.shape[0]):\n    fold = preds[fold_index][_a5_ok]\n    ordinal = fold.argsort(0).argsort(0).astype(np.float64)\n    rank = ordinal / max(len(fold) - 1, 1)\n    _a5_rank_mean[_a5_ok] += rank\n\n    full_rank = np.full(\n        (len(studies), len(LABELS)),\n        np.nan,\n        np.float64,\n    )\n    full_rank[_a5_ok] = rank\n    _v8_fold_ranks.append(full_rank)\n\n_a5_rank_mean /= preds.shape[0]\n_a5_rank_mean[~_a5_ok] = np.nan\n\n_v8_prob_mean = np.nanmean(preds, axis=0)\n_v8_prob_rank = np.full_like(_a5_rank_mean, np.nan, dtype=np.float64)\n\nif _a5_ok.any():\n    _v8_prob_rank[_a5_ok] = pd.DataFrame(\n        _v8_prob_mean[_a5_ok],\n        columns=A5_LABELS,\n    ).rank(\n        method='average',\n        pct=True,\n    ).to_numpy(np.float64)\n\n_v8_stack = np.stack(_v8_fold_ranks)\n_v8_stability = np.zeros(len(LABELS), np.float64)\n_v8_pairs = 0\n\nfor _i in range(len(_v8_stack)):\n    for _j in range(_i + 1, len(_v8_stack)):\n        for _t in range(len(LABELS)):\n            _x = _v8_stack[_i, _a5_ok, _t]\n            _y = _v8_stack[_j, _a5_ok, _t]\n            if len(_x) > 2 and np.std(_x) > 0 and np.std(_y) > 0:\n                _v8_stability[_t] += float(np.corrcoef(_x, _y)[0, 1])\n        _v8_pairs += 1\n\n_v8_stability /= max(_v8_pairs, 1)\n\nA5_PREDS = dict(\n    zip(\n        sub_df['StudyInstanceUID'].astype(str),\n        _a5_rank_mean.astype(np.float32),\n    )\n)\nV8_D3_PROB_PREDS = dict(\n    zip(\n        sub_df['StudyInstanceUID'].astype(str),\n        _v8_prob_rank.astype(np.float32),\n    )\n)\nV8_D3_STABILITY = _v8_stability.astype(np.float64)\n\nfor _a5k, _a5v in _A5_SAVED.items():\n    globals()[_a5k] = _a5v\ndel _A5_SAVED, _a5k, _a5v\n\n_a5_sub = pd.read_csv(\n    '/kaggle/working/submission.csv',\n    dtype={'StudyInstanceUID': str},\n)\nassert _a5_sub.columns.tolist()[1:] == A5_LABELS, 'submission schema drift'\n\nif A5_W > 0:\n    _ids = _a5_sub['StudyInstanceUID'].astype(str).tolist()\n\n    _a5_ours = np.stack([A5_PREDS[_u] for _u in _ids])\n    _a5_prob = np.stack([V8_D3_PROB_PREDS[_u] for _u in _ids])\n\n    _a5_base_rank = _a5_sub[A5_LABELS].rank(\n        method='average',\n        pct=True,\n    )\n    _a5_ours_rank = pd.DataFrame(\n        _a5_ours,\n        columns=A5_LABELS,\n        index=_a5_sub.index,\n    ).rank(\n        method='average',\n        pct=True,\n    )\n\n    V8_D2_PUBLIC_RANK = _a5_base_rank.to_numpy(np.float64)\n    V8_D3_FOLD_RANK = _a5_ours_rank.to_numpy(np.float64)\n    V8_D3_PROB_RANK = pd.DataFrame(\n        _a5_prob,\n        columns=A5_LABELS,\n        index=_a5_sub.index,\n    ).rank(\n        method='average',\n        pct=True,\n    ).to_numpy(np.float64)\n\n    def _v8_align_frame(frame):\n        aligned = _a5_sub[['StudyInstanceUID']].merge(\n            frame[['StudyInstanceUID'] + A5_LABELS],\n            on='StudyInstanceUID',\n            how='left',\n            validate='one_to_one',\n        )\n        values = aligned[A5_LABELS].rank(\n            method='average',\n            pct=True,\n        ).to_numpy(np.float64)\n        if not np.isfinite(values).all():\n            raise RuntimeError('V8 DINO alternative alignment failed')\n        return values\n\n    V8_D2_WEIGHTED_RANK = _v8_align_frame(V8_D2_WEIGHTED_FRAME)\n    V8_D2_SOFT_RANK = _v8_align_frame(V8_D2_SOFT_FRAME)\n\n    _a5_sub[A5_LABELS] = (\n        (1.0 - A5_W) * _a5_base_rank\n        + A5_W * _a5_ours_rank\n    )\n\n    assert np.isfinite(_a5_sub[A5_LABELS].to_numpy()).all()\n    _a5_sub.to_csv('/kaggle/working/submission.csv', index=False)\n","metadata":{},"outputs":[],"execution_count":null},{"id":"6cbae761-6bfb-4f50-9309-0e33dd51f82a","cell_type":"code","source":"from __future__ import annotations\nimport contextlib as _rad_contextlib\nimport gc as _rad_gc\nimport hashlib as _rad_hashlib\nimport json as _rad_json\nimport os as _rad_os\nimport re as _rad_re\nimport time as _rad_time\nfrom concurrent.futures import ThreadPoolExecutor as _RadThreadPool\nfrom pathlib import Path as _RadPath\nimport numpy as _rad_np\nimport pandas as _rad_pd\nimport pydicom as _rad_pydicom\nimport torch as _rad_torch\nimport torch.nn as _rad_nn\nimport torch.nn.functional as _rad_F\nfrom torchvision.models import resnet50 as _rad_resnet50\n_RAD_LABELS = ['ACL', 'MCL', 'Medial Meniscus', 'Lateral Meniscus', 'Medial OA', 'Lateral OA', 'PF OA', 'Effusion', 'Synovitis', \"Baker's\", 'Contusion', 'Fracture']\n_RAD_ALPHA = 0.5\n_RAD_EXCLUDE = (\"Baker's\", 'Fracture')\n_RAD_REFERENCE_HEADS_SHA256 = '0f465649799ecfbccaac1767844639e7ced44e1bc9babde6e4bac7c5d9b89eaa'\n_RAD_ENCODER_SHA256 = '08629f7e7bd3e29b8ee9522ca3f65ce4d010a7ddf74f0ea3c7e3f3d0bbab0734'\n_RAD_E13_HEADS_SHA256 = 'ad9f19af73bfdf4e49263c0e45060dc3cb239e1195039b26dc8c0a3a6bcd1a8a'\n_RAD_E13_MEMBER_WEIGHT = 0.5\n_RAD_V48_SECOND_ALPHA = 0.15\n_RAD_TOKEN_DIM, _RAD_HEAD_DIM = (2048, 512)\n_RAD_E11_SLOTS = [('SAG_NOFS', 'Sagittal', None, False), ('COR_NOFS', 'Coronal', None, False), ('AX_NOFS', 'Axial', None, False), ('SAG_FS', 'Sagittal', None, True)]\n_RAD_E11_CROP_MM = 130.0\n_RAD_E13_SLOTS = [('SAG_FS', 'Sagittal', None, True), ('COR_FS', 'Coronal', None, True), ('AX_FS', 'Axial', None, True), ('SAG_NOFS', 'Sagittal', None, False)]\n_RAD_E13_CROP_MM = 130.0\n_RAD_E13_CACHE_SLICES = 8\n_RAD_E13_IMG = 224\nSLOTS = [('SAG_FS', 'Sagittal', None, True), ('COR_FS', 'Coronal', None, True), ('AX_FS', 'Axial', None, True)]\nN_SLOT = len(SLOTS)\nCACHE_SLICES = 8\n\ndef _rad_sha256(path, chunk=8 << 20):\n    digest = _rad_hashlib.sha256()\n    with open(path, 'rb') as handle:\n        for block in iter(lambda: handle.read(chunk), b''):\n            digest.update(block)\n    return digest.hexdigest()\n\ndef _rad_find_file(name, expected_sha=None, explicit_env=None):\n    files = {_RAD_ENCODER_SHA256: ASSET / 'resnet-50-radimagenet-marwan/ResNet50.pt', _RAD_REFERENCE_HEADS_SHA256: ASSET / 'rsna-knee-e9-radimagenet-heads-v15/v52_radimagenet_heads.pt', _RAD_E13_HEADS_SHA256: ASSET / 'kernel-sources/rsna-knee-e13-train/rsna_rad_e11/v52_e11_heads.pt'}\n    path = files.get(expected_sha)\n    if path is None or not path.is_file():\n        raise FileNotFoundError(name)\n    if _rad_sha256(path) != expected_sha:\n        raise RuntimeError(f'hash mismatch for {path}')\n    return path\n\nclass _RadEncoder(_rad_nn.Module):\n\n    def __init__(self):\n        super().__init__()\n        self.backbone = _rad_nn.Sequential(*list(_rad_resnet50(weights=None).children())[:-2])\n\n    def forward(self, image):\n        return self.backbone(image).mean(dim=(2, 3))\n\nclass _RadHead(_rad_nn.Module):\n\n    def __init__(self):\n        super().__init__()\n        self.project = _rad_nn.Sequential(_rad_nn.LayerNorm(_RAD_TOKEN_DIM), _rad_nn.Linear(_RAD_TOKEN_DIM, _RAD_HEAD_DIM), _rad_nn.GELU())\n        self.plane = _rad_nn.Parameter(_rad_torch.randn(N_SLOT, _RAD_HEAD_DIM) * 0.01)\n        self.position = _rad_nn.Parameter(_rad_torch.randn(CACHE_SLICES, _RAD_HEAD_DIM) * 0.01)\n        self.query = _rad_nn.Parameter(_rad_torch.randn(len(_RAD_LABELS), _RAD_HEAD_DIM) * 0.02)\n        self.attn = _rad_nn.MultiheadAttention(_RAD_HEAD_DIM, 8, dropout=0.1, batch_first=True)\n        self.fuse = _rad_nn.Sequential(_rad_nn.LayerNorm(_RAD_HEAD_DIM * 4), _rad_nn.Linear(_RAD_HEAD_DIM * 4, _RAD_HEAD_DIM), _rad_nn.GELU(), _rad_nn.Dropout(0.15))\n        self.weight = _rad_nn.Parameter(_rad_torch.randn(len(_RAD_LABELS), _RAD_HEAD_DIM) * 0.02)\n        self.bias = _rad_nn.Parameter(_rad_torch.zeros(len(_RAD_LABELS)))\n\n    def forward(self, feature, mask):\n        token = self.project(feature.float())\n        token = token.view(len(token), N_SLOT, CACHE_SLICES, _RAD_HEAD_DIM)\n        token = token + self.plane[None, :, None] + self.position[None, None]\n        token = token.flatten(1, 2)\n        key_padding = mask <= 0\n        all_empty = key_padding.all(1)\n        if all_empty.any():\n            key_padding = key_padding.clone()\n            key_padding[all_empty, 0] = False\n        query = self.query.unsqueeze(0).expand(len(token), -1, -1)\n        attended = query + self.attn(query, token, token, key_padding_mask=key_padding, need_weights=False)[0]\n        denominator = mask.sum(1, keepdim=True).clamp_min(1).unsqueeze(-1)\n        mean = (token * mask.unsqueeze(-1)).sum(1, keepdim=True) / denominator\n        mean = mean.expand(-1, len(_RAD_LABELS), -1)\n        fused = self.fuse(_rad_torch.cat([attended, mean, _rad_torch.abs(attended - mean), attended * mean], dim=-1))\n        return (fused * self.weight.unsqueeze(0)).sum(-1) + self.bias\n\ndef _rad_load_public_heads(device, expected_sha):\n    heads_path = _rad_find_file('v52_radimagenet_heads.pt', expected_sha)\n    payload = _rad_torch.load(heads_path, map_location='cpu', weights_only=True)\n    expected = {'version': 'v52-radimagenet-resnet50-official-1', 'targets': _RAD_LABELS, 'encoder_sha256': _RAD_ENCODER_SHA256, 'encoder_source_commit': '0ce16f7375db4236e646829d1eca61cdb4282133', 'img': 224, 'slices_per_plane': 8, 'feature': 'global_average_pool'}\n    for key, value in expected.items():\n        if payload.get(key) != value:\n            raise RuntimeError(f'public-v15 head contract drift for {key}')\n    folds = payload.get('folds')\n    if not isinstance(folds, list) or len(folds) != 5:\n        raise RuntimeError('public-v15 bundle requires exactly five heads')\n    if sorted((int(record.get('fold', -1)) for record in folds)) != list(range(5)):\n        raise RuntimeError('public-v15 fold identity drift')\n    heads = []\n    for record in folds:\n        head = _RadHead().to(device).eval()\n        head.load_state_dict(record['state_dict'], strict=True)\n        heads.append(head)\n    return (heads, str(heads_path))\n\ndef _rad_load_e13_heads(device):\n    heads_path = _rad_find_file('v52_e11_heads.pt', _RAD_E13_HEADS_SHA256)\n    payload = _rad_torch.load(heads_path, map_location='cpu', weights_only=False)\n    expected = {'version': 'e11-radimagenet-resnet50-diverse-1', 'targets': _RAD_LABELS, 'encoder_sha256': _RAD_ENCODER_SHA256, 'slots': [list(slot) for slot in _RAD_E13_SLOTS], 'crop_mm': _RAD_E13_CROP_MM, 'img': _RAD_E13_IMG, 'slices_per_plane': _RAD_E13_CACHE_SLICES, 'feature': 'global_average_pool'}\n    for key, value in expected.items():\n        if payload.get(key) != value:\n            raise RuntimeError(f'E13 head contract drift for {key}')\n    folds = payload.get('folds')\n    if not isinstance(folds, list) or len(folds) != 5:\n        raise RuntimeError('E13 bundle requires exactly five heads')\n    if sorted((int(record.get('fold', -1)) for record in folds)) != list(range(5)):\n        raise RuntimeError('E13 fold identity drift')\n    heads = []\n    for record in folds:\n        head = _RadHead().to(device).eval()\n        head.load_state_dict(record['state_dict'], strict=True)\n        heads.append(head)\n    return (heads, str(heads_path))\n\n@_rad_torch.inference_mode()\ndef _rad_encode(encoder, pixels, slot_mask, device):\n    n, slots, slices, height, width = pixels.shape\n    features = _rad_np.zeros((n, slots * slices, _RAD_TOKEN_DIM), _rad_np.float16)\n    token_mask = _rad_np.repeat(slot_mask[:, :, None], slices, axis=2).reshape(n, -1)\n    valid = _rad_np.flatnonzero(token_mask.reshape(-1) > 0)\n    flat = pixels.reshape(-1, height, width)\n    batch = 192 if device.type == 'cuda' and _rad_torch.cuda.device_count() > 1 else 96 if device.type == 'cuda' else 8\n    for start in range(0, len(valid), batch):\n        indices = valid[start:start + batch]\n        image = _rad_torch.from_numpy(flat[indices]).to(device).float().div_(127.5).sub_(1.0)\n        image = image.unsqueeze(1).expand(-1, 3, -1, -1).contiguous()\n        amp = _rad_torch.autocast('cuda') if device.type == 'cuda' else _rad_contextlib.nullcontext()\n        with amp:\n            feature = encoder(image)\n        values = feature.float().cpu().numpy()\n        if not _rad_np.isfinite(values).all():\n            raise RuntimeError('V36 non-finite RadImageNet feature')\n        features.reshape(-1, _RAD_TOKEN_DIM)[indices] = values.astype(_rad_np.float16)\n    return (features, token_mask.astype(_rad_np.float32))\n\n@_rad_torch.inference_mode()\ndef _rad_predict_head(head, features, masks, device, batch=64):\n    predictions = []\n    for start in range(0, len(features), batch):\n        image = _rad_torch.from_numpy(features[start:start + batch]).to(device)\n        mask = _rad_torch.from_numpy(masks[start:start + batch]).to(device)\n        amp = _rad_torch.autocast('cuda') if device.type == 'cuda' else _rad_contextlib.nullcontext()\n        with amp:\n            predictions.append(_rad_torch.sigmoid(head(image, mask)).float().cpu())\n    return _rad_torch.cat(predictions).numpy()\n\ndef _rad_rank_columns(values):\n    return _rad_pd.DataFrame(_rad_np.asarray(values, dtype=_rad_np.float64)).rank(method='average', pct=True).to_numpy(_rad_np.float64)\n\ndef _rad_validate(frame, expected_ids):\n    if frame.columns.tolist() != ['StudyInstanceUID', *_RAD_LABELS]:\n        raise RuntimeError('V36 submission schema drift')\n    ids = frame['StudyInstanceUID'].astype(str).tolist()\n    if ids != list(map(str, expected_ids)) or len(ids) != len(set(ids)):\n        raise RuntimeError('V36 submission study identity/order drift')\n    values = frame[_RAD_LABELS].to_numpy(_rad_np.float64)\n    if not _rad_np.isfinite(values).all() or values.min() < 0 or values.max() > 1:\n        raise RuntimeError('V36 invalid submission values')\n\n_V8_LOCALIZED = {\n    \"ACL\",\n    \"MCL\",\n    \"Medial Meniscus\",\n    \"Lateral Meniscus\",\n    \"Baker's\",\n    \"Contusion\",\n    \"Fracture\",\n}\n\n\ndef _v8_rank_bank(predictions):\n    return _rad_np.stack([\n        _rad_rank_columns(p)\n        for p in predictions\n    ])\n\n\ndef _v8_target_stability(predictions):\n    bank = _v8_rank_bank(predictions)\n    result = _rad_np.zeros(len(_RAD_LABELS), _rad_np.float64)\n    count = 0\n\n    for a in range(len(bank)):\n        for b in range(a + 1, len(bank)):\n            for target in range(len(_RAD_LABELS)):\n                x = bank[a, :, target]\n                y = bank[b, :, target]\n                if len(x) > 2 and _rad_np.std(x) > 0 and _rad_np.std(y) > 0:\n                    result[target] += float(_rad_np.corrcoef(x, y)[0, 1])\n            count += 1\n\n    return result / max(count, 1)\n\n\ndef _v8_robust_z(values, floor=0.015):\n    values = _rad_np.asarray(values, _rad_np.float64)\n    center = float(_rad_np.median(values))\n    mad = float(\n        _rad_np.median(_rad_np.abs(values - center))\n    ) * 1.4826\n    scale = max(mad, float(floor))\n    return (values - center) / scale\n\n\ndef _v8_consensus(predictions):\n    probability = _rad_np.mean(\n        _rad_np.stack(predictions),\n        axis=0,\n    )\n    probability_rank = _rad_rank_columns(probability)\n    fold_rank = _v8_rank_bank(predictions).mean(axis=0)\n    consensus = _rad_rank_columns(\n        0.90 * probability_rank\n        + 0.10 * fold_rank\n    )\n    stability = _v8_target_stability(predictions)\n    return probability_rank, consensus, stability\n\n\ndef _v8_extract_metric_vector(record):\n    candidates = []\n\n    def visit(value, path=\"\"):\n        if isinstance(value, dict):\n            for key, child in value.items():\n                visit(child, f\"{path}/{key}\".lower())\n            return\n\n        if isinstance(value, (list, tuple, _rad_np.ndarray)):\n            try:\n                array = _rad_np.asarray(value, _rad_np.float64)\n            except Exception:\n                return\n\n            if (\n                array.ndim == 1\n                and len(array) == len(_RAD_LABELS)\n                and _rad_np.isfinite(array).all()\n                and any(\n                    token in path\n                    for token in (\"auc\", \"metric\", \"score\", \"valid\", \"/val\")\n                )\n                and not any(\n                    token in path\n                    for token in (\"weight\", \"threshold\", \"prior\", \"preval\", \"loss\")\n                )\n            ):\n                candidates.append((path, array))\n\n    visit(record)\n\n    if not candidates:\n        return None\n\n    candidates.sort(\n        key=lambda item: (\n            0 if \"auc\" in item[0] else 1,\n            len(item[0]),\n        )\n    )\n    return candidates[0][1]\n\n\ndef _v8_bundle_metrics(path):\n    try:\n        payload = _rad_torch.load(\n            path,\n            map_location=\"cpu\",\n            weights_only=False,\n        )\n    except Exception:\n        return None\n\n    folds = payload.get(\"folds\")\n    if not isinstance(folds, list):\n        return None\n\n    vectors = []\n    for record in folds:\n        vector = _v8_extract_metric_vector(record)\n        if vector is None:\n            return None\n        vectors.append(vector)\n\n    if not vectors:\n        return None\n\n    return _rad_np.mean(_rad_np.stack(vectors), axis=0)\n\n\ndef _v8_discover_oof_auc(kind):\n    roots = [\n        ASSET,\n        _RadPath(\"/kaggle/input/kernel-sources\"),\n    ]\n    paths = []\n\n    for root in roots:\n        if not root.exists():\n            continue\n        try:\n            paths.extend(root.rglob(\"*oof*.csv\"))\n        except Exception:\n            pass\n\n    try:\n        from sklearn.metrics import roc_auc_score\n    except Exception:\n        return None\n\n    train = _rad_pd.read_csv(\n        ROOT / \"train.csv\",\n        dtype={\"StudyInstanceUID\": str},\n    )\n\n    best = None\n    best_n = -1\n\n    for path in paths:\n        text = str(path).lower()\n\n        if kind == \"e13\":\n            if not (\"e13\" in text or \"e11\" in text):\n                continue\n        else:\n            if \"e13\" in text or \"e11\" in text:\n                continue\n            if not (\n                \"e9\" in text\n                or \"radimagenet\" in text\n                or \"public\" in text\n            ):\n                continue\n\n        try:\n            frame = _rad_pd.read_csv(\n                path,\n                dtype={\"StudyInstanceUID\": str},\n            )\n        except Exception:\n            continue\n\n        if (\n            \"StudyInstanceUID\" not in frame.columns\n            or not set(_RAD_LABELS).issubset(frame.columns)\n        ):\n            continue\n\n        merged = train[\n            [\"StudyInstanceUID\"] + _RAD_LABELS\n        ].merge(\n            frame[[\"StudyInstanceUID\"] + _RAD_LABELS],\n            on=\"StudyInstanceUID\",\n            how=\"inner\",\n            suffixes=(\"_gold\", \"_pred\"),\n        )\n\n        auc = _rad_np.full(\n            len(_RAD_LABELS),\n            _rad_np.nan,\n            _rad_np.float64,\n        )\n        usable = 0\n\n        for j, target in enumerate(_RAD_LABELS):\n            y = _rad_pd.to_numeric(\n                merged[f\"{target}_gold\"],\n                errors=\"coerce\",\n            ).to_numpy()\n            p = _rad_pd.to_numeric(\n                merged[f\"{target}_pred\"],\n                errors=\"coerce\",\n            ).to_numpy()\n\n            mask = _rad_np.isfinite(y) & _rad_np.isfinite(p)\n\n            if (\n                mask.sum() >= 8\n                and len(_rad_np.unique(y[mask])) == 2\n            ):\n                auc[j] = roc_auc_score(y[mask], p[mask])\n                usable += int(mask.sum())\n\n        if _rad_np.isfinite(auc).sum() >= 8 and usable > best_n:\n            best = auc\n            best_n = usable\n\n    return best\n\n\ndef _v8_parent_specialist(baseline_rank):\n    output = _rad_np.asarray(\n        baseline_rank,\n        _rad_np.float64,\n    ).copy()\n\n    d2_soft = globals().get(\"V8_D2_SOFT_RANK\")\n    d2_weighted = globals().get(\"V8_D2_WEIGHTED_RANK\")\n    d3_probability = globals().get(\"V8_D3_PROB_RANK\")\n\n    if d2_soft is None or d2_weighted is None or d3_probability is None:\n        return output\n\n    d3_stability = _rad_np.asarray(\n        globals().get(\n            \"V8_D3_STABILITY\",\n            _rad_np.ones(len(_RAD_LABELS)),\n        ),\n        _rad_np.float64,\n    )\n    d3_z = _v8_robust_z(d3_stability, floor=0.02)\n\n    for j, target in enumerate(_RAD_LABELS):\n        soft_w = 0.055 if target in _V8_LOCALIZED else 0.015\n        prob_w = float(\n            _rad_np.clip(\n                0.022 + 0.012 * _rad_np.tanh(d3_z[j]),\n                0.008,\n                0.038,\n            )\n        )\n        weighted_w = 0.018 if target in _V8_LOCALIZED else 0.008\n\n        total = soft_w + prob_w + weighted_w\n\n        output[:, j] = (\n            (1.0 - total) * baseline_rank[:, j]\n            + soft_w * d2_soft[:, j]\n            + prob_w * d3_probability[:, j]\n            + weighted_w * d2_weighted[:, j]\n        )\n\n    return _rad_rank_columns(output)\n\n\n\n# ----------------------- V10 OOF meta stack -----------------------\n\ndef _v10_find_artifact(filename):\n    matches = []\n\n    # Search attached datasets/kernel outputs while pruning the enormous\n    # competition DICOM trees. This keeps startup deterministic.\n    root = _RadPath(\"/kaggle/input\")\n    if root.exists():\n        for current, dirs, files in os.walk(root):\n            dirs[:] = [\n                d for d in dirs\n                if d not in (\n                    \"train_series\",\n                    \"test_series\",\n                    \".git\",\n                    \"__pycache__\",\n                )\n            ]\n            if filename in files:\n                candidate = (\n                    _RadPath(current)\n                    / filename\n                )\n                if candidate.is_file():\n                    matches.append(\n                        candidate\n                    )\n\n    work = _RadPath(\n        \"/kaggle/working\"\n    )\n    if work.exists():\n        candidate = work / filename\n        if candidate.is_file():\n            matches.append(\n                candidate\n            )\n        for child in work.iterdir():\n            if not child.is_dir():\n                continue\n            nested = child / filename\n            if nested.is_file():\n                matches.append(\n                    nested\n                )\n\n    if not matches:\n        return None\n\n    unique = {}\n    for candidate in matches:\n        try:\n            key = str(\n                candidate.resolve()\n            )\n        except Exception:\n            key = str(candidate)\n        unique[key] = candidate\n\n    ordered = sorted(\n        unique.values(),\n        key=lambda p: (\n            len(p.parts),\n            str(p),\n        ),\n    )\n    return ordered\n\n\ndef _v10_rank(matrix):\n    return _rad_rank_columns(\n        _rad_np.asarray(\n            matrix,\n            dtype=_rad_np.float64,\n        )\n    )\n\n\ndef _v10_protocol_features(series, ids):\n    ids = [str(x) for x in ids]\n    frame = series.copy()\n    frame[\"StudyInstanceUID\"] = (\n        frame[\"StudyInstanceUID\"]\n        .astype(str)\n    )\n\n    result = _rad_pd.DataFrame(\n        index=_rad_pd.Index(\n            ids,\n            name=\"StudyInstanceUID\",\n        )\n    )\n\n    grouped = frame.groupby(\n        \"StudyInstanceUID\",\n        sort=False,\n    )\n\n    result[\"series_total\"] = (\n        grouped.size()\n        .reindex(result.index)\n        .fillna(0)\n    )\n\n    if \"Anatomical_Plane\" in frame.columns:\n        for plane in (\n            \"Sagittal\",\n            \"Coronal\",\n            \"Axial\",\n        ):\n            count = (\n                frame[\n                    frame[\"Anatomical_Plane\"]\n                    .astype(str)\n                    .eq(plane)\n                ]\n                .groupby(\n                    \"StudyInstanceUID\"\n                )\n                .size()\n            )\n            result[\n                f\"plane_{plane.lower()}\"\n            ] = (\n                count\n                .reindex(result.index)\n                .fillna(0)\n            )\n\n    for flag_name in (\n        \"Fat_Suppression\",\n        \"Fluid_Sensitive\",\n    ):\n        if flag_name not in frame.columns:\n            continue\n\n        numeric = _rad_pd.to_numeric(\n            frame[flag_name],\n            errors=\"coerce\",\n        ).fillna(0)\n\n        flag_frame = frame[\n            numeric > 0\n        ]\n\n        total = (\n            flag_frame.groupby(\n                \"StudyInstanceUID\"\n            )\n            .size()\n        )\n        result[\n            flag_name.lower()\n        ] = (\n            total\n            .reindex(result.index)\n            .fillna(0)\n        )\n\n        if \"Anatomical_Plane\" in frame.columns:\n            for plane in (\n                \"Sagittal\",\n                \"Coronal\",\n                \"Axial\",\n            ):\n                count = (\n                    flag_frame[\n                        flag_frame[\n                            \"Anatomical_Plane\"\n                        ]\n                        .astype(str)\n                        .eq(plane)\n                    ]\n                    .groupby(\n                        \"StudyInstanceUID\"\n                    )\n                    .size()\n                )\n                result[\n                    f\"{flag_name.lower()}_\"\n                    f\"{plane.lower()}\"\n                ] = (\n                    count\n                    .reindex(result.index)\n                    .fillna(0)\n                )\n\n    values = result.to_numpy(\n        dtype=_rad_np.float64\n    )\n\n    if values.shape[1] == 0:\n        return _rad_np.zeros(\n            (len(ids), 1),\n            dtype=_rad_np.float64,\n        )\n\n    return values\n\n\ndef _v10_demographic_features(frame, ids):\n    ids = [str(x) for x in ids]\n    if \"StudyInstanceUID\" not in frame.columns:\n        return _rad_np.zeros(\n            (len(ids), 3),\n            dtype=_rad_np.float64,\n        )\n\n    base = frame.copy()\n    base[\"StudyInstanceUID\"] = (\n        base[\"StudyInstanceUID\"]\n        .astype(str)\n    )\n    base = (\n        _rad_pd.DataFrame(\n            {\"StudyInstanceUID\": ids}\n        )\n        .merge(\n            base,\n            on=\"StudyInstanceUID\",\n            how=\"left\",\n            validate=\"one_to_one\",\n        )\n    )\n\n    sex = (\n        base[\"PatientSex\"]\n        .astype(str)\n        .str.upper()\n        if \"PatientSex\" in base.columns\n        else _rad_pd.Series(\n            [\"\"] * len(base)\n        )\n    )\n\n    return _rad_np.stack(\n        [\n            sex.eq(\"M\").to_numpy(\n                _rad_np.float64\n            ),\n            sex.eq(\"F\").to_numpy(\n                _rad_np.float64\n            ),\n            (\n                ~sex.isin(\n                    [\"M\", \"F\"]\n                )\n            ).to_numpy(\n                _rad_np.float64\n            ),\n        ],\n        axis=1,\n    )\n\n\ndef _v10_load_oof():\n    \"\"\"\n    Load three genuinely out-of-fold model families:\n      1. E2 DINOv2 ensemble\n      2. public RadImageNet family\n      3. diverse E11 RadImageNet family\n\n    The function is intentionally strict. Any contract mismatch disables\n    V10 and leaves the already valid V8 prediction untouched.\n    \"\"\"\n    npz_candidates = (\n        _v10_find_artifact(\n            \"oof.npz\"\n        )\n        or []\n    )\n    rad_candidates = (\n        _v10_find_artifact(\n            \"v52_oof.csv\"\n        )\n        or []\n    )\n    e11_candidates = (\n        _v10_find_artifact(\n            \"v52_e11_oof.csv\"\n        )\n        or []\n    )\n\n    if (\n        not npz_candidates\n        or not rad_candidates\n        or not e11_candidates\n    ):\n        return None\n\n    train = _rad_pd.read_csv(\n        ROOT / \"train.csv\",\n        dtype={\n            \"StudyInstanceUID\": str\n        },\n    )\n    ids = (\n        train[\"StudyInstanceUID\"]\n        .astype(str)\n        .to_numpy()\n    )\n\n    bundle_data = None\n\n    for path in npz_candidates:\n        try:\n            with _rad_np.load(\n                path,\n                allow_pickle=False,\n            ) as bundle:\n                required = {\n                    \"ids\",\n                    \"pred\",\n                    \"y_derived\",\n                    \"gold_mask\",\n                    \"targets\",\n                }\n                if not required.issubset(\n                    bundle.files\n                ):\n                    continue\n\n                targets = (\n                    bundle[\"targets\"]\n                    .astype(str)\n                    .tolist()\n                )\n                bundle_ids = (\n                    bundle[\"ids\"]\n                    .astype(str)\n                )\n\n                if targets != list(\n                    _RAD_LABELS\n                ):\n                    continue\n                if not _rad_np.array_equal(\n                    bundle_ids,\n                    ids,\n                ):\n                    continue\n\n                bundle_data = {\n                    \"pred\": bundle[\n                        \"pred\"\n                    ].astype(\n                        _rad_np.float64\n                    ),\n                    \"y\": bundle[\n                        \"y_derived\"\n                    ].astype(\n                        _rad_np.float64\n                    ),\n                    \"gold\": bundle[\n                        \"gold_mask\"\n                    ].astype(bool),\n                    \"path\": str(path),\n                }\n                break\n        except Exception:\n            continue\n\n    if bundle_data is None:\n        return None\n\n    def load_csv(\n        candidates,\n        require_fold=True,\n    ):\n        for path in candidates:\n            try:\n                frame = _rad_pd.read_csv(\n                    path,\n                    dtype={\n                        \"StudyInstanceUID\": str\n                    },\n                )\n            except Exception:\n                continue\n\n            if not {\n                \"StudyInstanceUID\",\n                *_RAD_LABELS,\n            }.issubset(\n                frame.columns\n            ):\n                continue\n\n            aligned = (\n                train[\n                    [\"StudyInstanceUID\"]\n                ]\n                .merge(\n                    frame,\n                    on=\"StudyInstanceUID\",\n                    how=\"left\",\n                    validate=\"one_to_one\",\n                )\n            )\n\n            if aligned[\n                _RAD_LABELS\n            ].isna().any().any():\n                continue\n\n            if (\n                require_fold\n                and \"fold\"\n                not in aligned.columns\n            ):\n                continue\n\n            return (\n                aligned,\n                str(path),\n            )\n\n        return (\n            None,\n            None,\n        )\n\n    rad_frame, rad_path = load_csv(\n        rad_candidates\n    )\n    e11_frame, e11_path = load_csv(\n        e11_candidates\n    )\n\n    if (\n        rad_frame is None\n        or e11_frame is None\n    ):\n        return None\n\n    gold = bundle_data[\"gold\"]\n\n    official_gold = (\n        train[\n            _RAD_LABELS\n        ]\n        .notna()\n        .all(axis=1)\n        .to_numpy()\n    )\n\n    if not _rad_np.array_equal(\n        gold,\n        official_gold,\n    ):\n        return None\n\n    y = bundle_data[\"y\"].copy()\n\n    if (\n        y.shape\n        != (\n            len(train),\n            len(_RAD_LABELS),\n        )\n        or bundle_data[\"pred\"].shape\n        != (\n            len(train),\n            len(_RAD_LABELS),\n        )\n    ):\n        return None\n\n    # Replace any non-finite weak target with the neutral value. Gold rows\n    # are overwritten immediately below by official labels.\n    y = _rad_np.where(\n        _rad_np.isfinite(y),\n        y,\n        0.5,\n    )\n\n    # Official labels always override report-derived targets.\n    y[gold] = (\n        train.loc[\n            gold,\n            _RAD_LABELS,\n        ]\n        .to_numpy(\n            _rad_np.float64\n        )\n    )\n\n    fold = _rad_pd.to_numeric(\n        e11_frame[\"fold\"],\n        errors=\"coerce\",\n    ).to_numpy()\n\n    if not _rad_np.isfinite(\n        fold\n    ).all():\n        return None\n\n    fold = fold.astype(\n        _rad_np.int64\n    )\n\n    base = _v10_rank(\n        bundle_data[\"pred\"]\n    )\n    public = _v10_rank(\n        rad_frame[\n            _RAD_LABELS\n        ].to_numpy(\n            _rad_np.float64\n        )\n    )\n    pass2 = _v10_rank(\n        e11_frame[\n            _RAD_LABELS\n        ].to_numpy(\n            _rad_np.float64\n        )\n    )\n\n    train_series = _rad_pd.read_csv(\n        ROOT / \"train_series.csv\",\n        dtype={\n            \"StudyInstanceUID\": str,\n            \"SeriesInstanceUID\": str,\n        },\n    )\n\n    protocol = _v10_protocol_features(\n        train_series,\n        ids,\n    )\n    demographics = (\n        _v10_demographic_features(\n            train,\n            ids,\n        )\n    )\n\n    return {\n        \"train\": train,\n        \"ids\": ids,\n        \"y\": y,\n        \"gold\": gold,\n        \"fold\": fold,\n        \"base\": base,\n        \"public\": public,\n        \"pass2\": pass2,\n        \"protocol\": protocol,\n        \"demographics\": demographics,\n        \"paths\": {\n            \"base\": bundle_data[\n                \"path\"\n            ],\n            \"public\": rad_path,\n            \"pass2\": e11_path,\n        },\n    }\n\n\ndef _v10_design(\n    base,\n    public,\n    pass2,\n    protocol,\n    demographics,\n):\n    base = _rad_np.asarray(\n        base,\n        _rad_np.float64,\n    )\n    public = _rad_np.asarray(\n        public,\n        _rad_np.float64,\n    )\n    pass2 = _rad_np.asarray(\n        pass2,\n        _rad_np.float64,\n    )\n\n    injury = base[\n        :,\n        [\n            _RAD_LABELS.index(\"ACL\"),\n            _RAD_LABELS.index(\"MCL\"),\n            _RAD_LABELS.index(\"Contusion\"),\n            _RAD_LABELS.index(\"Fracture\"),\n        ],\n    ].mean(axis=1, keepdims=True)\n\n    meniscus = base[\n        :,\n        [\n            _RAD_LABELS.index(\n                \"Medial Meniscus\"\n            ),\n            _RAD_LABELS.index(\n                \"Lateral Meniscus\"\n            ),\n        ],\n    ].mean(axis=1, keepdims=True)\n\n    oa = base[\n        :,\n        [\n            _RAD_LABELS.index(\n                \"Medial OA\"\n            ),\n            _RAD_LABELS.index(\n                \"Lateral OA\"\n            ),\n            _RAD_LABELS.index(\n                \"PF OA\"\n            ),\n        ],\n    ].mean(axis=1, keepdims=True)\n\n    inflammatory = base[\n        :,\n        [\n            _RAD_LABELS.index(\n                \"Effusion\"\n            ),\n            _RAD_LABELS.index(\n                \"Synovitis\"\n            ),\n            _RAD_LABELS.index(\n                \"Baker's\"\n            ),\n        ],\n    ].mean(axis=1, keepdims=True)\n\n    return _rad_np.concatenate(\n        [\n            base,\n            public,\n            pass2,\n            public - base,\n            pass2 - base,\n            injury,\n            meniscus,\n            oa,\n            inflammatory,\n            _rad_np.asarray(\n                protocol,\n                _rad_np.float64,\n            ),\n            _rad_np.asarray(\n                demographics,\n                _rad_np.float64,\n            ),\n        ],\n        axis=1,\n    )\n\n\ndef _v10_fit_ridge(\n    x,\n    y,\n    sample_weight,\n    alpha=22.0,\n):\n    from sklearn.linear_model import Ridge\n\n    x = _rad_np.asarray(\n        x,\n        _rad_np.float64,\n    )\n    y = _rad_np.asarray(\n        y,\n        _rad_np.float64,\n    )\n    weight = _rad_np.asarray(\n        sample_weight,\n        _rad_np.float64,\n    )\n\n    mean = x.mean(\n        axis=0,\n        keepdims=True,\n    )\n    scale = x.std(\n        axis=0,\n        keepdims=True,\n    )\n    scale = _rad_np.where(\n        scale > 1e-7,\n        scale,\n        1.0,\n    )\n\n    z = (\n        x - mean\n    ) / scale\n\n    model = Ridge(\n        alpha=float(alpha),\n        fit_intercept=True,\n    )\n    model.fit(\n        z,\n        y,\n        sample_weight=weight,\n    )\n\n    return (\n        model,\n        mean,\n        scale,\n    )\n\n\ndef _v10_predict_ridge(\n    fitted,\n    x,\n):\n    model, mean, scale = fitted\n    x = _rad_np.asarray(\n        x,\n        _rad_np.float64,\n    )\n    z = (\n        x - mean\n    ) / scale\n    return model.predict(z)\n\n\ndef _v10_target_auc(y, p):\n    from sklearn.metrics import (\n        roc_auc_score\n    )\n\n    y = _rad_np.asarray(y)\n    p = _rad_np.asarray(p)\n\n    mask = (\n        _rad_np.isfinite(y)\n        & _rad_np.isfinite(p)\n    )\n\n    if (\n        mask.sum() < 4\n        or len(\n            _rad_np.unique(\n                y[mask]\n            )\n        ) < 2\n    ):\n        return _rad_np.nan\n\n    return float(\n        roc_auc_score(\n            y[mask],\n            p[mask],\n        )\n    )\n\n\ndef _v10_bootstrap_positive_fraction(\n    y,\n    anchor,\n    candidate,\n    seed,\n    repeats=240,\n):\n    y = _rad_np.asarray(y)\n    anchor = _rad_np.asarray(anchor)\n    candidate = _rad_np.asarray(candidate)\n\n    positive = _rad_np.flatnonzero(\n        y > 0.5\n    )\n    negative = _rad_np.flatnonzero(\n        y <= 0.5\n    )\n\n    if (\n        len(positive) < 2\n        or len(negative) < 2\n    ):\n        return 0.0\n\n    rng = _rad_np.random.default_rng(\n        int(seed)\n    )\n    gains = []\n\n    for _ in range(int(repeats)):\n        pos = rng.choice(\n            positive,\n            size=len(positive),\n            replace=True,\n        )\n        neg = rng.choice(\n            negative,\n            size=len(negative),\n            replace=True,\n        )\n        index = _rad_np.concatenate(\n            [pos, neg]\n        )\n\n        base_auc = _v10_target_auc(\n            y[index],\n            anchor[index],\n        )\n        new_auc = _v10_target_auc(\n            y[index],\n            candidate[index],\n        )\n\n        if (\n            _rad_np.isfinite(\n                base_auc\n            )\n            and _rad_np.isfinite(\n                new_auc\n            )\n        ):\n            gains.append(\n                new_auc - base_auc\n            )\n\n    if not gains:\n        return 0.0\n\n    gains = _rad_np.asarray(\n        gains,\n        _rad_np.float64,\n    )\n    return float(\n        (gains > 0).mean()\n    )\n\n\ndef _v10_meta_stack(\n    test_base,\n    test_public,\n    test_pass2,\n    test_ids,\n):\n    \"\"\"\n    Cross-fitted, label-dependency-aware stacking.\n\n    The stack is trained on model OOF predictions rather than in-sample\n    predictions. All weak rows are available for fitting; the 58 official\n    rows receive much larger weight. A target gets non-zero deployment\n    weight only when its cross-fitted gold prediction improves the OOF\n    anchor with bootstrap support.\n    \"\"\"\n    data = _v10_load_oof()\n\n    if data is None:\n        return (\n            None,\n            _rad_np.zeros(\n                len(_RAD_LABELS),\n                _rad_np.float64,\n            ),\n        )\n\n    train = data[\"train\"]\n    y = data[\"y\"]\n    gold = data[\"gold\"]\n    fold = data[\"fold\"]\n\n    x_train = _v10_design(\n        data[\"base\"],\n        data[\"public\"],\n        data[\"pass2\"],\n        data[\"protocol\"],\n        data[\"demographics\"],\n    )\n\n    test_series = _rad_pd.read_csv(\n        ROOT / \"test_series.csv\",\n        dtype={\n            \"StudyInstanceUID\": str,\n            \"SeriesInstanceUID\": str,\n        },\n    )\n    test_frame = _rad_pd.read_csv(\n        ROOT / \"test.csv\",\n        dtype={\n            \"StudyInstanceUID\": str\n        },\n    )\n\n    test_protocol = (\n        _v10_protocol_features(\n            test_series,\n            test_ids,\n        )\n    )\n    test_demographics = (\n        _v10_demographic_features(\n            test_frame,\n            test_ids,\n        )\n    )\n\n    x_test = _v10_design(\n        test_base,\n        test_public,\n        test_pass2,\n        test_protocol,\n        test_demographics,\n    )\n\n    # Approximation of the strong pre-E13 OOF route.\n    oof_e10 = _v10_rank(\n        0.50 * data[\"base\"]\n        + 0.50 * data[\"public\"]\n    )\n    oof_anchor = _v10_rank(\n        0.85 * oof_e10\n        + 0.15 * data[\"pass2\"]\n    )\n\n    meta_cross = _rad_np.full(\n        y.shape,\n        _rad_np.nan,\n        _rad_np.float64,\n    )\n\n    # Weak report labels get lower weight when close to 0.5.\n    weak_conf = (\n        0.40\n        + 1.60\n        * _rad_np.abs(\n            y - 0.5\n        )\n        * 2.0\n    )\n    weak_conf = _rad_np.clip(\n        weak_conf,\n        0.40,\n        2.0,\n    )\n\n    unique_folds = sorted(\n        int(v)\n        for v in _rad_np.unique(\n            fold[gold]\n        )\n        if int(v) >= 0\n    )\n\n    if len(unique_folds) < 3:\n        return (\n            None,\n            _rad_np.zeros(\n                len(_RAD_LABELS),\n                _rad_np.float64,\n            ),\n        )\n\n    for outer in unique_folds:\n        train_mask = (\n            fold != int(outer)\n        )\n        valid_mask = (\n            gold\n            & (fold == int(outer))\n        )\n\n        if not valid_mask.any():\n            continue\n\n        for target in range(\n            len(_RAD_LABELS)\n        ):\n            target_y = y[:, target]\n            weight = weak_conf[\n                :, target\n            ].copy()\n\n            # Official labels dominate the weak report targets.\n            weight[gold] = 14.0\n\n            fitted = _v10_fit_ridge(\n                x_train[train_mask],\n                target_y[train_mask],\n                weight[train_mask],\n                alpha=24.0,\n            )\n\n            meta_cross[\n                valid_mask,\n                target,\n            ] = _v10_predict_ridge(\n                fitted,\n                x_train[valid_mask],\n            )\n\n    gold_index = _rad_np.flatnonzero(\n        gold\n    )\n\n    if not _rad_np.isfinite(\n        meta_cross[\n            gold_index\n        ]\n    ).all():\n        return (\n            None,\n            _rad_np.zeros(\n                len(_RAD_LABELS),\n                _rad_np.float64,\n            ),\n        )\n\n    meta_cross_rank = _v10_rank(\n        meta_cross[\n            gold_index\n        ]\n    )\n    anchor_gold = _v10_rank(\n        oof_anchor[\n            gold_index\n        ]\n    )\n    gold_y = y[\n        gold_index\n    ]\n\n    deployment = _rad_np.zeros(\n        len(_RAD_LABELS),\n        _rad_np.float64,\n    )\n\n    grid = _rad_np.asarray(\n        [\n            0.00,\n            0.05,\n            0.10,\n            0.15,\n            0.20,\n            0.25,\n            0.30,\n        ],\n        _rad_np.float64,\n    )\n\n    for target in range(\n        len(_RAD_LABELS)\n    ):\n        truth = gold_y[\n            :, target\n        ]\n\n        base_auc = _v10_target_auc(\n            truth,\n            anchor_gold[\n                :, target\n            ],\n        )\n\n        if not _rad_np.isfinite(\n            base_auc\n        ):\n            continue\n\n        best_weight = 0.0\n        best_auc = base_auc\n\n        for weight in grid[1:]:\n            candidate = (\n                (1.0 - weight)\n                * anchor_gold[\n                    :, target\n                ]\n                + weight\n                * meta_cross_rank[\n                    :, target\n                ]\n            )\n\n            auc = _v10_target_auc(\n                truth,\n                candidate,\n            )\n\n            # Small complexity penalty discourages large meta votes.\n            penalized = (\n                auc\n                - 0.0025\n                * float(weight)\n            )\n\n            current = (\n                best_auc\n                - 0.0025\n                * float(best_weight)\n            )\n\n            if penalized > current:\n                best_auc = auc\n                best_weight = float(\n                    weight\n                )\n\n        if best_weight <= 0:\n            continue\n\n        best_candidate = (\n            (1.0 - best_weight)\n            * anchor_gold[\n                :, target\n            ]\n            + best_weight\n            * meta_cross_rank[\n                :, target\n            ]\n        )\n\n        improvement = (\n            best_auc - base_auc\n        )\n\n        support = (\n            _v10_bootstrap_positive_fraction(\n                truth,\n                anchor_gold[\n                    :, target\n                ],\n                best_candidate,\n                seed=1017 + target,\n            )\n        )\n\n        # Conservative gate: only deploy signal that is visible in\n        # cross-fitted official labels and stable to class-stratified\n        # bootstrap resampling.\n        if (\n            improvement >= 0.006\n            and support >= 0.62\n        ):\n            deployment[target] = min(\n                best_weight,\n                0.28,\n            )\n        elif (\n            improvement >= 0.003\n            and support >= 0.58\n        ):\n            deployment[target] = min(\n                best_weight,\n                0.12,\n            )\n\n    # Expose the exact cross-fitted V10 gold ordering for the next\n    # meta layer. This is validation-only state; it is never written out.\n    v10_gold_final = _v10_rank(\n        (\n            1.0\n            - deployment\n        )[None, :]\n        * anchor_gold\n        + deployment[None, :]\n        * meta_cross_rank\n    )\n\n    globals()[\"V11_V10_GOLD_CONTEXT\"] = {\n        \"gold_index\": gold_index.copy(),\n        \"gold_y\": gold_y.copy(),\n        \"gold_fold\": fold[gold_index].copy(),\n        \"v10_gold\": v10_gold_final.copy(),\n        \"deployment\": deployment.copy(),\n    }\n\n    if not (\n        deployment > 0\n    ).any():\n        return (\n            None,\n            deployment,\n        )\n\n    meta_test = _rad_np.zeros(\n        (\n            len(test_ids),\n            len(_RAD_LABELS),\n        ),\n        _rad_np.float64,\n    )\n\n    for target in range(\n        len(_RAD_LABELS)\n    ):\n        target_y = y[:, target]\n        weight = weak_conf[\n            :, target\n        ].copy()\n        weight[gold] = 14.0\n\n        fitted = _v10_fit_ridge(\n            x_train,\n            target_y,\n            weight,\n            alpha=24.0,\n        )\n\n        meta_test[\n            :, target\n        ] = _v10_predict_ridge(\n            fitted,\n            x_test,\n        )\n\n    return (\n        _v10_rank(\n            meta_test\n        ),\n        deployment,\n    )\n\n\n\n\n# ----------------------- V11 graph + nonlinear OOF stack -----------------------\n\ndef _v11_label_graph(y):\n    \"\"\"\n    Learn a conservative positive label-correlation graph.\n\n    The diagonal is removed so a target cannot simply copy itself.\n    Only the strongest four positive neighbours per target survive.\n    \"\"\"\n    values = _rad_np.asarray(\n        y,\n        dtype=_rad_np.float64,\n    )\n\n    if values.ndim != 2 or values.shape[1] != len(_RAD_LABELS):\n        return _rad_np.zeros(\n            (len(_RAD_LABELS), len(_RAD_LABELS)),\n            dtype=_rad_np.float64,\n        )\n\n    corr = _rad_np.corrcoef(\n        values,\n        rowvar=False,\n    )\n    corr = _rad_np.nan_to_num(\n        corr,\n        nan=0.0,\n        posinf=0.0,\n        neginf=0.0,\n    )\n    corr = _rad_np.maximum(\n        corr,\n        0.0,\n    )\n    _rad_np.fill_diagonal(\n        corr,\n        0.0,\n    )\n\n    graph = _rad_np.zeros_like(\n        corr,\n        dtype=_rad_np.float64,\n    )\n\n    for target in range(\n        len(_RAD_LABELS)\n    ):\n        row = corr[target]\n        order = _rad_np.argsort(\n            row\n        )[::-1]\n        kept = [\n            int(index)\n            for index in order\n            if row[index] >= 0.05\n        ][:4]\n\n        if kept:\n            graph[\n                target,\n                kept,\n            ] = row[kept]\n\n    # Symmetric shrinkage makes the graph less dependent on one noisy\n    # report-derived direction.\n    graph = 0.5 * (\n        graph\n        + graph.T\n    )\n\n    denom = graph.sum(\n        axis=1,\n        keepdims=True,\n    )\n    denom = _rad_np.where(\n        denom > 1e-8,\n        denom,\n        1.0,\n    )\n    graph = graph / denom\n\n    # Keep label propagation as a feature, not a dominant prediction.\n    return 0.80 * graph\n\n\ndef _v11_design(\n    base,\n    public,\n    pass2,\n    protocol,\n    demographics,\n    graph,\n):\n    base = _rad_np.asarray(\n        base,\n        _rad_np.float64,\n    )\n    public = _rad_np.asarray(\n        public,\n        _rad_np.float64,\n    )\n    pass2 = _rad_np.asarray(\n        pass2,\n        _rad_np.float64,\n    )\n\n    core = _v10_design(\n        base,\n        public,\n        pass2,\n        protocol,\n        demographics,\n    )\n\n    stack = _rad_np.stack(\n        [\n            base,\n            public,\n            pass2,\n        ],\n        axis=2,\n    )\n\n    consensus = stack.mean(\n        axis=2\n    )\n    disagreement = stack.std(\n        axis=2\n    )\n    spread = (\n        stack.max(axis=2)\n        - stack.min(axis=2)\n    )\n\n    # Low-order cross-family interactions help the linear learner, while\n    # HGB can use them as explicit agreement/reliability signals.\n    pair_product = _rad_np.concatenate(\n        [\n            base * public,\n            base * pass2,\n            public * pass2,\n        ],\n        axis=1,\n    )\n\n    graph = _rad_np.asarray(\n        graph,\n        _rad_np.float64,\n    )\n\n    graph_base = (\n        base\n        @ graph.T\n    )\n    graph_public = (\n        public\n        @ graph.T\n    )\n    graph_pass2 = (\n        pass2\n        @ graph.T\n    )\n    graph_consensus = (\n        consensus\n        @ graph.T\n    )\n\n    return _rad_np.concatenate(\n        [\n            core,\n            consensus,\n            disagreement,\n            spread,\n            pair_product,\n            graph_base,\n            graph_public,\n            graph_pass2,\n            graph_consensus,\n        ],\n        axis=1,\n    )\n\n\ndef _v11_fit_hgb(\n    x,\n    y,\n    sample_weight,\n    seed,\n):\n    from sklearn.ensemble import (\n        HistGradientBoostingRegressor\n    )\n\n    model = HistGradientBoostingRegressor(\n        loss=\"squared_error\",\n        learning_rate=0.035,\n        max_iter=140,\n        max_leaf_nodes=7,\n        max_depth=3,\n        min_samples_leaf=42,\n        l2_regularization=9.0,\n        early_stopping=False,\n        random_state=int(seed),\n    )\n    model.fit(\n        _rad_np.asarray(\n            x,\n            _rad_np.float64,\n        ),\n        _rad_np.asarray(\n            y,\n            _rad_np.float64,\n        ),\n        sample_weight=_rad_np.asarray(\n            sample_weight,\n            _rad_np.float64,\n        ),\n    )\n    return model\n\n\ndef _v11_fold_consistency(\n    truth,\n    baseline,\n    candidate,\n    folds,\n):\n    gains = []\n\n    for fold_id in sorted(\n        int(value)\n        for value in _rad_np.unique(\n            folds\n        )\n    ):\n        mask = (\n            folds == int(fold_id)\n        )\n\n        if mask.sum() < 4:\n            continue\n\n        base_auc = _v10_target_auc(\n            truth[mask],\n            baseline[mask],\n        )\n        candidate_auc = (\n            _v10_target_auc(\n                truth[mask],\n                candidate[mask],\n            )\n        )\n\n        if (\n            _rad_np.isfinite(\n                base_auc\n            )\n            and _rad_np.isfinite(\n                candidate_auc\n            )\n        ):\n            gains.append(\n                candidate_auc\n                - base_auc\n            )\n\n    if not gains:\n        return (\n            0,\n            0.0,\n            0.0,\n        )\n\n    gains = _rad_np.asarray(\n        gains,\n        _rad_np.float64,\n    )\n\n    return (\n        int(len(gains)),\n        float(\n            (gains > 0).mean()\n        ),\n        float(\n            _rad_np.median(gains)\n        ),\n    )\n\n\ndef _v11_meta_challenger(\n    test_base,\n    test_public,\n    test_pass2,\n    test_ids,\n):\n    \"\"\"\n    Nonlinear challenger above V10.\n\n    It combines:\n      - the original linear Ridge stack;\n      - a small HGB regressor that can learn conditional family reliability;\n      - label-correlation graph features;\n      - explicit disagreement / spread / pairwise family interactions.\n\n    Deployment is target-specific and accepted only when the candidate\n    beats the already cross-fitted V10 gold prediction.\n    \"\"\"\n    context = globals().get(\n        \"V11_V10_GOLD_CONTEXT\"\n    )\n    data = _v10_load_oof()\n\n    if (\n        context is None\n        or data is None\n    ):\n        return (\n            None,\n            _rad_np.zeros(\n                len(_RAD_LABELS),\n                _rad_np.float64,\n            ),\n            [\"none\"] * len(_RAD_LABELS),\n        )\n\n    y = data[\"y\"]\n    gold = data[\"gold\"]\n    fold = data[\"fold\"]\n\n    gold_index = _rad_np.asarray(\n        context[\"gold_index\"],\n        dtype=_rad_np.int64,\n    )\n    gold_y = _rad_np.asarray(\n        context[\"gold_y\"],\n        dtype=_rad_np.float64,\n    )\n    gold_fold = _rad_np.asarray(\n        context[\"gold_fold\"],\n        dtype=_rad_np.int64,\n    )\n    v10_gold = _rad_np.asarray(\n        context[\"v10_gold\"],\n        dtype=_rad_np.float64,\n    )\n\n    expected_gold = _rad_np.flatnonzero(\n        gold\n    )\n    if not _rad_np.array_equal(\n        gold_index,\n        expected_gold,\n    ):\n        return (\n            None,\n            _rad_np.zeros(\n                len(_RAD_LABELS),\n                _rad_np.float64,\n            ),\n            [\"none\"] * len(_RAD_LABELS),\n        )\n\n    train_series = _rad_pd.read_csv(\n        ROOT / \"train_series.csv\",\n        dtype={\n            \"StudyInstanceUID\": str,\n            \"SeriesInstanceUID\": str,\n        },\n    )\n    test_series = _rad_pd.read_csv(\n        ROOT / \"test_series.csv\",\n        dtype={\n            \"StudyInstanceUID\": str,\n            \"SeriesInstanceUID\": str,\n        },\n    )\n    test_frame = _rad_pd.read_csv(\n        ROOT / \"test.csv\",\n        dtype={\n            \"StudyInstanceUID\": str\n        },\n    )\n\n    train_protocol = (\n        _v10_protocol_features(\n            train_series,\n            data[\"ids\"],\n        )\n    )\n    test_protocol = (\n        _v10_protocol_features(\n            test_series,\n            test_ids,\n        )\n    )\n    train_demographics = (\n        _v10_demographic_features(\n            data[\"train\"],\n            data[\"ids\"],\n        )\n    )\n    test_demographics = (\n        _v10_demographic_features(\n            test_frame,\n            test_ids,\n        )\n    )\n\n    weak_conf = (\n        0.35\n        + 1.65\n        * _rad_np.abs(\n            y - 0.5\n        )\n        * 2.0\n    )\n    weak_conf = _rad_np.clip(\n        weak_conf,\n        0.35,\n        2.0,\n    )\n\n    unique_folds = sorted(\n        int(value)\n        for value in _rad_np.unique(\n            fold[gold]\n        )\n        if int(value) >= 0\n    )\n\n    if len(unique_folds) < 3:\n        return (\n            None,\n            _rad_np.zeros(\n                len(_RAD_LABELS),\n                _rad_np.float64,\n            ),\n            [\"none\"] * len(_RAD_LABELS),\n        )\n\n    ridge_cross = _rad_np.full(\n        y.shape,\n        _rad_np.nan,\n        _rad_np.float64,\n    )\n    hgb_cross = _rad_np.full(\n        y.shape,\n        _rad_np.nan,\n        _rad_np.float64,\n    )\n\n    for outer in unique_folds:\n        train_mask = (\n            fold != int(outer)\n        )\n        valid_mask = (\n            gold\n            & (fold == int(outer))\n        )\n\n        if not valid_mask.any():\n            continue\n\n        # Strictly fold-safe label graph.\n        graph = _v11_label_graph(\n            y[train_mask]\n        )\n\n        x_fold = _v11_design(\n            data[\"base\"],\n            data[\"public\"],\n            data[\"pass2\"],\n            train_protocol,\n            train_demographics,\n            graph,\n        )\n\n        for target in range(\n            len(_RAD_LABELS)\n        ):\n            target_y = y[\n                :, target\n            ]\n            weight = weak_conf[\n                :, target\n            ].copy()\n\n            # V11 trusts official labels slightly more than V10, while\n            # regularization and cross-fit gates prevent memorization.\n            weight[gold] = 18.0\n\n            ridge = _v10_fit_ridge(\n                x_fold[train_mask],\n                target_y[train_mask],\n                weight[train_mask],\n                alpha=20.0,\n            )\n            ridge_cross[\n                valid_mask,\n                target,\n            ] = _v10_predict_ridge(\n                ridge,\n                x_fold[valid_mask],\n            )\n\n            try:\n                hgb = _v11_fit_hgb(\n                    x_fold[train_mask],\n                    target_y[train_mask],\n                    weight[train_mask],\n                    seed=1147\n                    + 31 * int(outer)\n                    + target,\n                )\n                hgb_cross[\n                    valid_mask,\n                    target,\n                ] = hgb.predict(\n                    x_fold[\n                        valid_mask\n                    ]\n                )\n            except Exception:\n                # Ridge remains a complete fallback candidate.\n                hgb_cross[\n                    valid_mask,\n                    target,\n                ] = ridge_cross[\n                    valid_mask,\n                    target,\n                ]\n\n    if not (\n        _rad_np.isfinite(\n            ridge_cross[\n                gold_index\n            ]\n        ).all()\n        and _rad_np.isfinite(\n            hgb_cross[\n                gold_index\n            ]\n        ).all()\n    ):\n        return (\n            None,\n            _rad_np.zeros(\n                len(_RAD_LABELS),\n                _rad_np.float64,\n            ),\n            [\"none\"] * len(_RAD_LABELS),\n        )\n\n    ridge_gold = _v10_rank(\n        ridge_cross[\n            gold_index\n        ]\n    )\n    hgb_gold = _v10_rank(\n        hgb_cross[\n            gold_index\n        ]\n    )\n    blend_gold = _v10_rank(\n        0.68 * ridge_gold\n        + 0.32 * hgb_gold\n    )\n\n    candidate_gold = {\n        \"ridge\": ridge_gold,\n        \"hgb\": hgb_gold,\n        \"blend\": blend_gold,\n    }\n\n    deployment = _rad_np.zeros(\n        len(_RAD_LABELS),\n        _rad_np.float64,\n    )\n    chosen_model = [\n        \"none\"\n        for _ in _RAD_LABELS\n    ]\n\n    grid = _rad_np.asarray(\n        [\n            0.05,\n            0.10,\n            0.15,\n            0.20,\n            0.25,\n            0.30,\n            0.35,\n        ],\n        _rad_np.float64,\n    )\n\n    for target in range(\n        len(_RAD_LABELS)\n    ):\n        truth = gold_y[\n            :, target\n        ]\n        base = v10_gold[\n            :, target\n        ]\n\n        base_auc = _v10_target_auc(\n            truth,\n            base,\n        )\n        if not _rad_np.isfinite(\n            base_auc\n        ):\n            continue\n\n        best = None\n\n        for model_name, matrix in (\n            candidate_gold.items()\n        ):\n            for mix in grid:\n                candidate = (\n                    (1.0 - mix)\n                    * base\n                    + mix\n                    * matrix[\n                        :, target\n                    ]\n                )\n\n                auc = _v10_target_auc(\n                    truth,\n                    candidate,\n                )\n                if not _rad_np.isfinite(\n                    auc\n                ):\n                    continue\n\n                support = (\n                    _v10_bootstrap_positive_fraction(\n                        truth,\n                        base,\n                        candidate,\n                        seed=2111\n                        + 97 * target\n                        + int(\n                            100 * mix\n                        ),\n                        repeats=280,\n                    )\n                )\n\n                (\n                    valid_folds,\n                    positive_fraction,\n                    median_fold_gain,\n                ) = _v11_fold_consistency(\n                    truth,\n                    base,\n                    candidate,\n                    gold_fold,\n                )\n\n                # Penalize nonlinear complexity and large deployment votes.\n                complexity = (\n                    0.0008\n                    if model_name == \"hgb\"\n                    else (\n                        0.0004\n                        if model_name == \"blend\"\n                        else 0.0\n                    )\n                )\n                objective = (\n                    auc\n                    - 0.0022\n                    * float(mix)\n                    - complexity\n                )\n\n                record = {\n                    \"model\": model_name,\n                    \"mix\": float(mix),\n                    \"auc\": float(auc),\n                    \"gain\": float(\n                        auc - base_auc\n                    ),\n                    \"support\": float(\n                        support\n                    ),\n                    \"valid_folds\": int(\n                        valid_folds\n                    ),\n                    \"fold_positive\": float(\n                        positive_fraction\n                    ),\n                    \"fold_median\": float(\n                        median_fold_gain\n                    ),\n                    \"objective\": float(\n                        objective\n                    ),\n                }\n\n                if (\n                    best is None\n                    or record[\"objective\"]\n                    > best[\"objective\"]\n                ):\n                    best = record\n\n        if best is None:\n            continue\n\n        # Strong gate against 58-study overfitting.\n        fold_ok = (\n            best[\"valid_folds\"] < 2\n            or best[\"fold_positive\"]\n            >= 0.60\n        )\n\n        strong = (\n            best[\"gain\"] >= 0.005\n            and best[\"support\"] >= 0.62\n            and fold_ok\n        )\n        moderate = (\n            best[\"gain\"] >= 0.0025\n            and best[\"support\"] >= 0.59\n            and fold_ok\n        )\n\n        if strong:\n            deployment[target] = min(\n                best[\"mix\"],\n                0.30,\n            )\n            chosen_model[target] = (\n                best[\"model\"]\n            )\n        elif moderate:\n            deployment[target] = min(\n                best[\"mix\"],\n                0.12,\n            )\n            chosen_model[target] = (\n                best[\"model\"]\n            )\n\n    chosen_gold = _rad_np.zeros_like(\n        v10_gold,\n        dtype=_rad_np.float64,\n    )\n\n    for target in range(\n        len(_RAD_LABELS)\n    ):\n        model_name = chosen_model[target]\n        if model_name == \"none\":\n            chosen_gold[:, target] = v10_gold[:, target]\n        else:\n            chosen_gold[:, target] = candidate_gold[\n                model_name\n            ][:, target]\n\n    v11_gold = _v10_rank(\n        (\n            1.0\n            - deployment\n        )[None, :]\n        * v10_gold\n        + deployment[None, :]\n        * chosen_gold\n    )\n\n    globals()[\"V13_V11_GOLD_CONTEXT\"] = {\n        \"gold_index\": gold_index.copy(),\n        \"gold_y\": gold_y.copy(),\n        \"gold_fold\": gold_fold.copy(),\n        \"v11_gold\": v11_gold.copy(),\n        \"deployment\": deployment.copy(),\n        \"model\": list(chosen_model),\n    }\n\n    if not (\n        deployment > 0\n    ).any():\n        return (\n            None,\n            deployment,\n            chosen_model,\n        )\n\n    full_graph = _v11_label_graph(\n        y\n    )\n    x_train = _v11_design(\n        data[\"base\"],\n        data[\"public\"],\n        data[\"pass2\"],\n        train_protocol,\n        train_demographics,\n        full_graph,\n    )\n    x_test = _v11_design(\n        test_base,\n        test_public,\n        test_pass2,\n        test_protocol,\n        test_demographics,\n        full_graph,\n    )\n\n    challenger = _rad_np.zeros(\n        (\n            len(test_ids),\n            len(_RAD_LABELS),\n        ),\n        _rad_np.float64,\n    )\n\n    for target in range(\n        len(_RAD_LABELS)\n    ):\n        model_name = chosen_model[\n            target\n        ]\n\n        if model_name == \"none\":\n            # Value is irrelevant because deployment is zero.\n            challenger[\n                :, target\n            ] = test_base[\n                :, target\n            ]\n            continue\n\n        target_y = y[\n            :, target\n        ]\n        weight = weak_conf[\n            :, target\n        ].copy()\n        weight[gold] = 18.0\n\n        ridge = _v10_fit_ridge(\n            x_train,\n            target_y,\n            weight,\n            alpha=20.0,\n        )\n        ridge_test = _v10_predict_ridge(\n            ridge,\n            x_test,\n        )\n\n        if model_name == \"ridge\":\n            challenger[\n                :, target\n            ] = ridge_test\n            continue\n\n        try:\n            hgb = _v11_fit_hgb(\n                x_train,\n                target_y,\n                weight,\n                seed=4171 + target,\n            )\n            hgb_test = hgb.predict(\n                x_test\n            )\n        except Exception:\n            hgb_test = ridge_test\n\n        if model_name == \"hgb\":\n            challenger[\n                :, target\n            ] = hgb_test\n        else:\n            # Same fixed mixture used for cross-fitted validation.\n            challenger[\n                :, target\n            ] = (\n                0.68 * ridge_test\n                + 0.32 * hgb_test\n            )\n\n    return (\n        _v10_rank(\n            challenger\n        ),\n        deployment,\n        chosen_model,\n    )\n\n\n\ndef _rad_main_v13_anchor():\n    work = _RadPath(\"/kaggle/working\")\n    primary = work / \"submission.csv\"\n\n    test = _rad_pd.read_csv(\n        ROOT / \"test.csv\",\n        dtype={\"StudyInstanceUID\": str},\n    )\n    expected_ids = test.StudyInstanceUID.astype(str).tolist()\n\n    baseline = _rad_pd.read_csv(\n        primary,\n        dtype={\"StudyInstanceUID\": str},\n    )\n    _rad_validate(baseline, expected_ids)\n\n    device = _rad_torch.device(\"cuda:0\")\n\n    test_series = _rad_pd.read_csv(\n        ROOT / \"test_series.csv\",\n        dtype={\n            \"StudyInstanceUID\": str,\n            \"SeriesInstanceUID\": str,\n        },\n    )\n    plane = dict(\n        zip(\n            test_series.SeriesInstanceUID,\n            test_series.Anatomical_Plane,\n        )\n    )\n\n    def cache(slots, crop, tag, threshold):\n        globals().update(\n            SLOTS=list(slots),\n            N_SLOT=len(slots),\n            CACHE_SLICES=8,\n            IMG=224,\n            CACHE_IMG=224,\n            CROP_MM=float(crop),\n            RULES=dict(RULES_LEGACY),\n        )\n\n        headers = annotate(walk(\"test_series\"))\n        studies, pixels, masks = build_cache(\n            pick_slots(headers, plane),\n            plane,\n            lat_of(headers, tag + \" \"),\n            tag,\n        )\n\n        positions = {\n            str(uid): index\n            for index, uid in enumerate(studies)\n        }\n        missing = [\n            uid\n            for uid in expected_ids\n            if uid not in positions\n        ]\n        if missing:\n            raise RuntimeError(\n                f\"{len(missing)} studies absent from {tag}\"\n            )\n\n        order = _rad_np.asarray(\n            [positions[uid] for uid in expected_ids],\n            dtype=_rad_np.int64,\n        )\n        pixels = pixels[order]\n        masks = masks[order]\n\n        tokens = int(\n            _rad_np.repeat(\n                masks[:, :, None],\n                CACHE_SLICES,\n                axis=2,\n            ).sum()\n        )\n\n        if tokens < int(\n            threshold\n            * len(test)\n            * N_SLOT\n            * CACHE_SLICES\n        ):\n            raise RuntimeError(\n                f\"insufficient slices for {tag}: {tokens}\"\n            )\n\n        return pixels, masks\n\n    encoder_path = _rad_find_file(\n        \"ResNet50.pt\",\n        _RAD_ENCODER_SHA256,\n    )\n    encoder = _RadEncoder()\n    encoder.load_state_dict(\n        _rad_torch.load(\n            encoder_path,\n            map_location=\"cpu\",\n            weights_only=True,\n        ),\n        strict=True,\n    )\n    encoder.eval().to(device)\n\n    for parameter in encoder.parameters():\n        parameter.requires_grad_(False)\n\n    if _rad_torch.cuda.device_count() > 1:\n        encoder = _rad_nn.DataParallel(\n            encoder,\n            device_ids=list(range(_rad_torch.cuda.device_count())),\n        )\n\n    public_slots = [\n        (\"SAG_FS\", \"Sagittal\", None, True),\n        (\"COR_FS\", \"Coronal\", None, True),\n        (\"AX_FS\", \"Axial\", None, True),\n    ]\n\n    pixels, masks = cache(\n        public_slots,\n        10000.0,\n        \"test-v11-public\",\n        0.85,\n    )\n\n    public_heads, public_path = _rad_load_public_heads(\n        device,\n        _RAD_REFERENCE_HEADS_SHA256,\n    )\n\n    features, token_mask = _rad_encode(\n        encoder,\n        pixels,\n        masks,\n        device,\n    )\n\n    public_predictions = [\n        _rad_predict_head(\n            head,\n            features,\n            token_mask,\n            device,\n        )\n        for head in public_heads\n    ]\n\n    (\n        public_probability_rank,\n        public_consensus,\n        public_stability,\n    ) = _v8_consensus(public_predictions)\n\n    del public_heads, features, token_mask, pixels, masks\n    _rad_gc.collect()\n    _rad_torch.cuda.empty_cache()\n\n    globals().update(\n        SLOTS=list(_RAD_E13_SLOTS),\n        N_SLOT=len(_RAD_E13_SLOTS),\n        CACHE_SLICES=_RAD_E13_CACHE_SLICES,\n        IMG=_RAD_E13_IMG,\n        CACHE_IMG=_RAD_E13_IMG,\n        CROP_MM=_RAD_E13_CROP_MM,\n        RULES=dict(RULES_LEGACY),\n    )\n\n    e13_heads, e13_path = _rad_load_e13_heads(device)\n\n    pixels, masks = cache(\n        _RAD_E13_SLOTS,\n        _RAD_E13_CROP_MM,\n        \"test-v11-e13\",\n        0.85,\n    )\n\n    features, token_mask = _rad_encode(\n        encoder,\n        pixels,\n        masks,\n        device,\n    )\n\n    e13_predictions = [\n        _rad_predict_head(\n            head,\n            features,\n            token_mask,\n            device,\n        )\n        for head in e13_heads\n    ]\n\n    (\n        e13_probability_rank,\n        e13_consensus,\n        e13_stability,\n    ) = _v8_consensus(e13_predictions)\n\n    del features, token_mask, pixels, masks\n    _rad_gc.collect()\n    _rad_torch.cuda.empty_cache()\n\n    public_metric = _v8_bundle_metrics(_RadPath(public_path))\n    e13_metric = _v8_bundle_metrics(_RadPath(e13_path))\n\n    public_oof = _v8_discover_oof_auc(\"public\")\n    e13_oof = _v8_discover_oof_auc(\"e13\")\n\n    if public_oof is not None and e13_oof is not None:\n        diff = _rad_np.nan_to_num(\n            e13_oof - public_oof,\n            nan=0.0,\n        )\n        e13_weight = _rad_np.clip(\n            0.50 + 0.55 * diff,\n            0.42,\n            0.58,\n        )\n    elif public_metric is not None and e13_metric is not None:\n        diff = _rad_np.nan_to_num(\n            e13_metric - public_metric,\n            nan=0.0,\n        )\n        e13_weight = _rad_np.clip(\n            0.50 + 0.45 * diff,\n            0.43,\n            0.57,\n        )\n    else:\n        relative = (\n            _v8_robust_z(e13_stability, floor=0.02)\n            - _v8_robust_z(public_stability, floor=0.02)\n        )\n        e13_weight = _rad_np.clip(\n            0.50 + 0.025 * _rad_np.tanh(relative),\n            0.465,\n            0.535,\n        )\n\n    reference_adaptive = _rad_rank_columns(\n        (1.0 - e13_weight)[None, :] * public_consensus\n        + e13_weight[None, :] * e13_consensus\n    )\n\n    reference_exact = _rad_rank_columns(\n        (1.0 - _RAD_E13_MEMBER_WEIGHT) * public_probability_rank\n        + _RAD_E13_MEMBER_WEIGHT * e13_probability_rank\n    )\n\n    baseline_rank = _rad_rank_columns(\n        baseline[_RAD_LABELS].to_numpy()\n    )\n    parent_specialist = _v8_parent_specialist(baseline_rank)\n\n    exact_e10 = baseline_rank.copy()\n    for index, target in enumerate(_RAD_LABELS):\n        if target not in _RAD_EXCLUDE:\n            exact_e10[:, index] = (\n                (1.0 - _RAD_ALPHA) * baseline_rank[:, index]\n                + _RAD_ALPHA * reference_exact[:, index]\n            )\n    exact_e10_rank = _rad_rank_columns(exact_e10)\n\n    adaptive_e10 = parent_specialist.copy()\n\n    ref_quality = _rad_np.maximum(\n        public_stability,\n        e13_stability,\n    )\n    ref_z = _v8_robust_z(ref_quality, floor=0.02)\n    e10_alpha = _rad_np.clip(\n        0.50 + 0.025 * _rad_np.tanh(ref_z),\n        0.47,\n        0.53,\n    )\n\n    for index, target in enumerate(_RAD_LABELS):\n        if target not in _RAD_EXCLUDE:\n            adaptive_e10[:, index] = (\n                (1.0 - e10_alpha[index]) * parent_specialist[:, index]\n                + e10_alpha[index] * reference_adaptive[:, index]\n            )\n\n    adaptive_e10_rank = _rad_rank_columns(adaptive_e10)\n\n    pixels, masks = cache(\n        _RAD_E11_SLOTS,\n        _RAD_E11_CROP_MM,\n        \"test-v11-pass2\",\n        0.55,\n    )\n\n    features, token_mask = _rad_encode(\n        encoder,\n        pixels,\n        masks,\n        device,\n    )\n\n    pass2_predictions = [\n        _rad_predict_head(\n            head,\n            features,\n            token_mask,\n            device,\n        )\n        for head in e13_heads\n    ]\n\n    (\n        pass2_probability_rank,\n        pass2_consensus,\n        pass2_stability,\n    ) = _v8_consensus(pass2_predictions)\n\n    pass2_z = _v8_robust_z(pass2_stability, floor=0.02)\n\n    diversity = _rad_np.zeros(\n        len(_RAD_LABELS),\n        _rad_np.float64,\n    )\n\n    for j in range(len(_RAD_LABELS)):\n        x = pass2_consensus[:, j]\n        y = adaptive_e10_rank[:, j]\n        corr = (\n            float(_rad_np.corrcoef(x, y)[0, 1])\n            if _rad_np.std(x) > 0 and _rad_np.std(y) > 0\n            else 1.0\n        )\n        diversity[j] = 1.0 - abs(corr)\n\n    diversity_z = _v8_robust_z(diversity, floor=0.01)\n\n    pass2_alpha = _rad_np.clip(\n        _RAD_V48_SECOND_ALPHA\n        + 0.022 * _rad_np.tanh(pass2_z)\n        + 0.010 * _rad_np.tanh(diversity_z),\n        0.105,\n        0.205,\n    )\n\n    priors = {\n        \"ACL\": 0.020,\n        \"MCL\": -0.010,\n        \"Medial Meniscus\": 0.005,\n        \"Lateral Meniscus\": 0.005,\n        \"Medial OA\": 0.020,\n        \"Lateral OA\": 0.020,\n        \"PF OA\": 0.010,\n        \"Effusion\": -0.020,\n        \"Synovitis\": -0.015,\n        \"Baker's\": 0.000,\n        \"Contusion\": -0.010,\n        \"Fracture\": 0.020,\n    }\n\n    for j, target in enumerate(_RAD_LABELS):\n        pass2_alpha[j] = float(\n            _rad_np.clip(\n                pass2_alpha[j] + priors.get(target, 0.0),\n                0.095,\n                0.215,\n            )\n        )\n\n    exact_final = _rad_rank_columns(\n        (1.0 - _RAD_V48_SECOND_ALPHA) * exact_e10_rank\n        + _RAD_V48_SECOND_ALPHA * pass2_probability_rank\n    )\n\n    adaptive_final = _rad_rank_columns(\n        (1.0 - pass2_alpha)[None, :] * adaptive_e10_rank\n        + pass2_alpha[None, :] * pass2_consensus\n    )\n\n    # V8 is the measured high-performing anchor.\n    v8_anchor = _rad_rank_columns(\n        0.65 * exact_final\n        + 0.35 * adaptive_final\n    )\n\n    # New trained ensemble layer. It uses only genuine OOF train\n    # predictions for fitting and cross-fitted official labels for\n    # deciding whether each target is allowed to change at all.\n    meta_rank, meta_weight = _v10_meta_stack(\n        test_base=baseline_rank,\n        test_public=public_probability_rank,\n        test_pass2=pass2_probability_rank,\n        test_ids=expected_ids,\n    )\n\n    if meta_rank is None:\n        v10_anchor = v8_anchor\n    else:\n        v10_anchor = _rad_rank_columns(\n            (\n                1.0\n                - meta_weight\n            )[None, :]\n            * v8_anchor\n            + meta_weight[None, :]\n            * meta_rank\n        )\n\n    # V11 is a challenger above the measured 0.921 V10 route.\n    # If its evidence is not strong enough, final_rank remains V10 exactly.\n    (\n        v11_rank,\n        v11_weight,\n        v11_model,\n    ) = _v11_meta_challenger(\n        test_base=baseline_rank,\n        test_public=public_probability_rank,\n        test_pass2=pass2_probability_rank,\n        test_ids=expected_ids,\n    )\n\n    if v11_rank is None:\n        final_rank = v10_anchor\n    else:\n        final_rank = _rad_rank_columns(\n            (\n                1.0\n                - v11_weight\n            )[None, :]\n            * v10_anchor\n            + v11_weight[None, :]\n            * v11_rank\n        )\n\n    final = baseline.copy()\n    final[_RAD_LABELS] = final_rank\n\n    _rad_validate(final, expected_ids)\n    final.to_csv(primary, index=False)\n\n    for candidate in work.glob(\"submission*.csv\"):\n        if candidate.name != \"submission.csv\":\n            try:\n                candidate.unlink()\n            except OSError:\n                pass\n\n    for candidate in work.glob(\"*diagnostics*.csv\"):\n        try:\n            candidate.unlink()\n        except OSError:\n            pass\n\n    del (\n        encoder,\n        e13_heads,\n        features,\n        token_mask,\n        pixels,\n        masks,\n        public_predictions,\n        e13_predictions,\n        pass2_predictions,\n    )\n    _rad_gc.collect()\n    _rad_torch.cuda.empty_cache()\n\n\n_rad_main_v13_anchor()\n","metadata":{},"outputs":[],"execution_count":null},{"id":"be906de4-693e-44f9-a163-649cd9b4a7b5","cell_type":"code","source":"import base64\nimport gc\nimport hashlib\nimport io\nimport json\nimport math\nimport os\nimport random\nimport time\nimport zlib\nfrom concurrent.futures import ThreadPoolExecutor\nfrom functools import lru_cache\nfrom pathlib import Path\nimport cv2\nimport joblib\nimport numpy as np\nimport pandas as pd\nimport pydicom\nfrom scipy.stats import rankdata\nfrom sklearn.ensemble import ExtraTreesClassifier, HistGradientBoostingClassifier\nfrom sklearn.decomposition import PCA\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.pipeline import make_pipeline\nfrom sklearn.preprocessing import StandardScaler\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom transformers import AutoModel\nHYB_PREFIX = 'v8_hybrid_dino224_6slot_5pos_radiomics'\nHYB_EXPECTED_TRAIN_ID_SHA256 = '21c1944bd15c3397290f0816de614ad4153f62e84c4bfb0e4d6147ac72084af8'\nHYB_TEACHER_PAYLOAD = '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'\nHYB_START_CUTOFF_S = 7.2 * 3600\nHYB_DEADLINE_S = 8.72 * 3600\nHYB_IMG_SIZE = 224\nHYB_N_POSITIONS = 5\nHYB_N_SLOTS = 6\nHYB_SLOT_META_DIM = 8\nHYB_STUDY_META_DIM = 13\nHYB_RAD_DIM = 14\nHYB_RAD_AGG_DIM = 56\nHYB_SEEDS = (20260809, 20260810, 20260811, 20260814, 20260815, 20260816, 20260817, 20260818)\nHYB_LM_FAMILY_WEIGHTS = (0.5227272727272728, 0.27272727272727276, 0.20454545454545456, 0.0)\nHYB_FAMILIES = ('lr', 'et', 'hgb', 'exact_lr')\nHYB_FAMILY_WEIGHTS = (0.46, 0.24, 0.18, 0.12)\nHYB_LR_CS = (0.015, 0.05, 0.16, 0.5)\nHYB_EXACT_LR_CS = (0.01, 0.03, 0.1, 0.3)\nHYB_TARGET = 'Lateral Meniscus'\nHYB_OA_TARGET = 'Lateral OA'\nHYB_OA_SEEDS = (20260809, 20260810, 20260811, 20260812, 20260813, 20260814, 20260815, 20260816, 20260817, 20260818)\nHYB_OA_FAMILY_WEIGHTS = (0.5227272727272728, 0.27272727272727276, 0.20454545454545456, 0.0)\nHYB_PLANES = ('Sagittal', 'Coronal', 'Axial')\nHYB_CONTRASTS = ('Fluid', 'Structural')\nHYB_SLOT_NAMES = tuple((f'{plane}_{contrast}' for plane in HYB_PLANES for contrast in HYB_CONTRASTS))\n\ndef _hyb_required_cache_names():\n    names = []\n    for split in ('train', 'test'):\n        stem = f'{split}_{HYB_PREFIX}_'\n        names.extend((stem + suffix for suffix in ('slot_features.npy', 'slot_mask.npy', 'slot_meta.npy', 'radiomics.npy', 'study_meta.npy', 'sex.npy', 'ids.npy')))\n    names.append(f'{HYB_PREFIX}_ipca_192.joblib')\n    return names\n\ndef _hyb_find_cache_dir():\n    local = globals().get('HYB_LOCAL_CACHE_DIR')\n    candidates = []\n    if local:\n        candidates.append(Path(local))\n    root = Path('/kaggle/input')\n    if root.is_dir():\n        marker = f'train_{HYB_PREFIX}_slot_features.npy'\n        candidates.extend((hit.parent for hit in root.glob(f'*/{marker}')))\n        candidates.extend((hit.parent for hit in root.glob(f'*/*/{marker}')))\n    required = _hyb_required_cache_names()\n    for path in candidates:\n        if all(((path / name).is_file() for name in required)):\n            return path\n    raise FileNotFoundError('the complete public hybrid feature/PCA cache is absent')\n\ndef _hyb_find_dino_small():\n    preferred = (Path('/kaggle/input/models/metaresearch/dinov2/pytorch/small/1'), Path('/kaggle/input/dinov2/pytorch/small/1'), Path('/kaggle/input/dinov2-small/pytorch/small/1'))\n    for path in preferred:\n        if (path / 'config.json').is_file():\n            return path\n    for top in Path('/kaggle/input').glob('*'):\n        if not top.is_dir() or 'dino' not in top.name.lower():\n            continue\n        for config_path in top.glob('**/config.json'):\n            try:\n                cfg = json.loads(config_path.read_text())\n                if cfg.get('model_type') == 'dinov2' and int(cfg.get('hidden_size', -1)) == 384:\n                    return config_path.parent\n            except Exception:\n                continue\n    raise FileNotFoundError('offline DINOv2-small model is absent')\n\ndef _hyb_numeric(value, default=0.0):\n    try:\n        value = float(value)\n        return value if np.isfinite(value) else default\n    except Exception:\n        return default\n\ndef _hyb_sex_to_id(row):\n    value = str(row.get('PatientSex', '')).strip().lower()\n    if value.startswith('m'):\n        return 1\n    if value.startswith('f'):\n        return 2\n    return 0\n\ndef _hyb_choose_series(part, contrast, used_ids):\n    if len(part) == 0:\n        return None\n    fluid = part['Fluid_Sensitive'].fillna(0).astype(float)\n    fat = part['Fat_Suppression'].fillna(0).astype(float)\n    if contrast == 'Fluid':\n        score = 4.0 * fluid + 2.0 * fat\n    else:\n        score = 3.5 * (1.0 - fluid) + 1.5 * (1.0 - fat)\n    ordered = part.assign(_slot_score=score).sort_values('_slot_score', ascending=False)\n    for _, row in ordered.iterrows():\n        series_id = str(row['SeriesInstanceUID'])\n        if series_id not in used_ids:\n            return row\n    return ordered.iloc[0]\n\ndef _hyb_build_slots(series_df):\n    slots, study_meta = ({}, {})\n    for study_id, rows in series_df.groupby('StudyInstanceUID', sort=False):\n        study_id = str(study_id)\n        selected, meta = ({}, [])\n        plane_lower = rows['Anatomical_Plane'].astype(str).str.lower()\n        for plane in HYB_PLANES:\n            part = rows[plane_lower == plane.lower()]\n            count = len(part)\n            fluid_mean = part['Fluid_Sensitive'].fillna(0).astype(float).mean() if count else 0.0\n            fat_mean = part['Fat_Suppression'].fillna(0).astype(float).mean() if count else 0.0\n            meta.extend([np.log1p(count) / 3.0, fluid_mean, fat_mean])\n            used = set()\n            for contrast in HYB_CONTRASTS:\n                row = _hyb_choose_series(part, contrast, used)\n                if row is None:\n                    continue\n                sid = str(row['SeriesInstanceUID'])\n                used.add(sid)\n                selected[f'{plane}_{contrast}'] = {'series_id': sid, 'contrast': contrast, 'fluid': _hyb_numeric(row.get('Fluid_Sensitive', 0)), 'fat': _hyb_numeric(row.get('Fat_Suppression', 0))}\n        total = len(rows)\n        meta.extend([np.log1p(total) / 4.0, rows['Fluid_Sensitive'].fillna(0).astype(float).mean() if total else 0.0, rows['Fat_Suppression'].fillna(0).astype(float).mean() if total else 0.0, rows['SeriesInstanceUID'].nunique() / 12.0 if total else 0.0])\n        slots[study_id] = selected\n        study_meta[study_id] = np.asarray(meta, dtype=np.float32)\n    return (slots, study_meta)\n\ndef _hyb_locate_series_dir(study_uid, series_uid):\n    candidates = (ROOT / 'test_series' / str(study_uid) / str(series_uid), ROOT / 'test_series' / str(series_uid), ROOT / 'test' / str(study_uid) / str(series_uid), ROOT / 'test_images' / str(study_uid) / str(series_uid), ROOT / 'test_dicom' / str(study_uid) / str(series_uid), ROOT / 'test_dicoms' / str(study_uid) / str(series_uid), ROOT / 'images' / 'test' / str(study_uid) / str(series_uid))\n    for path in candidates:\n        if path.is_dir():\n            return path\n    raise FileNotFoundError(f'hybrid series missing: study={study_uid}, series={series_uid}')\n\ndef _hyb_read_header(path):\n    try:\n        return pydicom.dcmread(str(path), stop_before_pixels=True, force=True)\n    except Exception:\n        return None\n\ndef _hyb_header_position(ds):\n    if ds is None:\n        return None\n    try:\n        ipp = np.asarray([float(x) for x in ds.ImagePositionPatient], dtype=np.float64)\n        iop = np.asarray([float(x) for x in ds.ImageOrientationPatient], dtype=np.float64)\n        return float(np.dot(ipp, np.cross(iop[:3], iop[3:])))\n    except Exception:\n        pass\n    for name in ('SliceLocation', 'InstanceNumber'):\n        try:\n            return float(getattr(ds, name))\n        except Exception:\n            continue\n    return None\n\n@lru_cache(maxsize=8192)\ndef _hyb_ordered_files(folder_str):\n    files = sorted(Path(folder_str).glob('*.dcm'))\n    if not files:\n        files = sorted((path for path in Path(folder_str).iterdir() if path.is_file()))\n    keyed, ok = ([], 0)\n    for fallback, path in enumerate(files):\n        key = _hyb_header_position(_hyb_read_header(path))\n        if key is None:\n            key = fallback\n        else:\n            ok += 1\n        keyed.append((key, str(path)))\n    if ok >= max(3, len(files) // 3):\n        keyed.sort(key=lambda pair: pair[0])\n    return tuple((path for _, path in keyed))\n\ndef _hyb_spacing(ds):\n    spacing_x = spacing_y = thickness = 0.0\n    try:\n        ps = [float(x) for x in ds.PixelSpacing]\n        spacing_y, spacing_x = (ps[0], ps[1])\n    except Exception:\n        pass\n    for name in ('SliceThickness', 'SpacingBetweenSlices'):\n        try:\n            thickness = float(getattr(ds, name))\n            break\n        except Exception:\n            continue\n    return (spacing_x, spacing_y, thickness)\n\ndef _hyb_read_pixel(path):\n    ds = pydicom.dcmread(str(path), force=True)\n    array = ds.pixel_array.astype(np.float32)\n    array = array * _hyb_numeric(getattr(ds, 'RescaleSlope', 1.0), 1.0)\n    array += _hyb_numeric(getattr(ds, 'RescaleIntercept', 0.0), 0.0)\n    if str(getattr(ds, 'PhotometricInterpretation', '')).upper() == 'MONOCHROME1':\n        array = array.max() - array\n    return (array, ds)\n\ndef _hyb_robust_uint8(stack):\n    stack = np.asarray(stack, dtype=np.float32)\n    finite = stack[np.isfinite(stack)]\n    if finite.size == 0:\n        return np.zeros(stack.shape, dtype=np.uint8)\n    low, high = np.percentile(finite, [1.0, 99.4])\n    if high <= low:\n        low, high = (float(finite.min()), float(finite.max()))\n    if high <= low:\n        return np.zeros(stack.shape, dtype=np.uint8)\n    return (255.0 * np.clip((stack - low) / (high - low), 0.0, 1.0)).astype(np.uint8)\n\ndef _hyb_crop_foreground(image):\n    gray = image.max(axis=2)\n    mask = gray > max(8, np.percentile(gray, 55) * 0.18)\n    if mask.sum() < 64:\n        return image\n    ys, xs = np.where(mask)\n    y0, y1, x0, x1 = (int(ys.min()), int(ys.max()) + 1, int(xs.min()), int(xs.max()) + 1)\n    pad_y, pad_x = (int(0.08 * (y1 - y0 + 1)), int(0.08 * (x1 - x0 + 1)))\n    y0, y1 = (max(0, y0 - pad_y), min(image.shape[0], y1 + pad_y))\n    x0, x1 = (max(0, x0 - pad_x), min(image.shape[1], x1 + pad_x))\n    if y1 - y0 < 32 or x1 - x0 < 32:\n        return image\n    return image[y0:y1, x0:x1]\n\ndef _hyb_resize(image):\n    return cv2.resize(image, (HYB_IMG_SIZE, HYB_IMG_SIZE), interpolation=cv2.INTER_AREA)\n\ndef _hyb_view_radiomics(image):\n    gray = image.astype(np.float32).mean(axis=2) / 255.0\n    height, width = gray.shape\n    q = np.percentile(gray, [1, 5, 10, 25, 50, 75, 90, 95, 99])\n    center = gray[height // 4:3 * height // 4, width // 4:3 * width // 4]\n    gy, gx = np.gradient(gray)\n    grad = np.sqrt(gx * gx + gy * gy)\n    foreground = gray > 0.08\n    return np.asarray([gray.mean(), gray.std(), q[0], q[2], q[4], q[6], q[8], center.mean(), center.std(), grad.mean(), grad.std(), foreground.mean(), gray[foreground].mean() if foreground.any() else 0.0, gray[foreground].std() if foreground.any() else 0.0], dtype=np.float32)\n\ndef _hyb_make_view(paths):\n    arrays, first_ds = ([], None)\n    for path in paths:\n        try:\n            array, ds = _hyb_read_pixel(path)\n            first_ds = ds if first_ds is None else first_ds\n            arrays.append(array)\n        except Exception:\n            return (None, np.zeros(HYB_RAD_DIM, np.float32), (0.0, 0.0, 0.0))\n    image = np.transpose(_hyb_robust_uint8(np.stack(arrays)), (1, 2, 0))\n    image = _hyb_resize(_hyb_crop_foreground(image))\n    return (np.transpose(image, (2, 0, 1)), _hyb_view_radiomics(image), _hyb_spacing(first_ds) if first_ds is not None else (0.0, 0.0, 0.0))\n\ndef _hyb_sampled_triplets(study_uid, series_uid):\n    files = list(_hyb_ordered_files(str(_hyb_locate_series_dir(study_uid, series_uid))))\n    if not files:\n        return ([], 0)\n    centers = np.round(np.linspace(0.08 * (len(files) - 1), 0.92 * (len(files) - 1), HYB_N_POSITIONS)).astype(int)\n    centers = np.clip(centers, 0, len(files) - 1)\n    return ([[files[max(0, center - 1)], files[center], files[min(len(files) - 1, center + 1)]] for center in centers], len(files))\n\ndef _hyb_load_study(row, slots, study_meta):\n    study_uid = str(row['StudyInstanceUID'])\n    images = np.zeros((6, 5, 3, 224, 224), np.uint8)\n    view_mask = np.zeros((6, 5), bool)\n    slot_meta = np.zeros((6, 8), np.float32)\n    radiomics = np.zeros((6, 56), np.float32)\n    selected = slots.get(study_uid, {})\n    for slot_index, slot_name in enumerate(HYB_SLOT_NAMES):\n        info = selected.get(slot_name)\n        if info is None:\n            continue\n        triplets, n_files = _hyb_sampled_triplets(study_uid, info['series_id'])\n        rad_values, spacings = ([], [])\n        for pos_index, paths in enumerate(triplets[:5]):\n            image, rad, spacing = _hyb_make_view(paths)\n            if image is None:\n                continue\n            images[slot_index, pos_index] = image\n            view_mask[slot_index, pos_index] = True\n            rad_values.append(rad)\n            spacings.append(spacing)\n        if rad_values:\n            rad_array = np.stack(rad_values).astype(np.float32)\n            radiomics[slot_index] = np.concatenate([rad_array.mean(0), rad_array.std(0), rad_array.min(0), rad_array.max(0)])\n            spacing_mean = np.asarray(spacings, np.float32).mean(0)\n        else:\n            spacing_mean = np.zeros(3, np.float32)\n        slot_meta[slot_index] = np.asarray([info['fluid'], info['fat'], float(info['contrast'] == 'Structural'), np.log1p(n_files) / 6.0, float(view_mask[slot_index].mean()), spacing_mean[0] / 2.5 if spacing_mean[0] else 0.0, spacing_mean[1] / 2.5 if spacing_mean[1] else 0.0, spacing_mean[2] / 8.0 if spacing_mean[2] else 0.0], np.float32)\n    return (images, view_mask, slot_meta, radiomics, study_meta.get(study_uid, np.zeros(13, np.float32)), _hyb_sex_to_id(row), study_uid)\n\nclass _HybridDinoEncoder(nn.Module):\n\n    def __init__(self, backbone):\n        super().__init__()\n        self.backbone = backbone\n\n    def forward(self, pixel_values):\n        tokens = self.backbone(pixel_values=pixel_values).last_hidden_state\n        patches = tokens[:, 1:]\n        return torch.cat([F.normalize(tokens[:, 0], dim=1), F.normalize(patches.mean(dim=1), dim=1), F.normalize(patches.amax(dim=1), dim=1)], dim=1)\n\ndef _hyb_load_cached_split(cache_dir, split):\n    stem = f'{split}_{HYB_PREFIX}_'\n    return tuple((np.load(cache_dir / (stem + suffix), mmap_mode=None if suffix == 'ids.npy' else 'r', allow_pickle=suffix == 'ids.npy') for suffix in ('slot_features.npy', 'slot_mask.npy', 'slot_meta.npy', 'radiomics.npy', 'study_meta.npy', 'sex.npy', 'ids.npy')))\n\ndef _hyb_extract_test_bundle(test_df, series_df, cache_dir, dev):\n    expected_uids = test_df['StudyInstanceUID'].astype(str).to_numpy()\n    cached = _hyb_load_cached_split(cache_dir, 'test')\n    if np.array_equal(np.asarray(cached[-1]).astype(str), expected_uids):\n        log('hybrid: exact attached visible-test features reused')\n        return cached\n    if time.time() - T0 > HYB_START_CUTOFF_S:\n        raise TimeoutError('insufficient runtime reserve for hybrid feature extraction')\n    slots, study_meta = _hyb_build_slots(series_df)\n    backbone = AutoModel.from_pretrained(str(_hyb_find_dino_small()), local_files_only=True, trust_remote_code=False)\n    if int(backbone.config.hidden_size) != 384:\n        raise AssertionError('the hybrid specialist requires DINOv2-small hidden size 384')\n    model = _HybridDinoEncoder(backbone).eval().to(dev)\n    for parameter in model.parameters():\n        parameter.requires_grad_(False)\n    mean = torch.tensor([0.485, 0.456, 0.406], device=dev).view(1, 3, 1, 1)\n    std = torch.tensor([0.229, 0.224, 0.225], device=dev).view(1, 3, 1, 1)\n\n    @torch.inference_mode()\n    def encode(images):\n        outputs = []\n        for start in range(0, len(images), 64):\n            batch = images[start:start + 64].to(dev, non_blocking=True).float().div_(255.0)\n            batch = (batch - mean) / std\n            with torch.autocast('cuda', dtype=torch.float16, enabled=dev.type == 'cuda'):\n                outputs.append(model(batch).float().cpu())\n        return torch.cat(outputs, dim=0)\n    n = len(test_df)\n    features = np.zeros((n, 6, 3456), np.float16)\n    masks = np.zeros((n, 6), bool)\n    slot_meta_array = np.zeros((n, 6, 8), np.float16)\n    radiomics_array = np.zeros((n, 6, 56), np.float16)\n    study_meta_array = np.zeros((n, 13), np.float16)\n    sexes = np.zeros(n, np.int8)\n    ids = expected_uids.astype(object)\n\n    def safe_load(index):\n        try:\n            return _hyb_load_study(test_df.iloc[index], slots, study_meta)\n        except Exception as exc:\n            uid = str(test_df.iloc[index]['StudyInstanceUID'])\n            log(f'hybrid study decode failed safely: {uid}: {exc}')\n            return (np.zeros((6, 5, 3, 224, 224), np.uint8), np.zeros((6, 5), bool), np.zeros((6, 8), np.float32), np.zeros((6, 56), np.float32), np.zeros(13, np.float32), 0, uid)\n    workers = max(1, min(8, os.cpu_count() or 8))\n    with ThreadPoolExecutor(max_workers=workers) as executor:\n        for start in range(0, n, 6):\n            if time.time() - T0 > HYB_DEADLINE_S:\n                raise TimeoutError('hybrid deadline reached during feature extraction')\n            stop = min(start + 6, n)\n            items = list(executor.map(safe_load, range(start, stop)))\n            image_batch = torch.from_numpy(np.stack([item[0] for item in items]))\n            view_mask = torch.from_numpy(np.stack([item[1] for item in items]))\n            valid = view_mask.reshape(-1)\n            view_features = torch.zeros(len(items) * 30, 1152, dtype=torch.float32)\n            if valid.any():\n                flat_images = image_batch.reshape(-1, 3, 224, 224)\n                view_features[valid] = encode(flat_images[valid])\n            view_features = view_features.reshape(len(items), 6, 5, 1152)\n            aggregate = torch.zeros(len(items), 6, 3456, dtype=torch.float32)\n            slot_mask = view_mask.any(dim=2)\n            for batch_index in range(len(items)):\n                for slot_index in range(6):\n                    present = view_mask[batch_index, slot_index]\n                    if present.any():\n                        values = view_features[batch_index, slot_index, present]\n                        aggregate[batch_index, slot_index] = torch.cat([values.mean(0), values.amax(0), values.std(0, unbiased=False)])\n            features[start:stop] = aggregate.numpy().astype(np.float16)\n            masks[start:stop] = slot_mask.numpy()\n            slot_meta_array[start:stop] = np.stack([item[2] for item in items]).astype(np.float16)\n            radiomics_array[start:stop] = np.stack([item[3] for item in items]).astype(np.float16)\n            study_meta_array[start:stop] = np.stack([item[4] for item in items]).astype(np.float16)\n            sexes[start:stop] = np.asarray([item[5] for item in items], np.int8)\n            if start == 0 or stop % 100 == 0 or stop == n:\n                log(f'hybrid features {stop}/{n}')\n    del model, backbone\n    gc.collect()\n    if dev.type == 'cuda':\n        torch.cuda.empty_cache()\n    return (features, masks, slot_meta_array, radiomics_array, study_meta_array, sexes, ids)\n\ndef _hyb_align_bundle(bundle, expected_uids):\n    ids = np.asarray(bundle[-1]).astype(str)\n    expected_uids = np.asarray(expected_uids).astype(str)\n    if np.array_equal(ids, expected_uids):\n        return bundle\n    if len(set(ids)) != len(ids) or set(ids) != set(expected_uids):\n        raise AssertionError('hybrid cache StudyInstanceUID set mismatch')\n    positions = {uid: index for index, uid in enumerate(ids)}\n    order = np.asarray([positions[uid] for uid in expected_uids], dtype=int)\n    return tuple((np.asarray(array)[order] for array in bundle[:-1])) + (expected_uids,)\n\ndef _hyb_transform(bundle, pca):\n    features, masks, slot_meta, radiomics, study_meta, sex, _ = bundle\n    n = len(features)\n    result = np.zeros((n, 6, 192), np.float32)\n    for start in range(0, n, 96):\n        stop = min(start + 96, n)\n        block = np.asarray(features[start:stop], np.float32)\n        block_mask = np.asarray(masks[start:stop]).reshape(-1).astype(bool)\n        flat = block.reshape(-1, block.shape[-1])\n        transformed = np.zeros((len(flat), 192), np.float32)\n        if block_mask.any():\n            transformed[block_mask] = pca.transform(flat[block_mask]).astype(np.float32)\n        result[start:stop] = transformed.reshape(stop - start, 6, 192)\n    sex_onehot = np.eye(3, dtype=np.float32)[np.asarray(sex, dtype=int).clip(0, 2)]\n    matrix = np.concatenate([result.reshape(n, -1), np.asarray(masks, np.float32), np.asarray(slot_meta, np.float32).reshape(n, -1), np.asarray(radiomics, np.float32).reshape(n, -1), np.asarray(study_meta, np.float32), sex_onehot], axis=1)\n    matrix = np.nan_to_num(matrix, nan=0.0, posinf=0.0, neginf=0.0)\n    if matrix.shape != (n, 1558):\n        raise AssertionError(f'unexpected hybrid matrix shape {matrix.shape}')\n    return matrix.astype(np.float32)\n\ndef _hyb_rank(values, denominator_offset=0.0):\n    values = np.asarray(values, np.float64)\n    if len(values) <= 1 or np.ptp(values) < 1e-12:\n        return np.full(len(values), 0.5, np.float64)\n    return rankdata(values, method='average') / (len(values) + denominator_offset)\n\ndef _hyb_payload():\n    raw = zlib.decompress(base64.b64decode(HYB_TEACHER_PAYLOAD.encode('ascii')))\n    with np.load(io.BytesIO(raw), allow_pickle=False) as payload:\n        return {name: payload[name].astype(np.float32) for name in payload.files}\n\ndef _hyb_select_top(indices, scores, labels, class_value, cap=2200):\n    keep = indices[labels == class_value]\n    if len(keep) <= cap:\n        return keep\n    keep_scores = scores[labels == class_value]\n    return keep[np.argsort(-keep_scores)[:cap]]\n\ndef _hyb_training_arrays(pseudo_y, pseudo_conf, exact_mask, exact_y):\n    exact_idx = np.flatnonzero(exact_mask)\n    pseudo_pool = ~exact_mask\n    confidence = np.clip(pseudo_conf, 0.0, 1.0)\n    candidates = np.flatnonzero(pseudo_pool & (confidence >= 0.2))\n    candidate_labels = (pseudo_y[candidates] >= 0.5).astype(int)\n    pos = _hyb_select_top(candidates, confidence[candidates], candidate_labels, 1)\n    neg = _hyb_select_top(candidates, confidence[candidates], candidate_labels, 0)\n    pseudo_idx = np.concatenate([pos, neg]).astype(int)\n    pseudo_labels = (pseudo_y[pseudo_idx] >= 0.5).astype(int)\n    pseudo_weight = 0.18 + 1.15 * np.power(np.clip(confidence[pseudo_idx], 0, 1), 1.4)\n    fit_idx = np.concatenate([exact_idx, pseudo_idx]).astype(int)\n    fit_y = np.concatenate([exact_y[exact_idx].astype(int), pseudo_labels]).astype(int)\n    fit_weight = np.concatenate([np.full(len(exact_idx), 7.0, np.float32), pseudo_weight.astype(np.float32)])\n    return (fit_idx, fit_y, fit_weight, exact_idx, exact_y[exact_idx].astype(int))\n\ndef _hyb_fit_lr(x_fit, y_fit, x_test, weights, cs, seed):\n    predictions = []\n    for index, c_value in enumerate(cs):\n        model = LogisticRegression(C=c_value, solver='liblinear', class_weight='balanced', max_iter=3000, random_state=seed + 31 * index)\n        model.fit(x_fit, y_fit, sample_weight=weights)\n        predictions.append(model.predict_proba(x_test)[:, 1])\n    return np.mean(predictions, axis=0).astype(np.float32)\n\ndef _hyb_fit_family(family, x_train, fit_idx, fit_y, fit_weight, x_test, seed):\n    if time.time() - T0 > HYB_DEADLINE_S:\n        raise TimeoutError('hybrid deadline reached during model fitting')\n    if family == 'lr':\n        return _hyb_fit_lr(x_train[fit_idx], fit_y, x_test, fit_weight, HYB_LR_CS, seed)\n    if family == 'exact_lr':\n        return _hyb_fit_lr(x_train[fit_idx], fit_y, x_test, fit_weight, HYB_EXACT_LR_CS, seed)\n    if family == 'et':\n        model = ExtraTreesClassifier(n_estimators=420, max_features='sqrt', min_samples_leaf=4, min_samples_split=8, bootstrap=False, class_weight='balanced', random_state=seed, n_jobs=-1)\n    elif family == 'hgb':\n        model = HistGradientBoostingClassifier(learning_rate=0.035, max_iter=180, max_leaf_nodes=15, min_samples_leaf=18, l2_regularization=0.25, early_stopping=True, validation_fraction=0.15, random_state=seed)\n    else:\n        raise ValueError(f'unknown hybrid family {family}')\n    model.fit(x_train[fit_idx], fit_y, sample_weight=fit_weight)\n    return model.predict_proba(x_test)[:, 1].astype(np.float32)\n\ndef _hyb_teacher_arm(x_train, x_test, pseudo_y, pseudo_conf, exact_mask, exact_y, exact_lr):\n    fit_idx, fit_y, fit_weight, _, _ = _hyb_training_arrays(pseudo_y, pseudo_conf, exact_mask, exact_y)\n    predictions = {}\n    for family in ('lr', 'et', 'hgb'):\n        seed_predictions = []\n        for seed in HYB_SEEDS:\n            model_seed = seed + 101 * TARGETS.index(HYB_TARGET) + len(family)\n            seed_predictions.append(_hyb_fit_family(family, x_train, fit_idx, fit_y, fit_weight, x_test, model_seed))\n        predictions[family] = np.mean(np.stack(seed_predictions), axis=0)\n    predictions['exact_lr'] = exact_lr\n    weighted_rank = np.zeros(len(x_test), np.float64)\n    weighted_prob = np.zeros(len(x_test), np.float64)\n    for weight, family in zip(HYB_FAMILY_WEIGHTS, HYB_FAMILIES):\n        pred = np.clip(predictions[family], 1e-05, 1.0 - 1e-05)\n        weighted_rank += weight * _hyb_rank(pred, denominator_offset=1.0)\n        weighted_prob += weight * pred\n    return 0.9 * weighted_rank + 0.1 * weighted_prob\n\n# ----------------------- V13 nested hybrid specialists -----------------------\n\nV13_SPECIALIST_TARGETS = (\n    \"Lateral Meniscus\",\n    \"Lateral OA\",\n    \"Synovitis\",\n)\n\nV13_CV_SEEDS = {\n    \"Lateral Meniscus\": HYB_SEEDS[:3],\n    \"Lateral OA\": HYB_OA_SEEDS[:3],\n}\n\nV13_FINAL_SEEDS = {\n    \"Lateral Meniscus\": HYB_SEEDS[:5],\n    \"Lateral OA\": HYB_OA_SEEDS[:6],\n}\n\nV13_PCA_SEEDS = (\n    20260809,\n    20260819,\n    20260829,\n)\n\n\ndef _v13_rank(values):\n    values = np.asarray(\n        values,\n        dtype=np.float64,\n    )\n    if (\n        len(values) <= 1\n        or np.ptp(values) < 1e-12\n    ):\n        return np.full(\n            len(values),\n            0.5,\n            dtype=np.float64,\n        )\n    return rankdata(\n        values,\n        method=\"average\",\n    ) / len(values)\n\n\ndef _v13_training_arrays(\n    pseudo_y,\n    pseudo_conf,\n    exact_all_mask,\n    exact_train_mask,\n    exact_y,\n):\n    exact_idx = np.flatnonzero(\n        exact_train_mask\n    )\n\n    # Held-out gold rows are excluded from BOTH exact and pseudo training.\n    pseudo_pool = ~exact_all_mask\n\n    confidence = np.clip(\n        pseudo_conf,\n        0.0,\n        1.0,\n    )\n\n    candidates = np.flatnonzero(\n        pseudo_pool\n        & (confidence >= 0.2)\n    )\n\n    candidate_labels = (\n        pseudo_y[candidates] >= 0.5\n    ).astype(int)\n\n    pos = _hyb_select_top(\n        candidates,\n        confidence[candidates],\n        candidate_labels,\n        1,\n    )\n    neg = _hyb_select_top(\n        candidates,\n        confidence[candidates],\n        candidate_labels,\n        0,\n    )\n\n    pseudo_idx = np.concatenate(\n        [pos, neg]\n    ).astype(int)\n\n    pseudo_labels = (\n        pseudo_y[pseudo_idx] >= 0.5\n    ).astype(int)\n\n    pseudo_weight = (\n        0.18\n        + 1.15\n        * np.power(\n            np.clip(\n                confidence[pseudo_idx],\n                0,\n                1,\n            ),\n            1.4,\n        )\n    )\n\n    fit_idx = np.concatenate(\n        [\n            exact_idx,\n            pseudo_idx,\n        ]\n    ).astype(int)\n\n    fit_y = np.concatenate(\n        [\n            exact_y[\n                exact_idx\n            ].astype(int),\n            pseudo_labels,\n        ]\n    ).astype(int)\n\n    fit_weight = np.concatenate(\n        [\n            np.full(\n                len(exact_idx),\n                7.0,\n                np.float32,\n            ),\n            pseudo_weight.astype(\n                np.float32\n            ),\n        ]\n    )\n\n    return (\n        fit_idx,\n        fit_y,\n        fit_weight,\n    )\n\n\ndef _v13_family_raw_predictions(\n    target_name,\n    x_train,\n    x_eval,\n    pseudo_y,\n    pseudo_conf,\n    exact_all_mask,\n    exact_train_mask,\n    exact_y,\n    seeds,\n    family_weights,\n):\n    fit_idx, fit_y, fit_weight = (\n        _v13_training_arrays(\n            pseudo_y,\n            pseudo_conf,\n            exact_all_mask,\n            exact_train_mask,\n            exact_y,\n        )\n    )\n\n    output = {}\n\n    for family, family_weight in zip(\n        HYB_FAMILIES,\n        family_weights,\n    ):\n        if (\n            family_weight <= 0\n            or family == \"exact_lr\"\n        ):\n            continue\n\n        seed_predictions = []\n\n        for seed in seeds:\n            model_seed = (\n                int(seed)\n                + 101\n                * TARGETS.index(\n                    target_name\n                )\n                + len(family)\n            )\n\n            seed_predictions.append(\n                _hyb_fit_family(\n                    family,\n                    x_train,\n                    fit_idx,\n                    fit_y,\n                    fit_weight,\n                    x_eval,\n                    model_seed,\n                )\n            )\n\n        output[family] = np.mean(\n            np.stack(\n                seed_predictions,\n                axis=0,\n            ),\n            axis=0,\n        )\n\n    return output\n\n\ndef _v13_family_rank_mix(\n    predictions,\n    family_weights,\n):\n    result = None\n    total = 0.0\n\n    for family, weight in zip(\n        HYB_FAMILIES,\n        family_weights,\n    ):\n        if (\n            weight <= 0\n            or family not in predictions\n        ):\n            continue\n\n        rank = _v13_rank(\n            predictions[family]\n        )\n\n        if result is None:\n            result = np.zeros_like(\n                rank,\n                dtype=np.float64,\n            )\n\n        result += float(weight) * rank\n        total += float(weight)\n\n    if result is None or total <= 0:\n        raise RuntimeError(\n            \"hybrid family rank mix is empty\"\n        )\n\n    return result / total\n\n\ndef _v13_crossfit_teacher(\n    target_name,\n    pseudo_y,\n    pseudo_conf,\n    x_train,\n    train_df,\n    fold,\n    seeds,\n    family_weights,\n):\n    exact_all_mask = (\n        train_df[target_name]\n        .notna()\n        .to_numpy()\n    )\n\n    exact_y = np.nan_to_num(\n        train_df[target_name]\n        .to_numpy(\n            np.float32\n        ),\n        nan=0.0,\n    )\n\n    raw = {\n        family: np.full(\n            len(train_df),\n            np.nan,\n            dtype=np.float64,\n        )\n        for family, weight\n        in zip(\n            HYB_FAMILIES,\n            family_weights,\n        )\n        if (\n            weight > 0\n            and family != \"exact_lr\"\n        )\n    }\n\n    unique_folds = sorted(\n        int(value)\n        for value in np.unique(\n            fold[exact_all_mask]\n        )\n        if int(value) >= 0\n    )\n\n    for outer in unique_folds:\n        valid_mask = (\n            exact_all_mask\n            & (fold == int(outer))\n        )\n        exact_train_mask = (\n            exact_all_mask\n            & (fold != int(outer))\n        )\n\n        if not valid_mask.any():\n            continue\n\n        prediction = (\n            _v13_family_raw_predictions(\n                target_name,\n                x_train,\n                x_train[valid_mask],\n                pseudo_y,\n                pseudo_conf,\n                exact_all_mask,\n                exact_train_mask,\n                exact_y,\n                seeds,\n                family_weights,\n            )\n        )\n\n        for family, values in (\n            prediction.items()\n        ):\n            raw[family][\n                valid_mask\n            ] = values\n\n    exact_index = np.flatnonzero(\n        exact_all_mask\n    )\n\n    for values in raw.values():\n        if not np.isfinite(\n            values[exact_index]\n        ).all():\n            raise RuntimeError(\n                f\"incomplete cross-fit for \"\n                f\"{target_name}\"\n            )\n\n    # Rank each family only after every held-out fold has been predicted.\n    ranked = {\n        family:\n            _v13_rank(\n                values[exact_index]\n            )\n        for family, values in raw.items()\n    }\n\n    return (\n        _v13_family_rank_mix(\n            ranked,\n            family_weights,\n        ),\n        exact_index,\n    )\n\n\ndef _v13_fit_teacher_test(\n    target_name,\n    pseudo_y,\n    pseudo_conf,\n    x_train,\n    x_test,\n    train_df,\n    seeds,\n    family_weights,\n):\n    exact_all_mask = (\n        train_df[target_name]\n        .notna()\n        .to_numpy()\n    )\n\n    exact_y = np.nan_to_num(\n        train_df[target_name]\n        .to_numpy(\n            np.float32\n        ),\n        nan=0.0,\n    )\n\n    prediction = (\n        _v13_family_raw_predictions(\n            target_name,\n            x_train,\n            x_test,\n            pseudo_y,\n            pseudo_conf,\n            exact_all_mask,\n            exact_all_mask,\n            exact_y,\n            seeds,\n            family_weights,\n        )\n    )\n\n    return _v13_family_rank_mix(\n        prediction,\n        family_weights,\n    )\n\n\ndef _v13_pca_crossfit(\n    target_name,\n    x_train_raw,\n    x_test_raw,\n    train_df,\n    fold,\n    dimensions,\n    c_value,\n):\n    exact_mask = (\n        train_df[target_name]\n        .notna()\n        .to_numpy()\n    )\n\n    exact_y = np.nan_to_num(\n        train_df[target_name]\n        .to_numpy(\n            np.float32\n        ),\n        nan=0.0,\n    ).astype(int)\n\n    train_mean = x_train_raw.mean(\n        axis=0,\n        dtype=np.float64,\n    ).astype(np.float32)\n\n    train_scale = x_train_raw.std(\n        axis=0,\n        dtype=np.float64,\n    ).astype(np.float32)\n\n    train_scale[\n        train_scale < 1e-5\n    ] = 1.0\n\n    train_norm = (\n        (\n            x_train_raw\n            - train_mean\n        )\n        / train_scale\n    ).astype(np.float32)\n\n    test_norm = (\n        (\n            x_test_raw\n            - train_mean\n        )\n        / train_scale\n    ).astype(np.float32)\n\n    oof_seeds = []\n    test_seeds = []\n\n    for pca_seed in V13_PCA_SEEDS:\n        decomposition = PCA(\n            n_components=128,\n            whiten=True,\n            svd_solver=\"randomized\",\n            n_oversamples=20,\n            random_state=int(\n                pca_seed\n            ),\n        )\n\n        train_embedding = (\n            decomposition.fit_transform(\n                train_norm\n            )\n        )\n        test_embedding = (\n            decomposition.transform(\n                test_norm\n            )\n        )\n\n        oof = np.full(\n            len(train_df),\n            np.nan,\n            dtype=np.float64,\n        )\n\n        for outer in sorted(\n            int(value)\n            for value in np.unique(\n                fold[exact_mask]\n            )\n            if int(value) >= 0\n        ):\n            valid_mask = (\n                exact_mask\n                & (fold == int(outer))\n            )\n            train_mask = (\n                exact_mask\n                & (fold != int(outer))\n            )\n\n            if (\n                train_mask.sum() < 8\n                or not valid_mask.any()\n                or len(\n                    np.unique(\n                        exact_y[\n                            train_mask\n                        ]\n                    )\n                ) < 2\n            ):\n                continue\n\n            model = make_pipeline(\n                StandardScaler(),\n                LogisticRegression(\n                    C=float(c_value),\n                    solver=\"liblinear\",\n                    class_weight=\"balanced\",\n                    max_iter=5000,\n                    random_state=int(\n                        pca_seed\n                    ),\n                ),\n            )\n\n            model.fit(\n                train_embedding[\n                    train_mask,\n                    :dimensions,\n                ],\n                exact_y[\n                    train_mask\n                ],\n            )\n\n            oof[\n                valid_mask\n            ] = model.predict_proba(\n                train_embedding[\n                    valid_mask,\n                    :dimensions,\n                ]\n            )[:, 1]\n\n        exact_index = np.flatnonzero(\n            exact_mask\n        )\n\n        if not np.isfinite(\n            oof[exact_index]\n        ).all():\n            raise RuntimeError(\n                f\"incomplete PCA cross-fit \"\n                f\"for {target_name}\"\n            )\n\n        oof_seeds.append(\n            oof[exact_index]\n        )\n\n        final_model = make_pipeline(\n            StandardScaler(),\n            LogisticRegression(\n                C=float(c_value),\n                solver=\"liblinear\",\n                class_weight=\"balanced\",\n                max_iter=5000,\n                random_state=int(\n                    pca_seed\n                ),\n            ),\n        )\n\n        final_model.fit(\n            train_embedding[\n                exact_mask,\n                :dimensions,\n            ],\n            exact_y[\n                exact_mask\n            ],\n        )\n\n        test_seeds.append(\n            final_model.predict_proba(\n                test_embedding[\n                    :,\n                    :dimensions,\n                ]\n            )[:, 1]\n        )\n\n    oof_mean = np.mean(\n        np.stack(\n            oof_seeds,\n            axis=0,\n        ),\n        axis=0,\n    )\n    test_mean = np.mean(\n        np.stack(\n            test_seeds,\n            axis=0,\n        ),\n        axis=0,\n    )\n\n    return (\n        _v13_rank(\n            oof_mean\n        ),\n        _v13_rank(\n            test_mean\n        ),\n        np.flatnonzero(\n            exact_mask\n        ),\n    )\n\n\ndef _v13_nested_candidate(\n    truth,\n    base,\n    folds,\n    candidates,\n):\n    \"\"\"\n    Nested blend selection:\n      - choose model/mix using all OTHER gold folds;\n      - predict the held-out gold fold with that choice;\n      - only after every fold is predicted evaluate the nested result.\n\n    This prevents the candidate that wins a noisy 58-study search from\n    evaluating itself on the same cases used to select its weight.\n    \"\"\"\n    truth = np.asarray(\n        truth,\n        np.float64,\n    )\n    base = np.asarray(\n        base,\n        np.float64,\n    )\n    folds = np.asarray(\n        folds,\n    )\n\n    grid = (\n        0.05,\n        0.10,\n        0.15,\n        0.20,\n        0.25,\n        0.30,\n        0.35,\n        0.40,\n    )\n\n    nested = np.full_like(\n        base,\n        np.nan,\n        dtype=np.float64,\n    )\n\n    chosen = []\n\n    for outer in sorted(\n        int(value)\n        for value in np.unique(\n            folds\n        )\n    ):\n        selection = (\n            folds != int(outer)\n        )\n        validation = (\n            folds == int(outer)\n        )\n\n        if (\n            selection.sum() < 12\n            or not validation.any()\n        ):\n            continue\n\n        selection_base_auc = (\n            _v10_target_auc(\n                truth[selection],\n                base[selection],\n            )\n        )\n\n        if not np.isfinite(\n            selection_base_auc\n        ):\n            continue\n\n        best = None\n\n        for name, candidate in (\n            candidates.items()\n        ):\n            candidate = np.asarray(\n                candidate,\n                np.float64,\n            )\n\n            for mix in grid:\n                blended = (\n                    (1.0 - mix)\n                    * base[selection]\n                    + mix\n                    * candidate[selection]\n                )\n\n                auc = _v10_target_auc(\n                    truth[selection],\n                    blended,\n                )\n\n                if not np.isfinite(auc):\n                    continue\n\n                # Penalize high specialist weight during selection.\n                objective = (\n                    auc\n                    - 0.0020\n                    * float(mix)\n                )\n\n                if (\n                    best is None\n                    or objective\n                    > best[\"objective\"]\n                ):\n                    best = {\n                        \"name\": name,\n                        \"mix\": float(mix),\n                        \"auc\": float(auc),\n                        \"objective\":\n                            float(objective),\n                    }\n\n        if best is None:\n            nested[\n                validation\n            ] = base[\n                validation\n            ]\n            chosen.append(\n                (\"base\", 0.0)\n            )\n        else:\n            candidate = np.asarray(\n                candidates[\n                    best[\"name\"]\n                ],\n                np.float64,\n            )\n\n            nested[\n                validation\n            ] = (\n                (\n                    1.0\n                    - best[\"mix\"]\n                )\n                * base[\n                    validation\n                ]\n                + best[\"mix\"]\n                * candidate[\n                    validation\n                ]\n            )\n\n            chosen.append(\n                (\n                    best[\"name\"],\n                    best[\"mix\"],\n                )\n            )\n\n    if not np.isfinite(\n        nested\n    ).all():\n        return None\n\n    base_auc = _v10_target_auc(\n        truth,\n        base,\n    )\n    nested_auc = _v10_target_auc(\n        truth,\n        nested,\n    )\n\n    if not (\n        np.isfinite(base_auc)\n        and np.isfinite(\n            nested_auc\n        )\n    ):\n        return None\n\n    support = (\n        _v10_bootstrap_positive_fraction(\n            truth,\n            base,\n            nested,\n            seed=13013,\n            repeats=360,\n        )\n    )\n\n    (\n        valid_folds,\n        fold_positive,\n        fold_median,\n    ) = _v11_fold_consistency(\n        truth,\n        base,\n        nested,\n        folds,\n    )\n\n    gain = float(\n        nested_auc\n        - base_auc\n    )\n\n    # Final model/mix is selected on all gold cases only AFTER the nested\n    # evaluation has established that the specialist family generalizes.\n    final_best = None\n\n    for name, candidate in (\n        candidates.items()\n    ):\n        candidate = np.asarray(\n            candidate,\n            np.float64,\n        )\n\n        for mix in grid:\n            blended = (\n                (1.0 - mix)\n                * base\n                + mix\n                * candidate\n            )\n\n            auc = _v10_target_auc(\n                truth,\n                blended,\n            )\n\n            if not np.isfinite(auc):\n                continue\n\n            objective = (\n                auc\n                - 0.0020\n                * float(mix)\n            )\n\n            if (\n                final_best is None\n                or objective\n                > final_best[\"objective\"]\n            ):\n                final_best = {\n                    \"name\": name,\n                    \"mix\": float(mix),\n                    \"auc\": float(auc),\n                    \"objective\":\n                        float(objective),\n                }\n\n    if final_best is None:\n        return None\n\n    class_support = min(\n        int(\n            (truth > 0.5).sum()\n        ),\n        int(\n            (truth <= 0.5).sum()\n        ),\n    )\n\n    strong = (\n        gain >= 0.0040\n        and support >= 0.62\n        and (\n            valid_folds < 2\n            or fold_positive >= 0.60\n        )\n        and class_support >= 5\n    )\n\n    moderate = (\n        gain >= 0.0020\n        and support >= 0.59\n        and (\n            valid_folds < 2\n            or fold_positive >= 0.50\n        )\n        and class_support >= 4\n    )\n\n    if strong:\n        deploy = min(\n            final_best[\"mix\"],\n            0.35,\n        )\n    elif moderate:\n        deploy = min(\n            final_best[\"mix\"],\n            0.12,\n        )\n    else:\n        deploy = 0.0\n\n    return {\n        \"nested_gain\": gain,\n        \"support\": float(\n            support\n        ),\n        \"fold_positive\": float(\n            fold_positive\n        ),\n        \"fold_median\": float(\n            fold_median\n        ),\n        \"deploy\": float(\n            deploy\n        ),\n        \"name\": (\n            final_best[\"name\"]\n            if deploy > 0\n            else \"base\"\n        ),\n    }\n\n\ndef run_v13_hybrid_specialists():\n    context = globals().get(\n        \"V13_V11_GOLD_CONTEXT\"\n    )\n\n    if context is None:\n        log(\n            \"V13 hybrid skipped: \"\n            \"V11 gold context unavailable\"\n        )\n        return False\n\n    if time.time() - T0 > HYB_START_CUTOFF_S:\n        log(\n            \"V13 hybrid skipped: \"\n            \"insufficient runtime reserve\"\n        )\n        return False\n\n    try:\n        oof_data = _v10_load_oof()\n        if oof_data is None:\n            log(\n                \"V13 hybrid skipped: \"\n                \"OOF fold contract unavailable\"\n            )\n            return False\n\n        cache_dir = (\n            _hyb_find_cache_dir()\n        )\n\n        primary_path = Path(\n            \"/kaggle/working/submission.csv\"\n        )\n\n        primary = pd.read_csv(\n            primary_path,\n            dtype={\n                \"StudyInstanceUID\": str\n            },\n        )\n\n        train_df = pd.read_csv(\n            ROOT / \"train.csv\",\n            dtype={\n                \"StudyInstanceUID\": str\n            },\n        )\n        test_df = pd.read_csv(\n            ROOT / \"test.csv\",\n            dtype={\n                \"StudyInstanceUID\": str\n            },\n        )\n        series_df = pd.read_csv(\n            ROOT / \"test_series.csv\",\n            dtype={\n                \"StudyInstanceUID\": str,\n                \"SeriesInstanceUID\": str,\n            },\n        )\n\n        expected_columns = (\n            [\"StudyInstanceUID\"]\n            + TARGETS\n        )\n\n        if (\n            primary.columns.tolist()\n            != expected_columns\n        ):\n            raise AssertionError(\n                \"V13 primary schema mismatch\"\n            )\n\n        train_uids = (\n            train_df[\n                \"StudyInstanceUID\"\n            ]\n            .astype(str)\n            .to_numpy()\n        )\n\n        uid_hash = hashlib.sha256(\n            \"\\n\".join(\n                train_uids\n            ).encode()\n        ).hexdigest()\n\n        if (\n            uid_hash\n            != HYB_EXPECTED_TRAIN_ID_SHA256\n        ):\n            raise AssertionError(\n                \"V13 hybrid train ID \"\n                \"contract drifted\"\n            )\n\n        test_uids = (\n            test_df[\n                \"StudyInstanceUID\"\n            ]\n            .astype(str)\n            .to_numpy()\n        )\n\n        dev = DEVS[0]\n\n        train_bundle = _hyb_align_bundle(\n            _hyb_load_cached_split(\n                cache_dir,\n                \"train\",\n            ),\n            train_uids,\n        )\n\n        test_bundle = _hyb_align_bundle(\n            _hyb_extract_test_bundle(\n                test_df,\n                series_df,\n                cache_dir,\n                dev,\n            ),\n            test_uids,\n        )\n\n        pca = joblib.load(\n            cache_dir\n            / f\"{HYB_PREFIX}_ipca_192.joblib\"\n        )\n\n        x_train_raw = _hyb_transform(\n            train_bundle,\n            pca,\n        )\n        x_test_raw = _hyb_transform(\n            test_bundle,\n            pca,\n        )\n\n        # Same label-free normalization as the source specialist.\n        joint = np.concatenate(\n            [\n                x_train_raw,\n                x_test_raw,\n            ],\n            axis=0,\n        )\n\n        mean = joint.mean(\n            axis=0,\n            dtype=np.float64,\n        ).astype(np.float32)\n\n        scale = joint.std(\n            axis=0,\n            dtype=np.float64,\n        ).astype(np.float32)\n\n        scale[\n            scale < 1e-5\n        ] = 1.0\n\n        x_train = (\n            (\n                x_train_raw\n                - mean\n            )\n            / scale\n        ).astype(np.float32)\n\n        x_test = (\n            (\n                x_test_raw\n                - mean\n            )\n            / scale\n        ).astype(np.float32)\n\n        payload = _hyb_payload()\n\n        if any(\n            len(payload[name])\n            != len(train_df)\n            for name in payload\n        ):\n            raise AssertionError(\n                \"V13 hybrid teacher \"\n                \"payload length mismatch\"\n            )\n\n        fold = np.asarray(\n            oof_data[\"fold\"],\n            dtype=np.int64,\n        )\n\n        context_gold_index = np.asarray(\n            context[\"gold_index\"],\n            dtype=np.int64,\n        )\n\n        if not np.array_equal(\n            context_gold_index,\n            np.flatnonzero(\n                oof_data[\"gold\"]\n            ),\n        ):\n            raise AssertionError(\n                \"V13 gold index mismatch\"\n            )\n\n        gold_y = np.asarray(\n            context[\"gold_y\"],\n            dtype=np.float64,\n        )\n        gold_fold = np.asarray(\n            context[\"gold_fold\"],\n            dtype=np.int64,\n        )\n        v11_gold = np.asarray(\n            context[\"v11_gold\"],\n            dtype=np.float64,\n        )\n\n        # ---------------- Lateral Meniscus teacher ----------------\n        lm_oof, lm_index = (\n            _v13_crossfit_teacher(\n                HYB_TARGET,\n                payload[\n                    \"lm_consensus_y\"\n                ],\n                payload[\n                    \"lm_consensus_conf\"\n                ],\n                x_train,\n                train_df,\n                fold,\n                V13_CV_SEEDS[\n                    HYB_TARGET\n                ],\n                HYB_LM_FAMILY_WEIGHTS,\n            )\n        )\n\n        lm_test = (\n            _v13_fit_teacher_test(\n                HYB_TARGET,\n                payload[\n                    \"lm_consensus_y\"\n                ],\n                payload[\n                    \"lm_consensus_conf\"\n                ],\n                x_train,\n                x_test,\n                train_df,\n                V13_FINAL_SEEDS[\n                    HYB_TARGET\n                ],\n                HYB_LM_FAMILY_WEIGHTS,\n            )\n        )\n\n        # ---------------- Lateral OA teacher ----------------\n        oa_oof, oa_index = (\n            _v13_crossfit_teacher(\n                HYB_OA_TARGET,\n                payload[\n                    \"oa_pilkwang_y\"\n                ],\n                payload[\n                    \"oa_pilkwang_conf\"\n                ],\n                x_train,\n                train_df,\n                fold,\n                V13_CV_SEEDS[\n                    HYB_OA_TARGET\n                ],\n                HYB_OA_FAMILY_WEIGHTS,\n            )\n        )\n\n        oa_test = (\n            _v13_fit_teacher_test(\n                HYB_OA_TARGET,\n                payload[\n                    \"oa_pilkwang_y\"\n                ],\n                payload[\n                    \"oa_pilkwang_conf\"\n                ],\n                x_train,\n                x_test,\n                train_df,\n                V13_FINAL_SEEDS[\n                    HYB_OA_TARGET\n                ],\n                HYB_OA_FAMILY_WEIGHTS,\n            )\n        )\n\n        # ---------------- Exact PCA specialists ----------------\n        (\n            lm_pca_oof,\n            lm_pca_test,\n            lm_pca_index,\n        ) = _v13_pca_crossfit(\n            HYB_TARGET,\n            x_train_raw,\n            x_test_raw,\n            train_df,\n            fold,\n            dimensions=128,\n            c_value=0.1,\n        )\n\n        (\n            syn_pca_oof,\n            syn_pca_test,\n            syn_index,\n        ) = _v13_pca_crossfit(\n            \"Synovitis\",\n            x_train_raw,\n            x_test_raw,\n            train_df,\n            fold,\n            dimensions=32,\n            c_value=1.0,\n        )\n\n        # Every fully labelled target uses the same 58 gold rows.\n        for index in (\n            lm_index,\n            oa_index,\n            lm_pca_index,\n            syn_index,\n        ):\n            if not np.array_equal(\n                index,\n                context_gold_index,\n            ):\n                raise AssertionError(\n                    \"V13 specialist gold \"\n                    \"alignment mismatch\"\n                )\n\n        result = primary.copy()\n\n        test_position = {\n            str(uid): i\n            for i, uid in enumerate(\n                test_uids\n            )\n        }\n\n        primary_order = np.asarray(\n            [\n                test_position[\n                    str(uid)\n                ]\n                for uid in result[\n                    \"StudyInstanceUID\"\n                ].astype(str)\n            ],\n            dtype=int,\n        )\n\n        specialist_catalog = {\n            HYB_TARGET: {\n                \"gold\": {\n                    \"teacher\": lm_oof,\n                    \"pca\": lm_pca_oof,\n                    \"teacher_pca\": _v13_rank(\n                        0.57 * lm_oof\n                        + 0.43 * lm_pca_oof\n                    ),\n                },\n                \"test\": {\n                    \"teacher\":\n                        lm_test[\n                            primary_order\n                        ],\n                    \"pca\":\n                        lm_pca_test[\n                            primary_order\n                        ],\n                    \"teacher_pca\":\n                        _v13_rank(\n                            0.57\n                            * lm_test[\n                                primary_order\n                            ]\n                            + 0.43\n                            * lm_pca_test[\n                                primary_order\n                            ]\n                        ),\n                },\n            },\n            HYB_OA_TARGET: {\n                \"gold\": {\n                    \"teacher\": oa_oof,\n                },\n                \"test\": {\n                    \"teacher\":\n                        oa_test[\n                            primary_order\n                        ],\n                },\n            },\n            \"Synovitis\": {\n                \"gold\": {\n                    \"pca\":\n                        syn_pca_oof,\n                },\n                \"test\": {\n                    \"pca\":\n                        syn_pca_test[\n                            primary_order\n                        ],\n                },\n            },\n        }\n\n        changed = []\n\n        for target_name in (\n            V13_SPECIALIST_TARGETS\n        ):\n            target_index = (\n                TARGETS.index(\n                    target_name\n                )\n            )\n\n            truth = gold_y[\n                :, target_index\n            ]\n            base_gold = v11_gold[\n                :, target_index\n            ]\n\n            decision = (\n                _v13_nested_candidate(\n                    truth,\n                    base_gold,\n                    gold_fold,\n                    specialist_catalog[\n                        target_name\n                    ][\"gold\"],\n                )\n            )\n\n            if (\n                decision is None\n                or decision[\n                    \"deploy\"\n                ] <= 0\n            ):\n                continue\n\n            base_test = result[\n                target_name\n            ].rank(\n                method=\"average\",\n                pct=True,\n            ).to_numpy(\n                np.float64\n            )\n\n            specialist_test = (\n                specialist_catalog[\n                    target_name\n                ][\"test\"][\n                    decision[\"name\"]\n                ]\n            )\n\n            specialist_test = (\n                _v13_rank(\n                    specialist_test\n                )\n            )\n\n            deploy = float(\n                decision[\n                    \"deploy\"\n                ]\n            )\n\n            result[\n                target_name\n            ] = _v13_rank(\n                (\n                    1.0 - deploy\n                )\n                * base_test\n                + deploy\n                * specialist_test\n            )\n\n            changed.append(\n                target_name\n            )\n\n        untouched = [\n            target\n            for target in TARGETS\n            if target not in changed\n        ]\n\n        if not result[\n            untouched\n        ].equals(\n            primary[\n                untouched\n            ]\n        ):\n            raise AssertionError(\n                \"V13 specialist modified \"\n                \"an ungated target\"\n            )\n\n        if (\n            result.shape\n            != primary.shape\n            or not np.isfinite(\n                result[\n                    TARGETS\n                ].to_numpy()\n            ).all()\n        ):\n            raise AssertionError(\n                \"invalid V13 hybrid output\"\n            )\n\n        result.to_csv(\n            primary_path,\n            index=False,\n        )\n\n        log(\n            \"V13 nested hybrid complete; \"\n            f\"promoted targets={changed}\"\n        )\n\n        return bool(changed)\n\n    except Exception as exc:\n        # V11 is already a valid measured anchor; specialist failure must\n        # never destroy it.\n        log(\n            \"V13 hybrid skipped safely: \"\n            f\"{type(exc).__name__}: {exc}\"\n        )\n        return False\n\n\nrun_v13_hybrid_specialists()\n","metadata":{},"outputs":[],"execution_count":null}]}