{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":67356,"databundleVersionId":8006601,"sourceType":"competition"}],"dockerImageVersionId":30684,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"! pip install -qq duckdb","metadata":{"_uuid":"3ca28711-7d13-45ae-8654-3bfab478fe68","_cell_guid":"01578101-a283-4ac3-ae7e-829006ce2a07","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:27:40.612331Z","iopub.execute_input":"2024-04-09T16:27:40.612919Z","iopub.status.idle":"2024-04-09T16:27:55.428514Z","shell.execute_reply.started":"2024-04-09T16:27:40.612887Z","shell.execute_reply":"2024-04-09T16:27:55.426958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import duckdb\nimport pandas as pd\n\ntrain_path = '/kaggle/input/leash-BELKA/train.parquet'\ntest_path = '/kaggle/input/leash-BELKA/test.parquet'\n\ncon = duckdb.connect()","metadata":{"_uuid":"5388d62f-33ca-40bd-901e-13718a976be6","_cell_guid":"b45809c4-929a-4251-952f-a52914f03f1c","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:27:55.430959Z","iopub.execute_input":"2024-04-09T16:27:55.431384Z","iopub.status.idle":"2024-04-09T16:27:56.684384Z","shell.execute_reply.started":"2024-04-09T16:27:55.431350Z","shell.execute_reply":"2024-04-09T16:27:56.683179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nall_building_blocks_df = con.query(f\"\"\"(SELECT * FROM (\n    SELECT distinct buildingblock1_smiles as smile, 'buildingblock1' as group, 'test' as split, protein_name, 2 as binds  FROM parquet_scan('{test_path}')\n    UNION\n    SELECT distinct buildingblock1_smiles as smile, 'buildingblock1' as group, 'train' as split, protein_name, binds FROM parquet_scan('{train_path}')\n    UNION\n    SELECT distinct buildingblock2_smiles as smile, 'buildingblock2' as group, 'test' as split, protein_name, 2 as binds  FROM parquet_scan('{test_path}')\n    UNION\n    SELECT distinct buildingblock2_smiles as smile, 'buildingblock2' as group, 'train' as split, protein_name, binds FROM parquet_scan('{train_path}')\n    UNION\n    SELECT distinct buildingblock3_smiles as smile, 'buildingblock3' as group, 'test' as split, protein_name, 2 as binds  FROM parquet_scan('{test_path}')\n    UNION\n    SELECT distinct buildingblock3_smiles as smile, 'buildingblock3' as group, 'train' as split, protein_name, binds FROM parquet_scan('{train_path}')\n    ) as t)\"\"\").df()","metadata":{"_uuid":"e8211d84-abf0-44ce-bacb-ada37a2d671e","_cell_guid":"7872dc13-a212-4d79-bb80-b55d2d7c59e8","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:27:56.686451Z","iopub.execute_input":"2024-04-09T16:27:56.687487Z","iopub.status.idle":"2024-04-09T16:28:38.225705Z","shell.execute_reply.started":"2024-04-09T16:27:56.687441Z","shell.execute_reply":"2024-04-09T16:28:38.224549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_building_blocks_df","metadata":{"_uuid":"71a526a4-b51e-4bf7-93cd-c7fd604419b4","_cell_guid":"205bb0ab-d700-4b95-803b-41dcaab108f9","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:28:38.228463Z","iopub.execute_input":"2024-04-09T16:28:38.229519Z","iopub.status.idle":"2024-04-09T16:28:38.254497Z","shell.execute_reply.started":"2024-04-09T16:28:38.229483Z","shell.execute_reply":"2024-04-09T16:28:38.253365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"smiles = list(set(all_building_blocks_df['smile']))\nlen(smiles)","metadata":{"_uuid":"311960a2-6e39-459e-bdf0-551d4e0de0a8","_cell_guid":"202c0a00-8dfa-4025-9718-fed672395d87","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:28:38.256151Z","iopub.execute_input":"2024-04-09T16:28:38.256817Z","iopub.status.idle":"2024-04-09T16:28:38.269530Z","shell.execute_reply.started":"2024-04-09T16:28:38.256780Z","shell.execute_reply":"2024-04-09T16:28:38.268494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! pip3 install -qq sentence_transformers","metadata":{"_uuid":"ffa2a47b-fb80-4c84-888d-65bd050c9c0b","_cell_guid":"df455593-8c20-407e-9330-91cb2c150f5c","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:28:38.271134Z","iopub.execute_input":"2024-04-09T16:28:38.271730Z","iopub.status.idle":"2024-04-09T16:28:51.781162Z","shell.execute_reply.started":"2024-04-09T16:28:38.271698Z","shell.execute_reply":"2024-04-09T16:28:51.779898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sentence_transformers import SentenceTransformer\nmodel = SentenceTransformer('UdS-LSV/siamese-smole-bert-muv-1x')","metadata":{"_uuid":"bf0af87f-c144-4a3c-8f5f-35775b4b80f8","_cell_guid":"0c79a724-0e79-44f1-a379-8c65e5b26baf","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:28:51.782774Z","iopub.execute_input":"2024-04-09T16:28:51.783278Z","iopub.status.idle":"2024-04-09T16:29:05.127146Z","shell.execute_reply.started":"2024-04-09T16:28:51.783232Z","shell.execute_reply":"2024-04-09T16:29:05.125797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def smile_to_emb(smile):\n    emb = model.encode(smile)\n    return emb","metadata":{"_uuid":"78db8949-b81f-4bb8-b97e-3cc8f7d8d1eb","_cell_guid":"ab7c183b-6737-46e3-8f83-e54f0fa6fe4e","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:29:05.128771Z","iopub.execute_input":"2024-04-09T16:29:05.130101Z","iopub.status.idle":"2024-04-09T16:29:05.135054Z","shell.execute_reply.started":"2024-04-09T16:29:05.130058Z","shell.execute_reply":"2024-04-09T16:29:05.133781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"smile_to_emb(smiles[0]).shape","metadata":{"execution":{"iopub.status.busy":"2024-04-09T16:29:05.137275Z","iopub.execute_input":"2024-04-09T16:29:05.137615Z","iopub.status.idle":"2024-04-09T16:29:05.316492Z","shell.execute_reply.started":"2024-04-09T16:29:05.137587Z","shell.execute_reply":"2024-04-09T16:29:05.315291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"smiles_emb = smile_to_emb(smiles)","metadata":{"_uuid":"31a2a524-1fb1-46f9-b56e-45c18c9bc4ef","_cell_guid":"c9e48138-a92c-493b-8b0b-1273239f4164","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:29:05.321474Z","iopub.execute_input":"2024-04-09T16:29:05.321973Z","iopub.status.idle":"2024-04-09T16:29:23.480658Z","shell.execute_reply.started":"2024-04-09T16:29:05.321928Z","shell.execute_reply":"2024-04-09T16:29:23.479456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"smiles_hash = { smile:smile_emb for smile, smile_emb in zip(smiles, smiles_emb)}","metadata":{"_uuid":"1aa3d8f1-874f-4894-86b9-dd507f4762a1","_cell_guid":"69ca1990-c81c-429c-b5a4-43ae6ca0be28","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:29:23.482362Z","iopub.execute_input":"2024-04-09T16:29:23.482814Z","iopub.status.idle":"2024-04-09T16:29:23.490415Z","shell.execute_reply.started":"2024-04-09T16:29:23.482775Z","shell.execute_reply":"2024-04-09T16:29:23.489131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\ntqdm.pandas()\nall_building_blocks_df['emb'] = all_building_blocks_df['smile'].progress_apply(lambda smile: smiles_hash[smile])","metadata":{"_uuid":"fc843b8d-b699-49ee-8728-f73ce3fbb258","_cell_guid":"6fc314bc-37fa-489f-ada1-6746e9ccfa09","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:29:23.492009Z","iopub.execute_input":"2024-04-09T16:29:23.492852Z","iopub.status.idle":"2024-04-09T16:29:23.554310Z","shell.execute_reply.started":"2024-04-09T16:29:23.492814Z","shell.execute_reply":"2024-04-09T16:29:23.552903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Building Blocks ","metadata":{}},{"cell_type":"code","source":"from sklearn.manifold import TSNE\nimport matplotlib.pyplot as plt\nimport plotly.express as px\nimport seaborn as sns\nimport numpy as np","metadata":{"_uuid":"43e66d64-a3ae-456c-a200-7b336b9f49d2","_cell_guid":"6002fea7-e6ae-43f9-b1b5-1e0016cf688f","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-04-09T16:29:23.556454Z","iopub.execute_input":"2024-04-09T16:29:23.556896Z","iopub.status.idle":"2024-04-09T16:29:24.662241Z","shell.execute_reply.started":"2024-04-09T16:29:23.556862Z","shell.execute_reply":"2024-04-09T16:29:24.661148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nemb_array = np.stack(all_building_blocks_df['emb'].tolist())\ntsne = TSNE(n_components=2, random_state=42)\nprojection = tsne.fit_transform(emb_array)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T16:29:24.663801Z","iopub.execute_input":"2024-04-09T16:29:24.664308Z","iopub.status.idle":"2024-04-09T16:31:17.533981Z","shell.execute_reply.started":"2024-04-09T16:29:24.664265Z","shell.execute_reply":"2024-04-09T16:31:17.532972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_building_blocks_df['emb_1'] = projection[:,0]\nall_building_blocks_df['emb_2'] = projection[:,1]","metadata":{"execution":{"iopub.status.busy":"2024-04-09T16:31:17.535341Z","iopub.execute_input":"2024-04-09T16:31:17.536207Z","iopub.status.idle":"2024-04-09T16:31:17.542402Z","shell.execute_reply.started":"2024-04-09T16:31:17.536172Z","shell.execute_reply":"2024-04-09T16:31:17.541314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import time\ncolors = ['blue', 'green', 'red', 'cyan', 'magenta', 'yellow', 'black', 'white']\ndef viz_smiles(columns, title):\n    all_building_blocks_df['target'] = all_building_blocks_df.apply(lambda row:  \"-\".join([str(row[column]) for column in columns]), axis=1)\n    \n    targets = sorted(all_building_blocks_df['target'].unique())\n    for i_c, target in enumerate(targets):\n        fig, ax = plt.subplots(figsize=(12, 6))\n        subset = all_building_blocks_df[all_building_blocks_df['target'] == target]\n        ax.scatter(subset['emb_1'], subset['emb_2'], label=target, s=12, alpha=1, color=colors[i_c])\n        ax.set_title(f'{title} {target}- (Train vs Test)')\n        ax.set_xlabel('emb_1')\n        ax.set_ylabel('emb_2')\n        ax.legend(title='Target')\n        plt.show()\n    \n    all_building_blocks_df['target'] = all_building_blocks_df.apply(lambda row:  \"-\".join([str(row[column]) for column in columns]), axis=1)\n    all_groups = sorted(list(set(all_building_blocks_df['group'])))\n    all_proteins = sorted(list(set(all_building_blocks_df['protein_name'])))\n    for group in all_groups:\n        filtered_building_blocks_df = all_building_blocks_df[((all_building_blocks_df['group'] == group))]\n        \n        targets = sorted(filtered_building_blocks_df['target'].unique())\n        for i_c, target in enumerate(targets):\n            fig, ax = plt.subplots(figsize=(12, 6))\n            subset = filtered_building_blocks_df[filtered_building_blocks_df['target'] == target]\n            ax.scatter(subset['emb_1'], subset['emb_2'], label=target, s=12, alpha=1, color=colors[i_c])\n            ax.set_title(f'{title} - {group} - {target} - (Train vs Test)')\n            ax.set_xlabel('emb_1')\n            ax.set_ylabel('emb_2')\n            ax.legend(title='Target')\n            plt.show()\n\n        time.sleep(2)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T17:30:36.522715Z","iopub.execute_input":"2024-04-09T17:30:36.523174Z","iopub.status.idle":"2024-04-09T17:30:36.539927Z","shell.execute_reply.started":"2024-04-09T17:30:36.523141Z","shell.execute_reply":"2024-04-09T17:30:36.538793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"viz_smiles(columns=[\"binds\"], title=\"Targets \")","metadata":{"execution":{"iopub.status.busy":"2024-04-09T17:30:38.208085Z","iopub.execute_input":"2024-04-09T17:30:38.209459Z","iopub.status.idle":"2024-04-09T17:30:48.961972Z","shell.execute_reply.started":"2024-04-09T17:30:38.209416Z","shell.execute_reply":"2024-04-09T17:30:48.960553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"viz_smiles(columns=[\"split\"], title=\"Data Split \")","metadata":{"execution":{"iopub.status.busy":"2024-04-09T17:30:57.515308Z","iopub.execute_input":"2024-04-09T17:30:57.516081Z","iopub.status.idle":"2024-04-09T17:31:07.835416Z","shell.execute_reply.started":"2024-04-09T17:30:57.516016Z","shell.execute_reply":"2024-04-09T17:31:07.833999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"viz_smiles(columns=[\"split\",\"binds\"], title=\"Targets by Split \")","metadata":{"execution":{"iopub.status.busy":"2024-04-09T17:31:17.386204Z","iopub.execute_input":"2024-04-09T17:31:17.387404Z","iopub.status.idle":"2024-04-09T17:31:28.353029Z","shell.execute_reply.started":"2024-04-09T17:31:17.387352Z","shell.execute_reply":"2024-04-09T17:31:28.351733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Relation between molecule vs building blocks ( few samples )","metadata":{}},{"cell_type":"code","source":"def viz_smiles_of_molecule(sample):\n    total_samples = con.query(f\"\"\"(SELECT * FROM parquet_scan('{train_path}') WHERE buildingblock1_smiles='{sample[\"buildingblock1_smiles\"]}' AND  buildingblock2_smiles='{sample[\"buildingblock2_smiles\"]}' AND  buildingblock3_smiles='{sample[\"buildingblock3_smiles\"]}')\"\"\").df()\n    data = [\n        {'smiles': sample['molecule_smiles'], 'name': 'molecule', 'type': 'molecule'},\n        {'smiles': sample['buildingblock1_smiles'], 'name': 'buildingblock1_smiles', 'type': '1-of-3-buildingblock'},\n        {'smiles': sample['buildingblock2_smiles'], 'name': 'buildingblock2_smiles', 'type': '1-of-3-buildingblock'},\n        {'smiles': sample['buildingblock3_smiles'], 'name': 'buildingblock3_smiles', 'type': '1-of-3-buildingblock'},\n        {'smiles': sample['buildingblock1_smiles']+sample['buildingblock2_smiles'], 'name': 'buildingblock1+2', 'type': '2-of-3-buildingblock'},\n        {'smiles': sample['buildingblock1_smiles']+sample['buildingblock3_smiles'], 'name': 'buildingblock1+3', 'type': '2-of-3-buildingblock'},\n        {'smiles': sample['buildingblock2_smiles']+sample['buildingblock3_smiles'], 'name': 'buildingblock2+3', 'type': '2-of-3-buildingblock'},\n        {'smiles': sample['buildingblock1_smiles']+sample['buildingblock2_smiles']+sample['buildingblock3_smiles'], 'name': 'buildingblock1+2+3', 'type': '3-of-3-buildingblock'},\n    ]\n\n    smiles_emb = smile_to_emb([x['smiles'] for x in data])\n    for i in range(len(data)):\n        data[i]['emb'] = smiles_emb[i]\n    df = pd.DataFrame(data)\n    tsne = TSNE(n_components=2, random_state=42, perplexity=3)\n    projection_all = tsne.fit_transform(smiles_emb)\n    df['emb_1'] = projection_all[:,0]\n    df['emb_2'] = projection_all[:,1]\n\n    fig, ax = plt.subplots(figsize=(12, 6))\n    targets = df['type'].unique()\n    for target in targets:\n        subset = df[df['type'] == target]\n        ax.scatter(subset['emb_1'], subset['emb_2'], label=target, s=500)\n    ax.set_title(f\"Sample:{sample['id']} - Protein vs Molecule vs BuildingBlock\")\n    ax.set_xlabel('emb_1')\n    ax.set_ylabel('emb_2')\n    ax.legend(title='Target')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-09T17:31:46.805504Z","iopub.execute_input":"2024-04-09T17:31:46.805941Z","iopub.status.idle":"2024-04-09T17:31:46.818262Z","shell.execute_reply.started":"2024-04-09T17:31:46.805908Z","shell.execute_reply":"2024-04-09T17:31:46.817349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samples = con.query(f\"\"\"(SELECT * FROM parquet_scan('{train_path}') WHERE binds=1 LIMIT 10)\"\"\").df().to_dict(orient='records')\nfor sample in samples:\n    viz_smiles_of_molecule(sample)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T17:31:49.795913Z","iopub.execute_input":"2024-04-09T17:31:49.797050Z","iopub.status.idle":"2024-04-09T17:31:57.679116Z","shell.execute_reply.started":"2024-04-09T17:31:49.796986Z","shell.execute_reply":"2024-04-09T17:31:57.677907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samples = con.query(f\"\"\"(SELECT * FROM parquet_scan('{train_path}') WHERE binds=0 LIMIT 10)\"\"\").df().to_dict(orient='records')\nfor sample in samples:\n    viz_smiles_of_molecule(sample)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T17:32:00.679750Z","iopub.execute_input":"2024-04-09T17:32:00.680226Z","iopub.status.idle":"2024-04-09T17:32:08.073076Z","shell.execute_reply.started":"2024-04-09T17:32:00.680193Z","shell.execute_reply":"2024-04-09T17:32:08.071800Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}