{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":118765,"databundleVersionId":15231210},{"sourceType":"datasetVersion","sourceId":14822484,"datasetId":9479395,"databundleVersionId":15679639},{"sourceType":"datasetVersion","sourceId":11118830,"datasetId":6933267,"databundleVersionId":11511771},{"sourceType":"datasetVersion","sourceId":11922858,"datasetId":7495841,"databundleVersionId":12430654},{"sourceType":"datasetVersion","sourceId":14519720,"datasetId":9271415,"databundleVersionId":15347344},{"sourceType":"datasetVersion","sourceId":14534919,"datasetId":9283271,"databundleVersionId":15363994},{"sourceType":"datasetVersion","sourceId":14805765,"datasetId":9467172,"databundleVersionId":15661298},{"sourceType":"datasetVersion","sourceId":10855324,"datasetId":6742586,"databundleVersionId":11219268},{"sourceType":"modelInstanceVersion","sourceId":311741,"databundleVersionId":11641144,"modelInstanceId":264400,"modelId":285488}],"dockerImageVersionId":31260,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# =========================================================\n# CELL 0 — Environment Setup\n# Purpose:\n#   Detect runtime environment and configure scoring mode.\n#\n# Function:\n#   - Detect Kaggle scoring run\n#   - Define global flags\n#\n# Sanity Checks:\n#   - Confirm Kaggle environment\n# =========================================================\n\nimport os\nimport sys\n\n# Determine if running in Kaggle scoring environment\nIS_SCORING_RUN = os.getenv(\"KAGGLE_IS_COMPETITION_RERUN\")\n\nprint(\"IS_SCORING_RUN =\", IS_SCORING_RUN)\n\n# Working directory\nWORK_DIR = \"/kaggle/working\"\n\nprint(\"Working directory:\", WORK_DIR)\n\nassert os.path.exists(\"/kaggle\"), \"Kaggle environment not detected\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:28:08.042854Z","iopub.execute_input":"2026-03-08T10:28:08.043428Z","iopub.status.idle":"2026-03-08T10:28:08.051974Z","shell.execute_reply.started":"2026-03-08T10:28:08.043396Z","shell.execute_reply":"2026-03-08T10:28:08.051167Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 1 — Imports\n# Kaggle-safe (no external dependencies)\n# =========================================================\n\nimport numpy as np\nimport pandas as pd\nimport json\nimport random\nfrom pathlib import Path\n\nprint(\"Core libraries loaded\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:28:08.053474Z","iopub.execute_input":"2026-03-08T10:28:08.053798Z","iopub.status.idle":"2026-03-08T10:28:08.32467Z","shell.execute_reply.started":"2026-03-08T10:28:08.053776Z","shell.execute_reply":"2026-03-08T10:28:08.323899Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 2 — Dataset Paths\n# Purpose:\n#   Define dataset locations used throughout the notebook.\n#\n# Function:\n#   - Configure template datasets\n#   - Configure competition datasets\n#\n# Sanity Checks:\n#   - Verify directories exist\n# =========================================================\n\nCOMP_DATA = Path(\"/kaggle/input/stanford-rna-3d-folding-2\")\n\nTEMPLATE_DATA = Path(\n    \"/kaggle/input/datasets/odat1248/stanfordrna2026-training-ribonanza-rep\"\n)\n\nprint(\"Competition dataset:\", COMP_DATA)\nprint(\"Template dataset:\", TEMPLATE_DATA)\n\nassert COMP_DATA.exists()\nassert TEMPLATE_DATA.exists()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:28:08.325568Z","iopub.execute_input":"2026-03-08T10:28:08.325994Z","iopub.status.idle":"2026-03-08T10:28:08.332111Z","shell.execute_reply.started":"2026-03-08T10:28:08.32596Z","shell.execute_reply":"2026-03-08T10:28:08.331433Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 3 — Utility Functions\n# Purpose:\n#   Provide helper utilities used throughout the pipeline.\n#\n# Function:\n#   - FASTA parsing\n#   - Sequence normalization\n#\n# Sanity Checks:\n#   - Ensure functions operate correctly\n# =========================================================\n\ndef fasta_loader(path):\n    \"\"\"Load sequences from FASTA file.\"\"\"\n    sequences = {}\n    current_id = None\n\n    with open(path) as f:\n        for line in f:\n            line = line.strip()\n\n            if line.startswith(\">\"):\n                current_id = line[1:]\n                sequences[current_id] = \"\"\n            else:\n                sequences[current_id] += line\n\n    return sequences\n\n\nprint(\"Utility functions ready\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:28:08.334514Z","iopub.execute_input":"2026-03-08T10:28:08.334822Z","iopub.status.idle":"2026-03-08T10:28:08.342074Z","shell.execute_reply.started":"2026-03-08T10:28:08.3348Z","shell.execute_reply":"2026-03-08T10:28:08.34149Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 4 — Load Test Dataset\n# Purpose:\n#   Load competition test data.\n#\n# Function:\n#   - Read CSV\n#   - Extract sequences\n#\n# Sanity Checks:\n#   - Confirm dataset shape\n# =========================================================\n\ntest_csv = COMP_DATA / \"test_sequences.csv\"\n\ntest_df = pd.read_csv(test_csv)\n\nprint(\"Test dataset loaded\")\n\nprint(\"Rows:\", len(test_df))\nprint(\"Columns:\", list(test_df.columns))\n\nassert \"sequence\" in test_df.columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:28:08.343777Z","iopub.execute_input":"2026-03-08T10:28:08.344032Z","iopub.status.idle":"2026-03-08T10:28:08.359416Z","shell.execute_reply.started":"2026-03-08T10:28:08.344002Z","shell.execute_reply":"2026-03-08T10:28:08.358748Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 5 — Template Metadata Builder\n# Purpose:\n#   Build template metadata by scanning the training directory.\n#\n# Function:\n#   - Locate all .mat files containing RNA structures\n#   - Store file paths and identifiers\n#\n# Sanity Checks:\n#   - Confirm templates were discovered\n# =========================================================\n\nimport glob\n\nTEMPLATE_STRUCTURE_DIR = (\n    TEMPLATE_DATA /\n    \"StanfordRNA2026_training_ribonanza_rep\" /\n    \"train_full_ribonanza_rep\"\n)\n\nprint(\"Scanning template directory:\", TEMPLATE_STRUCTURE_DIR)\n\nmat_files = glob.glob(str(TEMPLATE_STRUCTURE_DIR / \"*.mat\"))\n\nprint(\"Number of template structures found:\", len(mat_files))\n\nassert len(mat_files) > 0, \"No template structures found\"\n\ntemplate_meta_df = pd.DataFrame({\n    \"mat_file\": mat_files\n})\n\ntemplate_meta_df[\"template_id\"] = template_meta_df[\"mat_file\"].apply(\n    lambda x: Path(x).stem\n)\n\nprint(template_meta_df.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:28:08.360337Z","iopub.execute_input":"2026-03-08T10:28:08.360651Z","iopub.status.idle":"2026-03-08T10:28:08.40212Z","shell.execute_reply.started":"2026-03-08T10:28:08.360629Z","shell.execute_reply":"2026-03-08T10:28:08.401492Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 6 — Template Embedding Loader\n# Purpose:\n#   Parse Ribonanza embedding files.\n#\n# Function:\n#   - Extract sequence\n#   - Extract embedding vectors\n#\n# Output:\n#   sequence (string)\n#   embedding matrix (L x D)\n# =========================================================\n\ndef load_template_embedding(mat_path):\n\n    sequence = []\n    embeddings = []\n\n    with open(mat_path, \"r\") as f:\n\n        header = f.readline().strip()\n\n        for line in f:\n\n            parts = line.strip().split()\n\n            base = parts[0]\n            vector = list(map(float, parts[1:]))\n\n            sequence.append(base)\n            embeddings.append(vector)\n\n    sequence = \"\".join(sequence)\n    embeddings = np.array(embeddings)\n\n    return sequence, embeddings","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:28:08.402877Z","iopub.execute_input":"2026-03-08T10:28:08.403107Z","iopub.status.idle":"2026-03-08T10:28:08.40819Z","shell.execute_reply.started":"2026-03-08T10:28:08.403088Z","shell.execute_reply":"2026-03-08T10:28:08.407371Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 6B — Embedding Loader Test\n# =========================================================\n\nsample_file = template_meta_df.iloc[0][\"mat_file\"]\n\nseq, emb = load_template_embedding(sample_file)\n\nprint(\"Sequence length:\", len(seq))\nprint(\"Embedding shape:\", emb.shape)\n\nassert len(seq) == emb.shape[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:28:08.409034Z","iopub.execute_input":"2026-03-08T10:28:08.409332Z","iopub.status.idle":"2026-03-08T10:28:08.425912Z","shell.execute_reply.started":"2026-03-08T10:28:08.409285Z","shell.execute_reply":"2026-03-08T10:28:08.425145Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 7 — Build Template Embedding Index\n# Purpose:\n#   Build a compact index of all template embeddings.\n#\n# Function:\n#   - Load each template embedding file\n#   - Compute mean embedding\n#   - Store sequence + length\n#\n# Output:\n#   template_sequences\n#   template_lengths\n#   template_embeddings\n#\n# Sanity Checks:\n#   - Ensure shapes are correct\n# =========================================================\n\ntemplate_sequences = []\ntemplate_lengths = []\ntemplate_embeddings = []\n\nfor _, row in template_meta_df.iterrows():\n\n    seq, emb = load_template_embedding(row[\"mat_file\"])\n\n    template_sequences.append(seq)\n    template_lengths.append(len(seq))\n\n    # mean embedding for fast similarity search\n    template_embeddings.append(emb.mean(axis=0))\n\ntemplate_embeddings = np.array(template_embeddings)\n\nprint(\"Templates indexed:\", len(template_sequences))\nprint(\"Embedding matrix shape:\", template_embeddings.shape)\n\nassert template_embeddings.shape[0] == len(template_sequences)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:28:08.426804Z","iopub.execute_input":"2026-03-08T10:28:08.42729Z","iopub.status.idle":"2026-03-08T10:31:08.881366Z","shell.execute_reply.started":"2026-03-08T10:28:08.427268Z","shell.execute_reply":"2026-03-08T10:31:08.880504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 8 — Query Embedding Generator\n# Purpose:\n#   Convert RNA sequence into an embedding vector.\n#\n# Note:\n#   Placeholder until RibonanzaNet is integrated.\n#\n# Function:\n#   - Encode A,U,G,C\n#   - Produce embedding compatible with template vectors\n#\n# Sanity Checks:\n#   - Output dimension matches template embeddings\n# =========================================================\n\nbase_vectors = {\n    \"A\": np.random.randn(256),\n    \"U\": np.random.randn(256),\n    \"G\": np.random.randn(256),\n    \"C\": np.random.randn(256),\n}\n\ndef embed_sequence(sequence):\n\n    vecs = []\n\n    for base in sequence:\n        vecs.append(base_vectors.get(base, np.zeros(256)))\n\n    vecs = np.array(vecs)\n\n    return vecs.mean(axis=0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:08.883994Z","iopub.execute_input":"2026-03-08T10:31:08.884224Z","iopub.status.idle":"2026-03-08T10:31:08.890396Z","shell.execute_reply.started":"2026-03-08T10:31:08.884201Z","shell.execute_reply":"2026-03-08T10:31:08.889828Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 9 — Template Retrieval\n# Purpose:\n#   Retrieve nearest templates using embedding similarity.\n#\n# Function:\n#   - Compute cosine similarity\n#   - Return top-k templates\n#\n# Sanity Checks:\n#   - Ensure templates returned\n# =========================================================\n\ndef run_template_retrieval(sequence, top_k=5):\n\n    q_emb = embed_sequence(sequence)\n\n    scores = template_embeddings @ q_emb\n\n    idx = np.argsort(scores)[::-1][:top_k]\n\n    hits = []\n\n    for i in idx:\n        hits.append({\n            \"sequence\": template_sequences[i],\n            \"score\": scores[i],\n            \"index\": i\n        })\n\n    return hits","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:08.891217Z","iopub.execute_input":"2026-03-08T10:31:08.891522Z","iopub.status.idle":"2026-03-08T10:31:08.903042Z","shell.execute_reply.started":"2026-03-08T10:31:08.891503Z","shell.execute_reply":"2026-03-08T10:31:08.902338Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 9B — Retrieval Test\n# =========================================================\n\ntest_seq = \"AUGCUAGCUAGCUA\"\n\nhits = run_template_retrieval(test_seq)\n\nprint(\"Retrieved templates:\", len(hits))\nprint(\"Top score:\", hits[0][\"score\"])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:08.903982Z","iopub.execute_input":"2026-03-08T10:31:08.904261Z","iopub.status.idle":"2026-03-08T10:31:08.921496Z","shell.execute_reply.started":"2026-03-08T10:31:08.904231Z","shell.execute_reply":"2026-03-08T10:31:08.920876Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 10 — Length Bucketing Index\n# Purpose:\n#   Speed up template retrieval by grouping templates by length.\n#\n# Function:\n#   - Build mapping from length → template indices\n#\n# Benefit:\n#   Retrieval now compares against ~50 templates instead of 5226\n#\n# Sanity Checks:\n#   - Ensure buckets created\n# =========================================================\n\nlength_buckets = {}\n\nfor i, L in enumerate(template_lengths):\n\n    bucket = int(L / 20)  # bucket size = 20 nt\n\n    if bucket not in length_buckets:\n        length_buckets[bucket] = []\n\n    length_buckets[bucket].append(i)\n\nprint(\"Number of buckets:\", len(length_buckets))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:08.922389Z","iopub.execute_input":"2026-03-08T10:31:08.922638Z","iopub.status.idle":"2026-03-08T10:31:08.946779Z","shell.execute_reply.started":"2026-03-08T10:31:08.922604Z","shell.execute_reply":"2026-03-08T10:31:08.946059Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 11 — Fast Template Retrieval\n# Purpose:\n#   Retrieve nearest templates using embedding similarity\n#   with length filtering.\n#\n# Function:\n#   - Identify relevant length bucket\n#   - Compare only nearby templates\n#\n# Sanity Checks:\n#   - Ensure templates returned\n# =========================================================\n\ndef run_template_retrieval(sequence, top_k=5):\n\n    q_emb = embed_sequence(sequence)\n    q_len = len(sequence)\n\n    bucket = int(q_len / 20)\n\n    candidate_indices = []\n\n    for b in [bucket-1, bucket, bucket+1]:\n\n        if b in length_buckets:\n            candidate_indices.extend(length_buckets[b])\n\n    if len(candidate_indices) == 0:\n        candidate_indices = list(range(len(template_sequences)))\n\n    scores = template_embeddings[candidate_indices] @ q_emb\n\n    idx = np.argsort(scores)[::-1][:top_k]\n\n    hits = []\n\n    for i in idx:\n        template_index = candidate_indices[i]\n\n        hits.append({\n            \"sequence\": template_sequences[template_index],\n            \"score\": scores[i],\n            \"index\": template_index\n        })\n\n    return hits","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:08.947402Z","iopub.execute_input":"2026-03-08T10:31:08.947683Z","iopub.status.idle":"2026-03-08T10:31:08.959804Z","shell.execute_reply.started":"2026-03-08T10:31:08.947658Z","shell.execute_reply":"2026-03-08T10:31:08.958576Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_seq = \"AUGCUAGCUAGCUA\"\n\nhits = run_template_retrieval(test_seq)\n\nprint(\"Retrieved templates:\", len(hits))\nprint(\"Top score:\", hits[0][\"score\"])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:08.962669Z","iopub.execute_input":"2026-03-08T10:31:08.964556Z","iopub.status.idle":"2026-03-08T10:31:08.976875Z","shell.execute_reply.started":"2026-03-08T10:31:08.964529Z","shell.execute_reply":"2026-03-08T10:31:08.976276Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 12 — Sequence Alignment (placeholder)\n# =========================================================\n\ndef align_sequences(query, template):\n    # Alignment not required in current baseline\n    return None","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:08.977517Z","iopub.execute_input":"2026-03-08T10:31:08.977794Z","iopub.status.idle":"2026-03-08T10:31:08.99103Z","shell.execute_reply.started":"2026-03-08T10:31:08.977767Z","shell.execute_reply":"2026-03-08T10:31:08.990324Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# Dummy RNA Structure Generator (5 atoms per residue)\n# Output shape: (L,5,3)\n# =========================================================\n\ndef generate_dummy_structure(sequence):\n\n    L = len(sequence)\n\n    coords = np.zeros((L,5,3))\n\n    for i in range(L):\n\n        base_x = i * 3.4\n\n        coords[i,0] = [base_x,0,0]        # atom 1\n        coords[i,1] = [base_x+0.5,0.2,0]  # atom 2\n        coords[i,2] = [base_x-0.3,-0.4,0] # atom 3\n        coords[i,3] = [base_x+0.1,0.6,0]  # atom 4\n        coords[i,4] = [base_x-0.2,0.1,0]  # atom 5\n\n    return coords","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:08.992341Z","iopub.execute_input":"2026-03-08T10:31:08.993008Z","iopub.status.idle":"2026-03-08T10:31:09.004578Z","shell.execute_reply.started":"2026-03-08T10:31:08.992976Z","shell.execute_reply":"2026-03-08T10:31:09.004021Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 14 — Prediction Pipeline\n# Purpose:\n#   Generate coordinates for all test sequences.\n#\n# Steps:\n#   1. Retrieve templates\n#   2. (future) load template structures\n#   3. generate coordinates\n#\n# Sanity Checks:\n#   - Ensure predictions generated\n# =========================================================\n\npredictions = []\n\nfor _, row in test_df.iterrows():\n\n    sequence = row[\"sequence\"]\n    seq_id = row[\"target_id\"]\n\n    hits = run_template_retrieval(sequence)\n\n    if len(hits) == 0:\n        coords = generate_dummy_structure(sequence)\n\n    else:\n        # placeholder until real structures are integrated\n        coords = generate_dummy_structure(sequence)\n\n    predictions.append((seq_id, coords))\n\nprint(\"Predictions generated:\", len(predictions))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:09.006825Z","iopub.execute_input":"2026-03-08T10:31:09.008555Z","iopub.status.idle":"2026-03-08T10:31:09.116986Z","shell.execute_reply.started":"2026-03-08T10:31:09.008523Z","shell.execute_reply":"2026-03-08T10:31:09.116381Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_path = \"/kaggle/input/stanford-rna-3d-folding-2/sample_submission.csv\"\n\nsubmission_df = pd.read_csv(sample_path)\n\ncoord_lookup = {}\n\nfor seq_id, coords in predictions:\n\n    for i in range(coords.shape[0]):\n\n        coord_lookup[f\"{seq_id}_{i+1}\"] = coords[i]\n\n\nfor i,row in submission_df.iterrows():\n\n    rid = row[\"ID\"]\n\n    if rid in coord_lookup:\n\n        atoms = coord_lookup[rid]\n\n        for a in range(5):\n\n            submission_df.at[i,f\"x_{a+1}\"] = atoms[a,0]\n            submission_df.at[i,f\"y_{a+1}\"] = atoms[a,1]\n            submission_df.at[i,f\"z_{a+1}\"] = atoms[a,2]\n\n\nsubmission_df.to_csv(\"submission.csv\", index=False)\n\nprint(\"submission.csv written\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:09.118206Z","iopub.execute_input":"2026-03-08T10:31:09.11855Z","iopub.status.idle":"2026-03-08T10:31:11.647561Z","shell.execute_reply.started":"2026-03-08T10:31:09.118523Z","shell.execute_reply":"2026-03-08T10:31:11.646829Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# CELL 16 — Submission Format Validation\n# Purpose:\n#   Ensure submission.csv matches Kaggle sample_submission.csv\n#\n# Checks:\n#   1. Column names identical\n#   2. Row counts match\n#   3. ID column ordering identical\n#   4. No NaNs\n#   5. Coordinate columns numeric\n# =========================================================\n\nsample_path = \"/kaggle/input/stanford-rna-3d-folding-2/sample_submission.csv\"\n\n\nsample_df = pd.read_csv(sample_path)\nsubmission_df = pd.read_csv(\"submission.csv\")\n\nprint(\"Sample rows:\", len(sample_df))\nprint(\"Submission rows:\", len(submission_df))\n\n\n# Column check\nassert list(sample_df.columns) == list(submission_df.columns)\nprint(\"✓ Column names match\")\n\n\n# Row count\nassert len(sample_df) == len(submission_df)\nprint(\"✓ Row count matches\")\n\n\n# ID order\nassert (sample_df[\"ID\"].values == submission_df[\"ID\"].values).all()\nprint(\"✓ ID ordering matches\")\n\n\n# NaN check\nassert not submission_df.isna().any().any()\nprint(\"✓ No NaNs found\")\n\n\n# Coordinate check\ncoord_cols = [c for c in submission_df.columns if c.startswith((\"x_\",\"y_\",\"z_\"))]\n\nfor c in coord_cols:\n    assert np.issubdtype(submission_df[c].dtype, np.number)\n\nprint(\"✓ Coordinate columns valid\")\n\n\nprint(\"\\n✅ Submission format validation PASSED\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:11.648521Z","iopub.execute_input":"2026-03-08T10:31:11.64876Z","iopub.status.idle":"2026-03-08T10:31:11.68343Z","shell.execute_reply.started":"2026-03-08T10:31:11.648739Z","shell.execute_reply":"2026-03-08T10:31:11.682719Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:11.684482Z","iopub.execute_input":"2026-03-08T10:31:11.685143Z","iopub.status.idle":"2026-03-08T10:31:11.697108Z","shell.execute_reply.started":"2026-03-08T10:31:11.685119Z","shell.execute_reply":"2026-03-08T10:31:11.696348Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =========================================================\n# FINAL CELL — Write Submission + Kaggle Format Validation\n# =========================================================\n\nprint(\"Preparing submission...\")\n\nsample_path = \"/kaggle/input/stanford-rna-3d-folding-2/sample_submission.csv\"\nsample_df = pd.read_csv(sample_path)\n\nsubmission_df = sample_df.copy()\n\n# ---------------------------------------------------------\n# Build coordinate lookup from predictions\n# ---------------------------------------------------------\n\ncoord_lookup = {}\n\nfor seq_id, coords in predictions:\n\n    for i in range(coords.shape[0]):\n\n        coord_lookup[f\"{seq_id}_{i+1}\"] = coords[i]\n\n\n# ---------------------------------------------------------\n# Fill coordinates into submission dataframe\n# ---------------------------------------------------------\n\nfor idx,row in submission_df.iterrows():\n\n    rid = row[\"ID\"]\n\n    if rid in coord_lookup:\n\n        atoms = coord_lookup[rid]\n\n        for a in range(5):\n\n            submission_df.at[idx,f\"x_{a+1}\"] = atoms[a,0]\n            submission_df.at[idx,f\"y_{a+1}\"] = atoms[a,1]\n            submission_df.at[idx,f\"z_{a+1}\"] = atoms[a,2]\n\n\n# ---------------------------------------------------------\n# Write submission\n# ---------------------------------------------------------\n\nsubmission_df.to_csv(\"submission.csv\", index=False)\n\nprint(\"submission.csv written\")\n\n\n# =========================================================\n# Validation Against Sample Submission\n# =========================================================\n\nprint(\"\\nRunning submission validation...\")\n\ntest_df = pd.read_csv(\"submission.csv\")\n\nprint(\"Sample rows:\", len(sample_df))\nprint(\"Submission rows:\", len(test_df))\n\n\n# Column validation\nassert list(sample_df.columns) == list(test_df.columns)\nprint(\"✓ Column names match\")\n\n\n# Row count validation\nassert len(sample_df) == len(test_df)\nprint(\"✓ Row count matches\")\n\n\n# ID ordering validation\nassert (sample_df[\"ID\"].values == test_df[\"ID\"].values).all()\nprint(\"✓ ID ordering matches\")\n\n\n# NaN validation\nassert not test_df.isna().any().any()\nprint(\"✓ No NaNs found\")\n\n\n# Coordinate type validation\ncoord_cols = [c for c in test_df.columns if c.startswith((\"x_\",\"y_\",\"z_\"))]\n\nfor c in coord_cols:\n    assert np.issubdtype(test_df[c].dtype, np.number)\n\nprint(\"✓ Coordinate columns numeric\")\n\n\nprint(\"\\n✅ SUBMISSION FILE VALIDATED\")\nprint(\"submission.csv ready for Kaggle scoring\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-08T10:31:11.698166Z","iopub.execute_input":"2026-03-08T10:31:11.698441Z","iopub.status.idle":"2026-03-08T10:31:14.216259Z","shell.execute_reply.started":"2026-03-08T10:31:11.698412Z","shell.execute_reply":"2026-03-08T10:31:14.215534Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}