{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install obonet -q\n!pip install pyvis -q","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-05-20T20:26:08.094203Z","iopub.execute_input":"2023-05-20T20:26:08.095221Z","iopub.status.idle":"2023-05-20T20:26:39.382600Z","shell.execute_reply.started":"2023-05-20T20:26:08.095175Z","shell.execute_reply":"2023-05-20T20:26:39.381044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport json\nfrom PIL import Image\nfrom typing import Dict\nfrom collections import Counter\n\nimport random\nimport cv2\nimport obonet\nimport networkx\nimport pandas as pd\nimport numpy as np\nimport plotly.express as px\nimport plotly.graph_objects as go\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as mpatch\nfrom Bio import SeqIO\nfrom pyvis.network import Network","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:26:39.385476Z","iopub.execute_input":"2023-05-20T20:26:39.385990Z","iopub.status.idle":"2023-05-20T20:26:41.221959Z","shell.execute_reply.started":"2023-05-20T20:26:39.385944Z","shell.execute_reply":"2023-05-20T20:26:41.220881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    train_go_obo_path: str = \"/kaggle/input/cafa-5-protein-function-prediction/Train/go-basic.obo\"\n    train_seq_fasta_path: str = \"/kaggle/input/cafa-5-protein-function-prediction/Train/train_sequences.fasta\"\n    train_terms_path: str = \"/kaggle/input/cafa-5-protein-function-prediction/Train/train_terms.tsv\"\n    train_taxonomy_path: str = \"/kaggle/input/cafa-5-protein-function-prediction/Train/train_taxonomy.tsv\"\n    train_ia_path: str = \"/kaggle/input/cafa-5-protein-function-prediction/IA.txt\"","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:26:41.223341Z","iopub.execute_input":"2023-05-20T20:26:41.224288Z","iopub.status.idle":"2023-05-20T20:26:41.230656Z","shell.execute_reply.started":"2023-05-20T20:26:41.224249Z","shell.execute_reply":"2023-05-20T20:26:41.229350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class color:\n   PURPLE = '\\033[95m'\n   CYAN = '\\033[96m'\n   DARKCYAN = '\\033[36m'\n   BLUE = '\\033[94m'\n   GREEN = '\\033[92m'\n   YELLOW = '\\033[93m'\n   RED = '\\033[91m'\n   BOLD = '\\033[1m'\n   UNDERLINE = '\\033[4m'\n   END = '\\033[0m'","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:26:41.233462Z","iopub.execute_input":"2023-05-20T20:26:41.234745Z","iopub.status.idle":"2023-05-20T20:26:41.245373Z","shell.execute_reply.started":"2023-05-20T20:26:41.234701Z","shell.execute_reply":"2023-05-20T20:26:41.244058Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_dag(graph, term, radius=1):\n    # create smaller subgraph\n    # radius - include all neighbors of distance<=radius from n (increse it to add further parent's branches).\n    ng_graph = networkx.ego_graph(graph, term, radius=radius)\n\n    for n in ng_graph.nodes(data=True):\n        # concatenate label of the node with its attribute\n        n[1][\"label\"] = n[0] + \" \" +n[1][\"name\"]\n\n    nt = Network(directed=True, notebook=True, cdn_resources=\"in_line\")\n    nt.from_nx(ng_graph)\n    return nt.show(\"network.html\")","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:26:41.247362Z","iopub.execute_input":"2023-05-20T20:26:41.247805Z","iopub.status.idle":"2023-05-20T20:26:41.259125Z","shell.execute_reply.started":"2023-05-20T20:26:41.247770Z","shell.execute_reply":"2023-05-20T20:26:41.257779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"subontology_roots = {'BPO':'GO:0008150',\n                     'CCO':'GO:0005575',\n                     'MFO':'GO:0003674'}","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:26:41.262716Z","iopub.execute_input":"2023-05-20T20:26:41.263243Z","iopub.status.idle":"2023-05-20T20:26:41.271625Z","shell.execute_reply.started":"2023-05-20T20:26:41.263190Z","shell.execute_reply":"2023-05-20T20:26:41.270324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ngraph = obonet.read_obo(CFG.train_go_obo_path)","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:26:41.273637Z","iopub.execute_input":"2023-05-20T20:26:41.274120Z","iopub.status.idle":"2023-05-20T20:27:01.392105Z","shell.execute_reply.started":"2023-05-20T20:26:41.274081Z","shell.execute_reply":"2023-05-20T20:27:01.390730Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Number of edges: {graph.number_of_edges()}\")","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:01.393658Z","iopub.execute_input":"2023-05-20T20:27:01.394095Z","iopub.status.idle":"2023-05-20T20:27:01.562521Z","shell.execute_reply.started":"2023-05-20T20:27:01.394050Z","shell.execute_reply":"2023-05-20T20:27:01.561179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Number of nodes: {len(graph)}\")","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:01.564068Z","iopub.execute_input":"2023-05-20T20:27:01.564881Z","iopub.status.idle":"2023-05-20T20:27:01.571658Z","shell.execute_reply.started":"2023-05-20T20:27:01.564824Z","shell.execute_reply":"2023-05-20T20:27:01.570305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"term = \"GO:0034655\"","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:01.577758Z","iopub.execute_input":"2023-05-20T20:27:01.578587Z","iopub.status.idle":"2023-05-20T20:27:01.588830Z","shell.execute_reply.started":"2023-05-20T20:27:01.578526Z","shell.execute_reply":"2023-05-20T20:27:01.587547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graph.nodes[term]","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:01.590329Z","iopub.execute_input":"2023-05-20T20:27:01.590792Z","iopub.status.idle":"2023-05-20T20:27:01.604231Z","shell.execute_reply.started":"2023-05-20T20:27:01.590752Z","shell.execute_reply":"2023-05-20T20:27:01.603220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_dag(graph, term, radius=1)","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:01.605341Z","iopub.execute_input":"2023-05-20T20:27:01.605720Z","iopub.status.idle":"2023-05-20T20:27:01.901688Z","shell.execute_reply.started":"2023-05-20T20:27:01.605689Z","shell.execute_reply":"2023-05-20T20:27:01.900168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_dag(graph, term, radius=1000)","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:01.903694Z","iopub.execute_input":"2023-05-20T20:27:01.904290Z","iopub.status.idle":"2023-05-20T20:27:02.191954Z","shell.execute_reply.started":"2023-05-20T20:27:01.904236Z","shell.execute_reply":"2023-05-20T20:27:02.190631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"term = \"GO:0044270\"","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:02.193848Z","iopub.execute_input":"2023-05-20T20:27:02.194397Z","iopub.status.idle":"2023-05-20T20:27:02.200708Z","shell.execute_reply.started":"2023-05-20T20:27:02.194351Z","shell.execute_reply":"2023-05-20T20:27:02.199348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"graph.nodes[term]","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:02.202241Z","iopub.execute_input":"2023-05-20T20:27:02.203558Z","iopub.status.idle":"2023-05-20T20:27:02.216014Z","shell.execute_reply.started":"2023-05-20T20:27:02.203499Z","shell.execute_reply":"2023-05-20T20:27:02.214285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_dag(graph, term, radius=1)","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:02.217765Z","iopub.execute_input":"2023-05-20T20:27:02.218300Z","iopub.status.idle":"2023-05-20T20:27:02.511362Z","shell.execute_reply.started":"2023-05-20T20:27:02.218251Z","shell.execute_reply":"2023-05-20T20:27:02.510190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_dag(graph, term, radius=1000)","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:02.513003Z","iopub.execute_input":"2023-05-20T20:27:02.513500Z","iopub.status.idle":"2023-05-20T20:27:02.801836Z","shell.execute_reply.started":"2023-05-20T20:27:02.513452Z","shell.execute_reply":"2023-05-20T20:27:02.800625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Sequence example:\\n\\n\", next(iter(SeqIO.parse(CFG.train_seq_fasta_path, \"fasta\"))))","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:02.803472Z","iopub.execute_input":"2023-05-20T20:27:02.804011Z","iopub.status.idle":"2023-05-20T20:27:02.842381Z","shell.execute_reply.started":"2023-05-20T20:27:02.803961Z","shell.execute_reply":"2023-05-20T20:27:02.841104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sequences = SeqIO.parse(CFG.train_seq_fasta_path, \"fasta\")\nnum_sequences = sum(1 for seq in sequences)\n\nprint(\"Number of sequences:\", num_sequences)","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:02.844191Z","iopub.execute_input":"2023-05-20T20:27:02.845248Z","iopub.status.idle":"2023-05-20T20:27:05.456575Z","shell.execute_reply.started":"2023-05-20T20:27:02.845176Z","shell.execute_reply":"2023-05-20T20:27:05.455197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sequences = SeqIO.parse(CFG.train_seq_fasta_path, \"fasta\")\navg_length = sum(len(seq) for seq in sequences)/num_sequences\navg_length","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:05.458505Z","iopub.execute_input":"2023-05-20T20:27:05.459085Z","iopub.status.idle":"2023-05-20T20:27:07.703958Z","shell.execute_reply.started":"2023-05-20T20:27:05.459036Z","shell.execute_reply":"2023-05-20T20:27:07.702757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sequences = SeqIO.parse(CFG.train_seq_fasta_path, \"fasta\")\nlengths = [len(seq) for seq in sequences]\nmedian = np.sort(lengths)\nmedian[int(num_sequences/2)]","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:07.705654Z","iopub.execute_input":"2023-05-20T20:27:07.706102Z","iopub.status.idle":"2023-05-20T20:27:09.956333Z","shell.execute_reply.started":"2023-05-20T20:27:07.706066Z","shell.execute_reply":"2023-05-20T20:27:09.955080Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sequences = SeqIO.parse(CFG.train_seq_fasta_path, \"fasta\")\n\n# get the length of each sequence\nlengths = [len(seq) for seq in sequences]\n\nfig = px.histogram(x=lengths, nbins=1000, color_discrete_sequence=['goldenrod'],histfunc = \"min\")\nfig.update_layout(\n    title={\n        'text': \"Distribution of protein sequence lengths\",\n        'y':0.95,\n        'x':1.0,\n        'xanchor': 'center',\n        'yanchor': 'top'\n    },\n    xaxis_title=\"Sequence length\", yaxis_title=\"Count\"\n)\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:09.957995Z","iopub.execute_input":"2023-05-20T20:27:09.958447Z","iopub.status.idle":"2023-05-20T20:27:14.406648Z","shell.execute_reply.started":"2023-05-20T20:27:09.958412Z","shell.execute_reply":"2023-05-20T20:27:14.405377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.percentile(lengths, 90)","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:14.408489Z","iopub.execute_input":"2023-05-20T20:27:14.409303Z","iopub.status.idle":"2023-05-20T20:27:14.450190Z","shell.execute_reply.started":"2023-05-20T20:27:14.409245Z","shell.execute_reply":"2023-05-20T20:27:14.449177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"taxon_df = pd.read_csv(CFG.train_taxonomy_path,'\\t')\ntaxon_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:14.451509Z","iopub.execute_input":"2023-05-20T20:27:14.452797Z","iopub.status.idle":"2023-05-20T20:27:14.646489Z","shell.execute_reply.started":"2023-05-20T20:27:14.452757Z","shell.execute_reply":"2023-05-20T20:27:14.645089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"terms_df = pd.read_csv(CFG.train_terms_path,'\\t')\nterms_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:14.648229Z","iopub.execute_input":"2023-05-20T20:27:14.648939Z","iopub.status.idle":"2023-05-20T20:27:18.700116Z","shell.execute_reply.started":"2023-05-20T20:27:14.648874Z","shell.execute_reply":"2023-05-20T20:27:18.698832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_GO_terms = len(pd.unique(terms_df['term']))\nnum_protein_terms = len(pd.unique(terms_df['EntryID']))\nprint(f\"Number of Unique Proteins: {num_protein_terms}\")\nprint(f\"Number of Unique GO terms: {num_GO_terms}\")","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:18.702141Z","iopub.execute_input":"2023-05-20T20:27:18.702683Z","iopub.status.idle":"2023-05-20T20:27:19.793290Z","shell.execute_reply.started":"2023-05-20T20:27:18.702636Z","shell.execute_reply":"2023-05-20T20:27:19.791700Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\n\ndef stat_calcs(df, colname):\n    if 'Ontology' in df.columns:\n        all_ont = pd.DataFrame()\n        for ont in df['Ontology'].unique():\n            df_ont = df[df['Ontology'] == ont]\n            out = df_ont.agg({\n                colname: ['min', lambda x: np.percentile(x, 10), lambda x: np.percentile(x, 25),\n                          'median', 'mean', lambda x: np.percentile(x, 75),\n                          lambda x: np.percentile(x, 90), 'max']\n            }).T.reset_index().rename(columns={'index': 'stat'})\n            out['Ontology'] = ont\n            all_ont = all_ont.append(out)\n        \n        out = all_ont.melt(id_vars=['stat'], value_vars=['Ontology'], var_name='Ontology') \\\n            .pivot(index='stat', columns='Ontology', values='value') \\\n            .apply(lambda x: round(x, 0) if pd.api.types.is_numeric_dtype(x) else x)\n        \n    else:\n        out = df.agg({\n            colname: ['min', lambda x: np.percentile(x, 10), lambda x: np.percentile(x, 25),\n                      'median', 'mean', lambda x: np.percentile(x, 75),\n                      lambda x: np.percentile(x, 90), 'max']\n        }).T.reset_index().rename(columns={'index': 'stat'})\n        out[colname] = out[colname].round(0)\n    \n    out['stat'] = pd.Categorical(out['stat'], categories=out['stat'])\n    return out","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:27:19.795369Z","iopub.execute_input":"2023-05-20T20:27:19.795776Z","iopub.status.idle":"2023-05-20T20:27:19.809542Z","shell.execute_reply.started":"2023-05-20T20:27:19.795742Z","shell.execute_reply":"2023-05-20T20:27:19.808106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Number of terms per protein\ndstats_prot = terms_df.groupby('EntryID').agg(term_per_prot=('term', 'nunique')).reset_index()\n\n# Number of proteins per GO term\ndstats_term = terms_df.groupby('term').agg(prot_per_term=('EntryID', 'nunique')).reset_index()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:28:10.092326Z","iopub.execute_input":"2023-05-20T20:28:10.093213Z","iopub.status.idle":"2023-05-20T20:28:15.398232Z","shell.execute_reply.started":"2023-05-20T20:28:10.093152Z","shell.execute_reply":"2023-05-20T20:28:15.396967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dstats_term.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:29:45.442974Z","iopub.execute_input":"2023-05-20T20:29:45.444229Z","iopub.status.idle":"2023-05-20T20:29:45.454738Z","shell.execute_reply.started":"2023-05-20T20:29:45.444182Z","shell.execute_reply":"2023-05-20T20:29:45.453709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dstats_prot.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:29:48.371192Z","iopub.execute_input":"2023-05-20T20:29:48.371778Z","iopub.status.idle":"2023-05-20T20:29:48.392763Z","shell.execute_reply.started":"2023-05-20T20:29:48.371728Z","shell.execute_reply":"2023-05-20T20:29:48.388033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"colname = 'term_per_prot'\nout = dstats_prot[colname].agg(['min',\n                                lambda x: x.quantile(0.1),\n                                lambda x: x.quantile(0.25),\n                                'median',\n                                'mean',\n                                lambda x: x.quantile(0.75),\n                                lambda x: x.quantile(0.90),\n                                'max']).reset_index()\n\nout.columns = ['stat', colname]\nout[colname] = out[colname].round(0)\nout = out.drop_duplicates(subset='stat')  # Remove duplicates in 'stat' column\nout['stat'] = pd.Categorical(out['stat'], categories=out['stat'], ordered=True)\n","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:59:51.489366Z","iopub.execute_input":"2023-05-20T20:59:51.489840Z","iopub.status.idle":"2023-05-20T20:59:51.545372Z","shell.execute_reply.started":"2023-05-20T20:59:51.489799Z","shell.execute_reply":"2023-05-20T20:59:51.543918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"out.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:59:53.681920Z","iopub.execute_input":"2023-05-20T20:59:53.683289Z","iopub.status.idle":"2023-05-20T20:59:53.701548Z","shell.execute_reply.started":"2023-05-20T20:59:53.683232Z","shell.execute_reply":"2023-05-20T20:59:53.698837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.histogram(x=dstats_prot['term_per_prot'], nbins=200, color_discrete_sequence=['red'])\nfig.update_layout(\n    title={\n        'text': \"Distribution of GO term per protein\",\n        #'y':0.95,\n        #'x':0.5,\n        #'xanchor': 'center',\n        #'yanchor': 'top'\n    },\n    xaxis_title=\"Number of terms per protein\", yaxis_title=\"Count\"\n)\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T21:08:38.474710Z","iopub.execute_input":"2023-05-20T21:08:38.475312Z","iopub.status.idle":"2023-05-20T21:08:38.600275Z","shell.execute_reply.started":"2023-05-20T21:08:38.475274Z","shell.execute_reply":"2023-05-20T21:08:38.598572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.histogram(x=dstats_term['prot_per_term'], nbins=5, color_discrete_sequence=['green'])\nfig.update_layout(\n    title={\n        'text': \"Distribution of protein per GO term\",\n        #'y':0.95,\n        #'x':0.5,\n        #'xanchor': 'center',\n        #'yanchor': 'top'\n    },\n    xaxis_title=\"Number of proteins per GO term\", yaxis_title=\"Count\"\n)\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T21:10:27.743240Z","iopub.execute_input":"2023-05-20T21:10:27.743985Z","iopub.status.idle":"2023-05-20T21:10:27.839198Z","shell.execute_reply.started":"2023-05-20T21:10:27.743923Z","shell.execute_reply":"2023-05-20T21:10:27.837604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"colname = 'prot_per_term'\nout2 = dstats_term[colname].agg(['min',\n                                lambda x: x.quantile(0.1),\n                                lambda x: x.quantile(0.25),\n                                'median',\n                                'mean',\n                                lambda x: x.quantile(0.75),\n                                lambda x: x.quantile(0.90),\n                                'max']).reset_index()\n\nout2.columns = ['stat', colname]\nout2[colname] = out2[colname].round(0)\nout2 = out2.drop_duplicates(subset='stat')  # Remove duplicates in 'stat' column\nout2['stat'] = pd.Categorical(out2['stat'], categories=out2['stat'], ordered=True)\nout2.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-20T20:59:54.284249Z","iopub.execute_input":"2023-05-20T20:59:54.284714Z","iopub.status.idle":"2023-05-20T20:59:54.322418Z","shell.execute_reply.started":"2023-05-20T20:59:54.284675Z","shell.execute_reply":"2023-05-20T20:59:54.321341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}