{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.11.13"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":154281,"sourceType":"competition"},{"sourceId":18842180,"sourceType":"datasetVersion"},{"sourceId":18839182,"sourceType":"datasetVersion"},{"sourceId":18229736,"sourceType":"datasetVersion"},{"sourceId":18956429,"sourceType":"datasetVersion"},{"sourceId":19075719,"sourceType":"datasetVersion"},{"sourceId":18875869,"sourceType":"datasetVersion"},{"sourceId":18673646,"sourceType":"datasetVersion"},{"sourceId":18673450,"sourceType":"datasetVersion"},{"sourceId":18716507,"sourceType":"datasetVersion"},{"sourceId":18879001,"sourceType":"datasetVersion"},{"sourceId":18757740,"sourceType":"datasetVersion"},{"sourceId":342671664,"sourceType":"kernelVersion"},{"sourceId":342849430,"sourceType":"kernelVersion"},{"sourceId":4533,"sourceType":"modelInstanceVersion"}],"dockerImageVersionId":31430,"isGpuEnabled":true,"isInternetEnabled":false,"language":"python","sourceType":"notebook"},"rsna_optimization":{"official_source_score":0.891,"revision":"v36","source":"pilkwang/rsna-knee-baseline-v1","parent_script_version_id":348195103,"raptor_arm_weights":[0.6,0.1,0.1,0.2],"inner_raptor_coat_weights":[0.6,0.4],"inner_rerank":true,"parent_kernel_version":32,"parent_submission_id":56169402,"release_guard":"no DINOv2 retry/drop; require 20/20 fingerprints","new_models":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Bend the Knee to the Dinosaurs (ALL PUBLIC)\n\n## New addition: CoAtNet MRI reader\n\nInspired by [dreaddevelopment's discussion](https://www.kaggle.com/competitions/rsna-knee-abnormality-detection/discussion/737696), this version adds my public [CoAtNet MRI model](https://www.kaggle.com/datasets/mattiaangeli/rsna-knee-coat-resgated-ep10-top3).\n\nEach 384 px adjacent-slice triplet passes through a CoAtNet RMLP-2 backbone. A finding-specific gated spatial head blends localized evidence with a protected global-average residual; a second finding-specific attention stage pools windows across the study. Three checkpoints are combined by per-finding rank averaging before joining the existing ensemble.\n\nInference-only submission.\n\n## Credits\n\n[Pilkwang](https://www.kaggle.com/datasets/pilkwang/rsna-knee-weights) · Sofia Anjenje · Antoine G. · prvsiyan · Marwan Mahmoud · dreaddevelopment / Roman Tamrazov · [renta.k](https://www.kaggle.com/code/renta0426/rsna-knee-hybrid-raptor-lateral-meniscus-r100) · [Anvith Pothula](https://www.kaggle.com/code/anvithpothula/rsna-base)\n","metadata":{}},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from __future__ import annotations\nimport time as _startup_time\n_STARTUP_T0 = _startup_time.perf_counter()\nimport os\nfor _v in ('OMP_NUM_THREADS', 'OPENBLAS_NUM_THREADS', 'MKL_NUM_THREADS'):\n    os.environ.setdefault(_v, '4')\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\n\ndef _cuda_execution_probe(index):\n    dev = torch.device(f'cuda:{index}')\n    try:\n        major, minor = torch.cuda.get_device_capability(index)\n        probe = nn.Conv2d(3, 4, kernel_size=3, padding=1).eval().to(dev)\n        with torch.inference_mode():\n            out = probe(torch.zeros((1, 3, 16, 16), device=dev))\n            if tuple(out.shape) != (1, 4, 16, 16):\n                raise RuntimeError(f'unexpected CUDA probe shape {tuple(out.shape)}')\n        torch.cuda.synchronize(index)\n        print(f'cuda:{index} probe PASS (compute {major}.{minor})')\n        del probe, out\n        torch.cuda.empty_cache()\n        return True\n    except Exception as exc:\n        print(f'cuda:{index} probe FAIL ({type(exc).__name__}: {exc}); using CPU fallback')\n        try:\n            torch.cuda.empty_cache()\n        except Exception:\n            pass\n        return False\nDEVS = []\nif torch.cuda.is_available():\n    DEVS = [torch.device(f'cuda:{i}') for i in range(torch.cuda.device_count()) if _cuda_execution_probe(i)]\nif not DEVS:\n    raise RuntimeError('GPU required')\nprint(f'devices: {[str(d) for d in DEVS]}')\n_STARTUP_GPU_IMPORT_S = _startup_time.perf_counter() - _STARTUP_T0\nprint(f'[startup] imports+GPU preflight: {_STARTUP_GPU_IMPORT_S:.2f}s', flush=True)\nT0 = time.time()\nSEED = 2026\nnp.random.seed(SEED)\ntorch.manual_seed(SEED)\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\nRUNS = [{'name': 'r224', 'img': 224}, {'name': 'r336', 'img': 336}]\nEPOCHS = 10\nBATCH_STUDIES = 8\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\nLR_HEAD = 0.001\nLR_BACKBONE = 8e-06\nUNFREEZE_LAST = 6\nWEIGHT_DECAY = 0.02\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')","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def log(msg):\n    print(f'[{time.time() - T0:7.1f}s] {msg}', flush=True)\n\ndef _one_direct(tag, candidates, required):\n    matches = []\n    for candidate in map(Path, candidates):\n        if candidate.is_dir() and all((candidate / item).exists() for item in required):\n            matches.append(candidate)\n    unique = []\n    for match in matches:\n        if str(match) not in {str(item) for item in unique}:\n            unique.append(match)\n    if len(unique) != 1:\n        raise FileNotFoundError(\n            f'{tag}: expected exactly one direct mounted artifact, found '\n            f'{[str(item) for item in unique]}; checked {[str(Path(item)) for item in candidates]}'\n        )\n    return unique[0]\n\ndef find_root():\n    return _one_direct('competition', [\n        '/kaggle/input/competitions/rsna-knee-abnormality-detection',\n        '/kaggle/input/rsna-knee-abnormality-detection',\n    ], ['test.csv', 'test_series.csv', 'test_series'])\n\ndef find_dinov2(variant='small'):\n    if variant != 'small':\n        raise ValueError(f'unpinned DINOv2 variant: {variant}')\n    return _one_direct('DINOv2-S model', [\n        '/kaggle/input/models/metaresearch/dinov2/PyTorch/small/1',\n        '/kaggle/input/models/metaresearch/dinov2/pytorch/small/1',\n        '/kaggle/input/dinov2/PyTorch/small/1',\n        '/kaggle/input/dinov2/pytorch/small/1',\n    ], ['config.json', 'pytorch_model.bin'])\nROOT = find_root()\nDINOV2_SOURCE = find_dinov2('small')\nlog(f'input root: {ROOT}')\n_STARTUP_PATH_S = _startup_time.perf_counter() - _STARTUP_T0 - _STARTUP_GPU_IMPORT_S\nprint(f'[startup] competition-root preflight: {_STARTUP_PATH_S:.2f}s', 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\nlog(f'cache layout: {N_GROUP} groups x {GROUP} slices = {CACHE_SLICES} per slot')","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"HDR_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","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def 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","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ORDER_TAGS = [(32, 50), (32, 55), (32, 19)]\nDECODE_FAILED = []\n\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)","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def 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])","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ORDER_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)","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class 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","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class 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)","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def 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 DINOV2_SOURCE\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)","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"FINGERPRINT_TOL = 0.002\nEXPECTED_DINOV2_MEMBERS = 20\n_DINOV2_MATCHED_MEMBERS = 0\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\n\ndef find_weights(name='manifest.json'):\n    import json\n    roots = [\n        Path('/kaggle/input/datasets/pilkwang/rsna-knee-weights'),\n        Path('/kaggle/input/rsna-knee-weights'),\n    ]\n    valid = []\n    for root in roots:\n        path = root / name\n        if not path.is_file():\n            continue\n        try:\n            man = json.loads(path.read_text())\n        except (OSError, ValueError) as exc:\n            raise WeightsError(f'invalid pinned weights manifest at {path}: {exc}') from exc\n        if not isinstance(man.get('members'), list) or len(man['members']) != EXPECTED_DINOV2_MEMBERS:\n            raise WeightsError(f'{path} must list exactly {EXPECTED_DINOV2_MEMBERS} members')\n        if len({m.get('id') for m in man['members']}) != EXPECTED_DINOV2_MEMBERS:\n            raise WeightsError(f'{path} has duplicate or missing member ids')\n        missing = [m['file'] for m in man['members'] if not (root / m['file']).is_file()]\n        if missing:\n            raise WeightsError(\n                f'{root} lists {len(man[\"members\"])} members but misses {missing[0]!r}'\n            )\n        valid.append(root)\n    if len(valid) != 1:\n        raise WeightsError(f'expected one pinned rsna-knee-weights root, found {valid}')\n    return valid[0]\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'}\n# No-extra-pass diversity branch: smooth focal pooling is evaluated from\n# the same no-jitter public-member windows already used by the parent.\nLEGACY_FOLD_SOFTPOOL_BETA = {\n    'ACL': 6.0, 'MCL': 6.0,\n    'Medial Meniscus': 8.0, 'Lateral Meniscus': 8.0,\n    \"Baker's\": 8.0, 'Contusion': 8.0, 'Fracture': 10.0,\n}\nLEGACY_FOLD_SOFTPOOL_ALPHA = {\n    'ACL': 0.20, 'MCL': 0.20,\n    'Medial Meniscus': 0.25, 'Lateral Meniscus': 0.25,\n    \"Baker's\": 0.20, 'Contusion': 0.20, 'Fracture': 0.15,\n}\nLEGACY_MEMBER_WEIGHT_BY_TARGET = {'Lateral Meniscus': 15.0, 'Medial OA': 2.5, 'Lateral OA': 15.0, 'Contusion': 5.0}\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()\nLEGACY_BUNDLE_FILE = 'rsna_20260807_v1.pt'\nLEGACY_WEIGHT = 0.5\n\ndef find_legacy_bundle():\n    candidates = [\n        Path('/kaggle/input/datasets/pilkwang/rsna-knee-weights') / LEGACY_BUNDLE_FILE,\n        Path('/kaggle/input/rsna-knee-weights') / LEGACY_BUNDLE_FILE,\n    ]\n    hits = [path for path in candidates if path.is_file()]\n    if len(hits) > 1:\n        raise WeightsError(f'ambiguous legacy bundle: {hits}')\n    return hits[0] if hits else None\n\ndef legacy_group_members():\n    return {}\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            raise WeightsError(f\"{m['id']}: inline legacy state is forbidden\")\n        ck = torch.load(Path(path) / m['file'], map_location='cpu', weights_only=False)\n        state, fp = (ck['model'], ck.get('fingerprint'))\n        if fp is None:\n            raise WeightsError(f\"{m['id']}: stored fingerprint is required\")\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        check_fingerprint(model, dev, IMG, fp, tag=f\"{m['id']}: \")\n        global _DINOV2_MATCHED_MEMBERS\n        _DINOV2_MATCHED_MEMBERS += 1\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    # Raw-average the four members within each fold, rank each fold,\n    # then give all five folds equal weight.\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    if len(members) != EXPECTED_DINOV2_MEMBERS:\n        raise WeightsError(f'expected {EXPECTED_DINOV2_MEMBERS} DINOv2 members, found {len(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    failures = []\n    abort = threading.Event()\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            raise WeightsError(f\"{m['id']}: degenerate predictions\")\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                raise WeightsError(f\"{m['id']}: incomplete public-frontier windows\")\n            log(f\"  banked {m['id']} fold {m.get('fold', '?')} ({len(starts)} window(s); {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                    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            while not abort.is_set():\n                m, starts, jit = pop_next()\n                if m is None:\n                    return\n                try:\n                    p, public_p, public_soft, (fs, ws) = _run_member(path, m, dev, 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                except Exception as exc:\n                    with STATE_LOCK:\n                        failures.append((m['id'], str(dev), type(exc).__name__, str(exc)))\n                    abort.set()\n                    return\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        if failures:\n            raise WeightsError(f'DINOv2 member failure; no fallback permitted: {failures[0]}')\n        del Cte, Mte\n        gc.collect()\n    if _DINOV2_MATCHED_MEMBERS != EXPECTED_DINOV2_MEMBERS:\n        raise WeightsError(f'fingerprint gate failed: {_DINOV2_MATCHED_MEMBERS} / {EXPECTED_DINOV2_MEMBERS}')\n    if len(public_frontier_members) != EXPECTED_DINOV2_MEMBERS:\n        raise WeightsError(f'public-frontier inference incomplete: {len(public_frontier_members)} / {EXPECTED_DINOV2_MEMBERS} members')\n    log(f'DINOv2 fail-closed gate PASS: {_DINOV2_MATCHED_MEMBERS}/{EXPECTED_DINOV2_MEMBERS} fingerprints and members')\n    frontier_ids, frontier_acc = _combine(public_frontier_members)\n    sub = write_submission(frontier_acc, frontier_ids, test_df, 'submission.csv')\n    log(f'submission.csv = exact no-jitter public-frontier rank mean of {len(public_frontier_members)} member(s); {sub.shape}')\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\")","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def 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    if sub[TARGETS].isna().any().any():\n        raise WeightsError('missing study prediction; neutral fill is forbidden')\n    sub.to_csv(path, index=False)\n    return sub\n\ndef _v37_validate_submission(path, test_df, tag):\n    frame = pd.read_csv(path)\n    expected = ['StudyInstanceUID'] + TARGETS\n    if list(frame.columns) != expected:\n        raise ValueError(f'{tag}: columns differ from the competition contract')\n    if len(frame) != len(test_df) or not frame['StudyInstanceUID'].is_unique:\n        raise ValueError(f'{tag}: row count or StudyInstanceUID uniqueness failed')\n    if set(frame['StudyInstanceUID'].astype(str)) != set(test_df['StudyInstanceUID'].astype(str)):\n        raise ValueError(f'{tag}: StudyInstanceUID set differs from test.csv')\n    values = frame[TARGETS].to_numpy(np.float64)\n    if not np.isfinite(values).all():\n        raise ValueError(f'{tag}: non-finite prediction')\n    return frame\n\ndef main():\n    pkg = find_weights()\n    if pkg is None:\n        raise WeightsError('required public checkpoint manifest not found')\n    infer_from_package(pkg, DEVS[0])\n    _v37_validate_submission('submission.csv', pd.read_csv(ROOT / 'test.csv'), 'public frontier')\n","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"main()\nlog('done')","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if globals().get('_DINOV2_MATCHED_MEMBERS') != 20:\n    raise RuntimeError('DINOv2 20/20 fingerprint gate did not pass')\n_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']\n\ndef _one_a5_root(tag, candidates, marker):\n    hits = [Path(path) for path in candidates if Path(path).is_dir() and (Path(path) / marker).exists()]\n    if len(hits) != 1:\n        raise RuntimeError(f'{tag}: expected one direct root, found {hits}')\n    return hits[0]\n\nCOMP = _one_a5_root('competition', [\n    '/kaggle/input/competitions/rsna-knee-abnormality-detection',\n    '/kaggle/input/rsna-knee-abnormality-detection',\n], 'sample_submission.csv')\nCKPT = _one_a5_root('A5 weights', [\n    '/kaggle/input/datasets/mattiaangeli/knee-mri-fold-weights',\n    '/kaggle/input/knee-mri-fold-weights',\n], 'm_f0.pt')\nassert COMP is not None, 'competition data not attached'\nassert CKPT is not None, 'fold weights not attached'\nassert (COMP / 'sample_submission.csv').exists(), f'no competition data at {COMP}'\nassert list(CKPT.glob('*_f*.pt')), f'no checkpoints at {CKPT}'\nDEV = 'cuda' if torch.cuda.is_available() else 'cpu'\n","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"SERIES_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')","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"N_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 [k for k in missing if not k.startswith('enc.')], 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')}\")","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"AMP_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(\n                model(im, sl, sm, si, len(masks), vm=vm).float()\n            )\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\n\n# Macro ROC-AUC depends on ordering, so combine fold orderings rather\n# than allowing a fold's probability scale to dominate the mean.\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_a5_rank_mean = np.zeros((len(studies), len(LABELS)), np.float64)\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    _a5_rank_mean[_a5_ok] += ordinal / max(len(fold) - 1, 1)\n_a5_rank_mean /= preds.shape[0]\n_a5_rank_mean[~_a5_ok] = np.nan\nA5_PREDS = dict(zip(\n    sub_df['StudyInstanceUID'].astype(str), _a5_rank_mean.astype(np.float32)\n))\nfor _a5k, _a5v in _A5_SAVED.items():\n    globals()[_a5k] = _a5v\ndel _A5_SAVED, _a5k, _a5v","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"_a5_sub = pd.read_csv('/kaggle/working/submission.csv',\n                      dtype={'StudyInstanceUID': str})\nassert _a5_sub.columns.tolist()[1:] == A5_LABELS, 'submission schema drift'\nif A5_W > 0:\n    _a5_ours = np.stack([A5_PREDS[_u]\n                         for _u in _a5_sub['StudyInstanceUID'].astype(str)])\n    _a5_base_rank = _a5_sub[A5_LABELS].rank(method='average', pct=True)\n    _a5_ours_rank = pd.DataFrame(_a5_ours, columns=A5_LABELS,\n                                 index=_a5_sub.index).rank(method='average', pct=True)\n    _a5_sub[A5_LABELS] = (1.0 - A5_W) * _a5_base_rank + A5_W * _a5_ours_rank\n    assert np.isfinite(_a5_sub[A5_LABELS].to_numpy()).all()\n    _a5_sub.to_csv('/kaggle/working/submission.csv', index=False)","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from __future__ import annotations\nimport base64 as _rad_b64\nimport zlib as _rad_zlib\n_RAD_CAL_PAYLOAD = 'eNrtmk1vI8cRhv9KsJdcKKE/q6tzc4z4ZCMBcjQWhrCRDSG2ZEjaIEGQ/57n7RlRQ3KG4jqLJAcDS4o709NdXR9vvVU9/3z30+3N/bvffRuuawgxlm7eq2ePeffrpV8v/V9euvLraD3k6ilW6zn126vYd+U6eKmx9RiaF7OSx+X1weE67K7SdSgpVSauuaecUxr3rtp1LK0HyyV7y9Gmy/E6pBhTL61Zt2gWx+WtSew6JmOoM5AHutXp+ro8+ZrlsnvJOfDdfRL+Kl4zd2bqllNmga7rvrva2OzGNFuynGxpmnxrS/069hCtpt6T1dLLOQVsTbJ1fWunG2qXAX8NiU+7VK8rdqvNU89uwQwjpWyeLdTCnVy84ua9pthSjznHXLjDpZxbLe4WPRAQCT+LrSVcGGdLzNX0XKhesC2eV5uZ67lQPDlmSzUhS2+61ELtoTOyWGjdPudc73fvnj7c/Hg7ElpyzYXjdwIZ32m7X3INZ0crtvtc833ua6fyoUYUGf4H13rJpX+GK5aa5VbeWO9ye/03bLi97i8SpaSCl49nc4gdxI2p1dZyVmQnfL56jBH/j70GqSq6dyMROLHQGvCpcSnkYsyeohNErnVjbamVjs47wOpBa7BAsa61SXulDfSIwAbAkQqDmSK38WwImKK1kFJ3d11CpFqR1mPHlj1pWVAHeDfyU2hk0vGogz0GqCBbKmFMx9xIWEAbQ8I4PUvmAplQCeuij7GNXGMk3yhBsFIfEnvVE6HFYMHDtFuLzKwpya9gisaZduAkcyAvmw1ROjmd7OnBYytpOBqJjTyK4KzT0Pi0tQJYslc0nGqcNZV7dEaRvfcSewg9h4p41iwO+4CWMkNG1326VBmHFUoB7VoakzE+JAtYN/NknS9lLJ+9S5qR56Q2kLA4qgTuplGNmUJAkbXiGbrU0HCIsgtYaGOUVXbayNeykLfpGv8lulBfgiFEmx61xm3LTlrOPoa51Ng7IyJiT4tWxrE0ZmnJRnhawZsyLgjXIC9MRu0tRAgImkJ7bUyHKk1eUgIewtRjXGDJqO1mNJrHfNUty1HRW2SSoV3FAVIA//hrUXKANxhbRbEkgqAFKiCC43qOEXsPTaKtKCdkqx3/koMYsuP+mh4HrHoQtqSIw/h4DM7EpRL5zRirAcHiUDj2SUlr9fFAsElHBX/zWgJCQlw+83Qksw8Pt9+Ty0hmOBQBh9XQAr7fxjRQ2IkGTT/w8cAiBKwRc1jwcMh+WKtMgFShNaDGJWRAechNSOMUldXTynNIUPAaEKKkCv1cLFzxaowBOmX8vU8Pj1voWa5JTPFcGN4QXm+PpZPjA8QQYYp9Qab9rZiIAuLX8AA8f/jX4kHgI+BXCtBEeOTFvNPapIyC92YAEOmHypJcCSiFOpQi712M73IL8KiBX8Hz62pDNsAH8MK/rMR+tNSRIRJwAkIIY8Rn/fD2kB2V9I7BMX+KSJ/XJtNAbwFglmQZbu/90CZcMhAeZKudKAvlSBLwNwP1aA88BYpPdJRkbADGeBzWN2IOvySVELxyU0Lx0JHQHsFpEQRsCB9iO1qT3IOHGUjMDqeczX4BiIbvCjkiLD6t6G239p+gAML1KQuAdaLLdidDV6Y6uPR+9+3LT8KrlYgzAsjg7ok+VJakimvgAjn5qUFmtTGJKXGxSadg2UuLkWok4EvGJ0Hdsr+DmpVlGsUMZkxtuTI8vDAVaIsnSIDbK0DhVSpAFlu4iRtgrLYWRaArADOcFDAfErEdwBS8dWpNqHupW3o7nIukTmxlmASq4L/51ESrznqJTSkgCzslVSMncekb8659ljeyYttxK0oX9k50n3h2kDqoapToWt8S9/yO3tTXyteLu+19rkPViKkIblLnzJhJUhYENUJCtdfWKkEFe9WTsWin6azpqJFIfEwNyLNes+PZXFV3h+tIOXjb5mzIRnCLaWKuhnPtjsCVPAOwdkhQhBSMfWLVruTgwEM/WXt1FYgv5AN4IsyBiHrOSscCBjIomksgZCPFn9grqDrE9UXDQCSPfs5RXyeuQl3gwcEIdn5JzADhpG34s4uF5NQ24eh1GWISkEmYA6iFiNezYAbkKNGJhIk+l9XNXK3r7AgLT4YnRUuHicJS0NRLLG0KDrF1IbkaMzj2MoeKzAH/kTo9KsnWJe8gDZUuxs1iPi0CayABMdLIT4qQCbfENfCiAsujIsj9KMUQ1kXwXUBFZspHZm9Zj/dB/SrVy1qOJg9ApKAlmSQNpr6SjibnNgVoqZQCr8gllgsTiFAOCFSeDcYWuKOChZQXi5dPxouF5Oo6ogVTaxDwnVE8KfQFI6Zomwgb/oI4VG2Ae1MdsTQCwQuZp5ZROZPcdudWHrZRfwe4cPE1cv9L/FDuwRwGNYOttGllMRItS1K3sFDQDAwQMvgpfIzyIeQj2yTFOhomGLsBVPtAASGLqiXKnChASW/4ILUTGlftQlUVl8FDjifbKYIzLKXmco4anNPK6ZVl8MhVBs+D5YgTo8HXuIEDQDJF4wHEYL5PvEExn4PIt7x0JumDeUgjxHeFIZDt+6xN5mALCc6pMjTZ7oy8EomCUA09MTRvvuCLxyFC+sEWCGiqjE+HIAJ4g39Bi5sadSN9MJZaFWLbpubBNBvlmwrPAONJWS1DpaIgbyKuZSbKg7qZzgNKsqnwIX8RAOvINdgfRg0jPNJBWE+5xAQ9qDaAPh4nKInagjAL9otj26U+sAnbUERTF0QYjHV8j8OEA+mohtH9SLLuoUIh6uAWHI6yAw54uEsqL6zufMAAt3yW+6xSFLmKwEmYgIPlXHYbPAo3AvKovCk/0KR5m3fmKkpFz2W3ng58h7KzqVVHqVYUpfGlAJHvQ2dN7QKmXoQITggHUz9HGZhSty5smYHeSL4pFdvbXlXZcSJV7GCHKPpsePEmVAOm41WxbuW3Y+qkrhYhisbrSBqbGiGdAkBwd5gzNehxGUVhzu5JCKa2VAyL2pfYgYgUtcTwu3RKZzO2JublhfCDbO1Qqypu8SdTWO0501Z6iAAH68g21mECvjX8bZZ7yvpViqq9BlHCnhj7DFuiXm8qEwgrAkK9hpfbuU/nN/i4l7I/qQEnpR4qVHUxgDjblWuM2UZFhOpzp+apb8i4ua8gnyHrqPMHs839gK7gaaYDDtILqNTWOF8kxVYdMxlVDwE68/F8DR2CgpCSkkzkEvKY3x9GoRqjpn8ZLj62TyEoRVV1dxrV2GtNOMosPAjqSC6pm6yRKRJFM5wnixbhh6uLl9FdjElsUvX7WxR61T1gGohOkQaej27MxiR+DQjAndQ5SgL4Yb+VMKT2UncGK4se5hfeR7Jr6nygbTJcPGK7QSpXOoBJkuMXlFTYQX0aRsObYEQn22BNrDQdKwmZ1DDaZNcANxumdkGs3pZIJcaCcxBuPSlGziTf+UNZIgqmLMTWS1/XYNBxFowH5FchZb7uT5EQqervUK+Rc15pP55mBpKra6Wju5MCbZwiKOSS/HFuZyVRBFeeIoVrc35oNnVt1ARpKDaHF2BO1z3DLILOrOVZdhIG52ojyFxsVa1k6Bq+sOS7AA0upIqpiCt9Om8+1SsIoI4/ZYFKZq9tdwnhCzrVRpoCxpqSo+0ua1DNLCOMc3X19vGSZZ9znfEAMTUpymSGqYW/kpXU6FWV6+pah9OGLveaTkopOV1d3U9oWfAhMiyK46fRgPeL9LTSDAtUjj5cFN4D8S5zmaCjmaTjJ/Kvxb3MaFrHVI27QS2vRfcMCmeqcUXY+NX6652okyj19OEC3SaFrdWyeyJMxo7gPrANn17GjQ5RgtqvregNjzr1hYOOxATeos4b/IItGRxEFZC4aNruVL1ZbGx8ojpE5moLiGNavazB+baxPoXr/gK56zjI1VGbjtG8nA3Xg3SpFl2gtqzqsM/oGgb5Axj4w+XD1g48MBFrMAnR+TRxMci1+8h+uCC1e1nmC7XEWhf2zEdIw5SsCe3Tcc18XibsU/PKhJhd7a380s67RLEvQQWUw9KKjmps7qefVeub/IZQoLbK0qxnHRFP7qlOy8BURC7Fy2LDPk7N1F1VEm1lrZbSmSWVSoNk63DQXgvIohAjYcjXU7b/zI8u7RVvPiRChSqVjkiU6YQjrT1ImVAAN/WoKEp62V2aQGAdAuQKhSW5qouyIdQ4jNe5NS6I8v10hLIeqIIMqplDn71o0dYl4fEFkRZ4LmhFJNUSQqZCNlBT2fIWnKzJ9XWwG48bOzGZWEIffcVx/q23xAziBV83gf1cE4/+mvI8/EFV3QVmPW0a6rB7ZD314ploTllOSlFYqX3X4u7TJg6jmxLRWxit1FaPtArKoHfHeb3jwPmNGDqfvS+Iv9Ns14Vv6p9rfyft+HGiFqmJIQSU++rlbegPBqDumli9zoOGSptec8O6GAWqtaAgkOgqZ3P1WhQQ08aj2KGONuEIqdZetzuLFB6qQniid8HkZTnlyGsPGnA4lY5Qu1456WnbokG9IupwU0NoPhHTwRRUqynZU0HObV8QUyZuo/lb6tFhsdxb7bCoU9qWe8vLxBwj2laVzgS+bIZGMfee1Qaldl87gBZ5jjr3Y4rq2Xaf3LatohHwxzbqBKtv4d8bHnh1eUqfVRx07jc4zfzySrj8IGV9NMFX4mBKrq6FXc4Jz154/3737u7++fbxw+3Pz9N7eg0X0mHCeHfHbHrNhrCIpdXRA/LRRC4WR9sU/ZqJB46XJsJouwU1rPT+il6uKHqNAdbJ2InUJp0wVWBV7w8NuldU7uMyajZqh2N6UfeoM6ym1zLGizF6T6AnNQZiHO/KZMijZMOV2/yKQFKv0TSXq0Hb5teE9F4HLp50QKJ3OX64edZ7ie+++PLrd7t339z+5e7mx9/88Qt+f82dx5f//Omr6e8fvv/+49Pdwz0/f3/z19vH3z7x68uH++fpKhP+/Pjw/PDh4cfv+Hz86f5Jk99/93T7eHersfff/fnmh/H3y4fH8feLv9/x96ub5+l7vq9f0wj9msf8+HH6fhnDr3kMvzRGG3p8+PizVt3vaXy/ysjox5sPzx8fbxn+7cuWv7m9v3v68PFpsfH9pcWwLc1oyEI3f/7H/cPf7p7vnhZ6ev/+X/8GYIe3xg=='\n# Surgical reproduction of V48's deployed prediction branch.\n#\n# The pinned reference Rad family is fused with correct-contract E13, then\n# the same E13 heads run on the E11 layout at 0.15. No twin/legacy wrapper\n# follows it, matching the branch that produced V48's visible submission.\n\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\n\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\n_RAD_LABELS = [\n    'ACL', 'MCL', 'Medial Meniscus', 'Lateral Meniscus', 'Medial OA',\n    'Lateral OA', 'PF OA', 'Effusion', 'Synovitis', \"Baker's\",\n    'Contusion', 'Fracture',\n]\n_RAD_ALPHA = 0.50\n_RAD_EXCLUDE = (\"Baker's\", 'Fracture')\n_RAD_HEADS_SHA256 = '54f657826b3458a7ba3d462e198ba380732f2b136246182312704929874a9a2c'\n_RAD_REFERENCE_HEADS_SHA256 = '0f465649799ecfbccaac1767844639e7ced44e1bc9babde6e4bac7c5d9b89eaa'\n_RAD_ENCODER_SHA256 = '08629f7e7bd3e29b8ee9522ca3f65ce4d010a7ddf74f0ea3c7e3f3d0bbab0734'\n_RAD_E13_HEADS_SHA256 = 'ad9f19af73bfdf4e49263c0e45060dc3cb239e1195039b26dc8c0a3a6bcd1a8a'\n_RAD_E13_MEMBER_WEIGHT = 0.50\n_RAD_V48_SECOND_ALPHA = 0.15\n_RAD_TWIN_ALT_WEIGHT = 0.500001\n_RAD_TOKEN_DIM, _RAD_HEAD_DIM = 2048, 512\n\n_RAD_E11_SLOTS = [\n    ('SAG_NOFS', 'Sagittal', None, False),\n    ('COR_NOFS', 'Coronal', None, False),\n    ('AX_NOFS', 'Axial', None, False),\n    ('SAG_FS', 'Sagittal', None, True),\n]\n_RAD_E11_CROP_MM = 130.0\n_RAD_E11_CACHE_SLICES = 8\n_RAD_E11_IMG = 224\n\n_RAD_E13_SLOTS = [\n    ('SAG_FS', 'Sagittal', None, True),\n    ('COR_FS', 'Coronal', None, True),\n    ('AX_FS', 'Axial', None, True),\n    ('SAG_NOFS', 'Sagittal', None, False),\n]\n_RAD_E13_CROP_MM = 130.0\n_RAD_E13_CACHE_SLICES = 8\n_RAD_E13_IMG = 224\n\n# Our independently trained five-fold family.  Its preprocessing and estimator\n# are preserved from V35: native DICOM geometry/fat-sat handling and a mean of\n# per-fold percentile ranks (rather than v15's rank of the probability mean).\n_OUR_N_SLOT, _OUR_N_SLICE, _OUR_IMG = 3, 8, 224\n\n# Exact V40/E10 test representation: three fat-suppressed planes, eight\n# acquired slices per plane, full frame, legacy ordering/laterality/fill.\nSLOTS = [\n    ('SAG_FS', 'Sagittal', None, True),\n    ('COR_FS', 'Coronal', None, True),\n    ('AX_FS', 'Axial', None, True),\n]\nN_SLOT = len(SLOTS)\nCACHE_SLICES = 8\nIMG = CACHE_IMG = 224\nCROP_MM = 10_000.0\nSLICE_BAND = (0.2, 0.8)\nRULES = dict(RULES_LEGACY)\nTIME_BUDGET = 8.0 * 3600\n\n\ndef _rad_log(message):\n    print(f'[Rad-dual5] {message}', flush=True)\n\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\n\ndef _rad_find_file(name, expected_sha=None, explicit_env=None):\n    if explicit_env and _rad_os.environ.get(explicit_env):\n        candidates = [_RadPath(_rad_os.environ[explicit_env])]\n    else:\n        by_name = {\n            'ResNet50.pt': [\n                '/kaggle/input/datasets/marwanmath/resnet-50-radimagenet-marwan/ResNet50.pt',\n                '/kaggle/input/resnet-50-radimagenet-marwan/ResNet50.pt',\n            ],\n            'v52_radimagenet_heads.pt': [\n                '/kaggle/input/datasets/prvsiyan/rsna-knee-v52-radimagenet-heads-20260812/v52_radimagenet_heads.pt',\n                '/kaggle/input/rsna-knee-v52-radimagenet-heads-20260812/v52_radimagenet_heads.pt',\n                '/kaggle/input/datasets/antoinegg1/rsna-knee-e9-radimagenet-heads-v15/v52_radimagenet_heads.pt',\n                '/kaggle/input/rsna-knee-e9-radimagenet-heads-v15/v52_radimagenet_heads.pt',\n            ],\n            'v52_e11_heads.pt': [\n                '/kaggle/input/notebooks/sofiaanjenje/rsna-knee-e13-train/rsna_rad_e11/v52_e11_heads.pt',\n                '/kaggle/input/rsna-knee-e13-train/rsna_rad_e11/v52_e11_heads.pt',\n                '/kaggle/input/notebooks/sofiaanjenje/rsna-knee-e11-train/rsna_rad_e11/v52_e11_heads.pt',\n                '/kaggle/input/rsna-knee-e11-train/rsna_rad_e11/v52_e11_heads.pt',\n                '/kaggle/input/datasets/antoinegg1/rsna-knee-e11-diverse-heads-v20/v52_e11_heads.pt',\n                '/kaggle/input/rsna-knee-e11-diverse-heads-v20/v52_e11_heads.pt',\n            ],\n        }\n        if name not in by_name:\n            raise FileNotFoundError(f'unpinned Rad artifact name: {name}')\n        candidates = [_RadPath(path) for path in by_name[name]]\n    existing = [path for path in candidates if path.is_file()]\n    valid = [\n        path for path in existing\n        if expected_sha is None or _rad_sha256(path) == expected_sha\n    ]\n    if len(valid) != 1:\n        raise RuntimeError(\n            f'expected one verified Rad artifact {name}, found {valid}; existing={existing}'\n        )\n    return valid[0]\n\n\nclass _RadEncoder(_rad_nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.backbone = _rad_nn.Sequential(\n            *list(_rad_resnet50(weights=None).children())[:-2]\n        )\n\n    def forward(self, image):\n        return self.backbone(image).mean(dim=(2, 3))\n\n\nclass _RadHead(_rad_nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.project = _rad_nn.Sequential(\n            _rad_nn.LayerNorm(_RAD_TOKEN_DIM),\n            _rad_nn.Linear(_RAD_TOKEN_DIM, _RAD_HEAD_DIM),\n            _rad_nn.GELU(),\n        )\n        self.plane = _rad_nn.Parameter(_rad_torch.randn(N_SLOT, _RAD_HEAD_DIM) * .01)\n        self.position = _rad_nn.Parameter(_rad_torch.randn(CACHE_SLICES, _RAD_HEAD_DIM) * .01)\n        self.query = _rad_nn.Parameter(_rad_torch.randn(len(_RAD_LABELS), _RAD_HEAD_DIM) * .02)\n        self.attn = _rad_nn.MultiheadAttention(\n            _RAD_HEAD_DIM, 8, dropout=.10, batch_first=True\n        )\n        self.fuse = _rad_nn.Sequential(\n            _rad_nn.LayerNorm(_RAD_HEAD_DIM * 4),\n            _rad_nn.Linear(_RAD_HEAD_DIM * 4, _RAD_HEAD_DIM),\n            _rad_nn.GELU(),\n            _rad_nn.Dropout(.15),\n        )\n        self.weight = _rad_nn.Parameter(\n            _rad_torch.randn(len(_RAD_LABELS), _RAD_HEAD_DIM) * .02\n        )\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(\n            query, token, token, key_padding_mask=key_padding, need_weights=False\n        )[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(\n            [attended, mean, _rad_torch.abs(attended - mean), attended * mean], dim=-1\n        ))\n        return (fused * self.weight.unsqueeze(0)).sum(-1) + self.bias\n\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 = {\n        'version': 'v52-radimagenet-resnet50-official-1',\n        'targets': _RAD_LABELS,\n        'encoder_sha256': _RAD_ENCODER_SHA256,\n        'encoder_source_commit': '0ce16f7375db4236e646829d1eca61cdb4282133',\n        'img': 224,\n        'slices_per_plane': 8,\n        'feature': 'global_average_pool',\n    }\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\n\ndef _rad_load_e13_heads(device):\n    # V48 used an unqualified filename shared by E11 and E13. Resolve the\n    # intended E13 bundle by content and validate its complete pixel contract.\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 = {\n        'version': 'e11-radimagenet-resnet50-diverse-1',\n        'targets': _RAD_LABELS,\n        'encoder_sha256': _RAD_ENCODER_SHA256,\n        'slots': [list(slot) for slot in _RAD_E13_SLOTS],\n        'crop_mm': _RAD_E13_CROP_MM,\n        'img': _RAD_E13_IMG,\n        'slices_per_plane': _RAD_E13_CACHE_SLICES,\n        'feature': 'global_average_pool',\n    }\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\ndef _rad_load_models(device):\n    encoder_path = _rad_find_file(\n        'ResNet50.pt', _RAD_ENCODER_SHA256, explicit_env='RSNA_RAD_WEIGHT_PATH'\n    )\n    encoder = _RadEncoder()\n    encoder.load_state_dict(\n        _rad_torch.load(encoder_path, map_location='cpu', weights_only=True), strict=True\n    )\n    if sum(parameter.numel() for parameter in encoder.parameters()) != 23_508_032:\n        raise RuntimeError('V36 RadImageNet encoder parameter-count drift')\n    encoder.eval().to(device)\n    for parameter in encoder.parameters():\n        parameter.requires_grad_(False)\n    if device.type == 'cuda' and _rad_torch.cuda.device_count() > 1:\n        encoder = _rad_nn.DataParallel(\n            encoder, device_ids=list(range(_rad_torch.cuda.device_count()))\n        )\n\n    alt_heads, alt_path = _rad_load_public_heads(device, _RAD_HEADS_SHA256)\n    reference_heads, reference_path = _rad_load_public_heads(\n        device, _RAD_REFERENCE_HEADS_SHA256\n    )\n    if alt_path == reference_path:\n        raise RuntimeError('twin E10 branches resolved to the same artifact')\n    return encoder, alt_heads, reference_heads, str(encoder_path), alt_path, reference_path\n\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        (n, slots * slices, _RAD_TOKEN_DIM), _rad_np.float16\n    )\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 (\n        96 if device.type == 'cuda' else 8\n    )\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')\n               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\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')\n               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\n\ndef _rad_rank_columns(values):\n    return _rad_pd.DataFrame(\n        _rad_np.asarray(values, dtype=_rad_np.float64)\n    ).rank(method='average', pct=True).to_numpy(_rad_np.float64)\n\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\ndef _rad_main():\n    started = _rad_time.time()\n    work = _RadPath(_rad_os.environ.get('RSNA_RAD_OUTPUT_DIR', '/kaggle/working'))\n    primary = work / 'submission.csv'\n    if not primary.is_file():\n        raise FileNotFoundError('V37 requires the completed DINO parent submission.csv')\n    test = _rad_pd.read_csv(ROOT / 'test.csv', dtype={'StudyInstanceUID': str})\n    expected_ids = test['StudyInstanceUID'].astype(str).tolist()\n    baseline = _rad_pd.read_csv(primary, dtype={'StudyInstanceUID': str})\n    _rad_validate(baseline, expected_ids)\n\n    device = _rad_torch.device('cuda:0' if _rad_torch.cuda.is_available() else 'cpu')\n    if device.type != 'cuda':\n        raise RuntimeError('V37 RadImageNet inference requires CUDA')\n    (encoder, public_heads, reference_heads, encoder_path,\n     public_heads_path, reference_heads_path) = _rad_load_models(device)\n\n    # Family 1: public v15/E10 legacy pixels.  Keep this path bit-for-bit as in\n    # V36, including rank(mean(fold probability)).\n    test_series = _rad_pd.read_csv(\n        ROOT / 'test_series.csv',\n        dtype={'StudyInstanceUID': str, 'SeriesInstanceUID': str},\n    )\n    plane = dict(zip(test_series.SeriesInstanceUID, test_series.Anatomical_Plane))\n    headers = annotate(walk('test_series'))\n    studies, pixels, slot_mask = build_cache(\n        pick_slots(headers, plane), plane, lat_of(headers, 'test-e10 '), 'test-e10'\n    )\n    by_uid = {str(uid): index for index, uid in enumerate(studies)}\n    missing = [uid for uid in expected_ids if uid not in by_uid]\n    if missing:\n        raise RuntimeError(f'{len(missing)} test studies absent from public-v15 cache')\n    order = _rad_np.asarray([by_uid[uid] for uid in expected_ids], dtype=_rad_np.int64)\n    pixels, slot_mask = pixels[order], slot_mask[order]\n    token_count = int(\n        _rad_np.repeat(slot_mask[:, :, None], CACHE_SLICES, axis=2).sum()\n    )\n    if token_count < int(0.85 * len(test) * N_SLOT * CACHE_SLICES):\n        raise RuntimeError(f'insufficient acquired public-v15 test slices: {token_count}')\n\n    features, token_mask = _rad_encode(encoder, pixels, slot_mask, device)\n    del pixels, slot_mask, headers\n    _rad_gc.collect()\n    public_fold_predictions = [\n        _rad_predict_head(head, features, token_mask, device)\n        for head in public_heads\n    ]\n    reference_fold_predictions = [\n        _rad_predict_head(head, features, token_mask, device)\n        for head in reference_heads\n    ]\n    if len(public_fold_predictions) != 5 or len(reference_fold_predictions) != 5:\n        raise RuntimeError('twin E10 inference did not use all ten heads')\n\n    # Preserve each public recipe's rank(mean(fold probability)) estimator.\n    public_probability = _rad_np.mean(_rad_np.stack(public_fold_predictions), axis=0)\n    reference_probability = _rad_np.mean(\n        _rad_np.stack(reference_fold_predictions), axis=0\n    )\n    public_rank = _rad_rank_columns(public_probability)\n    reference_rank = _rad_rank_columns(reference_probability)\n    del (public_heads, reference_heads, public_fold_predictions,\n         reference_fold_predictions, public_probability, reference_probability,\n         features, token_mask)\n    _rad_gc.collect()\n    _rad_torch.cuda.empty_cache()\n    _rad_log(\n        f'twin public-v15 families complete ({public_heads_path}; {reference_heads_path})'\n    )\n\n    # One new member from V48: three fat-sensitive planes plus a sagittal\n    # structural anchor, all at a 130 mm crop. Average ranks inside the Rad block\n    # and re-rank the result exactly as V48 does before the unchanged E10 vote.\n    globals().update(\n        SLOTS=list(_RAD_E13_SLOTS),\n        N_SLOT=len(_RAD_E13_SLOTS),\n        CACHE_SLICES=int(_RAD_E13_CACHE_SLICES),\n        IMG=int(_RAD_E13_IMG),\n        CACHE_IMG=int(_RAD_E13_IMG),\n        CROP_MM=float(_RAD_E13_CROP_MM),\n        RULES=dict(RULES_LEGACY),\n    )\n    e13_heads, e13_path = _rad_load_e13_heads(device)\n    headers = annotate(walk('test_series'))\n    studies, pixels, slot_mask = build_cache(\n        pick_slots(headers, plane), plane, lat_of(headers, 'test-e13 '), 'test-e13'\n    )\n    by_uid = {str(uid): index for index, uid in enumerate(studies)}\n    missing = [uid for uid in expected_ids if uid not in by_uid]\n    if missing:\n        raise RuntimeError(f'{len(missing)} test studies absent from E13 cache')\n    order = _rad_np.asarray([by_uid[uid] for uid in expected_ids], dtype=_rad_np.int64)\n    pixels, slot_mask = pixels[order], slot_mask[order]\n    e13_token_count = int(\n        _rad_np.repeat(slot_mask[:, :, None], CACHE_SLICES, axis=2).sum()\n    )\n    if e13_token_count < int(0.85 * len(test) * N_SLOT * CACHE_SLICES):\n        raise RuntimeError(f'insufficient acquired E13 test slices: {e13_token_count}')\n    e13_features, e13_token_mask = _rad_encode(\n        encoder, pixels, slot_mask, device\n    )\n    del pixels, slot_mask, headers\n    _rad_gc.collect()\n    e13_predictions = [\n        _rad_predict_head(head, e13_features, e13_token_mask, device)\n        for head in e13_heads\n    ]\n    if len(e13_predictions) != 5:\n        raise RuntimeError('E13 inference did not use all five heads')\n    e13_probability = _rad_np.mean(_rad_np.stack(e13_predictions), axis=0)\n    if (\n        e13_probability.shape != (len(test), len(_RAD_LABELS))\n        or not _rad_np.isfinite(e13_probability).all()\n    ):\n        raise RuntimeError(f'invalid E13 prediction shape/value: {e13_probability.shape}')\n    e13_rank = _rad_rank_columns(e13_probability)\n    public_rank = _rad_rank_columns(\n        (1.0 - _RAD_E13_MEMBER_WEIGHT) * public_rank\n        + _RAD_E13_MEMBER_WEIGHT * e13_rank\n    )\n    reference_rank = _rad_rank_columns(\n        (1.0 - _RAD_E13_MEMBER_WEIGHT) * reference_rank\n        + _RAD_E13_MEMBER_WEIGHT * e13_rank\n    )\n    # V48 resolves this same bundle again after switching pixel layouts.\n    del (e13_predictions, e13_probability, e13_rank,\n         e13_features, e13_token_mask)\n    _rad_gc.collect()\n    _rad_torch.cuda.empty_cache()\n    _rad_log(\n        f'E13 FS-crop member complete at Rad-block weight '\n        f'{_RAD_E13_MEMBER_WEIGHT:.2f} ({e13_path})'\n    )\n\n    # E10 keeps its audited 0.50 parent/Rad vote. The two excluded findings\n    # remain the raw parent values, matching the audited deployment.\n    baseline_rank = _rad_rank_columns(baseline[_RAD_LABELS].to_numpy())\n\n    def _rad_e10_branch(head_rank):\n        branch = baseline.copy()\n        for index, target in enumerate(_RAD_LABELS):\n            if target not in _RAD_EXCLUDE:\n                branch[target] = (\n                    (1.0 - _RAD_ALPHA) * baseline_rank[:, index]\n                    + _RAD_ALPHA * head_rank[:, index]\n                )\n        return branch\n\n    candidate_alt = _rad_e10_branch(public_rank)\n    candidate_reference = _rad_e10_branch(reference_rank)\n    for branch in (candidate_alt, candidate_reference):\n        for target in _RAD_EXCLUDE:\n            if not _rad_np.array_equal(\n                branch[target].to_numpy(), baseline[target].to_numpy()\n            ):\n                raise RuntimeError(f'E10 failed to preserve raw parent values for {target}')\n        _rad_validate(branch, expected_ids)\n    # Diagnostic E10 output only; the final equal rank mean is formed after E11\n    # and the legacy-DINO tie-break have completed independently in each branch.\n    candidate = baseline.copy()\n    alt_e10_rank = _rad_rank_columns(candidate_alt[_RAD_LABELS].to_numpy())\n    reference_e10_rank = _rad_rank_columns(\n        candidate_reference[_RAD_LABELS].to_numpy()\n    )\n    candidate[_RAD_LABELS] = (\n        _RAD_TWIN_ALT_WEIGHT * alt_e10_rank\n        + (1.0 - _RAD_TWIN_ALT_WEIGHT) * reference_e10_rank\n    )\n    _rad_validate(candidate, expected_ids)\n    e10_path = work / 'submission_e10_v2.csv'\n    candidate.to_csv(e10_path, index=False)\n    _rad_log(\n        f'twin E10 branches complete at alpha={_RAD_ALPHA:.2f}; '\n        f'preserved raw={list(_RAD_EXCLUDE)}'\n    )\n\n    # V48's successful run selected the E13 bundle a second time after\n    # installing the older E11 slot order. Express that observed behavior\n    # directly, without relying on duplicate-filename directory order.\n    globals().update(\n        SLOTS=list(_RAD_E11_SLOTS),\n        N_SLOT=len(_RAD_E11_SLOTS),\n        CACHE_SLICES=int(_RAD_E11_CACHE_SLICES),\n        IMG=int(_RAD_E11_IMG),\n        CACHE_IMG=int(_RAD_E11_IMG),\n        CROP_MM=float(_RAD_E11_CROP_MM),\n        RULES=dict(RULES_LEGACY),\n    )\n    headers = annotate(walk('test_series'))\n    studies, pixels, slot_mask = build_cache(\n        pick_slots(headers, plane), plane,\n        lat_of(headers, 'test-v48-pass2 '), 'test-v48-pass2'\n    )\n    by_uid = {str(uid): index for index, uid in enumerate(studies)}\n    missing = [uid for uid in expected_ids if uid not in by_uid]\n    if missing:\n        raise RuntimeError(f'{len(missing)} test studies absent from V48 pass-2 cache')\n    order = _rad_np.asarray([by_uid[uid] for uid in expected_ids], dtype=_rad_np.int64)\n    pixels, slot_mask = pixels[order], slot_mask[order]\n    v48_pass2_token_count = int(\n        _rad_np.repeat(slot_mask[:, :, None], CACHE_SLICES, axis=2).sum()\n    )\n    if v48_pass2_token_count < int(0.55 * len(test) * N_SLOT * CACHE_SLICES):\n        raise RuntimeError(\n            f'insufficient acquired V48 pass-2 slices: {v48_pass2_token_count}'\n        )\n    v48_features, v48_token_mask = _rad_encode(\n        encoder, pixels, slot_mask, device\n    )\n    del pixels, slot_mask, headers\n    _rad_gc.collect()\n    v48_pass2_predictions = [\n        _rad_predict_head(head, v48_features, v48_token_mask, device)\n        for head in e13_heads\n    ]\n    if len(v48_pass2_predictions) != 5:\n        raise RuntimeError('V48 second pass did not use all five E13 heads')\n    v48_pass2_probability = _rad_np.mean(\n        _rad_np.stack(v48_pass2_predictions), axis=0\n    )\n    if (\n        v48_pass2_probability.shape != (len(test), len(_RAD_LABELS))\n        or not _rad_np.isfinite(v48_pass2_probability).all()\n    ):\n        raise RuntimeError(\n            f'invalid V48 pass-2 prediction: {v48_pass2_probability.shape}'\n        )\n    v48_pass2_rank = _rad_rank_columns(v48_pass2_probability)\n\n    reference_branch = candidate_reference.copy()\n    reference_branch[_RAD_LABELS] = _rad_rank_columns(\n        (1.0 - _RAD_V48_SECOND_ALPHA)\n        * _rad_rank_columns(candidate_reference[_RAD_LABELS].to_numpy())\n        + _RAD_V48_SECOND_ALPHA * v48_pass2_rank\n    )\n    _rad_validate(reference_branch, expected_ids)\n    _rad_log(\n        f'V48 second E13 pass complete at alpha '\n        f'{_RAD_V48_SECOND_ALPHA:.2f} on the E11 slot layout'\n    )\n\n    # V48 deploys the pinned reference branch directly after the second pass.\n    # The alternative-head twin and legacy-DINO tie-break are not part of .917.\n    _RAD_CAL = _rad_json.loads(_rad_zlib.decompress(\n        _rad_b64.b64decode(_RAD_CAL_PAYLOAD)).decode())\n    _RAD_CAL_GATE = set(_RAD_CAL['gate'])\n    _RAD_CAL_W = 0.40\n\n    def _rad_cal_protocol(uids):\n        frame = _rad_pd.read_csv(\n            ROOT / 'test_series.csv',\n            dtype={'StudyInstanceUID': str, 'SeriesInstanceUID': str},\n        )\n        frame['StudyInstanceUID'] = frame['StudyInstanceUID'].astype(str)\n        index = _rad_pd.Index([str(u) for u in uids], name='StudyInstanceUID')\n        table = _rad_pd.DataFrame(index=index)\n        table['n_series'] = frame.groupby(\n            'StudyInstanceUID').size().reindex(index).fillna(0)\n        for plane in ('Sagittal', 'Coronal', 'Axial'):\n            part = frame[frame['Anatomical_Plane'].astype(str) == plane]\n            table[f'n_{plane[:3]}'] = part.groupby(\n                'StudyInstanceUID').size().reindex(index).fillna(0)\n        for flag in ('Fat_Suppression', 'Fluid_Sensitive'):\n            marked = frame[_rad_pd.to_numeric(\n                frame[flag], errors='coerce').fillna(0) > 0]\n            table[flag[:3]] = marked.groupby(\n                'StudyInstanceUID').size().reindex(index).fillna(0)\n            for plane in ('Sagittal', 'Coronal', 'Axial'):\n                part = marked[marked['Anatomical_Plane'].astype(str) == plane]\n                table[f'{flag[:3]}_{plane[:3]}'] = part.groupby(\n                    'StudyInstanceUID').size().reindex(index).fillna(0)\n        if list(table.columns) != list(_RAD_CAL['protocol_columns']):\n            raise RuntimeError('calibration protocol layout mismatch')\n        return table.to_numpy(_rad_np.float64)\n\n    def _rad_calibrate(branch):\n        base = baseline_rank\n        public = reference_rank\n        pass2 = v48_pass2_rank\n        mean = (base + public + pass2) / 3.0\n        blocks = [base, public, pass2, public - base, pass2 - base, mean]\n        for _grp in _RAD_CAL['groups']:\n            cols = [_RAD_LABELS.index(t) for t in _grp]\n            blocks.append(mean[:, cols].mean(axis=1, keepdims=True))\n        blocks.append(_rad_cal_protocol(expected_ids))\n        x = _rad_np.concatenate(blocks, axis=1)\n        centre = _rad_np.asarray(_RAD_CAL['mean'], _rad_np.float64)\n        spread = _rad_np.asarray(_RAD_CAL['scale'], _rad_np.float64)\n        coef = _rad_np.asarray(_RAD_CAL['coef'], _rad_np.float64)\n        bias = _rad_np.asarray(_RAD_CAL['intercept'], _rad_np.float64)\n        if x.shape[1] != coef.shape[1]:\n            raise RuntimeError(\n                f'calibration expects {coef.shape[1]} columns, built {x.shape[1]}')\n        adjusted = _rad_rank_columns(((x - centre) / spread) @ coef.T + bias)\n        out = branch.copy()\n        values = out[_RAD_LABELS].to_numpy(_rad_np.float64).copy()\n        for index, target in enumerate(_RAD_LABELS):\n            if target in _RAD_CAL_GATE:\n                values[:, index] = (\n                    (1.0 - _RAD_CAL_W) * values[:, index]\n                    + _RAD_CAL_W * adjusted[:, index]\n                )\n        out[_RAD_LABELS] = _rad_rank_columns(values)\n        _rad_validate(out, expected_ids)\n        return out\n\n    final = _rad_calibrate(reference_branch)\n    globals()['V18_CALIBRATOR_APPLIED'] = True\n    globals()['V18_CAL_GATE'] = tuple(sorted(_RAD_CAL_GATE))\n    _rad_validate(final, expected_ids)\n    temporary = primary.with_suffix('.csv.tmp')\n    final.to_csv(temporary, index=False)\n    _rad_os.replace(temporary, primary)\n\n    receipt = {\n        'recipe': 'V48 deployed reference branch: correct E13@0.50-inside-Rad -> E10@0.50 -> same E13 on E11 layout@0.15',\n        'e13_member_weight_inside_rad': _RAD_E13_MEMBER_WEIGHT,\n        'e10_alpha': _RAD_ALPHA,\n        'e10_preserved_targets': list(_RAD_EXCLUDE),\n        'v48_second_alpha': _RAD_V48_SECOND_ALPHA,\n        'reference_heads_sha256': _RAD_REFERENCE_HEADS_SHA256,\n        'e13_heads_sha256': _RAD_E13_HEADS_SHA256,\n        'v48_second_heads_sha256': _RAD_E13_HEADS_SHA256,\n        'v48_second_slots': [list(slot) for slot in _RAD_E11_SLOTS],\n        'encoder_sha256': _RAD_ENCODER_SHA256,\n        'test_studies': len(expected_ids),\n        'e10_tokens': token_count,\n        'v48_second_tokens': v48_pass2_token_count,\n        'e13_tokens': e13_token_count,\n        'submission_sha256': _rad_sha256(primary),\n    }\n    (work / 'v50_v2_repro_receipt.json').write_text(\n        _rad_json.dumps(receipt, indent=2, sort_keys=True) + '\\n'\n    )\n    del (encoder, e13_heads, v48_pass2_predictions,\n         v48_pass2_probability, v48_pass2_rank, v48_features, v48_token_mask)\n    _rad_gc.collect()\n    _rad_torch.cuda.empty_cache()\n    _rad_log(\n        f'V48 reference branch complete; reference-v15={reference_heads_path}; '\n        f'e13-two-pass={e13_path}; second_alpha='\n        f'{_RAD_V48_SECOND_ALPHA:.2f}; encoder={encoder_path}; '\n        f'elapsed={(_rad_time.time()-started)/60:.1f}m'\n    )\n\n\n_rad_main()\n","metadata":{},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if globals().get('_DINOV2_MATCHED_MEMBERS') != 20:\n    raise RuntimeError('DINOv2 20/20 fingerprint gate did not pass')\nimport numpy as _ke_np\nimport pandas as _ke_pd\nfrom pathlib import Path as _KePath\n\n_ke_primary = _KePath('/kaggle/working/submission.csv')\n_ke_ours = _ke_pd.read_csv(_ke_primary, dtype={'StudyInstanceUID': str})\n_KE_LAB = [c for c in _ke_ours.columns if c != 'StudyInstanceUID']\n\n_KE_SRC = 'import os, glob, time, gc, hashlib\\nos.environ.setdefault(\\'HF_HUB_OFFLINE\\', \\'1\\')\\nos.environ.setdefault(\\'TRANSFORMERS_OFFLINE\\', \\'1\\')\\nos.environ.setdefault(\\'HF_HUB_DISABLE_TELEMETRY\\', \\'1\\')\\nimport numpy as np\\nimport torch, torch.nn as nn, torch.nn.functional as F\\nimport timm\\ntorch.backends.cudnn.benchmark = True\\ntorch.backends.cuda.matmul.allow_tf32 = True\\nIMG = 336\\nCROP_MM = 140.0\\nSPAN_LO, SPAN_HI = 0.02, 0.98\\nSLOTS = [(\"Sagittal\", 1, 18), (\"Sagittal\", 0, 14),\\n         (\"Coronal\", 1, 12), (\"Coronal\", 0, 8), (\"Axial\", -1, 12)]\\nMAXS = sum(slot[2] for slot in SLOTS)\\nK_EVAL = 62\\nNORM = \"imagenet\"\\nLAB = [\"ACL\", \"MCL\", \"Medial Meniscus\", \"Lateral Meniscus\", \"Medial OA\",\\n       \"Lateral OA\", \"PF OA\", \"Effusion\", \"Synovitis\", \"Baker\\'s\",\\n       \"Contusion\", \"Fracture\"]\\n_MEAN = torch.tensor([0.485, 0.456, 0.406]).view(3, 1, 1)\\n_STD = torch.tensor([0.229, 0.224, 0.225]).view(3, 1, 1)\\n_SLOTS64 = [(\"Sagittal\", 1, 18), (\"Sagittal\", 0, 14),\\n            (\"Coronal\", 1, 12), (\"Coronal\", 0, 8), (\"Axial\", -1, 12)]\\n_SLOTS44 = [(\"Sagittal\", 1, 12), (\"Sagittal\", 0, 10),\\n            (\"Coronal\", 1, 8), (\"Coronal\", 0, 6), (\"Axial\", -1, 8)]\\nARMS = [\\n    {\"name\": \"maxspan-v5\", \"file\": \"raptor_ft_coatnet_v5_full_swa.pt\",\\n     \"arch\": \"coatnet_rmlp_2_rw_384.sw_in12k_ft_in1k\", \"res\": 384,\\n     \"img\": 336, \"slots\": _SLOTS64, \"span\": (0.02, 0.98), \"k_eval\": 62,\\n     \"reverse\": False, \"w\": 0.60},\\n    {\"name\": \"native384dense-v10\", \"file\": \"raptor_ft_coatnet_v10_full.pt\",\\n     \"arch\": \"coatnet_rmlp_2_rw_384.sw_in12k_ft_in1k\", \"res\": 384,\\n     \"img\": 384, \"slots\": _SLOTS64, \"span\": (0.02, 0.98), \"k_eval\": 62,\\n     \"reverse\": False, \"w\": 0.10},\\n    {\"name\": \"maxspan-v5-reverse\", \"file\": \"raptor_ft_coatnet_v5_full_swa.pt\",\\n     \"arch\": \"coatnet_rmlp_2_rw_384.sw_in12k_ft_in1k\", \"res\": 384,\\n     \"img\": 336, \"slots\": _SLOTS64, \"span\": (0.02, 0.98), \"k_eval\": 62,\\n     \"reverse\": True, \"w\": 0.10},\\n    {\"name\": \"native384-v8\", \"file\": \"raptor_ft_coatnet_v8_full_swa.pt\",\\n     \"arch\": \"coatnet_rmlp_2_rw_384.sw_in12k_ft_in1k\", \"res\": 384,\\n     \"img\": 384, \"slots\": _SLOTS44, \"span\": (0.06, 0.94), \"k_eval\": 42,\\n     \"reverse\": False, \"w\": 0.20},\\n]\\n\\ndef build_backbone(arch, pretrained=False):\\n    hybrid = arch.startswith((\\'maxvit\\', \\'maxxvit\\', \\'coatnet\\', \\'coat_\\', \\'convnext\\'))\\n    is_vit = not hybrid and any((k in arch for k in (\\'vit\\', \\'deit\\', \\'dinov2\\', \\'eva\\', \\'beit\\')))\\n    kw = dict(pretrained=pretrained, num_classes=0, in_chans=3)\\n    if is_vit:\\n        kw.update(global_pool=\\'token\\', dynamic_img_size=True)\\n    else:\\n        kw.update(global_pool=\\'avg\\')\\n    return timm.create_model(arch, **kw)\\n\\nclass RaptorClassifier(nn.Module):\\n\\n    def __init__(self, backbone, F_dim=768, n=12, drop=0.2):\\n        super().__init__()\\n        self.backbone = backbone\\n        self.norm = nn.LayerNorm(F_dim)\\n        self.att = nn.Sequential(nn.Linear(F_dim, 256), nn.Tanh(), nn.Dropout(drop), nn.Linear(256, n))\\n        self.clsW = nn.Parameter(torch.zeros(n, F_dim))\\n        self.clsb = nn.Parameter(torch.zeros(n))\\n        nn.init.trunc_normal_(self.clsW, std=0.02)\\n        self.n = n\\n\\n    def encode(self, x):\\n        B, K = x.shape[:2]\\n        f = self.backbone(x.flatten(0, 1))\\n        return f.view(B, K, -1)\\n\\n    def head(self, feats):\\n        h = self.norm(feats)\\n        a = self.att(h)\\n        a = torch.softmax(a, dim=1)\\n        pooled = torch.einsum(\\'bkn,bkf->bnf\\', a, h)\\n        logits = (pooled * self.clsW).sum(-1) + self.clsb\\n        return logits\\n\\n    def forward(self, x):\\n        return self.head(self.encode(x))\\n\\ndef load_model(pt_path, arch_default, res_default, device, ngpu=1):\\n    ck = torch.load(pt_path, map_location=\\'cpu\\', weights_only=False)\\n    arch = ck.get(\\'arch\\', arch_default)\\n    ck_res = int(ck.get(\\'res\\', res_default))\\n    bb = build_backbone(arch, pretrained=False)\\n    model = RaptorClassifier(bb, F_dim=bb.num_features)\\n    model.load_state_dict(ck[\\'model\\'], strict=True)\\n    model.eval().to(device)\\n    del ck\\n    gc.collect()\\n    return (model, ck_res)\\n\\ndef load_refit_head(pt_path, feature_dim, device):\\n    ck = torch.load(pt_path, map_location=\\'cpu\\', weights_only=False)\\n    state = ck.get(\\'model\\', ck)\\n    head = RaptorClassifier(nn.Identity(), F_dim=int(feature_dim))\\n    head_state = {name: tensor for name, tensor in state.items()\\n                  if not name.startswith(\\'backbone.\\')}\\n    head.load_state_dict(head_state, strict=True)\\n    head.eval().to(device)\\n    del ck, state, head_state\\n    gc.collect()\\n    return head\\n\\ndef _eval_centers(mask, D, k):\\n    valid = np.where(mask > 0)[0]\\n    if len(valid) < 3:\\n        valid = np.arange(min(3, D))\\n    lo, hi = (int(valid.min()), int(valid.max()))\\n    cs = [c for c in range(lo + 1, hi) if c - 1 >= lo and c + 1 <= hi]\\n    if not cs:\\n        cs = [max(1, min((lo + hi) // 2, D - 2))]\\n    idx = np.linspace(0, len(cs) - 1, k).round().astype(int)\\n    return [cs[i] for i in idx]\\n\\ndef eval_windows(vol, mask, k, res, norm=NORM):\\n    D = vol.shape[0]\\n    cs = _eval_centers(mask, D, k)\\n    wins = np.empty((len(cs), 3, res, res), np.float32)\\n    for j, c in enumerate(cs):\\n        c = max(1, min(c, D - 2))\\n        tri = np.stack([vol[c - 1], vol[c], vol[c + 1]], 0).astype(np.float32) / 255.0\\n        t = torch.from_numpy(tri)\\n        if t.shape[-1] != res:\\n            t = F.interpolate(t[None], size=(res, res), mode=\\'bilinear\\', align_corners=False)[0]\\n        wins[j] = t.numpy()\\n    x = torch.from_numpy(wins)\\n    if norm == \\'imagenet\\':\\n        x = (x - _MEAN) / _STD\\n    return x\\n\\n@torch.no_grad()\\ndef infer_probs(model, xwins, device):\\n    x = xwins.unsqueeze(0).to(device)\\n    use_cuda = device != \\'cpu\\' and str(device).startswith(\\'cuda\\')\\n    if use_cuda:\\n        try:\\n            with torch.autocast(\\'cuda\\', dtype=torch.float16):\\n                o = torch.sigmoid(model(x).float())\\n            return o[0].cpu().numpy()\\n        except RuntimeError:\\n            torch.cuda.empty_cache()\\n            o = torch.sigmoid(model(x).float())\\n            return o[0].cpu().numpy()\\n    o = torch.sigmoid(model(x).float())\\n    return o[0].cpu().numpy()\\n\\n@torch.no_grad()\\ndef infer_probs_two_heads(model, refit_head, xwins, device):\\n    x = xwins.unsqueeze(0).to(device)\\n    use_cuda = device != \\'cpu\\' and str(device).startswith(\\'cuda\\')\\n    def forward_heads():\\n        features = model.encode(x)\\n        original = torch.sigmoid(model.head(features).float())\\n        refitted = torch.sigmoid(refit_head.head(features).float())\\n        return (original[0].cpu().numpy(), refitted[0].cpu().numpy())\\n    if use_cuda:\\n        try:\\n            with torch.autocast(\\'cuda\\', dtype=torch.float16):\\n                return forward_heads()\\n        except RuntimeError:\\n            torch.cuda.empty_cache()\\n            return forward_heads()\\n    return forward_heads()\\n\\ndef rankpct(x):\\n    order = x.argsort(0).argsort(0).astype(np.float64)\\n    return order / max(1, x.shape[0] - 1)\\n\\ndef _make_reader():\\n    import pydicom, cv2\\n    from pydicom.pixel_data_handlers.util import apply_modality_lut\\n\\n    def order_and_meta(sdir):\\n        fs = glob.glob(sdir + \\'/*.dcm\\')\\n        recs = []\\n        ps_list = []\\n        for f in fs:\\n            try:\\n                h = pydicom.dcmread(f, stop_before_pixels=True)\\n                iop = getattr(h, \\'ImageOrientationPatient\\', None)\\n                ipp = getattr(h, \\'ImagePositionPatient\\', None)\\n                if iop is not None and ipp is not None and (len(iop) == 6):\\n                    r = np.array(iop[:3], float)\\n                    c = np.array(iop[3:], float)\\n                    n = np.cross(r, c)\\n                    pos = float(np.dot(np.array(ipp, float), n))\\n                else:\\n                    pos = float(getattr(h, \\'InstanceNumber\\', 0) or 0)\\n                ps = getattr(h, \\'PixelSpacing\\', None)\\n                ps = float(ps[0]) if ps is not None else 0.5\\n                ps_list.append(ps)\\n                recs.append((pos, f, ps))\\n            except Exception:\\n                recs.append((0.0, f, 0.5))\\n        recs.sort(key=lambda x: x[0])\\n        med_ps = float(np.median(ps_list)) if ps_list else 0.5\\n        return ([(f, ps) for _, f, ps in recs], med_ps)\\n\\n    def read_px(f):\\n        d = pydicom.dcmread(f)\\n        a = apply_modality_lut(d.pixel_array, d).astype(np.float32)\\n        if str(getattr(d, \\'PhotometricInterpretation\\', \\'\\')) == \\'MONOCHROME1\\':\\n            a = a.max() - a\\n        return a\\n\\n    def mm_crop_resize(a, ps):\\n        h, w = a.shape\\n        cpx = int(round(CROP_MM / max(ps, 0.001)))\\n        cpx = min(cpx, min(h, w))\\n        y0 = (h - cpx) // 2\\n        x0 = (w - cpx) // 2\\n        a = a[y0:y0 + cpx, x0:x0 + cpx]\\n        return cv2.resize(a, (IMG, IMG), interpolation=cv2.INTER_AREA)\\n    return (order_and_meta, read_px, mm_crop_resize)\\n\\ndef _pick_series_for_slot(rows, plane, fluid, used):\\n    cands = [r for r in rows if r[\\'Anatomical_Plane\\'] == plane and r[\\'SeriesInstanceUID\\'] not in used]\\n    if fluid in (0, 1):\\n        pref = [r for r in cands if int(r.get(\\'Fluid_Sensitive\\', 0) or 0) == fluid]\\n        if pref:\\n            return pref[0]\\n    return cands[0] if cands else None\\n\\ndef build_study(sid, ser_records, tsdir, reader):\\n    order_and_meta, read_px, mm_crop_resize = reader\\n    rows = ser_records.get(sid, [])\\n    vol = np.zeros((MAXS, IMG, IMG), np.uint8)\\n    idx = 0\\n    used = set()\\n    for plane, fluid, k in SLOTS:\\n        r = _pick_series_for_slot(rows, plane, fluid, used)\\n        if r is None:\\n            idx += k\\n            continue\\n        used.add(r[\\'SeriesInstanceUID\\'])\\n        files, med_ps = order_and_meta(f\"{tsdir}/{sid}/{r[\\'SeriesInstanceUID\\']}\")\\n        if not files:\\n            idx += k\\n            continue\\n        n = len(files)\\n        lo, hi = (int(n * SPAN_LO), int(n * SPAN_HI) - 1)\\n        hi = max(hi, lo)\\n        picks = np.linspace(lo, hi, k).round().astype(int) if n > 1 else [0] * k\\n        arrs = []\\n        pss = []\\n        for p in picks:\\n            fp, ps = files[min(p, n - 1)]\\n            try:\\n                arrs.append(read_px(fp))\\n                pss.append(ps)\\n            except Exception:\\n                arrs.append(None)\\n                pss.append(med_ps)\\n        valid = [a for a in arrs if a is not None]\\n        if valid:\\n            allpx = np.concatenate([a.ravel() for a in valid])\\n            loq, hiq = np.percentile(allpx, [2.0, 98.0])\\n        else:\\n            loq, hiq = (0.0, 1.0)\\n        for a, ps in zip(arrs, pss):\\n            if idx >= MAXS:\\n                break\\n            if a is None:\\n                idx += 1\\n                continue\\n            aw = np.clip((a - loq) / (hiq - loq + 1e-06), 0, 1)\\n            aw = mm_crop_resize(aw, ps if ps > 0 else med_ps)\\n            vol[idx] = (aw * 255).astype(np.uint8)\\n            idx += 1\\n        if idx >= MAXS:\\n            break\\n    mask = (vol.reshape(MAXS, -1).sum(1) > 0).astype(np.uint8)\\n    return (vol, mask)\\n\\ndef find_test_root():\\n    candidates = [\\n        \\'/kaggle/input/competitions/rsna-knee-abnormality-detection\\',\\n        \\'/kaggle/input/rsna-knee-abnormality-detection\\',\\n    ]\\n    hits = [base for base in candidates\\n            if os.path.isfile(base + \\'/test.csv\\')\\n            and os.path.isfile(base + \\'/test_series.csv\\')\\n            and os.path.isdir(base + \\'/test_series\\')]\\n    if len(hits) != 1:\\n        raise RuntimeError(f\\'expected one direct competition root, found {hits}\\')\\n    return hits[0]\\n\\ndef find_weight_file(fname):\\n    by_name = {\\n        \\'raptor_ft_coatnet_v5_full_swa.pt\\': [\\n            \\'/kaggle/input/datasets/dreaddevelopment/raptor-knee-maxspan/raptor_ft_coatnet_v5_full_swa.pt\\',\\n            \\'/kaggle/input/raptor-knee-maxspan/raptor_ft_coatnet_v5_full_swa.pt\\',\\n        ],\\n        \\'raptor_ft_coatnet_v10_full.pt\\': [\\n            \\'/kaggle/input/datasets/dreaddevelopment/raptor-knee-native384dense/raptor_ft_coatnet_v10_full.pt\\',\\n            \\'/kaggle/input/raptor-knee-native384dense/raptor_ft_coatnet_v10_full.pt\\',\\n        ],\\n        \\'raptor_ft_coatnet_v8_full_swa.pt\\': [\\n            \\'/kaggle/input/datasets/dreaddevelopment/raptor-knee-native384/raptor_ft_coatnet_v8_full_swa.pt\\',\\n            \\'/kaggle/input/raptor-knee-native384/raptor_ft_coatnet_v8_full_swa.pt\\',\\n        ],\\n    }\\n    if fname not in by_name:\\n        raise RuntimeError(f\\'unpinned Raptor checkpoint: {fname}\\')\\n    hits = [path for path in by_name[fname] if os.path.isfile(path)]\\n    if len(hits) != 1:\\n        raise RuntimeError(f\\'expected one direct Raptor checkpoint {fname}, found {hits}\\')\\n    expected_size = {\\n        \\'raptor_ft_coatnet_v5_full_swa.pt\\': 292831426,\\n        \\'raptor_ft_coatnet_v10_full.pt\\': 292829892,\\n        \\'raptor_ft_coatnet_v8_full_swa.pt\\': 292831426,\\n    }[fname]\\n    if os.path.getsize(hits[0]) != expected_size:\\n        raise RuntimeError(f\\'Raptor checkpoint size mismatch: {hits[0]}\\')\\n    return hits[0]\\n\\ndef main():\\n    import pandas as pd\\n    t0 = time.time()\\n    dev = \"cuda\" if torch.cuda.is_available() else \"cpu\"\\n    print(f\"device {dev} | gpus {torch.cuda.device_count()} | torch {torch.__version__}\", flush=True)\\n    root = find_test_root()\\n    tsdir = root + \"/test_series\"\\n    if not os.path.isdir(tsdir):\\n        tsdir = root + \"/test_images\"\\n    print(\"test root:\", root, \"| series dir:\", tsdir, flush=True)\\n    test = pd.read_csv(root + \"/test.csv\")\\n    test[\"StudyInstanceUID\"] = test[\"StudyInstanceUID\"].astype(str)\\n    test_ids = test[\"StudyInstanceUID\"].tolist()\\n    tser = pd.read_csv(root + \"/test_series.csv\")\\n    tser[\"StudyInstanceUID\"] = tser[\"StudyInstanceUID\"].astype(str)\\n    tser[\"SeriesInstanceUID\"] = tser[\"SeriesInstanceUID\"].astype(str)\\n    series = {key: frame.to_dict(\"records\") for key, frame in tser.groupby(\"StudyInstanceUID\")}\\n    print(f\"test studies {len(test_ids)} | test series {len(tser)}\", flush=True)\\n    sub_cols = [\"StudyInstanceUID\"] + LAB\\n    sample = os.path.join(root, \"sample_submission.csv\")\\n    if os.path.exists(sample):\\n        sub_cols = list(pd.read_csv(sample, nrows=1).columns)\\n    reader = _make_reader()\\n    n_study, n_arm = len(test_ids), len(ARMS)\\n    arm_probs = [np.full((n_study, len(LAB)), 0.5, np.float32) for _ in range(n_arm)]\\n    for arm_index, arm in enumerate(ARMS):\\n        globals()[\"IMG\"] = int(arm[\"img\"])\\n        globals()[\"SLOTS\"] = list(arm[\"slots\"])\\n        globals()[\"MAXS\"] = sum(slot[2] for slot in SLOTS)\\n        globals()[\"SPAN_LO\"], globals()[\"SPAN_HI\"] = map(float, arm[\"span\"])\\n        globals()[\"K_EVAL\"] = int(arm[\"k_eval\"])\\n        weight_path = find_weight_file(arm[\"file\"])\\n        model, resolution = load_model(weight_path, arm[\"arch\"], arm[\"res\"], dev)\\n        print(f\"[arm {arm_index}] {arm[\\'name\\']} | img {IMG} | slices {MAXS} | \"\\n              f\"span {SPAN_LO:.2f}-{SPAN_HI:.2f} | windows {K_EVAL} | \"\\n              f\"res {resolution} | {time.time() - t0:.0f}s\", flush=True)\\n        for study_index, study_uid in enumerate(test_ids):\\n            try:\\n                volume, mask = build_study(study_uid, series, tsdir, reader)\\n                windows = eval_windows(volume, mask, k=K_EVAL, res=resolution, norm=NORM)\\n                if bool(arm.get(\"reverse\", False)):\\n                    windows = windows.flip(1).contiguous()\\n                arm_probs[arm_index][study_index] = infer_probs(model, windows, dev)\\n                del volume, mask, windows\\n            except Exception as error:\\n                print(f\"  [arm {arm_index}] study {study_index} {study_uid[:16]} FALLBACK \"\\n                      f\"({type(error).__name__}: {error})\", flush=True)\\n            if (study_index + 1) % 100 == 0 or study_index + 1 == n_study:\\n                print(f\"  [arm {arm_index}] {study_index + 1}/{n_study} | \"\\n                      f\"{time.time() - t0:.0f}s\", flush=True)\\n        del model\\n        gc.collect()\\n        if str(dev).startswith(\"cuda\"):\\n            torch.cuda.empty_cache()\\n        print(f\"[arm {arm_index}] done + freed | {time.time() - t0:.0f}s\", flush=True)\\n    weights = np.array([float(arm.get(\"w\", 1.0)) for arm in ARMS], dtype=np.float64)\\n    weights /= weights.sum()\\n    print(f\"[blend] global probability mean w=\"\\n          f\"{dict(zip([arm[\\'name\\'] for arm in ARMS], weights.round(4)))}\", flush=True)\\n    probability_blend = np.tensordot(\\n        weights, np.stack([np.clip(values, 0, 1) for values in arm_probs]), axes=(0, 0))\\n    ranks = rankpct(probability_blend)\\n    if not np.isfinite(ranks).all():\\n        ranks[~np.isfinite(ranks)] = 0.5\\n    submission = pd.DataFrame(ranks.astype(np.float32), columns=LAB)\\n    submission.insert(0, \"StudyInstanceUID\", test_ids)\\n    submission = submission[sub_cols]\\n    assert submission[\"StudyInstanceUID\"].tolist() == test_ids\\n    assert np.isfinite(submission[LAB].values).all()\\n    out = \"/kaggle/working/_raptor.csv\"\\n    submission.to_csv(out, index=False)\\n    print(\"wrote\", out, \"|\", len(submission), \"rows x\", len(submission.columns), \"cols\", flush=True)\\n    print(submission.head().to_string(index=False), flush=True)\\n    print(f\"DONE {time.time() - t0:.0f}s\", flush=True)\\n'\n_KE_NS = {'__name__': '_ke_raptor'}\nexec(compile(_KE_SRC, '<raptor>', 'exec'), _KE_NS)\n_KE_NS['main']()\n\ndef _coat_substitute():\n    import hashlib as _h, os as _o, subprocess as _sp, sys as _sy\n    from pathlib import Path as _P\n    import pandas as _pd\n\n    MAN_SHA = '98511a8fdeb9da0e6e70c78d013ff636e1476f31c80b5dc134d294b18c3f284e'\n    WHL_SHA = '236c8df54a90f4d02076e6f9c1cc763d794542e886c576a6fee46ec8ff75a7a9'\n    raptor = _P('/kaggle/working/_raptor.csv')\n\n    def sha(p):\n        d = _h.sha256()\n        with _P(p).open('rb') as f:\n            for b in iter(lambda: f.read(8 << 20), b''):\n                d.update(b)\n        return d.hexdigest()\n\n    def find(name, want):\n        by_name = {\n            'coat_resgated_ep10_top3_manifest.json': [\n                '/kaggle/input/datasets/mattiaangeli/rsna-knee-coat-resgated-ep10-top3/coat_resgated_ep10_top3_manifest.json',\n                '/kaggle/input/rsna-knee-coat-resgated-ep10-top3/coat_resgated_ep10_top3_manifest.json',\n            ],\n            'opencv_python_headless-4.12.0.88-*.whl': [\n                '/kaggle/input/datasets/mattiaangeli/opencv-python-headless-4120088-x86/opencv_python_headless-4.12.0.88-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl',\n                '/kaggle/input/opencv-python-headless-4120088-x86/opencv_python_headless-4.12.0.88-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl',\n            ],\n        }\n        candidates = [_P(path) for path in by_name.get(name, [])]\n        hits = [path for path in candidates if path.is_file() and sha(path) == want]\n        if len(hits) != 1:\n            raise RuntimeError(f'expected one verified direct artifact {name}, found {hits}')\n        return hits[0]\n\n    man = find('coat_resgated_ep10_top3_manifest.json', MAN_SHA)\n    if man is None:\n        raise RuntimeError('coat manifest absent or hash mismatch')\n    art = man.parent\n    whl = find('opencv_python_headless-4.12.0.88-*.whl', WHL_SHA)\n    if whl is None:\n        raise RuntimeError('pinned opencv wheel absent or hash mismatch')\n\n    envd = _P('/kaggle/working/_coat_env')\n    _sp.run([_sy.executable, '-m', 'pip', 'install', '--no-deps', '--quiet',\n             '--target', str(envd), str(whl)], check=True)\n\n    out = _P('/kaggle/working/_coat_arm.csv')\n    child = (\n        \"import sys, json\\n\"\n        f\"sys.path.insert(0, {str(envd)!r})\\n\"\n        f\"sys.path.insert(0, {str(art)!r})\\n\"\n        \"import cv2; assert cv2.__version__ == '4.12.0', cv2.__version__\\n\"\n        \"import torch; assert torch.cuda.device_count() == 2\\n\"\n        \"import coatnet_resgated_ep10_top3_inference as rt\\n\"\n        \"assert rt.base.cv2.__version__ == '4.12.0'\\n\"\n        \"from pathlib import Path\\n\"\n        \"r = rt.run_submission(competition_root=Path('/kaggle/input/competitions/rsna-knee-abnormality-detection'),\\n\"\n        f\"    artifact_root=Path({str(art)!r}), output_path=Path({str(out)!r}),\\n\"\n        \"    gpu_batch_studies=2, backbone_micro_images=8)\\n\"\n        \"assert r['status'] == rt.SUBMISSION_STATUS\\n\"\n        \"assert r['models'] == 3\\n\"\n        \"assert [i['epoch'] for i in r['checkpoints']] == [4, 6, 8]\\n\"\n        \"assert r['fallback_studies'] == 0, r['failures']\\n\"\n        \"Path('/kaggle/working/_coat_arm_receipt.json').write_text(json.dumps(r, indent=2))\\n\")\n    env = dict(_o.environ)\n    env['PYTHONPATH'] = f\"{envd}:{art}:\" + env.get('PYTHONPATH', '')\n    proc = _sp.run([_sy.executable, '-c', child], env=env, capture_output=True, text=True)\n    if proc.returncode != 0:\n        raise RuntimeError(f'coat child failed: {proc.stderr[-700:]}')\n\n    pub = _pd.read_csv(raptor, dtype={'StudyInstanceUID': str})\n    ours = _pd.read_csv(out, dtype={'StudyInstanceUID': str})\n    if list(ours.columns) != list(pub.columns):\n        raise RuntimeError('coat arm column drift')\n    ours = ours.set_index('StudyInstanceUID').reindex(\n        pub.StudyInstanceUID.astype(str).tolist()).reset_index()\n    lab = [c for c in pub.columns if c != 'StudyInstanceUID']\n    if ours[lab].isna().any().any():\n        raise RuntimeError('coat arm does not cover every study')\n    import json as _j\n    import numpy as _np\n    private_alpha = 0.40000000000000002\n    public_rank = pub[lab].rank(method='average', pct=True)\n    private_rank = ours[lab].rank(method='average', pct=True)\n    hybrid = pub.copy()\n    hybrid[lab] = (\n        (1.0 - private_alpha) * public_rank\n        + private_alpha * private_rank\n    ).rank(method='average', pct=True)\n    if not _np.isfinite(hybrid[lab].to_numpy(_np.float64)).all():\n        raise RuntimeError('CoAt/Raptor hybrid contains non-finite values')\n    tmp = raptor.with_name('.raptor_coat_hybrid.csv')\n    hybrid.to_csv(tmp, index=False)\n    _o.replace(tmp, raptor)\n    raptor.with_name('_coat_raptor_blend_receipt.json').write_text(_j.dumps({\n        'contract': 'public_raptor_private_residual_coat_global_rank_blend_v1',\n        'private_alpha': private_alpha,\n        'public_raptor_alpha': 1.0 - private_alpha,\n        'study_count': len(ours),\n        'finding_specific_weights': False,\n    }, indent=2, sort_keys=True) + '\\n')\n    return len(ours)\n\n\n_coat_public_path = _KePath('/kaggle/working/_raptor.csv')\n_coat_n = _coat_substitute()\nprint(f'[coat-arm] blended OUR resgated e4/e6/e8 into the public Raptor arm '\n      f'(private alpha 0.400; {_coat_n} studies)', flush=True)\n\n_ke_theirs = _ke_pd.read_csv('/kaggle/working/_raptor.csv',\n                             dtype={'StudyInstanceUID': str})\nassert list(_ke_theirs.columns) == list(_ke_ours.columns), 'column drift'\n_ke_theirs = _ke_theirs.set_index('StudyInstanceUID').reindex(\n    _ke_ours['StudyInstanceUID']).reset_index()\nassert _ke_theirs[_KE_LAB].notna().all().all(), 'study identity drift'\n\n\n_ke_tr = _ke_ours[_KE_LAB].rank(method='average', pct=True)\n_ke_cr = _ke_theirs[_KE_LAB].copy()\n_blend_transformer = _ke_ours.copy()\n_blend_coatnet = _ke_theirs.copy()\n_blend_labels = list(_KE_LAB)\n_blend_tr = _ke_tr.copy()\n_blend_cr = _ke_cr.copy()\n_coatnet_weight = {label: 0.60 for label in _blend_labels}\n_coatnet_weight.update({\n    'ACL': 0.8250,\n    'Medial Meniscus': 0.9000,\n    'Lateral Meniscus': 1.0000,\n    'Lateral OA': 0.8250,\n    'Fracture': 0.8250,\n})  # expA145 scale=1.5: the author's deviations from 0.60 multiplied by 1.5 and clipped at 1.0. ONE free parameter. subF removed these and lost 0.002 on the board, so they are real; tuned on 58 studies they are more likely under-shot than over-shot.\n_blend_output = _blend_transformer.copy()\nfor _blend_label in _blend_labels:\n    _blend_w = float(_coatnet_weight[_blend_label])\n    _blend_output[_blend_label] = (\n        (1.0 - _blend_w) * _blend_tr[_blend_label]\n        + _blend_w * _blend_cr[_blend_label]\n    )\n_blend_output[_blend_labels] = _blend_output[_blend_labels].rank(\n    method='average', pct=True\n)\nassert _ke_np.isfinite(\n    _blend_output[_blend_labels].to_numpy(_ke_np.float64)\n).all()\n_blend_output.to_csv(_ke_primary, index=False)\n","metadata":{},"outputs":[],"execution_count":null}]}