{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%config InlineBackend.figure_format = \"retina\"\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import sympy as sp\n",
    "from IPython.display import Math, display\n",
    "from matplotlib.axes import Axes\n",
    "from scipy import constants as const\n",
    "from scipy.integrate import quad\n",
    "from scipy.optimize import root_scalar\n",
    "from tqdm import tqdm\n",
    "\n",
    "import fewfermions.analysis.units as si\n",
    "from fewfermions.simulate.traps.twod.trap import PancakeTrap\n",
    "from fewfermions.style import FIGS_PATH, setup\n",
    "\n",
    "colors, colors_alpha = setup()\n",
    "pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reproducing the spilling behaviour for the Li6 experiment:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "initial_power = 291.5 * si.uW\n",
    "\n",
    "#parameters for lithium setup\n",
    "wvl = 1064 * si.nm\n",
    "omega_l = 2 * np.pi * const.c / wvl\n",
    "omega_0 = 2 * np.pi * const.c / (671 * si.nm)\n",
    "gamma = 2 * np.pi * 5.8724 * const.mega\n",
    "\n",
    "trap: PancakeTrap = PancakeTrap(\n",
    "    power=0,  # Set pancake laser power to 0, no 2D trap\n",
    "    grad_z=15 * si.G / si.cm,\n",
    "    grad_r=0,\n",
    "    power_tweezer=initial_power,\n",
    "    waist_tweezer=1.838 * si.um,\n",
    "\n",
    "    wvl = 1064 * si.nm,\n",
    "    omega_0 = 2 * np.pi * const.c / (671 * si.nm),\n",
    "    a = (3 * sp.pi * const.c**2) / (2 * omega_0**3)* (gamma / (omega_0 - omega_l) + gamma / (omega_0 + omega_l)),\n",
    "    m = 6.0151228 * const.value(\"atomic mass constant\"),\n",
    "    mu_b = const.value(\"Bohr magneton\"),\n",
    ")\n",
    "axial_width = trap.get_tweezer_rayleigh()\n",
    "\n",
    "x, y, z = trap.x, trap.y, trap.z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\frac{\\omega_{t r}}{\\omega_{t ax}} \\approx 7.67$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "aspect_ratio = trap.get_omega_r_tweezer() / trap.get_omega_ax_tweezer()\n",
    "_aspect_ratio_latex = sp.latex(trap.omega_r_tweezer / trap.omega_ax_tweezer)\n",
    "display(Math(f\"{_aspect_ratio_latex} \\\\approx {trap.subs(aspect_ratio).evalf():.2f}\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  8%|▊         | 8/100 [00:42<07:59,  5.21s/it]"
     ]
    }
   ],
   "source": [
    "n_spill_steps = 100\n",
    "\n",
    "trap[trap.power_tweezer] = initial_power\n",
    "\n",
    "spill_power_factor = np.linspace(0.7, 0.52, num=n_spill_steps)\n",
    "powers = trap[trap.power_tweezer] * spill_power_factor\n",
    "t_spill = 25 * si.ms\n",
    "atom_number = np.zeros_like(powers)\n",
    "\n",
    "# Number of energy levels to compute\n",
    "# will change over time to avoid calculating too many levels\n",
    "n_levels = 30\n",
    "# Resolution of the potential when solving numerically\n",
    "n_pot_steps = 1000\n",
    "\n",
    "for i, power in enumerate(tqdm(powers)):\n",
    "    trap[trap.power_tweezer] = power\n",
    "    # Solve the hamiltonian numerically in axial direction\n",
    "    energies, states, potential, coords = trap.nstationary_solution(\n",
    "        trap.z, (-0.5 * axial_width, 1.8 * axial_width), n_pot_steps, k=n_levels\n",
    "    )\n",
    "\n",
    "    # Determine the potential and its derivatives\n",
    "    pot_ax = trap.subs(trap.get_potential())\n",
    "    pot_diff_ax = sp.diff(pot_ax, trap.z)\n",
    "    pot_diff2_ax = sp.diff(pot_diff_ax, trap.z)\n",
    "    pot_diff3_ax = sp.diff(pot_diff2_ax, trap.z)\n",
    "    pot_diff_ax_numpy = sp.lambdify(trap.z, pot_diff_ax.subs({x: 0, y: 0}))\n",
    "    pot_diff2_ax_numpy = sp.lambdify(trap.z, pot_diff2_ax.subs({x: 0, y: 0}))\n",
    "    pot_diff3_ax_numpy = sp.lambdify(trap.z, pot_diff3_ax.subs({x: 0, y: 0}))\n",
    "\n",
    "    barrier = root_scalar(\n",
    "        pot_diff_ax_numpy,\n",
    "        x0=1.5 * float(trap.subs(axial_width)),\n",
    "        fprime=pot_diff2_ax_numpy,\n",
    "        xtol=1e-28,\n",
    "        fprime2=pot_diff2_ax_numpy,\n",
    "    ).root\n",
    "    minimum = root_scalar(\n",
    "        pot_diff_ax_numpy,\n",
    "        x0=0,\n",
    "        fprime=pot_diff2_ax_numpy,\n",
    "        xtol=1e-28,\n",
    "        fprime2=pot_diff2_ax_numpy,\n",
    "    ).root\n",
    "    # States that are below the potential barrier\n",
    "    bound_states = energies < potential(barrier)\n",
    "\n",
    "    n_bound_states = np.sum(bound_states)\n",
    "    n_levles = n_bound_states + 3  # add 3 more levels to be safe\n",
    "\n",
    "    # Density of states is larger on the left than on the right\n",
    "    # Likely that the state in question is a true bound state\n",
    "    true_bound_states = np.logical_and(\n",
    "        bound_states,\n",
    "        np.sum(states[:, coords[z] < barrier] ** 2, axis=1)\n",
    "        > np.sum(states[:, coords[z] > barrier] ** 2, axis=1),\n",
    "    )\n",
    "\n",
    "    transmission_probability = np.full_like(energies, np.nan, dtype=float)\n",
    "    for j, energy in enumerate(energies):\n",
    "        if not true_bound_states[j]:\n",
    "            continue\n",
    "        intersect_end = root_scalar(\n",
    "            lambda x: potential(x) - energy,\n",
    "            bracket=(barrier, 3 * float(trap.subs(axial_width))),\n",
    "        ).root\n",
    "        intersect_start = root_scalar(\n",
    "            lambda x: potential(x) - energy,\n",
    "            bracket=(minimum, barrier),\n",
    "        ).root\n",
    "        barrier_interval = np.logical_and(\n",
    "            coords[z] > intersect_start, coords[z] < intersect_end\n",
    "        )\n",
    "        s = quad(\n",
    "            lambda x: np.sqrt(\n",
    "                2\n",
    "                * float(trap.subs(trap.m))\n",
    "                * np.clip(potential(x) - energy, a_min=0, a_max=None)\n",
    "            )\n",
    "            / const.hbar,\n",
    "            intersect_start,\n",
    "            intersect_end,\n",
    "        )\n",
    "        transmission_probability[j] = sp.exp(-2 * s[0])\n",
    "    tunneling_rate = (\n",
    "        transmission_probability * np.abs(energies - potential(minimum)) / const.h\n",
    "    )\n",
    "    atom_number[i] = 2 * np.sum(np.exp(-t_spill * tunneling_rate[true_bound_states]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PolyCollection at 0x294e7c32930>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 47776 characters]",
      "text/plain": [
       "<Figure size 375x375 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 373,
       "width": 375
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax: plt.Axes\n",
    "fig: plt.Figure\n",
    "fig, ax = plt.subplots(figsize=(2.5, 2.5))\n",
    "\n",
    "ax.set_xlabel(\"rel. tweezer power (a.u.)\")\n",
    "ax.set_ylabel(\"atom number\")\n",
    "ax.plot(spill_power_factor, atom_number, marker=\"None\")\n",
    "ax.fill_between(spill_power_factor, atom_number, fc=colors_alpha[\"red\"], alpha=0.5)\n",
    "#fig.savefig(FIGS_PATH / \"twodtrap\" / \"1D Stufenplot.pdf\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Now with absolute power:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 100/100 [04:45<00:00,  2.85s/it]\n"
     ]
    }
   ],
   "source": [
    "n_spill_steps = 100\n",
    "\n",
    "trap[trap.power_tweezer] = initial_power\n",
    "\n",
    "#spill_power_factor = np.linspace(0.7, 0.52, num=n_spill_steps)\n",
    "#powers = trap[trap.power_tweezer] * spill_power_factor\n",
    "powers = np.linspace(151.5,204,n_spill_steps)*si.uW\n",
    "t_spill = 25 * si.ms\n",
    "atom_number = np.zeros_like(powers)\n",
    "#array to store mean lifetime at specific power\n",
    "mean_lifetime = np.zeros_like(powers)\n",
    "\n",
    "# Number of energy levels to compute\n",
    "# will change over time to avoid calculating too many levels\n",
    "n_levels = 30\n",
    "# Resolution of the potential when solving numerically\n",
    "n_pot_steps = 1000\n",
    "\n",
    "for i, power in enumerate(tqdm(powers)):\n",
    "    trap[trap.power_tweezer] = power\n",
    "    # Solve the hamiltonian numerically in axial direction\n",
    "    energies, states, potential, coords = trap.nstationary_solution(\n",
    "        trap.z, (-0.5 * axial_width, 1.8 * axial_width), n_pot_steps, k=n_levels\n",
    "    )\n",
    "\n",
    "    # Determine the potential and its derivatives\n",
    "    pot_ax = trap.subs(trap.get_potential())\n",
    "    pot_diff_ax = sp.diff(pot_ax, trap.z)\n",
    "    pot_diff2_ax = sp.diff(pot_diff_ax, trap.z)\n",
    "    pot_diff3_ax = sp.diff(pot_diff2_ax, trap.z)\n",
    "    pot_diff_ax_numpy = sp.lambdify(trap.z, pot_diff_ax.subs({x: 0, y: 0}))\n",
    "    pot_diff2_ax_numpy = sp.lambdify(trap.z, pot_diff2_ax.subs({x: 0, y: 0}))\n",
    "    pot_diff3_ax_numpy = sp.lambdify(trap.z, pot_diff3_ax.subs({x: 0, y: 0}))\n",
    "\n",
    "    barrier = root_scalar(\n",
    "        pot_diff_ax_numpy,\n",
    "        x0=1.5 * float(trap.subs(axial_width)),\n",
    "        fprime=pot_diff2_ax_numpy,\n",
    "        xtol=1e-28,\n",
    "        fprime2=pot_diff2_ax_numpy,\n",
    "    ).root\n",
    "    minimum = root_scalar(\n",
    "        pot_diff_ax_numpy,\n",
    "        x0=0,\n",
    "        fprime=pot_diff2_ax_numpy,\n",
    "        xtol=1e-28,\n",
    "        fprime2=pot_diff2_ax_numpy,\n",
    "    ).root\n",
    "    # States that are below the potential barrier\n",
    "    bound_states = energies < potential(barrier)\n",
    "\n",
    "    n_bound_states = np.sum(bound_states)\n",
    "    n_levles = n_bound_states + 3  # add 3 more levels to be safe\n",
    "\n",
    "    # Density of states is larger on the left than on the right\n",
    "    # Likely that the state in question is a true bound state\n",
    "    true_bound_states = np.logical_and(\n",
    "        bound_states,\n",
    "        np.sum(states[:, coords[z] < barrier] ** 2, axis=1)\n",
    "        > np.sum(states[:, coords[z] > barrier] ** 2, axis=1),\n",
    "    )\n",
    "\n",
    "    transmission_probability = np.full_like(energies, np.nan, dtype=float)\n",
    "    for j, energy in enumerate(energies):\n",
    "        if not true_bound_states[j]:\n",
    "            continue\n",
    "        intersect_end = root_scalar(\n",
    "            lambda x: potential(x) - energy,\n",
    "            bracket=(barrier, 3 * float(trap.subs(axial_width))),\n",
    "        ).root\n",
    "        intersect_start = root_scalar(\n",
    "            lambda x: potential(x) - energy,\n",
    "            bracket=(minimum, barrier),\n",
    "        ).root\n",
    "        barrier_interval = np.logical_and(\n",
    "            coords[z] > intersect_start, coords[z] < intersect_end\n",
    "        )\n",
    "        s = quad(\n",
    "            lambda x: np.sqrt(\n",
    "                2\n",
    "                * float(trap.subs(trap.m))\n",
    "                * np.clip(potential(x) - energy, a_min=0, a_max=None)\n",
    "            )\n",
    "            / const.hbar,\n",
    "            intersect_start,\n",
    "            intersect_end,\n",
    "        )\n",
    "        transmission_probability[j] = sp.exp(-2 * s[0])\n",
    "    tunneling_rate = (\n",
    "        transmission_probability * np.abs(energies - potential(minimum)) / const.h\n",
    "    )\n",
    "    atom_number[i] = 2 * np.sum(np.exp(-t_spill * tunneling_rate[true_bound_states]))\n",
    "    mean_lifetime[i] = np.mean(1/tunneling_rate[~np.isnan(tunneling_rate)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PolyCollection at 0x1a2092ddcd0>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 53124 characters]",
      "text/plain": [
       "<Figure size 375x375 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 373,
       "width": 373
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax: plt.Axes\n",
    "fig: plt.Figure\n",
    "fig, ax = plt.subplots(figsize=(2.5, 2.5))\n",
    "\n",
    "ax.set_xlabel(\"absolute tweezer power (uW)\")\n",
    "ax.set_ylabel(\"atom number\")\n",
    "ax.plot(powers*1e6, atom_number, marker=\".\")\n",
    "ax.fill_between(powers*1e6, atom_number, fc=colors_alpha[\"red\"], alpha=0.5)\n",
    "#fig.savefig(FIGS_PATH / \"twodtrap\" / \"1D Stufenplot.pdf\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([5.27898241e-01, 7.55190291e-01, 1.08764880e+00, 7.88754368e-01,\n",
       "       1.14789644e+00, 1.74176623e+00, 2.50321259e+00, 3.70671199e+00,\n",
       "       5.52288736e+00, 8.27219254e+00, 1.24512166e+01, 1.88301231e+01,\n",
       "       2.86073590e+01, 4.36544601e+01, 6.69044499e+01, 1.02969864e+02,\n",
       "       1.59136113e+02, 2.46919886e+02, 3.84645515e+02, 6.01510043e+02,\n",
       "       9.44268355e+02, 1.48774340e+03, 2.35267259e+03, 3.73384346e+03,\n",
       "       3.96455358e+03, 6.33627267e+03, 1.01615545e+04, 1.63512456e+04,\n",
       "       2.63988219e+04, 4.27603106e+04, 6.94864566e+04, 1.13277517e+05,\n",
       "       1.85247942e+05, 3.03886818e+05, 5.00037299e+05, 8.25294399e+05,\n",
       "       1.36620483e+06, 2.26834009e+06, 3.77721281e+06, 4.73100003e+06,\n",
       "       7.92349099e+06, 1.33079289e+07, 2.24141334e+07, 3.78563466e+07,\n",
       "       6.41133944e+07, 1.08878113e+08, 1.85397077e+08, 3.16537180e+08,\n",
       "       5.41870498e+08, 9.30046964e+08, 1.60045252e+09, 2.76121019e+09,\n",
       "       4.77601152e+09, 8.28192336e+09, 1.43975283e+10, 2.50915069e+10,\n",
       "       4.38368169e+10, 7.67743844e+10, 1.34787786e+11, 1.89768264e+11,\n",
       "       3.34770886e+11, 5.91977469e+11, 1.04927325e+12, 1.86419204e+12,\n",
       "       3.31974079e+12, 5.92546164e+12, 1.06007808e+13, 1.90083522e+13,\n",
       "       3.41613858e+13, 6.15324855e+13, 1.11082363e+14, 2.00979274e+14,\n",
       "       3.64432329e+14, 6.62271481e+14, 1.20615447e+15, 2.20146519e+15,\n",
       "       4.02677289e+15, 6.15109072e+15, 1.12993617e+16, 2.08006036e+16,\n",
       "       3.83718741e+16, 7.09349106e+16, 1.31405023e+17, 2.43929266e+17,\n",
       "       4.53744114e+17, 8.45762635e+17, 1.57968938e+18, 2.95648726e+18,\n",
       "       5.54443007e+18, 1.04186138e+19, 1.96169154e+19, 3.17225541e+19,\n",
       "       5.99668949e+19, 1.13582127e+20, 2.15555617e+20, 4.09878891e+20,\n",
       "       7.80898586e+20, 1.49063961e+21, 2.85092485e+21, 5.46298684e+21])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_lifetime"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Different \"n_levels\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|          | 0/100 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 100/100 [04:28<00:00,  2.68s/it]\n"
     ]
    }
   ],
   "source": [
    "n_spill_steps = 100\n",
    "\n",
    "trap[trap.power_tweezer] = initial_power\n",
    "\n",
    "#spill_power_factor = np.linspace(0.7, 0.52, num=n_spill_steps)\n",
    "#powers = trap[trap.power_tweezer] * spill_power_factor\n",
    "powers = np.linspace(151.5,204,n_spill_steps)*si.uW\n",
    "t_spill = 25 * si.ms\n",
    "atom_number = np.zeros_like(powers)\n",
    "#array to store mean lifetime at specific power\n",
    "mean_lifetime = np.zeros_like(powers)\n",
    "\n",
    "# Number of energy levels to compute\n",
    "# will change over time to avoid calculating too many levels\n",
    "n_levels = 100\n",
    "# Resolution of the potential when solving numerically\n",
    "n_pot_steps = 1000\n",
    "\n",
    "for i, power in enumerate(tqdm(powers)):\n",
    "    trap[trap.power_tweezer] = power\n",
    "    # Solve the hamiltonian numerically in axial direction\n",
    "    energies, states, potential, coords = trap.nstationary_solution(\n",
    "        trap.z, (-0.5 * axial_width, 1.8 * axial_width), n_pot_steps, k=n_levels\n",
    "    )\n",
    "\n",
    "    # Determine the potential and its derivatives\n",
    "    pot_ax = trap.subs(trap.get_potential())\n",
    "    pot_diff_ax = sp.diff(pot_ax, trap.z)\n",
    "    pot_diff2_ax = sp.diff(pot_diff_ax, trap.z)\n",
    "    pot_diff3_ax = sp.diff(pot_diff2_ax, trap.z)\n",
    "    pot_diff_ax_numpy = sp.lambdify(trap.z, pot_diff_ax.subs({x: 0, y: 0}))\n",
    "    pot_diff2_ax_numpy = sp.lambdify(trap.z, pot_diff2_ax.subs({x: 0, y: 0}))\n",
    "    pot_diff3_ax_numpy = sp.lambdify(trap.z, pot_diff3_ax.subs({x: 0, y: 0}))\n",
    "\n",
    "    barrier = root_scalar(\n",
    "        pot_diff_ax_numpy,\n",
    "        x0=1.5 * float(trap.subs(axial_width)),\n",
    "        fprime=pot_diff2_ax_numpy,\n",
    "        xtol=1e-28,\n",
    "        fprime2=pot_diff2_ax_numpy,\n",
    "    ).root\n",
    "    minimum = root_scalar(\n",
    "        pot_diff_ax_numpy,\n",
    "        x0=0,\n",
    "        fprime=pot_diff2_ax_numpy,\n",
    "        xtol=1e-28,\n",
    "        fprime2=pot_diff2_ax_numpy,\n",
    "    ).root\n",
    "    # States that are below the potential barrier\n",
    "    bound_states = energies < potential(barrier)\n",
    "\n",
    "    n_bound_states = np.sum(bound_states)\n",
    "    n_levles = n_bound_states + 3  # add 3 more levels to be safe\n",
    "\n",
    "    # Density of states is larger on the left than on the right\n",
    "    # Likely that the state in question is a true bound state\n",
    "    true_bound_states = np.logical_and(\n",
    "        bound_states,\n",
    "        np.sum(states[:, coords[z] < barrier] ** 2, axis=1)\n",
    "        > np.sum(states[:, coords[z] > barrier] ** 2, axis=1),\n",
    "    )\n",
    "\n",
    "    transmission_probability = np.full_like(energies, np.nan, dtype=float)\n",
    "    for j, energy in enumerate(energies):\n",
    "        if not true_bound_states[j]:\n",
    "            continue\n",
    "        intersect_end = root_scalar(\n",
    "            lambda x: potential(x) - energy,\n",
    "            bracket=(barrier, 3 * float(trap.subs(axial_width))),\n",
    "        ).root\n",
    "        intersect_start = root_scalar(\n",
    "            lambda x: potential(x) - energy,\n",
    "            bracket=(minimum, barrier),\n",
    "        ).root\n",
    "        barrier_interval = np.logical_and(\n",
    "            coords[z] > intersect_start, coords[z] < intersect_end\n",
    "        )\n",
    "        s = quad(\n",
    "            lambda x: np.sqrt(\n",
    "                2\n",
    "                * float(trap.subs(trap.m))\n",
    "                * np.clip(potential(x) - energy, a_min=0, a_max=None)\n",
    "            )\n",
    "            / const.hbar,\n",
    "            intersect_start,\n",
    "            intersect_end,\n",
    "        )\n",
    "        transmission_probability[j] = sp.exp(-2 * s[0])\n",
    "    tunneling_rate = (\n",
    "        transmission_probability * np.abs(energies - potential(minimum)) / const.h\n",
    "    )\n",
    "    atom_number[i] = 2 * np.sum(np.exp(-t_spill * tunneling_rate[true_bound_states]))\n",
    "    mean_lifetime[i] = np.mean(1/tunneling_rate[~np.isnan(tunneling_rate)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PolyCollection at 0x1a20a6ce7e0>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 53124 characters]",
      "text/plain": [
       "<Figure size 375x375 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 373,
       "width": 373
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ax: plt.Axes\n",
    "fig: plt.Figure\n",
    "fig, ax = plt.subplots(figsize=(2.5, 2.5))\n",
    "\n",
    "ax.set_xlabel(\"absolute tweezer power (uW)\")\n",
    "ax.set_ylabel(\"atom number\")\n",
    "ax.plot(powers*1e6, atom_number, marker=\".\")\n",
    "ax.fill_between(powers*1e6, atom_number, fc=colors_alpha[\"red\"], alpha=0.5)\n",
    "#fig.savefig(FIGS_PATH / \"twodtrap\" / \"1D Stufenplot.pdf\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "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.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
