{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":118765,"databundleVersionId":15231210,"sourceType":"competition"}],"dockerImageVersionId":31260,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nimport os\n\n# Device configuration (T4 x 2 setup)\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nprint(f\"Using device: {device}\")\n\n# Paths\nDATA_DIR = \"/kaggle/input/stanford-rna-3d-folding-2\"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-20T15:40:52.365604Z","iopub.execute_input":"2026-01-20T15:40:52.366077Z","iopub.status.idle":"2026-01-20T15:40:52.371629Z","shell.execute_reply.started":"2026-01-20T15:40:52.366046Z","shell.execute_reply":"2026-01-20T15:40:52.37092Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# RNA base mapping\nBASE_MAP = {'A': 0, 'C': 1, 'G': 2, 'U': 3}\n\ndef preprocess_sequence(seq):\n    return [BASE_MAP.get(base, 4) for base in seq] # 4 for unknown\n\nclass RNADataset(Dataset):\n    def __init__(self, csv_file, is_test=False):\n        self.df = pd.read_csv(csv_file)\n        self.is_test = is_test\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        seq = row['sequence']\n        encoded_seq = torch.tensor(preprocess_sequence(seq), dtype=torch.long)\n        \n        if self.is_test:\n            return encoded_seq, row['id']\n        else:\n            # Training data logic (coordinates) yahan aayegi\n            pass","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-20T15:41:05.05113Z","iopub.execute_input":"2026-01-20T15:41:05.051529Z","iopub.status.idle":"2026-01-20T15:41:05.05732Z","shell.execute_reply.started":"2026-01-20T15:41:05.051502Z","shell.execute_reply":"2026-01-20T15:41:05.056449Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class RNAStructurePredictor(nn.Module):\n    def __init__(self, vocab_size=5, embed_dim=128, n_heads=8, n_layers=6):\n        super().__init__()\n        self.embedding = nn.Embedding(vocab_size, embed_dim)\n        \n        # Transformer layers to capture folding context\n        encoder_layer = nn.TransformerEncoderLayer(d_model=embed_dim, nhead=n_heads, batch_first=True)\n        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=n_layers)\n        \n        # Output layer: 3 coordinates (x, y, z) for 5 models\n        # Total outputs per residue = 3 * 5 = 15\n        self.fc_out = nn.Linear(embed_dim, 15) \n        \n    def forward(self, x):\n        # x shape: (batch_size, seq_len)\n        x = self.embedding(x) # (batch_size, seq_len, embed_dim)\n        x = self.transformer(x) # (batch_size, seq_len, embed_dim)\n        out = self.fc_out(x) # (batch_size, seq_len, 15)\n        return out","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-20T15:41:15.84584Z","iopub.execute_input":"2026-01-20T15:41:15.846492Z","iopub.status.idle":"2026-01-20T15:41:15.851813Z","shell.execute_reply.started":"2026-01-20T15:41:15.846463Z","shell.execute_reply":"2026-01-20T15:41:15.851003Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import glob\n\n# MSA folder path\nMSA_DIR = \"/kaggle/input/stanford-rna-3d-folding-2/MSA\"\n\ndef get_msa_features(target_id):\n    # Har target ki apni MSA file hai\n    msa_path = f\"{MSA_DIR}/{target_id}.MSA.fasta\"\n    if os.path.exists(msa_path):\n        # Yahan hum MSA se basic statistics nikal sakte hain \n        # (Jaise nucleotide frequency har position par)\n        # Abhi ke liye placeholder rakhte hain jo model ko extra context dega\n        return torch.randn(1, 64) # Example vector\n    return torch.zeros(1, 64)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-20T15:44:00.96447Z","iopub.execute_input":"2026-01-20T15:44:00.964935Z","iopub.status.idle":"2026-01-20T15:44:00.969477Z","shell.execute_reply.started":"2026-01-20T15:44:00.964907Z","shell.execute_reply":"2026-01-20T15:44:00.968681Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class RNA_Alpha_Model(nn.Module):\n    def __init__(self, embed_dim=256):\n        super(RNA_Alpha_Model, self).__init__()\n        self.embed = nn.Embedding(5, embed_dim)\n        \n        # Local context capture (CNN)\n        self.conv1 = nn.Conv1d(embed_dim, embed_dim, kernel_size=5, padding=2)\n        \n        # Global context capture (Attention)\n        encoder_layer = nn.TransformerEncoderLayer(d_model=embed_dim, nhead=16, batch_first=True)\n        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=8)\n        \n        # Predict 5 sets of coordinates (5 models * 3 axes = 15)\n        self.head = nn.Sequential(\n            nn.Linear(embed_dim, 512),\n            nn.ReLU(),\n            nn.Linear(512, 15) \n        )\n\n    def forward(self, seq):\n        x = self.embed(seq) # (B, L, D)\n        \n        # CNN block\n        x = x.transpose(1, 2)\n        x = torch.relu(self.conv1(x))\n        x = x.transpose(1, 2)\n        \n        # Transformer block\n        x = self.transformer(x)\n        \n        # Output coordinates\n        coords = self.head(x) # (B, L, 15)\n        return coords\n\nmodel = RNA_Alpha_Model().to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-20T15:44:10.158259Z","iopub.execute_input":"2026-01-20T15:44:10.159104Z","iopub.status.idle":"2026-01-20T15:44:10.231548Z","shell.execute_reply.started":"2026-01-20T15:44:10.159064Z","shell.execute_reply":"2026-01-20T15:44:10.230787Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"criterion = nn.MSELoss()\noptimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=0.01)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-20T15:44:27.281237Z","iopub.execute_input":"2026-01-20T15:44:27.281943Z","iopub.status.idle":"2026-01-20T15:44:27.286587Z","shell.execute_reply.started":"2026-01-20T15:44:27.281913Z","shell.execute_reply":"2026-01-20T15:44:27.285985Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def generate_submission():\n    test_df = pd.read_csv(f\"{DATA_DIR}/test_sequences.csv\")\n    submission_data = []\n\n    model.eval()\n    with torch.no_grad():\n        for _, row in test_df.iterrows():\n            target_id = row['target_id']\n            seq = torch.tensor([preprocess_sequence(row['sequence'])]).to(device)\n            \n            # Predict\n            preds = model(seq).cpu().numpy()[0] # Shape: (L, 15)\n            \n            # Har nucleotide ke liye row banayein\n            for i, base in enumerate(row['sequence']):\n                res_id = i + 1\n                row_id = f\"{target_id}_{res_id}\"\n                \n                # Coordinates x_1, y_1, z_1 ... x_5, y_5, z_5\n                coords = preds[i].tolist()\n                \n                # Formatting as per competition rules\n                submission_data.append([row_id, base, res_id] + coords)\n\n    # DataFrame banakar save karein\n    cols = ['ID', 'resname', 'resid', \n            'x_1', 'y_1', 'z_1', 'x_2', 'y_2', 'z_2', \n            'x_3', 'y_3', 'z_3', 'x_4', 'y_4', 'z_4', 'x_5', 'y_5', 'z_5']\n    sub_df = pd.DataFrame(submission_data, columns=cols)\n    sub_df.to_csv(\"submission.csv\", index=False)\n    print(\"Submission file saved!\")\n\n# Note: Model training ke baad hi isse call karein","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-20T15:44:39.172597Z","iopub.execute_input":"2026-01-20T15:44:39.173117Z","iopub.status.idle":"2026-01-20T15:44:39.179624Z","shell.execute_reply.started":"2026-01-20T15:44:39.17309Z","shell.execute_reply":"2026-01-20T15:44:39.178623Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class RNATrainDataset(Dataset):\n    def __init__(self, seq_df, label_df, max_len=200):\n        self.seq_df = seq_df\n        self.label_df = label_df\n        self.max_len = max_len\n        self.target_ids = seq_df['target_id'].unique()\n\n    def __len__(self):\n        return len(self.target_ids)\n\n    def __getitem__(self, idx):\n        tid = self.target_ids[idx]\n        sequence = self.seq_df[self.seq_df['target_id'] == tid]['sequence'].values[0]\n        \n        # Labels nikalna\n        target_labels = self.label_df[self.label_df['ID'].str.startswith(tid)]\n        # Hum sirf x_1, y_1, z_1 le rahe hain training ke liye (simple rakhne ko)\n        coords = target_labels[['x_1', 'y_1', 'z_1']].values\n        \n        # Padding/Truncating to max_len\n        seq_enc = preprocess_sequence(sequence)[:self.max_len]\n        coord_data = coords[:self.max_len]\n        \n        # Fill if shorter than max_len\n        actual_len = len(seq_enc)\n        padded_seq = np.zeros(self.max_len)\n        padded_seq[:actual_len] = seq_enc\n        \n        padded_coords = np.zeros((self.max_len, 3))\n        padded_coords[:actual_len] = coord_data\n        \n        return torch.tensor(padded_seq, dtype=torch.long), torch.tensor(padded_coords, dtype=torch.float32)\n\n# Data Load karna (Sirf pehle 500 samples for testing)\ntrain_seq = pd.read_csv(f\"{DATA_DIR}/train_sequences.csv\").head(500)\ntrain_labels = pd.read_csv(f\"{DATA_DIR}/train_labels.csv\")\n\ntrain_ds = RNATrainDataset(train_seq, train_labels)\ntrain_loader = DataLoader(train_ds, batch_size=16, shuffle=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-20T15:46:08.367526Z","iopub.execute_input":"2026-01-20T15:46:08.368266Z","iopub.status.idle":"2026-01-20T15:46:17.61772Z","shell.execute_reply.started":"2026-01-20T15:46:08.368239Z","shell.execute_reply":"2026-01-20T15:46:17.616855Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train_model(model, loader, epochs=5):\n    model.train()\n    for epoch in range(epochs):\n        total_loss = 0\n        for seq, labels in loader:\n            seq, labels = seq.to(device), labels.to(device)\n            \n            optimizer.zero_grad()\n            outputs = model(seq) # Shape: (B, L, 15)\n            \n            # Hum sirf pehle model (x_1, y_1, z_1) ko train kar rahe hain abhi\n            # outputs[:, :, :3] matlab x1, y1, z1\n            loss = criterion(outputs[:, :, :3], labels)\n            \n            loss.backward()\n            optimizer.step()\n            total_loss += loss.item()\n            \n        print(f\"Epoch {epoch+1}/{epochs}, Loss: {total_loss/len(loader):.4f}\")\n\n# Train shuru karein\ntrain_model(model, train_loader)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-20T15:46:31.498039Z","iopub.execute_input":"2026-01-20T15:46:31.498828Z","iopub.status.idle":"2026-01-20T16:09:00.647981Z","shell.execute_reply.started":"2026-01-20T15:46:31.498798Z","shell.execute_reply":"2026-01-20T16:09:00.64692Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}