{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":87793,"databundleVersionId":12276181,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":10855324,"sourceType":"datasetVersion","datasetId":6742586},{"sourceId":11118830,"sourceType":"datasetVersion","datasetId":6933267},{"sourceId":11830543,"sourceType":"datasetVersion","datasetId":7432215},{"sourceId":11830789,"sourceType":"datasetVersion","datasetId":7432367},{"sourceId":11831460,"sourceType":"datasetVersion","datasetId":7432831},{"sourceId":11831882,"sourceType":"datasetVersion","datasetId":7433107},{"sourceId":11833356,"sourceType":"datasetVersion","datasetId":7434181},{"sourceId":224830487,"sourceType":"kernelVersion"}],"dockerImageVersionId":30919,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install --no-index --find-links=/kaggle/input/linux-biowheels-310 biopython numpy\n!pip install --no-index --find-links=/kaggle/input/linux-mlwhl-311 ml-collections contextlib2\n!pip install --no-index --find-links=/kaggle/input/linux-biowheels-310 biopython\n!pip install --no-index --find-links=/kaggle/input/rdkit-cp310 rdkit\n!pip install --no-index --find-links=/kaggle/input/linux-mlwhl-311 biopython ml-collections contextlib2 rdkit\n!pip install --no-index --find-links=/kaggle/input/linux-mlwhl-311 biotite","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-16T03:41:56.088386Z","iopub.execute_input":"2025-05-16T03:41:56.088656Z","iopub.status.idle":"2025-05-16T03:42:00.555722Z","shell.execute_reply.started":"2025-05-16T03:41:56.088635Z","shell.execute_reply":"2025-05-16T03:42:00.554849Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 📌 필요 라이브러리 설치 (사전 업로드된 .whl 사용)\n!pip install --no-index --find-links=/kaggle/input/linux-mlwhl-311 biopython ml-collections contextlib2 rdkit biotite\n\n# 📌 기본 세팅\nimport os, sys, numpy as np, pandas as pd, torch, warnings\nfrom tqdm import tqdm\nwarnings.filterwarnings(\"ignore\")\n\n# 📌 GPU 설정\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"📌 Using device: {device}\")\n\n# 📌 USAlign 설정\nos.system(\"cp /kaggle/input/usalign/USalign /kaggle/working/\")\nos.system(\"chmod u+x /kaggle/working/USalign\")\n\n# 📌 Protenix 코드 및 패키지 경로 등록\nsys.path.append(\"/kaggle/input/protenix-main\")\nsys.path.append(\"/kaggle/input/protenix-packages\")\n\n# 📌 학습 데이터 병합 (v2 우선)\nseq_v1 = pd.read_csv('/kaggle/input/stanford-rna-3d-folding/train_sequences.csv')\nseq_v2 = pd.read_csv('/kaggle/input/stanford-rna-3d-folding/train_sequences.v2.csv')\nlabel_v1 = pd.read_csv('/kaggle/input/stanford-rna-3d-folding/train_labels.csv')\nlabel_v2 = pd.read_csv('/kaggle/input/stanford-rna-3d-folding/train_labels.v2.csv')\n\nseq_v1 = seq_v1[~seq_v1['target_id'].isin(seq_v2['target_id'])]\nlabel_v1 = label_v1[~label_v1['ID'].str.extract(r\"^(.+)_\\d+$\")[0].isin(label_v2['ID'].str.extract(r\"^(.+)_\\d+$\")[0])]\n\nmerged_seq = pd.concat([seq_v2, seq_v1], ignore_index=True)\nmerged_label = pd.concat([label_v2, label_v1], ignore_index=True)\n\n# 📌 입력 생성\ninputs = []\nfor _, row in merged_seq.iterrows():\n    tid = row[\"target_id\"]\n    seq = row[\"sequence\"]\n    lbl = merged_label[merged_label[\"ID\"].str.startswith(tid + \"_\")].copy()\n    lbl.sort_values(\"resid\", inplace=True)\n    if len(lbl) != len(seq):\n        continue\n    coords = lbl[[\"x_1\", \"y_1\", \"z_1\"]].values.astype(np.float32)\n    inputs.append({\n        \"name\": tid,\n        \"sequences\": [{\n            \"rnaSequence\": {\"sequence\": seq, \"count\": 1},\n            \"coordinates\": coords.tolist()\n        }]\n    })\n\nprint(f\"✅ 학습 가능한 시퀀스 수: {len(inputs)}\")\n\n# 📌 InferenceDataset 정의\nfrom protenix.data.infer_data_pipeline import InferenceDataset\n\nclass TrainDataset(InferenceDataset):\n    def __init__(self, data_list, use_msa=False):\n        self.inputs = data_list\n        self.use_msa = use_msa\n        self.dump_dir = \"output\"\n\ndataset = TrainDataset(inputs)\n\n# 📌 모델 설정\nfrom runner.inference import update_inference_configs, InferenceRunner\nfrom configs.configs_base import configs as configs_base\nfrom configs.configs_data import data_configs\nfrom configs.configs_inference import inference_configs\nfrom protenix.config.config import parse_configs\n\nconfigs_base[\"model\"][\"N_cycle\"] = 10\nconfigs_base[\"model\"][\"use_ds4sci\"] = False   # ✅ 오류 방지\nconfigs_base[\"sample_diffusion\"][\"N_sample\"] = 5\nconfigs_base[\"sample_diffusion\"][\"N_step\"] = 200\ninference_configs[\"load_checkpoint_path\"] = \"/kaggle/input/protenix-checkpoints/model_v0.2.0.pt\"\n\nconfigs = {**configs_base, **{\"data\": data_configs}, **inference_configs}\nconfigs = parse_configs(configs=configs, fill_required_with_null=True)\nrunner = InferenceRunner(configs)\nrunner.model.to(device)\ntorch.cuda.empty_cache()\n\n# 📌 테스트셋 로딩\ntest_df = pd.read_csv('/kaggle/input/stanford-rna-3d-folding/test_sequences.csv')\n\nclass TestDataset(InferenceDataset):\n    def __init__(self, seq_list, id_list):\n        self.use_msa = False\n        self.dump_dir = \"output\"\n        self.inputs = [{\n            \"sequences\": [{\"rnaSequence\": {\"sequence\": seq, \"count\": 1}}],\n            \"name\": i\n        } for i, seq in zip(id_list, seq_list)]\n\ntest_dataset = TestDataset(test_df[\"sequence\"], test_df[\"target_id\"])\n\n# 📌 예측 및 제출파일 생성\nwith open(\"submission.csv\", \"w\") as f:\n    for i in tqdm(range(len(test_dataset))):\n        try:\n            data, atom_array, err_msg = test_dataset[i]\n            if err_msg:\n                raise Exception(err_msg)\n            runner.update_model_configs(update_inference_configs(configs, data[\"N_token\"].item()))\n            out = runner.predict(data)\n            coords = out[\"coordinate\"][:, data[\"input_feature_dict\"][\"atom_to_tokatom_idx\"] == 12]\n\n            result = []\n            for j, res in enumerate(data['sequences'][0]['rnaSequence']['sequence']):\n                row = {\n                    \"ID\": f\"{data['sample_name']}_{j+1}\",\n                    \"resname\": res,\n                    \"resid\": j + 1,\n                }\n                for k in range(5):\n                    if k < coords.shape[0]:\n                        row.update({\n                            f\"x_{k+1}\": coords[k, j, 0],\n                            f\"y_{k+1}\": coords[k, j, 1],\n                            f\"z_{k+1}\": coords[k, j, 2],\n                        })\n                    else:\n                        row.update({f\"x_{k+1}\": 0.0, f\"y_{k+1}\": 0.0, f\"z_{k+1}\": 0.0})\n                result.append(row)\n            pd.DataFrame(result).to_csv(f, index=False, header=(i == 0))\n        except:\n            continue\n\nprint(\"✅ submission.csv 생성 완료 🎉\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}