{
 "cells": [
  {
   "cell_type": "raw",
   "id": "274fbd8b-2272-443c-b71d-4fcbc8946167",
   "metadata": {},
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import configparser\n",
    "import glob\n",
    "from tqdm import tqdm\n",
    "import h5py as h5\n",
    "import ast\n",
    "import os\n",
    "import corner\n",
    "import Pk_library as PKL\n",
    "import MAS_library as MASL\n",
    "from contextlib import contextmanager\n",
    "import sys\n",
    "import symbolic_pofk.linear\n",
    "\n",
    "@contextmanager\n",
    "def suppress_stdout():\n",
    "    with open(os.devnull, 'w') as devnull:\n",
    "        old_stdout = sys.stdout\n",
    "        sys.stdout = devnull\n",
    "        try:\n",
    "            yield\n",
    "        finally:\n",
    "            sys.stdout = old_stdout\n",
    "            \n",
    "from analysis import (\n",
    "    get_mcmc_steps, load_param_samples, get_truths,\n",
    "    crop_field, compute_ensemble_mean_field, \n",
    "    get_mock_field, get_spectra, get_both_fields,\n",
    "    get_likelihood_values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "3657066e-c3db-4675-b0c2-851fbdde7165",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "a1caa238-a287-45a6-8f0e-0b4f460811e5",
   "metadata": {},
   "source": [
    "# Plot the non-ic parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "d791f161-730a-464d-85cf-d76c708a3260",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TO SAMPLE ['sig_v']\n",
      "MY SAMPLER IS mvslice\n",
      "['sig_v']\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 758/758 [00:27<00:00, 27.64it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 758)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "# ini_name = '../conf/basic_ini.ini'\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/basic_run_cosmo_model'\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_pars_N64'\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_N64_all'\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_N64_not_ic_not_lam'\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/test_dir'\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/test_dir_mvslice'\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/test_dir_mvslice_modelpar'\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/test_dir_hmc_bulk'; iter_max = 3601\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/test_dir_hmc_modelpar'; iter_max = 1696\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/test_dir_transformedblackjax'; iter_max = 234\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/test_dir_blackjax'; iter_max = -1\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/test_dir_blackjax_model_par'; iter_max = 667\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/transformedblackjax_model_par'; iter_max = 1093\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_cosmo'; iter_max = -1\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v2'; iter_max = 1906\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v3'; iter_max = -1\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_bf_prior'; iter_max = -1\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/mvslice_model'; iter_max = 757\n",
    "ini_name = f'{dirname}/ini_file.ini'\n",
    "nframe = 700\n",
    "iter_min = -1\n",
    "# iter_max = -1\n",
    "\n",
    "names, steps, samples = load_param_samples(ini_name, dirname, nframe, iter_max, iter_min)\n",
    "print(samples.shape)\n",
    "truths = get_truths(ini_name, names)\n",
    "# print(samples[-1,:])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75734348-a319-417c-8969-d06c270a021a",
   "metadata": {},
   "source": [
    "Trace plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "26ad2d1e-ec36-48d5-a7d4-56cd0944dcd4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 22392 characters]",
      "text/plain": [
       "<Figure size 1600x300 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ncol = 4\n",
    "nrow = int(np.ceil(len(names) / ncol))\n",
    "\n",
    "fig, axs = plt.subplots(nrow, ncol, figsize=(ncol*4, nrow*3))\n",
    "axs = np.atleast_2d(axs)\n",
    "# for i in range(ncol):\n",
    "    # axs[-1,i].set_xlabel('Step Number')\n",
    "axs = axs.flatten()\n",
    "for i in range(len(names)):\n",
    "    axs[i].plot(steps, samples[i,:])\n",
    "    axs[i].set_title(names[i])\n",
    "    axs[i].axhline(truths[i], color='k')\n",
    "    axs[i].set_xlabel('Step Number')\n",
    "for i in range(len(names), len(axs)):\n",
    "    axs[i].remove()\n",
    "fig.tight_layout()\n",
    "fig.savefig('../figs/trace.png')\n",
    "\n",
    "if 'sigma8' in names and 'omega_m' in names:\n",
    "    sigma8 = samples[names.index('sigma8')]\n",
    "    omega_m = samples[names.index('omega_m')]\n",
    "\n",
    "    config = configparser.ConfigParser()\n",
    "    config.read(ini_name)\n",
    "    omega_b = float(config['cosmology']['omega_b'])\n",
    "    h = float(config['cosmology']['h100'])\n",
    "    n_s = float(config['cosmology']['n_s'])\n",
    "    A_s = 1.e-9 * symbolic_pofk.linear.sigma8_to_As(\n",
    "            sigma8, omega_m, omega_b, h, n_s)\n",
    "    print('A_s range:', A_s.min(), A_s.max())\n",
    "    plt.figure()\n",
    "    plt.hist(A_s)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c2a6ffc-1d05-4fb9-9de1-de660a97f4a8",
   "metadata": {},
   "source": [
    "Corner plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3c1189f8-4d17-4c4f-a9e3-78f4558a6bd6",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:root:Too few points to create valid contours\n",
      "WARNING:root:Too few points to create valid contours\n",
      "WARNING:root:Too few points to create valid contours\n",
      "WARNING:root:Too few points to create valid contours\n",
      "WARNING:root:Too few points to create valid contours\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 4725452 characters]",
      "text/plain": [
       "<Figure size 3490x3490 with 256 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "burn_in = 0\n",
    "burn_in = 1000\n",
    "\n",
    "m = steps > burn_in\n",
    "\n",
    "# Full corner plot\n",
    "corner.corner(\n",
    "    samples[:,m].T,\n",
    "    labels=names,\n",
    "    truths=truths\n",
    ");\n",
    "fig = plt.gcf()\n",
    "fig.savefig('../figs/corner_full.png', bbox_inches='tight', facecolor='white')\n",
    "\n",
    "# Cosmology corner plot\n",
    "if 'sigma8' in names and 'omega_m' in names:\n",
    "    idx = np.array([names.index('sigma8'), names.index('omega_m')], dtype=int)\n",
    "    corner.corner(\n",
    "        samples[idx,m].T,\n",
    "        labels=[names[i] for i in idx],\n",
    "        truths=[truths[i] for i in idx]\n",
    "    );\n",
    "    fig = plt.gcf()\n",
    "    fig.savefig('../figs/corner_cosmo.png', bbox_inches='tight', facecolor='white')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74f8de99-1ba0-475e-9894-cabe111ce40a",
   "metadata": {},
   "source": [
    "# Mock data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9b3ca440-3650-4c4b-b70a-669a39e5b944",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DENS -0.9808840727490473 17.530269738764385 -1.6263032587282567e-18 0.8490318268169118\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 75348 characters]",
      "text/plain": [
       "<Figure size 1500x500 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/basic_run_testing'\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_ics_N64_lam'\n",
    "\n",
    "with h5.File(f'{dirname}/mock_data.h5', 'r') as f:\n",
    "    dens = f['scalars/BORG_final_density'][:]\n",
    "    print('DENS', dens.min(), dens.max(), dens.mean(), dens.std())\n",
    "\n",
    "N = dens.shape[0]\n",
    "fig, axs = plt.subplots(1, 3, figsize=(15,5))\n",
    "axs[0].pcolor(dens[N//2])\n",
    "axs[1].pcolor(dens[:,N//2,:])\n",
    "axs[2].pcolor(dens[:,:,N//2])\n",
    "for ax in axs:\n",
    "    ax.set_aspect('equal')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "befe7801-3505-4774-8b2c-1433fad286fe",
   "metadata": {},
   "source": [
    "# Analyse density fields"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "b8ddf89c-7298-44d5-819a-ac733d1b99b0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Computing ensemble mean field\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 104/104 [00:12<00:00,  8.02it/s]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 232996 characters]",
      "text/plain": [
       "<Figure size 800x700 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 136496 characters]",
      "text/plain": [
       "<Figure size 800x700 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/basic_run_ic'; iter_max = 1748; iter_min = 0\n",
    "ini_name = '../conf/basic_ini.ini'\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_run_ic_N64'; iter_max = -1; iter_min = 1000\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_run_ic'; iter_max = -1; iter_min = 1000\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_ics_N64_lam'; iter_max = -1; iter_min = 1000\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_N64_all'; iter_max = -1; iter_min = 1000\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v2'; iter_max = 1773; iter_min = 1000\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v3'; iter_max = 3509; iter_min = 1000\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_bf_prior'; iter_max = -1; iter_min = 1000\n",
    "ini_name = f'{dirname}/ini_file.ini'\n",
    "nframe = 100\n",
    "\n",
    "all_true_delta = [None] * 2\n",
    "all_mean_delta = [None] * 2\n",
    "all_std_delta = [None] * 2\n",
    "\n",
    "# Uncropped\n",
    "all_true_delta[0], _ = get_mock_field(ini_name, dirname, cut_field=False)\n",
    "all_mean_delta[0], all_std_delta[0] = compute_ensemble_mean_field(ini_name, dirname, nframe, iter_max, iter_min, cut_field=False)\n",
    "\n",
    "# Cropped\n",
    "all_true_delta[1], Lcrop = crop_field(ini_name, all_true_delta[0])\n",
    "all_mean_delta[1], _ = crop_field(ini_name, all_mean_delta[0])\n",
    "all_std_delta[1], _ = crop_field(ini_name, all_std_delta[0])\n",
    "\n",
    "for cut_field in [False, True]:\n",
    "    \n",
    "    i = int(cut_field)\n",
    "    true_delta = all_true_delta[i]\n",
    "    mean_delta = all_mean_delta[i]\n",
    "    std_delta = all_std_delta[i]\n",
    "\n",
    "    fig, axs = plt.subplots(3, 3, figsize=(8,7))\n",
    "\n",
    "    config = configparser.ConfigParser()\n",
    "    config.read(ini_name)\n",
    "    Rmax = float(config['mock']['R_max'])\n",
    "    corner0 = float(config['system']['corner0'])\n",
    "    L0 = float(config['system']['L0'])\n",
    "    N0 = int(config['system']['N0'])\n",
    "    x = np.linspace(corner0, corner0+L0, N0)\n",
    "    if cut_field:\n",
    "        m = np.abs(x) < Rmax\n",
    "        x = x[m]\n",
    "\n",
    "    for i, field in enumerate([np.log10(2+true_delta), np.log10(2+mean_delta), std_delta]):\n",
    "        if i == 0:\n",
    "            vmin = field.min()\n",
    "            vmax = field.max()\n",
    "        N = field.shape[0]\n",
    "        j = N//2\n",
    "        axs[i,0].pcolor(x, x, field[j], vmin=vmin, vmax=vmax)\n",
    "        axs[i,1].pcolor(x, x, field[:,j,:], vmin=vmin, vmax=vmax)\n",
    "        axs[i,2].pcolor(x, x, field[:,:,j], vmin=vmin, vmax=vmax)\n",
    "        for ax in axs[i,:]:\n",
    "            circle = plt.Circle((0, 0), Rmax, color='red', fill=False, linestyle='dotted', lw=1.5)\n",
    "            xlim = ax.get_xlim()\n",
    "            ylim = ax.get_ylim()\n",
    "            ax.add_patch(circle)\n",
    "            ax.set_xlim(xlim)\n",
    "            ax.set_ylim(ylim)\n",
    "\n",
    "        for ax in axs[i,:]:\n",
    "            ax.set_aspect('equal')\n",
    "\n",
    "    axs[0,1].set_title('Truth')\n",
    "    axs[1,1].set_title('Ensemble Mean')\n",
    "    axs[2,1].set_title('Ensemble Std')\n",
    "            \n",
    "    fig.tight_layout()\n",
    "    \n",
    "    savename = '../figs/ensemble_mean'\n",
    "    if cut_field:\n",
    "        savename += '_cropped'\n",
    "    savename += '.png'\n",
    "    fig.savefig(savename, bbox_inches='tight', facecolor='w')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "a4dc64ee-d4ec-46e9-8073-f01b6f631332",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BOXSIZE 198.41269841269843\n",
      "\n",
      "Computing power spectrum of the field...\n",
      "Time to complete loop = 0.00\n",
      "Time taken = 0.01 seconds\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 104/104 [00:14<00:00,  7.18it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BOXSIZE 198.41269841269843\n",
      "\n",
      "Computing power spectrum of the field...\n",
      "Time to complete loop = 0.00\n",
      "Time taken = 0.00 seconds\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 104/104 [00:07<00:00, 13.07it/s]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 101088 characters]",
      "text/plain": [
       "<Figure size 1500x400 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 115684 characters]",
      "text/plain": [
       "<Figure size 1500x400 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# ini_name = '../conf/basic_ini.ini'\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/basic_run_ic'; iter_max = 1748\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/basic_run_cosmo_model'; iter_max = 3780\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_run_ic'; iter_max = -1\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_run_ic_N64'; iter_max = -1\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_ics_N64_lam'; iter_max = -1\n",
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_N64_all'; iter_max = -1\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v2'; iter_max = 1773\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v3'; iter_max = 3509\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_bf_prior'; iter_max = -1\n",
    "\n",
    "ini_name = f'{dirname}/ini_file.ini'\n",
    "nframe = 100\n",
    "iter_min = 0\n",
    "# which_field = 'ics'\n",
    "# which_field = 'delta'\n",
    "cut_field = True\n",
    "# cut_field = False\n",
    "\n",
    "for which_field in ['ics', 'delta']:\n",
    "\n",
    "    k, Pk_true, all_pk, all_r = get_spectra(ini_name, dirname, nframe, iter_max, iter_min, which_field=which_field, cut_field=cut_field)\n",
    "    all_mcmc = get_mcmc_steps(dirname, nframe, iter_max, iter_min=iter_min)\n",
    "\n",
    "    # Normalize the index for coloring\n",
    "    norm = plt.Normalize(all_mcmc[0], all_mcmc[-1])\n",
    "    cmap = plt.cm.spring  # Choose a colormap\n",
    "\n",
    "    fig, axs = plt.subplots(1, 2, figsize=(15,4))\n",
    "\n",
    "    # Plot Pk and r\n",
    "    for i in range(all_pk.shape[0]):\n",
    "        axs[0].loglog(k, all_pk[i, :], color=cmap(norm(all_mcmc[i])))\n",
    "        axs[1].semilogx(k, all_r[i, :], color=cmap(norm(all_mcmc[i])))\n",
    "    axs[0].loglog(k, Pk_true, color='k')\n",
    "    for i in [-1, 0, 1]:\n",
    "        axs[1].axhline(i, color='k')\n",
    "\n",
    "    sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)\n",
    "    sm.set_array([])\n",
    "    for ax in axs:\n",
    "        cbar = plt.colorbar(sm, ax=ax)\n",
    "        cbar.set_label('Step')\n",
    "        ax.set_title(which_field)\n",
    "        ax.set_xlabel(r'$k$')\n",
    "    axs[0].set_ylabel(r'$P(k)$')\n",
    "    axs[1].set_ylabel(r'$r(k)$')\n",
    "    fig.tight_layout()\n",
    "    fig.savefig(f'../figs/spectra_{which_field}.png')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "f2b100b1-dd1c-4e2d-8351-7acc3dc208ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 34976 characters]",
      "text/plain": [
       "<Figure size 1000x400 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_run_ic_N64'; step = 9554\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_run_ic'; step = 1860\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_ics_N64_lam'; step = 9624\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_N64_all'; step = 8609\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v2'; step = 1773\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v3'; step = 3509\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_bf_prior'; step = 4591\n",
    "ini_name = f'{dirname}/ini_file.ini'\n",
    "cut_field = True\n",
    "cut_field = False\n",
    "\n",
    "fig, axs = plt.subplots(1, 2, figsize=(10,4))\n",
    "\n",
    "for cut_field in [False, True]:\n",
    "\n",
    "    d1, d2 = get_both_fields(ini_name, dirname, step, which_field='delta', cut_field=cut_field)\n",
    "    d1 = np.log10(2 + d1)\n",
    "    d2 = np.log10(2 + d2)\n",
    "    \n",
    "    hist_kwargs = dict(bins=30, density=True, histtype='step')\n",
    "    i = int(cut_field)\n",
    "    axs[i].hist(d1.flatten(), label='Mock', **hist_kwargs)\n",
    "    axs[i].hist(d2.flatten(), label='Sample %i'%step, **hist_kwargs)\n",
    "    axs[i].legend()\n",
    "    axs[i].set_xlabel(r'$\\log_{10} (2 + \\delta)$')\n",
    "    \n",
    "axs[0].set_title('Full Box')\n",
    "axs[1].set_title('Central Region')\n",
    "fig.tight_layout()\n",
    "fig.savefig('../figs/density_histogram.png', bbox_inches='tight', facecolor='white')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef5f5027-3f64-4325-9811-b325a2a810ac",
   "metadata": {},
   "source": [
    "# Plot likelihood as a function of step"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "2c2e71f4-5a28-4d25-8354-8d322d145bf3",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|          | 0/102 [00:00<?, ?it/s]/tmp/ipykernel_2378/3269883151.py:279: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)\n",
      "  all_logL[i] = f['scalars/hmc_Elh'][:]\n",
      "/tmp/ipykernel_2378/3269883151.py:280: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)\n",
      "  all_logprior[i] = f['scalars/hmc_Eprior'][:]\n",
      "100%|██████████| 102/102 [00:01<00:00, 67.49it/s]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 67160 characters]",
      "text/plain": [
       "<Figure size 800x300 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ini_name = '../conf/basic_ini.ini'\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/basic_run_ic'; iter_max = 1748\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_run_ic_N64'; iter_max = 2421\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_ics_N64_lam'; iter_max = -1\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_N64_all'; iter_max = -1\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v2'; iter_max = 1773\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic_v3'; iter_max = 3509\n",
    "nframe = 100\n",
    "iter_min = 0\n",
    "\n",
    "all_mcmc = get_mcmc_steps(dirname, nframe, iter_max, iter_min=iter_min)\n",
    "logL, logP = get_likelihood_values(dirname, nframe, iter_max, iter_min)\n",
    "logL -= logL[-1]\n",
    "logP -= logP[-1]\n",
    "\n",
    "burnin = 10\n",
    "\n",
    "fig, axs = plt.subplots(1, 2, figsize=(8,3))\n",
    "axs[0].plot(all_mcmc[burnin:], logL[burnin:], label='logL')\n",
    "axs[1].plot(all_mcmc[burnin:], logP[burnin:], label='logPrior')\n",
    "axs[0].set_ylabel('Log-Likelihood')\n",
    "axs[1].set_ylabel('Log-Prior')\n",
    "for ax in axs:\n",
    "    ax.set_xlabel('Step')\n",
    "fig.tight_layout()\n",
    "fig.savefig('../figs/likelihood_trace.png', bbox_inches='tight', facecolor='white')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "677d5df8-915a-4c12-86be-d95ef351d551",
   "metadata": {},
   "source": [
    "# Mock Data Plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "47646eb5-85d8-4658-8866-1fdbd06a24b1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Using CIC mass assignment scheme\n",
      "Time taken = 0.000 seconds\n",
      "\n",
      "(64, 64, 64)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PolyCollection at 0x7f7ae66b1150>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_run_ic'\n",
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/supranta_ics_N64_lam'\n",
    "use_true = True\n",
    "# use_true = False\n",
    "\n",
    "ini_name = f'{dirname}/ini_file.ini'\n",
    "config = configparser.ConfigParser()\n",
    "config.read(ini_name)\n",
    "nsamp = int(config['run']['nsamp'])\n",
    "rmax = float(config['mock']['R_max'])\n",
    "L = float(config['system']['L0'])\n",
    "N = int(config['system']['N0'])\n",
    "\n",
    "hist_kwargs = dict(bins=30, density=True, histtype='step')\n",
    "scatter_kwargs = dict(marker='.', ms=1, lw=0)\n",
    "\n",
    "fig, axs = plt.subplots(1, 4, figsize=(20,4))\n",
    "fig2, axs2 = plt.subplots(1, 3, figsize=(15,4))\n",
    "    \n",
    "all_x = []\n",
    "\n",
    "with h5.File(dirname + \"/tracer_data_mock.h5\",'r') as mcmc_file:\n",
    "    for i in range(nsamp):\n",
    "        if use_true:\n",
    "            x = mcmc_file[f'sample_{i}/coord_true'][:]\n",
    "        else:\n",
    "            x = mcmc_file[f'sample_{i}/coord_meas'][:]\n",
    "        all_x.append(x)\n",
    "        r = np.sqrt(np.sum(x**2, axis=0))\n",
    "        for j in range(3):\n",
    "            axs[j].hist(x[j], **hist_kwargs)\n",
    "        axs[-1].hist(r, label=f'Sample {i}', **hist_kwargs)\n",
    "    \n",
    "        axs2[0].plot(x[0], x[1], **scatter_kwargs)\n",
    "        axs2[1].plot(x[1], x[2], **scatter_kwargs)\n",
    "        axs2[2].plot(x[2], x[0], **scatter_kwargs)\n",
    "        \n",
    "for ax in axs2:\n",
    "    ax.set_aspect('equal')    \n",
    "    \n",
    "fig3, axs3 = plt.subplots(1, 4, figsize=(15,4))\n",
    "with h5.File(dirname + \"/tracer_data_mock.h5\",'r') as mcmc_file:\n",
    "    for i in range(nsamp):\n",
    "        xtrue = mcmc_file[f'sample_{i}/coord_true'][:]\n",
    "        xmeas = mcmc_file[f'sample_{i}/coord_meas'][:]\n",
    "        for j in range(3):\n",
    "            axs3[j].plot(xtrue, xmeas, **scatter_kwargs)\n",
    "        rtrue = np.sqrt(np.sum(xtrue**2, axis=0))\n",
    "        rmeas = np.sqrt(np.sum(xmeas**2, axis=0))\n",
    "        axs3[-1].plot(rtrue, rmeas, **scatter_kwargs)\n",
    "    \n",
    "# construct 3D counts field\n",
    "all_x = np.hstack(all_x).T.astype(np.float32)\n",
    "counts = np.zeros((N, N, N), dtype=np.float32)\n",
    "MASL.MA(all_x, counts, L, 'CIC', verbose=True)\n",
    "print(counts.shape)\n",
    "\n",
    "plt.figure()\n",
    "plt.pcolor(counts[N//2])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e9c05de2-ff51-4f9f-a734-3d0858584cc9",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad626be4-8965-4c4f-982a-52634b8a5c23",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "baeee2e4-fc8b-4894-94cd-70e392dd2622",
   "metadata": {},
   "source": [
    "# Debug Underflow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "646553c1-444f-4135-be76-e021e5672b2f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Computing power spectra of the fields...\n",
      "Time FFTS = 0.00\n",
      "Time loop = 0.01\n",
      "Time taken = 0.01 seconds\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x149efc0d4110>"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 154176 characters]",
      "text/plain": [
       "<Figure size 1500x800 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 50292 characters]",
      "text/plain": [
       "<Figure size 1500x400 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 16924 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic/'\n",
    "boxsize = 500\n",
    "MAS = \"CIC\"\n",
    "\n",
    "with h5.File(f'{dirname}/mcmc_95.h5', 'r') as f:\n",
    "    dens_mcmc = f['scalars/BORG_final_density'][:]\n",
    "    \n",
    "with h5.File(f'{dirname}/mock_data.h5', 'r') as f:\n",
    "    dens_true = f['scalars/BORG_final_density'][:]\n",
    "    \n",
    "# Crop\n",
    "# ini_name = f\"{dirname}/ini_file.ini\"\n",
    "# dens_mcmc, boxsize = crop_field(ini_name, dens_mcmc)\n",
    "# dens_true, boxsize = crop_field(ini_name, dens_true)\n",
    "    \n",
    "fig, axs = plt.subplots(2, 3, figsize=(15,8))\n",
    "\n",
    "for i, f in enumerate([dens_true, dens_mcmc]):\n",
    "    N = f.shape[0]\n",
    "    axs[i,0].pcolor(f[:,:,N//2])\n",
    "    axs[i,1].pcolor(f[:,N//2,:])\n",
    "    axs[i,2].pcolor(f[N//2,:,:])\n",
    "for ax in axs.flatten():\n",
    "    ax.set_aspect('equal')\n",
    "    \n",
    "axs[0,1].set_title('True')\n",
    "axs[1,1].set_title('MCMC')\n",
    "\n",
    "Pk = PKL.XPk([dens_true.astype(np.float32),dens_mcmc.astype(np.float32)], boxsize, axis=0, MAS=[MAS, MAS], threads=1)\n",
    "Pk0_1  = Pk.Pk[:,0,0]  #monopole of field 1\n",
    "Pk0_2  = Pk.Pk[:,0,1]  #monopole of field 2\n",
    "Pk0_X  = Pk.XPk[:,0,0] #monopole of 1-2 cross P(k)\n",
    "k      = Pk.k3D\n",
    "r = Pk0_X / np.sqrt(Pk0_1 * Pk0_2)\n",
    "\n",
    "fig, axs = plt.subplots(1, 2, figsize=(15,4))\n",
    "axs[0].loglog(k, Pk0_1, label='True')\n",
    "axs[0].loglog(k, Pk0_2, label='MCMC')\n",
    "axs[1].semilogx(k, r, label='TruexMCMC')\n",
    "for ax in axs:\n",
    "    ax.legend()\n",
    "for y in [0, 1]:\n",
    "    axs[1].axhline(y, color='k')\n",
    "    \n",
    "    \n",
    "fig, ax = plt.subplots(1, 1)\n",
    "bins = np.linspace(np.log10(2 + min(dens_true.min(), dens_mcmc.min())), np.log10(2 + max(dens_true.max(), dens_mcmc.max())), 30) \n",
    "ax.hist(np.log10(2 + dens_true.flatten()), bins=bins, density=True, histtype='step', label='true')\n",
    "ax.hist(np.log10(2 + dens_mcmc.flatten()), bins=bins, density=True, histtype='step', label='mcmc')\n",
    "ax.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "551bbb9c-e465-4ba2-81c3-2133c6927603",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 126972 characters]",
      "text/plain": [
       "<Figure size 1500x800 with 6 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 30320 characters]",
      "text/plain": [
       "<Figure size 1500x400 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 346152 characters]",
      "text/plain": [
       "<Figure size 1500x400 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic/'\n",
    "component = 0\n",
    "\n",
    "vel_true = np.load(f'{dirname}/mock_vel.npy')\n",
    "vel_mcmc = np.load(f'{dirname}/mcmc_vel.npy')\n",
    "    \n",
    "fig, axs = plt.subplots(2, 3, figsize=(15,8))\n",
    "\n",
    "for i, f in enumerate([vel_true, vel_mcmc]):\n",
    "    N = f.shape[0]\n",
    "    axs[i,0].pcolor(f[component,:,:,N//2])\n",
    "    axs[i,1].pcolor(f[component,:,N//2,:])\n",
    "    axs[i,2].pcolor(f[component,N//2,:,:])\n",
    "for ax in axs.flatten():\n",
    "    ax.set_aspect('equal')\n",
    "    \n",
    "axs[0,1].set_title('True')\n",
    "axs[1,1].set_title('MCMC')\n",
    "\n",
    "fig, axs = plt.subplots(1, 3, figsize=(15,4))\n",
    "bins = np.linspace(min(vel_true.min(), vel_mcmc.min()), max(vel_true.min(), vel_mcmc.max()), 30)\n",
    "for i in range(len(axs)):\n",
    "    axs[i].hist(vel_true[i].flatten(), bins=bins, density=True, histtype='step', label='True')\n",
    "    axs[i].hist(vel_mcmc[i].flatten(), bins=bins, density=True, histtype='step', label='MCMC')\n",
    "    axs[i].legend()\n",
    "    axs[i].set_yscale('log')\n",
    "    \n",
    "fig, axs = plt.subplots(1, 3, figsize=(15,4))\n",
    "for i in range(len(axs)):\n",
    "    axs[i].hexbin(vel_true[i].flatten(), vel_mcmc[i].flatten(), mincnt=1)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "e08442d8-f156-4a83-a0d8-f0a7c2035d25",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "192 [2.8885622 1.8333287]\n",
      "976 [3.123437  2.7141156]\n",
      "129 [1.9811783 1.97686  ]\n",
      "282 [483.06342     2.1391425]\n",
      "Worst: 3 282 483.06342\n",
      "(3, 1225) (3, 1225)\n",
      "0.15200306866613814\n",
      "(1225,)\n",
      "(1225,)\n",
      "(1225,)\n",
      "True position: [ 180.07121842 -249.22822852   96.67707877]\n",
      "Measured r: [ 197.73909905 -273.68152333  106.16265399]\n",
      "True vr: -269.32922\n",
      "Observed cz: 32934.527\n",
      "Largest true (abs) along each axis: [180.07121842 249.22822852 150.8314107 ]\n",
      "Largest measured (abs) along each axis: [197.73909905 273.68152333 161.08961474]\n",
      "(201,)\n",
      "[ -26.74362669  -38.61752179 -147.64106462]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 106716 characters]",
      "text/plain": [
       "<Figure size 1600x400 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 42376 characters]",
      "text/plain": [
       "<Figure size 1500x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 45036 characters]",
      "text/plain": [
       "<Figure size 1500x400 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dirname = '/data101/bartlett/fsigma8/borg_velocity/blackjax_model_ic/'\n",
    "component = 0\n",
    "\n",
    "lkl_true = np.load(f'{dirname}/mock_lkl_ind.npz')\n",
    "lkl_mcmc = np.load(f'{dirname}/mcmc_lkl_ind.npz')\n",
    "nsamp = len(lkl_true.files)\n",
    "\n",
    "samp_num = None\n",
    "iworst = None\n",
    "worst_diff = 0\n",
    "\n",
    "fig, axs = plt.subplots(1, nsamp, figsize=(4*nsamp, 4))\n",
    "\n",
    "for i in range(nsamp):\n",
    "    xtrue = lkl_true[f'arr_{i}']\n",
    "    xmcmc = lkl_mcmc[f'arr_{i}']\n",
    "    axs[i].plot(xtrue, xmcmc, '.')\n",
    "    xlim = axs[i].get_xlim()\n",
    "    ylim = axs[i].get_ylim()\n",
    "    xlim = (min(xlim[0], ylim[0]), max(xlim[1], ylim[1]))\n",
    "    axs[i].plot(xlim, xlim, color='k')\n",
    "    axs[i].set_xlim(xlim)\n",
    "    axs[i].set_ylim(xlim)\n",
    "    axs[i].set_xlabel('True log-likelihood')\n",
    "    axs[i].set_ylabel('MCMC log-likelihood')\n",
    "    axs[i].set_title(f'Sample {i}')\n",
    "    \n",
    "    # Get worst point\n",
    "    diff = np.abs(xtrue - xmcmc)\n",
    "    isort = np.argsort(-diff)\n",
    "    if diff[isort[0]] > worst_diff:\n",
    "        worst_diff = diff[isort[0]]\n",
    "        samp_num = i\n",
    "        iworst = isort[0]\n",
    "    print(isort[0], diff[isort[:2]])    \n",
    "fig.tight_layout()\n",
    "fig.savefig('../figs/debug_logL.png', facecolor='white', bbox_inches='tight')\n",
    "    \n",
    "print('Worst:', samp_num, iworst, worst_diff)\n",
    "\n",
    "# Find information on this tracer\n",
    "with h5.File(f'{dirname}/tracer_data_mock.h5', 'r') as f:\n",
    "    coord_true = np.array(f[f'sample_{samp_num}/coord_true'][:])\n",
    "    coord_meas = np.array(f[f'sample_{samp_num}/coord_meas'][:])\n",
    "    sig_mu = f[f'sample_{samp_num}/sig_mu'][()]\n",
    "    vr_true = np.array(f[f'sample_{samp_num}/vr_true'][:])\n",
    "    cz_obs = np.array(f[f'sample_{samp_num}/cz_obs'][:])\n",
    "    r_hMpc = np.sqrt(np.sum(coord_meas ** 2, axis=0))\n",
    "    print(coord_true.shape, coord_meas.shape)\n",
    "    print(sig_mu)\n",
    "    print(vr_true.shape)\n",
    "    print(cz_obs.shape)\n",
    "    print(r_hMpc.shape)\n",
    "    \n",
    "print('True position:', coord_true[:,iworst])\n",
    "print('Measured r:', coord_meas[:,iworst])\n",
    "print('True vr:', vr_true[iworst])\n",
    "print('Observed cz:', cz_obs[iworst])\n",
    "\n",
    "xmax = np.amax(np.abs(coord_true), axis=1)\n",
    "print('Largest true (abs) along each axis:', xmax)\n",
    "xmax = np.amax(np.abs(coord_meas), axis=1)\n",
    "print('Largest measured (abs) along each axis:', xmax)\n",
    "\n",
    "# Plot radial velocity for the worst tracer\n",
    "vr_true = np.load(f'{dirname}/mock_tracer_vr.npz')[f'arr_{samp_num}'][iworst,:]\n",
    "vr_mcmc = np.load(f'{dirname}/mcmc_tracer_vr.npz')[f'arr_{samp_num}'][iworst,:]\n",
    "fig, ax = plt.subplots(1, 1, figsize=(15,4))\n",
    "ax.plot(vr_true, label='true')\n",
    "ax.plot(vr_mcmc, label='mcmc')\n",
    "ax.legend()\n",
    "print(vr_true.shape)\n",
    "\n",
    "# Plot the MB positions for the worst tracer\n",
    "itracer = iworst\n",
    "itracer = 3\n",
    "print(coord_true[:,itracer])\n",
    "MB_pos = np.load(f'{dirname}/MB_pos.npz')[f'arr_{samp_num}'][:,itracer,:]\n",
    "fig, axs = plt.subplots(1, 3, figsize=(15,4))\n",
    "for i in range(3):\n",
    "    axs[i].plot(MB_pos[i], '.', label='MB')\n",
    "    axs[i].axhline(coord_true[i,itracer], color='k', label='TRUE')\n",
    "    axs[i].axhline(coord_meas[i,itracer], color='r', label='MEASURED')\n",
    "    axs[i].legend()\n",
    "    axs[i].set_xlabel('Index')\n",
    "    axs[i].set_ylabel('Value')\n",
    "axs[0].set_title(r'$x$')\n",
    "axs[1].set_title(r'$y$')\n",
    "axs[2].set_title(r'$z$')\n",
    "fig.tight_layout()\n",
    "# fig.savefig(f'../figs/MB_pos_{samp_num}_{itracer}.png', facecolor='white', bbox_inches='tight')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3ad8a7e8-cd9e-4eec-ac8a-fd4d7bb78a7d",
   "metadata": {},
   "source": [
    "Use here to create warnings to implement in the code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "id": "de6bc4a7-7920-4f11-8697-0d6e7d57557b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7.269984374515526 210.9616513655193 (345,)\n",
      "6.541561558252167 255.9753565156616 (1682,)\n",
      "4.3919989345102 262.8841977513585 (556,)\n",
      "5.479083286248933 353.9390295101536 (1225,)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.lines.Line2D at 0x149eff55c4d0>"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 33232 characters]",
      "text/plain": [
       "<Figure size 1000x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "R_lim = 500 / 2\n",
    "\n",
    "fig, ax = plt.subplots(1, 1, figsize=(10,4))\n",
    "bins = np.linspace(0, 400, 100)\n",
    "\n",
    "with h5.File(f'{dirname}/tracer_data_mock.h5', 'r') as f:\n",
    "    for i in range(4):\n",
    "        coord_true = np.array(f[f'sample_{i}/coord_true'][:])\n",
    "        coord_meas = np.array(f[f'sample_{i}/coord_meas'][:])\n",
    "        r_hMpc = np.sqrt(np.sum(coord_meas ** 2, axis=0))\n",
    "        ax.hist(r_hMpc, bins=bins, density=True, histtype='step', label=f'sample_{i}')\n",
    "        m = r_hMpc > R_lim\n",
    "        print(i, m.sum())\n",
    "ax.legend()\n",
    "ax.axvline(R_lim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a3a81e62-f846-4e83-a6da-f8d8f53cf8dc",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "borg_new",
   "language": "python",
   "name": "borg_new"
  },
  "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.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
