{"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":70367,"databundleVersionId":9188054,"sourceType":"competition"}],"dockerImageVersionId":30746,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Ariel Data Challenge 2024: Quickstart ⭐️⭐️⭐️⭐️⭐️\n\nIn this quickstart notebook, we show how to make predictions for the Ariel Data Challenge 2024 using only the FGS1 data.\n\nOf course, we cross-validate our model before preparing a submission.\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport seaborn as sns\nimport scipy.stats\nfrom tqdm import tqdm\n\nfrom sklearn.model_selection import cross_val_predict\nfrom sklearn.linear_model import RidgeCV\nfrom sklearn.metrics import r2_score, mean_squared_error","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:20:38.497957Z","iopub.execute_input":"2024-08-09T11:20:38.498403Z","iopub.status.idle":"2024-08-09T11:20:39.860173Z","shell.execute_reply.started":"2024-08-09T11:20:38.498365Z","shell.execute_reply":"2024-08-09T11:20:39.858714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Reading the data\n\nWe start by reading the metadata:","metadata":{}},{"cell_type":"code","source":"train_adc_info = pd.read_csv('/kaggle/input/ariel-data-challenge-2024/train_adc_info.csv',\n                           index_col='planet_id')\ntrain_labels = pd.read_csv('/kaggle/input/ariel-data-challenge-2024/train_labels.csv',\n                           index_col='planet_id')\ntest_adc_info = pd.read_csv('/kaggle/input/ariel-data-challenge-2024/test_adc_info.csv',\n                           index_col='planet_id')\nsample_submission = pd.read_csv('/kaggle/input/ariel-data-challenge-2024/sample_submission.csv',\n                           index_col='planet_id')\n# wavelengths = pd.read_csv('/kaggle/input/ariel-data-challenge-2024/wavelengths.csv')\n# axis_info = pd.read_parquet('/kaggle/input/ariel-data-challenge-2024/axis_info.parquet')\n","metadata":{"execution":{"iopub.status.busy":"2024-08-09T11:20:39.862099Z","iopub.execute_input":"2024-08-09T11:20:39.862638Z","iopub.status.idle":"2024-08-09T11:20:39.982938Z","shell.execute_reply.started":"2024-08-09T11:20:39.862604Z","shell.execute_reply":"2024-08-09T11:20:39.981004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Some facts about the data:\n- We have 673 planets for training.\n- There are roughly 800 planets for testing (but the test data is hidden).\n- The competition is a multi-output regression task with 283 wavelengths to predict. The first one is from FGS1, the other 282 are from AIRS.","metadata":{}},{"cell_type":"code","source":"assert (train_adc_info.index == train_labels.index).all()\nassert (test_adc_info.index == sample_submission.index).all()\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:20:39.985205Z","iopub.execute_input":"2024-08-09T11:20:39.985753Z","iopub.status.idle":"2024-08-09T11:20:39.993698Z","shell.execute_reply.started":"2024-08-09T11:20:39.985708Z","shell.execute_reply":"2024-08-09T11:20:39.992085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## The regression target\n\n`train_labels` contains the training targets for the regression task. There is one row per planet, and the values are the sizes of the planets. You may ask two questions now:\n1. Question: What is the unit of these values? Answer: The value is the square of the radius of the planet divided by the radius of the star \\\\((\\frac{r}{R})^2\\\\). As planets always are much smaller than their host stars, the values are positive but much smaller than 1.\n2. Question: Why are there 283 values per row? Does the planet have 283 different sizes? Answer: We can measure the size of the planet by looking at it at different wavelengths. If the planet's atmosphere is intransparent for the specific wavelength, the planet looks slightly larger.\n","metadata":{}},{"cell_type":"code","source":"train_labels","metadata":{"execution":{"iopub.status.busy":"2024-08-09T11:20:39.998072Z","iopub.execute_input":"2024-08-09T11:20:39.998734Z","iopub.status.idle":"2024-08-09T11:20:40.04763Z","shell.execute_reply.started":"2024-08-09T11:20:39.998679Z","shell.execute_reply":"2024-08-09T11:20:40.045898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(6, 2))\nplt.title(\"Histogram of the planets' sizes (regression targets)\", fontsize=18)\nplt.hist(train_labels.values.ravel(), bins=20, density=True, color='olive')\nplt.xlabel(r\"Planet's size $(\\frac{r}{R})^2$\", fontsize=14)\nplt.ylabel('Density', fontsize=14)\nplt.xlim(0, 0.008)\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:46:19.009164Z","iopub.execute_input":"2024-08-09T11:46:19.009667Z","iopub.status.idle":"2024-08-09T11:46:19.353758Z","shell.execute_reply.started":"2024-08-09T11:46:19.009626Z","shell.execute_reply":"2024-08-09T11:46:19.352242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Reading and preprocessing the FGS1 data\n\nThe FGS1 measurements consist of one file per planet (673 files for 673 planets for training). For now, we ignore the calibration files.\n\nEach file contains 135,000 rows of images taken at 0.1 second time steps. Each row is a 32\\*32 image at a single wavelength.\n\nWe read a sample file:","metadata":{}},{"cell_type":"code","source":"planet_id = 14485303\nf_signal = pd.read_parquet(f'/kaggle/input/ariel-data-challenge-2024/train/{planet_id}/FGS1_signal.parquet')\nf_signal","metadata":{"execution":{"iopub.status.busy":"2024-08-09T11:20:40.480564Z","iopub.execute_input":"2024-08-09T11:20:40.481218Z","iopub.status.idle":"2024-08-09T11:20:42.659278Z","shell.execute_reply.started":"2024-08-09T11:20:40.481163Z","shell.execute_reply":"2024-08-09T11:20:42.65726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Every row of the file corresponds to an image of a star:","metadata":{}},{"cell_type":"code","source":"sns.heatmap(f_signal.iloc[1].values.reshape(32, 32))\nplt.gca().set_aspect('equal')\nplt.title('FGS1 image')\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:48:00.841257Z","iopub.execute_input":"2024-08-09T11:48:00.841707Z","iopub.status.idle":"2024-08-09T11:48:01.363669Z","shell.execute_reply.started":"2024-08-09T11:48:00.841669Z","shell.execute_reply":"2024-08-09T11:48:01.362445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"To see the so-called *light curve*, a time series, we first have to compute the difference between the even and the odd frames to get the net signal. The net signal is very noisy, and we smoothen it by computing a moving average. The plot of the smoothened signal clearly shows that the image gets darker while the planet passes in front of the star (between time steps 22000 and 45000).","metadata":{}},{"cell_type":"code","source":"mean_signal = f_signal.values.mean(axis=1)\nnet_signal = mean_signal[1::2] - mean_signal[0::2]\ncum_signal = net_signal.cumsum()\nwindow=800\nsmooth_signal = (cum_signal[window:] - cum_signal[:-window]) / window\n\n_, (ax1, ax2) = plt.subplots(2, 1, sharex=True)\nax1.plot(net_signal, label='raw net signal')\nax1.legend()\nax2.plot(smooth_signal, color='c', label='smoothened net signal')\nax2.legend()\nax2.set_xlabel('time')\nplt.suptitle('FGS1 light curve', y=0.96)\nplt.show()\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:47:00.257739Z","iopub.execute_input":"2024-08-09T11:47:00.25861Z","iopub.status.idle":"2024-08-09T11:47:01.570913Z","shell.execute_reply.started":"2024-08-09T11:47:00.258569Z","shell.execute_reply":"2024-08-09T11:47:01.569604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We now read the FGS1 data for all 673 training planets. We keep only three values for every planet: The mean signal before, during and after the planet passes in front of the star.","metadata":{}},{"cell_type":"code","source":"%%time\ndef f_read_and_preprocess(dataset, adc_info):\n    \"\"\"Read the FGS1 files for all planet_ids and extract the signal.\n    \n    Parameters\n    dataset: 'train' or 'test'\n    adc_info: metadata dataframe, either train_adc_info or test_adc_info\n    \n    Returns\n    dataframe with one row per planet_id\n    \n    \"\"\"\n    planet_ids = adc_info.index\n    phases = []\n    for i, planet_id in tqdm(list(enumerate(planet_ids))):\n        f_signal = pd.read_parquet(f'/kaggle/input/ariel-data-challenge-2024/{dataset}/{planet_id}/FGS1_signal.parquet')\n        mean_signal = f_signal.values.mean(axis=1) # mean over the 32*32 pixels\n        net_signal = mean_signal[1::2] - mean_signal[0::2]\n\n        gain = adc_info.FGS1_adc_gain.values[i]\n        step = 8000\n        phases.append([net_signal[i*step:(i+1)*step].mean() * gain for i in range(len(net_signal) // step + 1)])\n        \n    return pd.DataFrame(phases,\n                        columns=[f\"phase_{i}\" for i in range(len(net_signal) // step + 1)],\n                        index=planet_ids)\n    \ntrain = f_read_and_preprocess('train', train_adc_info)\n","metadata":{"execution":{"iopub.status.busy":"2024-08-09T11:20:44.379056Z","iopub.execute_input":"2024-08-09T11:20:44.379527Z","iopub.status.idle":"2024-08-09T11:39:57.080015Z","shell.execute_reply.started":"2024-08-09T11:20:44.379486Z","shell.execute_reply":"2024-08-09T11:39:57.076989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The following scatterplot shows a strong correlation between the dip in brightness when the planet is in front of the star and the planet's size.","metadata":{}},{"cell_type":"code","source":"plt.scatter(train.iloc[:, train.shape[1] * 3 // 10] - train.iloc[:, train.shape[1] // 2], train_labels.wl_1, color='g', s=15)\nplt.xlabel('signal reduction when planet is in front')\nplt.ylabel('target')\nplt.title('Correlation between signal reduction and target')\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:39:57.089369Z","iopub.execute_input":"2024-08-09T11:39:57.090101Z","iopub.status.idle":"2024-08-09T11:39:57.446327Z","shell.execute_reply.started":"2024-08-09T11:39:57.090063Z","shell.execute_reply":"2024-08-09T11:39:57.445076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model and cross-validation\n\nTo keep things simple, we predict the spectra with ridge regression.\n\nWe are interested in three cross-validation metrics:\n1. The R2 score is above 0.9, which confirms the correlation we've seen in the scatterplot.\n2. The root mean squared error will be the predicted uncertainty.\n3. The competition metric gives an indication of the leaderboard score. Unfortunately the competition metric depends on the value of `sigma_true`, which I don't know.","metadata":{}},{"cell_type":"code","source":"#####\nmodel = RidgeCV()\n\noof_pred = cross_val_predict(model, train, train_labels)\n\nprint(f\"# R2 score: {r2_score(train_labels, oof_pred):.3f}\")\nsigma_pred = mean_squared_error(train_labels, oof_pred, squared=False)\nprint(f\"# Root mean squared error: {sigma_pred:.6f}\")\n\ncol = 1\nplt.scatter(oof_pred[:,col], train_labels.iloc[:,col], s=15, c=train_adc_info.star)\nplt.gca().set_aspect('equal')\nplt.xlabel('y_pred')\nplt.ylabel('y_true')\nplt.title('Comparing y_true and y_pred')\nplt.show()\n\n# R2 score: 0.936\n# Root mean squared error: 0.000436 step=10000\n# R2 score: 0.949\n# Root mean squared error: 0.000390 step=9000","metadata":{"execution":{"iopub.status.busy":"2024-08-09T11:39:57.447661Z","iopub.execute_input":"2024-08-09T11:39:57.448034Z","iopub.status.idle":"2024-08-09T11:39:58.088996Z","shell.execute_reply.started":"2024-08-09T11:39:57.448001Z","shell.execute_reply":"2024-08-09T11:39:58.087834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = RidgeCV()\n\noof_pred = cross_val_predict(model, train, train_labels)\n\nprint(f\"# R2 score: {r2_score(train_labels, oof_pred):.3f}\")\nsigma_pred = mean_squared_error(train_labels, oof_pred, squared=False)\nprint(f\"# Root mean squared error: {sigma_pred:.6f}\")\n\ncol = 1\nplt.scatter(oof_pred[:,col], train_labels.iloc[:,col], s=15, c='lightgreen')\nplt.gca().set_aspect('equal')\nplt.xlabel('y_pred')\nplt.ylabel('y_true')\nplt.title('Comparing y_true and y_pred')\nplt.show()\n\n# R2 score: 0.936\n# Root mean squared error: 0.000436 step=10000\n# R2 score: 0.949\n# Root mean squared error: 0.000390 step=9000\n# R2 score: 0.952\n# Root mean squared error: 0.000378 step=8000","metadata":{"execution":{"iopub.status.busy":"2024-08-09T11:39:58.090573Z","iopub.execute_input":"2024-08-09T11:39:58.091023Z","iopub.status.idle":"2024-08-09T11:39:58.625165Z","shell.execute_reply.started":"2024-08-09T11:39:58.090976Z","shell.execute_reply":"2024-08-09T11:39:58.623982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The following hidden cell contains the function which evaluates the competition metric.","metadata":{}},{"cell_type":"code","source":"# Adapted from https://www.kaggle.com/code/metric/ariel-gaussian-log-likelihood\nclass ParticipantVisibleError(Exception):\n    pass\n\ndef competition_score(\n        solution: pd.DataFrame,\n        submission: pd.DataFrame,\n        naive_mean: float,\n        naive_sigma: float,\n        sigma_true: float,\n        row_id_column_name='planet_id',\n    ) -> float:\n    '''\n    This is a Gaussian Log Likelihood based metric. For a submission, which contains the predicted mean (x_hat) and variance (x_hat_std),\n    we calculate the Gaussian Log-likelihood (GLL) value to the provided ground truth (x). We treat each pair of x_hat,\n    x_hat_std as a 1D gaussian, meaning there will be 283 1D gaussian distributions, hence 283 values for each test spectrum,\n    the GLL value for one spectrum is the sum of all of them.\n\n    Inputs:\n        - solution: Ground Truth spectra (from test set)\n            - shape: (nsamples, n_wavelengths)\n        - submission: Predicted spectra and errors (from participants)\n            - shape: (nsamples, n_wavelengths*2)\n        naive_mean: (float) mean from the train set.\n        naive_sigma: (float) standard deviation from the train set.\n        sigma_true: (float) essentially sets the scale of the outputs.\n    '''\n\n    del solution[row_id_column_name]\n    del submission[row_id_column_name]\n\n    if submission.min().min() < 0:\n        raise ParticipantVisibleError('Negative values in the submission')\n    for col in submission.columns:\n        if not pd.api.types.is_numeric_dtype(submission[col]):\n            raise ParticipantVisibleError(f'Submission column {col} must be a number')\n\n    n_wavelengths = len(solution.columns)\n    if len(submission.columns) != n_wavelengths*2:\n        raise ParticipantVisibleError('Wrong number of columns in the submission')\n\n    y_pred = submission.iloc[:, :n_wavelengths].values\n    # Set a non-zero minimum sigma pred to prevent division by zero errors.\n    sigma_pred = np.clip(submission.iloc[:, n_wavelengths:].values, a_min=10**-15, a_max=None)\n    y_true = solution.values\n\n    GLL_pred = np.sum(scipy.stats.norm.logpdf(y_true, loc=y_pred, scale=sigma_pred))\n    GLL_true = np.sum(scipy.stats.norm.logpdf(y_true, loc=y_true, scale=sigma_true * np.ones_like(y_true)))\n    GLL_mean = np.sum(scipy.stats.norm.logpdf(y_true, loc=naive_mean * np.ones_like(y_true), scale=naive_sigma * np.ones_like(y_true)))\n\n    submit_score = (GLL_pred - GLL_mean)/(GLL_true - GLL_mean)\n    return float(np.clip(submit_score, 0.0, 1.0))","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:39:58.626594Z","iopub.execute_input":"2024-08-09T11:39:58.626975Z","iopub.status.idle":"2024-08-09T11:39:58.643603Z","shell.execute_reply.started":"2024-08-09T11:39:58.626944Z","shell.execute_reply":"2024-08-09T11:39:58.642286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_dataframe(pred_array, index, sigma_pred):\n    \"\"\"Create a submission dataframe from predictions and uncertainty\"\"\"\n    return pd.concat([pd.DataFrame(pred_array.clip(train_labels.values.min(), train_labels.values.max()), \n                                   index=index,\n                                   columns=train_labels.columns),\n                      pd.DataFrame(sigma_pred,\n                                   index=index,\n                                   columns=[f\"sigma_{i}\" for i in range(1, 284)])],\n                     axis=1)\n\noof_df = make_dataframe(oof_pred, train_adc_info.index, sigma_pred)\ndisplay(oof_df)\n\ngll_score = competition_score(train_labels.copy().reset_index(),\n                              oof_df.copy().reset_index(),\n                              naive_mean=train_labels.values.mean(),\n                              naive_sigma=train_labels.values.std(),\n                              sigma_true=0.00001)\nprint(f\"# Estimated competition score: {gll_score:.3f}\")\n","metadata":{"execution":{"iopub.status.busy":"2024-08-09T11:39:58.645374Z","iopub.execute_input":"2024-08-09T11:39:58.645875Z","iopub.status.idle":"2024-08-09T11:39:58.776029Z","shell.execute_reply.started":"2024-08-09T11:39:58.645831Z","shell.execute_reply":"2024-08-09T11:39:58.774799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission\n\nWhen I saw the cross-validation score of this notebook, I was happy and submitted the notebook. The result was a huge disappointment — the leaderboard score was 0.000. As I couldn't find the bug myself, I published the notebook and called for help (\"[Find the bug and win!](https://www.kaggle.com/competitions/ariel-data-challenge-2024/discussion/523949)\").\n\nIn that discussion it was suggested to separate training and inference code into two notebooks. The separation resolved the issue indeed. Please continue reading in the two notebooks\n1. [ADC24 Intro training](https://www.kaggle.com/code/ambrosm/adc24-intro-training)\n2. [ADC24 Intro inference](https://www.kaggle.com/code/ambrosm/adc24-intro-inference)\n\n","metadata":{}},{"cell_type":"code","source":"# Refit the model to the full dataset\nmodel.fit(train, train_labels)\n\n# Predict\ntest = f_read_and_preprocess('test', test_adc_info)\ntest_pred = model.predict(test)\n\n# Package into submission file\nsub = make_dataframe(test_pred, test_adc_info.index, sigma_pred)\ndisplay(sub)\n#sub.to_csv('submission.csv')\n#!head submission.csv","metadata":{"execution":{"iopub.status.busy":"2024-08-09T11:39:58.777475Z","iopub.execute_input":"2024-08-09T11:39:58.777824Z","iopub.status.idle":"2024-08-09T11:40:00.568793Z","shell.execute_reply.started":"2024-08-09T11:39:58.777776Z","shell.execute_reply":"2024-08-09T11:40:00.567621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Outlook: The AIRS measurements\n\nAIRS is the other sensor of the satellite. Again, it produces one file per planet.\n\nEach file contains 11,250 rows of images captured at constant time steps. Each 32 x 356 image has been flattened into 11392 columns.","metadata":{}},{"cell_type":"code","source":"a_signal = pd.read_parquet(f'/kaggle/input/ariel-data-challenge-2024/train/{planet_id}/AIRS-CH0_signal.parquet')\na_signal","metadata":{"execution":{"iopub.status.busy":"2024-08-09T11:53:11.365602Z","iopub.execute_input":"2024-08-09T11:53:11.366394Z","iopub.status.idle":"2024-08-09T11:53:12.701067Z","shell.execute_reply.started":"2024-08-09T11:53:11.366353Z","shell.execute_reply":"2024-08-09T11:53:12.700016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a_signal = a_signal.values.reshape(11250, 32, 356)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:53:13.756058Z","iopub.execute_input":"2024-08-09T11:53:13.757163Z","iopub.status.idle":"2024-08-09T11:53:13.762142Z","shell.execute_reply.started":"2024-08-09T11:53:13.757123Z","shell.execute_reply":"2024-08-09T11:53:13.760912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10, 3))\nplt.title('AIRS-CH0 image')\nsns.heatmap(a_signal[1])\nplt.ylabel('spatial dimension')\nplt.xlabel('wavelength dimension')\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:53:14.83128Z","iopub.execute_input":"2024-08-09T11:53:14.833441Z","iopub.status.idle":"2024-08-09T11:53:16.275304Z","shell.execute_reply.started":"2024-08-09T11:53:14.833386Z","shell.execute_reply":"2024-08-09T11:53:16.274045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The data again is a time series, and we can see the star being obscured while the planet is passing in front of it.","metadata":{}},{"cell_type":"code","source":"mean_signal = a_signal.mean(axis=2).mean(axis=1)\nnet_signal = mean_signal[1::2] - mean_signal[0::2]\ncum_signal = net_signal.cumsum()\nwindow=80\nsmooth_signal = (cum_signal[window:] - cum_signal[:-window]) / window\n\n_, (ax1, ax2) = plt.subplots(2, 1, sharex=True)\nax1.plot(net_signal, label='raw signal')\nax1.legend()\nax2.plot(smooth_signal, color='c', label='smoothened signal')\nax2.legend()\nax2.set_xlabel('time')\nplt.suptitle('AIRS-CH0 light curve', y=0.96)\nplt.show()\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-08-09T11:53:23.995486Z","iopub.execute_input":"2024-08-09T11:53:23.997653Z","iopub.status.idle":"2024-08-09T11:53:25.944627Z","shell.execute_reply.started":"2024-08-09T11:53:23.997517Z","shell.execute_reply":"2024-08-09T11:53:25.941387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}