{ "cells": [ { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "import os\n", "output_dir = \"output/seg_benchmark\"\n", "os.makedirs(output_dir, exist_ok=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Segmentation Benchmark" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "source_path = \"../REVISE/results\"\n", "task = \"seg\"\n", "patient_id = \"P2CRC\"\n", "\n", "result_path = f\"{source_path}/{task}/{patient_id}\"\n", "data_path = f\"../REVISE/data/{task}/{patient_id}\"\n", "\n", "REVISE_result_path = f\"{source_path}/{task}/{patient_id}\"\n", "\n", "methods = ['raw', 'sp_SVC']\n", "\n", "parts = [\"part3\", \"part1\", \"part2\"]\n", "metrics = [\"PCC\", \"SSIM\", \"MSE\"]\n", "spot_sizes = [1,2,3,4]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot seg benchmark" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gene_type = \"All\"\n", "gene_num = 50" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "import pandas as pd\n", "import scanpy as sc\n", "from tqdm import tqdm\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "\n", "def get_genes(result_path, data_path, part, spot_size, method, gene_type = \"HVG\", gene_num = 50, test_genes = None): \n", " ## Get HVG or HEG or All\n", " spot_path = os.path.join(data_path, f\"cut_{part}\", f\"spot_{spot_size}\")\n", " save_path = os.path.join(result_path, part, f\"{spot_size}_{method}\", \"select_gene\")\n", " os.makedirs(save_path, exist_ok=True)\n", "\n", " gene_file = f\"{save_path}/{gene_type}_genes_{gene_num}.txt\"\n", " if os.path.exists(gene_file):\n", " # print(f\"Find {gene_type} genes in {gene_file}\")\n", " with open(gene_file, \"r\") as f:\n", " genes = f.read().splitlines()\n", " return genes\n", "\n", " st_path = f\"{spot_path}/xenium_spot.h5ad\"\n", " adata = sc.read(st_path)\n", " if test_genes is not None:\n", " overlap_genes = [gene for gene in test_genes if gene in adata.var_names]\n", " adata = adata[:, overlap_genes]\n", " \n", " if gene_type == \"HVG\":\n", " sc.pp.filter_genes(adata, min_cells=1)\n", " sc.pp.normalize_total(adata, target_sum=1e4)\n", " sc.pp.highly_variable_genes(adata, flavor='seurat_v3', n_top_genes=gene_num)\n", " genes = adata.var[adata.var['highly_variable']].index.tolist()\n", " elif gene_type == \"HEG\":\n", " adata.var['sum'] = adata.X.toarray().sum(axis=0)\n", " adata.var.sort_values('sum', ascending=True, inplace=True)\n", " genes = adata.var.head(gene_num).index.tolist()\n", " else:\n", " genes = adata.var_names\n", " \n", " with open(gene_file, \"w\") as f:\n", " f.write(\"\\n\".join(genes))\n", " # print(f\"Save {gene_type} genes to {gene_file}\")\n", "\n", " return genes\n", "\n", "def get_merge_df(result_path, data_path, part, metric, spot_sizes, methods):\n", "\n", " merge_df = pd.DataFrame()\n", " for spot_size in tqdm(spot_sizes, desc=\"spot_sizes\"): \n", " for method in methods:\n", " if method == \"raw\":\n", " metric_file = f\"{result_path}/cut_{part}/spot_{spot_size}/raw_metrics_normalized.csv\"\n", " elif method == \"sp_SVC\":\n", " metric_file = f\"{result_path}/cut_{part}/spot_{spot_size}/metrics_normalized.csv\"\n", " df = pd.read_csv(metric_file, index_col=0)\n", " df.set_index('Gene', inplace=True)\n", " genes = get_genes(result_path, data_path, part, spot_size, method, gene_type = gene_type, gene_num = gene_num, test_genes = df.index)\n", " df = df.loc[genes]\n", " \n", " df = pd.DataFrame({\n", " 'Method': method,\n", " 'Value': df[metric].values,\n", " 'Spot_size': spot_size,\n", " 'Part': part,\n", " 'Metric': metric,\n", " })\n", " \n", " merge_df = pd.concat([merge_df, df])\n", " merge_df.reset_index(drop=True, inplace=True)\n", " return merge_df" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "spot_sizes: 100%|██████████| 4/4 [00:50<00:00, 12.73s/it]\n", "spot_sizes: 100%|██████████| 4/4 [00:30<00:00, 7.54s/it]\n", "spot_sizes: 100%|██████████| 4/4 [00:25<00:00, 6.48s/it]\n", "parts: 100%|██████████| 3/3 [01:46<00:00, 35.67s/it]\n" ] } ], "source": [ "# compute mean\n", "parts = [\"part3\", \"part1\", \"part2\"]\n", "metrics = [\"PCC\", \"SSIM\", \"MSE\"]\n", "\n", "save_dir = f\"{output_dir}/{gene_type}_mean\"\n", "os.makedirs(save_dir, exist_ok=True)\n", "for part in tqdm(parts, desc=\"parts\"):\n", " for spot_size in tqdm(spot_sizes, desc=\"spot_sizes\"): \n", " merge_df = pd.DataFrame() \n", " for method in methods:\n", " if method == \"raw\":\n", " metric_file = f\"{result_path}/cut_{part}/spot_{spot_size}/raw_metrics_normalized.csv\"\n", " elif method == \"sp_SVC\":\n", " metric_file = f\"{result_path}/cut_{part}/spot_{spot_size}/metrics_normalized.csv\"\n", " df = pd.read_csv(metric_file, index_col=0)\n", " df.set_index('Gene', inplace=True)\n", " genes = get_genes(result_path, data_path, part, spot_size, method, gene_type = gene_type, gene_num = gene_num, test_genes = df.index)\n", " df = df.loc[genes]\n", " \n", " df = df[metrics].mean(axis=0)\n", " \n", " merge_df = pd.concat([merge_df, df], axis=1)\n", " merge_df.reset_index(drop=True, inplace=True)\n", " merge_df.index = metrics\n", " merge_df.columns = methods\n", " merge_df.T.to_csv(f\"{save_dir}/{part}_{spot_size}_{gene_type}_{gene_num}.csv\")\n" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "gene_type = \"All\"\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "spot_sizes: 100%|██████████| 4/4 [00:00<00:00, 119.05it/s]\n", "spot_sizes: 100%|██████████| 4/4 [00:00<00:00, 278.60it/s]\n", "spot_sizes: 100%|██████████| 4/4 [00:00<00:00, 278.65it/s]\n", "spot_sizes: 100%|██████████| 4/4 [00:00<00:00, 275.21it/s]\n", "spot_sizes: 100%|██████████| 4/4 [00:00<00:00, 278.63it/s]\n", "spot_sizes: 100%|██████████| 4/4 [00:00<00:00, 277.66it/s]\n", "spot_sizes: 100%|██████████| 4/4 [00:00<00:00, 276.19it/s]\n", "spot_sizes: 100%|██████████| 4/4 [00:00<00:00, 274.75it/s]\n", "spot_sizes: 100%|██████████| 4/4 [00:00<00:00, 277.77it/s]\n" ] }, { "data": { "image/png": "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mc98ZqxYsSLuvvvuuOiiiyr1EgAoM7UCgELUCoDqkKpQKiJi69atsXXr1gkf279//7jtP/uzP4s/+7M/S6BVAFQTtQKAQtQKgMpLXSgFAAAAUEvy+Xzkcrmx7d7e3nHfT8lmszW1iIJQCgAAAKCCcrlc7Nix47T93d3d47Y7OjpiyZIlSTWr7IRSAAAAABWUzWajo6NjSsfVEqFUlXl6l7166a4HAAAA9SyTydRUD6ipEkpVmYm67NV6dz0AAACg/gilqsxUuuzVWnc9AAAAoP4IpapMvXbZqwb1utoBAAAAVIJQCv5dva52AAAAAJUglIJ/V6+rHQAAAEAlCKXg3xk6CQAAAMlpqHQDAAAAAKg/QikAAAAAEieUAgAAACBx5pSiZuTz+cjlcmPbvb29476fks1mI5PJJNo2AAAAYDyhFDUjl8vFjh07Ttvf3d09brujo8OE5gAAAFBhQilqRjabjY6OjikdBwAAAFSWUIqakclk9IACAACAlDDROQAAAACJE0oBAAAAkDihFAAAAACJE0oBAAAAkLjUhVJdXV2xdOnSmDt3bqxevTruueeeKZ132223xaxZs+Kqq64qbwMBqDi1AoBC1AqAyktVKLV3795ob2+P66+/Pu69995YtmxZrFu3Ln7605+e8bwf//jH8Yd/+Ifxile8IqGWAlApagUAhagVANUhVaHUzTffHJs3b45NmzbFRRddFLt374558+bFnj17Jj1neHg4fu/3fi9uuOGGeO5zn5tgawGoBLUCgELUCoDqkJpQamhoKA4ePBhr164d29fQ0BBr166NAwcOTHrejh074rzzzou3vvWtU3qefD4f/f39474ASAe1AoBC1AqA6pGaUOro0aMxPDwcra2t4/a3trZGLpeb8Jxvf/vb8elPfzq6u7un/DydnZ2xYMGCsa/FixeX1G4AkqNWAFCIWgFQPVITSk3X448/Hm9+85uju7s7Fi5cOOXztm/fHsePHx/7evTRR8vYSgAqSa0AoBC1AqB85lS6AVO1cOHCmD17dvT19Y3b39fXF9ls9rTj/+///b/x4x//OK644oqxfSMjIxERMWfOnDh06FA873nPO+28TCYTmUxmhlsPQBLUCgAKUSsAqkdqeko1NTXFihUroqenZ2zfyMhI9PT0xJo1a047/gUveEHcf//9cd999419XXnllfGqV70q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joaGX3X+etnLXhZf+MIX4rrrrov3v//98fznPz++8pWvxIte9KJKvQQAykytAKAQtQKgOswaTetargAAAACkVmrmlAIAAACgdgilAAAAAEicUAoAAACAxAmlAAAAAEicUAoAAACAxAmlAAAAAEicUAoAAACAxAmlAAAAAEicUAoAAACAxAmlAAAAAEicUAoAAACAxAmlAAAAAEicUAoAAACAxAmlAAAAAEicUAoAAACAxAmlAAAAAEicUAoAAACAxAmlAAAAAEhczYdSjz76aFx22WVx0UUXxYtf/OL44he/WOkmAVBl1AoAClErAGberNHR0dFKN6Kcent7o6+vL5YvXx65XC5WrFgRP/zhD+Oss86qdNMAqBJqBQCFqBUAM29OpRtQbm1tbdHW1hYREdlsNhYuXBg/+9nPFA8AxqgVABSiVgDMvIoP37vzzjvjiiuuiPPPPz9mzZoVX/nKV047pqurK5YuXRpz586N1atXxz333FPUcx08eDCGh4dj8eLFJbYagCSpFQAUolYApE/FQ6nBwcFYtmxZdHV1Tfj43r17o729Pa6//vq49957Y9myZbFu3br46U9/OnbM8uXL40UvetFpXz/5yU/GjvnZz34WGzZsiE9+8pNlf00AzCy1AoBC1AqA9KmqOaVmzZoVX/7yl+Oqq64a27d69eq45JJL4pZbbomIiJGRkVi8eHG8+93vjm3btk3p5+bz+Xj1q18dmzdvjje/+c0Fj83n82PbIyMj8bOf/SxaWlpi1qxZ039RACkyOjoajz/+eJx//vnR0FDx+xYTUisAKkutUCsACplqrajqOaWGhobi4MGDsX379rF9DQ0NsXbt2jhw4MCUfsbo6GhcffXV8Z/+038qWDgiIjo7O+OGG24ous0AteDRRx+NZz/72ZVuxpSoFQCVoVacmVoBULhWVHUodfTo0RgeHo7W1tZx+1tbW+OBBx6Y0s+46667Yu/evfHiF794bFz5Zz/72bj44osnPH779u3R3t4+tn38+PG44IIL4tFHH4358+cX90IAUqK/vz8WL14cZ599dqWbMmVqBUCy1Aq1AqCQqdaKqg6lZsLLX/7yGBkZmfLxmUwmMpnMafvnz5+veAB1o96GFagVANOnVpyZWgFQuFZU5yDwf7dw4cKYPXt29PX1jdvf19cX2Wy2Qq0CoJqoFQAUolYAVKeq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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib as mpl\n", "import matplotlib.pyplot as plt\n", "\n", "mpl.rcParams['pdf.fonttype'] = 42 \n", "mpl.rcParams['ps.useafm'] = False \n", "\n", "def plot_comp_seg(merge_df, metric, part, ax):\n", " \n", " spot_size_order = [1, 2, 3, 4]\n", " method_order = methods\n", " custom_palette = {\n", " methods[0]: '#80a9c8',\n", " methods[1]: '#e89786',\n", " # methods[2]: '#8ccfd9',\n", " # methods[3]: '#b39a94',\n", " }\n", " # Plot boxplots\n", " sns.boxplot(\n", " data=merge_df,\n", " x='Spot_size',\n", " y='Value',\n", " hue='Method',\n", " order=spot_size_order,\n", " hue_order=method_order,\n", " palette=[custom_palette[m] for m in method_order],\n", " width=0.4,\n", " fliersize=2,\n", " showfliers=False,\n", " ax=ax\n", " )\n", " # ax.set_title(f'{part}', fontsize=11, pad=8)\n", " # ax.set_xlabel('Spot Size', fontsize=10)\n", " ax.set_ylabel(metric, fontsize=10)\n", " ax.xaxis.set_visible(False)\n", "\n", " if metric == \"PCC\":\n", " ax.set_ylim(0.2, 1.02)\n", " elif metric == \"SSIM\":\n", " ax.set_ylim(0.0, 1.02)\n", " elif metric == \"MSE\":\n", " ax.set_ylim(1e-5, 0.01)\n", " ax.set_yscale('log')\n", "\n", " if ax.get_legend() is not None:\n", " ax.legend_.remove()\n", " ax.set_aspect('auto')\n", "\n", " \n", "fig, axes = plt.subplots(3, 3, figsize=(12, 9))\n", "\n", "for i, part in enumerate(parts):\n", " for j, metric in enumerate(metrics):\n", "\n", " merge_df = get_merge_df(result_path, data_path, part, metric, spot_sizes, methods=methods)\n", " \n", " ax = axes[j, i]\n", " plot_comp_seg(merge_df, metric, part, ax)\n", "\n", "plt.tight_layout()\n", "plt.savefig(f\"{output_dir}/{task}_{gene_type}_{gene_num}.pdf\", dpi=300)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## bin2cell" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "spot_sizes = [8]\n", "task = \"bin2cell\"\n", "\n", "import matplotlib as mpl\n", "import matplotlib.pyplot as plt\n", "\n", "mpl.rcParams['pdf.fonttype'] = 42 \n", "mpl.rcParams['ps.useafm'] = False " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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6CEjwwxqgTy3GTBSPErynnvuOS1dulQNDQ0aNWpUj31Hjx7VjBkzdM8992ju3LkjGiSCz1Aq+w3lGISmhIQELV26VEuXLtXrr7+uxx57TJmZmTr77LO1ePFiLV68uNeDKgAYCSUlJVq4cKEryZszZ44aGhp0xhlnSJK++uor/frXvybJ86KB5jZj/DBChUdJ3sMPP6yf//znvRI8STrllFO0dOlSPfjggyR56NdwK/tF8nQNHrrooot00UUXae3atZo/f75uvvlm/dd//ZfGjRtndGgAgtCJccD9rQcLf58nb7Cxx4wfRrDzKMl79913B3zy9P3vf1/Lly8fdlAIXgNV9uPpGrxhx44dqqmp0ebNmzVlyhRZrVadeuqpRocFAAGNefIA/+ZRkvfFF1/o+PHj/e4/duyYvvjii2EHheDG0zV4W3Nzs5544gk99thj+uKLL3TdddfpjTfe0Lnnnmt0aAAAAF7nUZKXkpKit956S1OnTu1z/1tvvcXNOQDDTZw4UUlJScrPz9dVV12lyMhIdXV16Z133unRbtq0aQZFCCCYPfLII66hBcePH9f69esVGxsr6evCKwDgbR4lefPmzdOyZct02WWXKT4+vsc+m82m5cuXa8GCBSMaIAB4yul0qqmpSatXr9YvfvELSb3HxYTyPHkAvGfixImqrq52rSckJOjJJ5/s1QYAvMmjJK+4uFh/+MMf9L3vfU8LFizQlClTJEl79+7VU089peTkZBUXF3slUABw1yeffGJ0CABC1Keffmp0CADgWZI3evRovfHGGyopKdGmTZtc4+9OPfVULViwQGvWrNHo0aO9EigAuItu4wAAIJR5PBn62LFj9dBDD8lqtaqtrU3d3d06/fTTFRYW5o34AMBj3x571x/G5AEYafX19Tp06JB++MMfurY98cQTKi0tVUdHh3JycvTAAw+4JkcHAG/waDbgf/3rX3rhhRd05MgRhYWF6fTTT1dcXJzCwsJkt9v1wgsvyOFweBSA1WpVSkqKoqOjlZmZqZ07dw7Y/ssvv1RhYaESExNlMpl05plnauvWrR6dE0BwS01N1fnnn6/U1NR+l/PPP9/oMAEEobKyMr333nuu9T179mjx4sXKyspScXGx/vjHP6q8vNzACAGEAo/e5P3mN7/RCy+8oKuuuqrXvjFjxuj+++/XgQMHVFhY6Nbnbdq0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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def get_merge_df(result_path, data_path, parts, metric, methods, gene_type, gene_num):\n", " merge_df = pd.DataFrame()\n", " spot_size = 8\n", " for part in parts:\n", " for method in methods:\n", " if method == \"raw\":\n", " metric_file = f\"{result_path}/cut_{part}/spot_{spot_size}/raw_metrics_normalized.csv\"\n", " elif method == \"sp_SVC\":\n", " metric_file = f\"{result_path}/cut_{part}/spot_{spot_size}/metrics_normalized.csv\"\n", " \n", " # Load data\n", " df_metric = pd.read_csv(metric_file, index_col=0)\n", " df_metric.set_index('Gene', inplace=True)\n", " \n", " # Pass the correct parameters\n", " genes = get_genes(result_path, data_path, part, spot_size, method, \n", " gene_type=gene_type, gene_num=gene_num, test_genes=df_metric.index)\n", " df_metric = df_metric.loc[genes]\n", " \n", " # Create a new DataFrame to avoid variable-name conflicts\n", " temp_df = pd.DataFrame({\n", " 'Method': method,\n", " 'Value': df_metric[metric].values, # Use the correct variable name\n", " 'Spot_size': spot_size,\n", " 'Part': part,\n", " 'Metric': metric,\n", " })\n", " \n", " merge_df = pd.concat([merge_df, temp_df])\n", " \n", " merge_df.reset_index(drop=True, inplace=True)\n", " return merge_df\n", "\n", "\n", "def plot_comp_seg(merge_df, metric, ax):\n", " custom_palette = {\n", " \"raw\": '#80a9c8',\n", " \"sp_SVC\": '#e89786',\n", " }\n", " \n", " sns.boxplot(\n", " data=merge_df,\n", " x='Part',\n", " y='Value',\n", " hue='Method',\n", " palette=custom_palette,\n", " width=0.4,\n", " fliersize=2,\n", " showfliers=False,\n", " ax=ax\n", " )\n", " \n", " ax.set_ylabel(metric, fontsize=10)\n", " ax.xaxis.set_visible(False)\n", "\n", " if metric == \"PCC\":\n", " ax.set_ylim(0.2, 1.02)\n", " elif metric == \"SSIM\":\n", " ax.set_ylim(0.0, 1.02)\n", " elif metric == \"MSE\":\n", " ax.set_ylim(1e-5, 0.01)\n", " ax.set_yscale('log')\n", "\n", " if ax.get_legend() is not None:\n", " ax.legend_.remove()\n", " ax.set_aspect('auto')\n", "\n", "\n", "fig, axes = plt.subplots(1, 3, figsize=(9, 3))\n", "\n", "for j, metric in enumerate(metrics):\n", " # Add missing parameters\n", " merge_df = get_merge_df(result_path, data_path, parts, metric, methods=methods, \n", " gene_type=gene_type, gene_num=gene_num)\n", " \n", " ax = axes[j]\n", " plot_comp_seg(merge_df, metric, ax)\n", "\n", "plt.tight_layout()\n", "plt.savefig(f\"{output_dir}/{task}_{gene_type}_{gene_num}.pdf\", dpi=300)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "spot_sizes: 100%|██████████| 1/1 [00:00<00:00, 81.41it/s]\n", "spot_sizes: 100%|██████████| 1/1 [00:00<00:00, 85.57it/s]\n", "spot_sizes: 100%|██████████| 1/1 [00:00<00:00, 85.37it/s]\n", "parts: 100%|██████████| 3/3 [00:00<00:00, 64.29it/s]\n" ] } ], "source": [ "# compute mean\n", "merge_df = pd.DataFrame()\n", "spot_sizes = [8]\n", "for part in tqdm(parts, desc=\"parts\"):\n", " for spot_size in tqdm(spot_sizes, desc=\"spot_sizes\"): \n", " merge_df = pd.DataFrame() \n", " for method in methods:\n", " if method == \"raw\":\n", " metric_file = f\"{result_path}/cut_{part}/spot_{spot_size}/raw_metrics_normalized.csv\"\n", " elif method == \"sp_SVC\":\n", " metric_file = f\"{result_path}/cut_{part}/spot_{spot_size}/metrics_normalized.csv\"\n", " df = pd.read_csv(metric_file, index_col=0)\n", " df.set_index('Gene', inplace=True)\n", " genes = get_genes(result_path, data_path, part, spot_size, method, gene_type = gene_type, gene_num = gene_num, test_genes = df.index)\n", " df = df.loc[genes]\n", " \n", " df = df[metrics].mean(axis=0)\n", " \n", " merge_df = pd.concat([merge_df, df], axis=1)\n", " merge_df.reset_index(drop=True, inplace=True)\n", " merge_df.index = metrics\n", " merge_df.columns = methods\n", " merge_df.T.to_csv(f\"{save_dir}/{part}_{spot_size}_{gene_type}_{gene_num}.csv\")\n" ] } ], "metadata": { "kernelspec": { "display_name": "python3.10", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.14" } }, "nbformat": 4, "nbformat_minor": 2 }