{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-16T04:01:22.524061Z",
     "start_time": "2019-09-16T04:01:22.036537Z"
    }
   },
   "outputs": [],
   "source": [
    "import batoid\n",
    "import numpy as np\n",
    "from ipywidgets import interact\n",
    "import ipywidgets as widgets\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-16T04:02:02.438580Z",
     "start_time": "2019-09-16T04:02:02.434571Z"
    }
   },
   "outputs": [],
   "source": [
    "def makeTelescope(L, F, dz):\n",
    "    \"\"\"\n",
    "    Parameters\n",
    "    ----------\n",
    "    L : float\n",
    "        focal length in meters\n",
    "    F : float\n",
    "        F-number\n",
    "    dz : float\n",
    "        Focal plane offset\n",
    "    \"\"\"\n",
    "    R = 2*L # radius of curvature\n",
    "    telescope = batoid.CompoundOptic(\n",
    "        items = [\n",
    "            batoid.Mirror(\n",
    "                batoid.Paraboloid(R),\n",
    "                name=\"Mirror\"\n",
    "            ),\n",
    "            batoid.Detector(\n",
    "                batoid.Plane(),\n",
    "                name=\"Detector\",\n",
    "                coordSys=batoid.CoordSys(origin=[0,0,L+dz])\n",
    "            )\n",
    "        ]\n",
    "    )\n",
    "    telescope.backDist = 1.1*L\n",
    "    telescope.pupilSize = L/F\n",
    "    telescope.sphereRadius = L\n",
    "    telescope.stopSurface = batoid.Interface(batoid.Plane())\n",
    "    return telescope"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-16T04:02:02.870467Z",
     "start_time": "2019-09-16T04:02:02.865829Z"
    }
   },
   "outputs": [],
   "source": [
    "def a4coef(L, F, dz, wavelength):\n",
    "    R = L\n",
    "    alpha = dz/R\n",
    "    term1 = alpha*R\n",
    "    term1 /= 4*np.sqrt(3)*(1-alpha)\n",
    "    term1 /= (2*F)**2\n",
    "    term2 = alpha*(1+alpha+alpha**2)*R\n",
    "    term2 /= 16*np.sqrt(3)*(1-alpha)**3\n",
    "    term2 /= (2*F)**4\n",
    "    return (term1+term2)/wavelength\n",
    "\n",
    "def a11coef(L, F, dz, wavelength):\n",
    "    R = L\n",
    "    alpha = dz/R\n",
    "    result = alpha*(1+alpha*alpha**2)*R\n",
    "    result /= 48*np.sqrt(5)*(1-alpha)**3\n",
    "    result /= (2*F)**4\n",
    "    return -result/wavelength"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-16T04:02:56.104414Z",
     "start_time": "2019-09-16T04:02:55.994900Z"
    }
   },
   "outputs": [],
   "source": [
    "@interact(\n",
    "    L = widgets.FloatSlider(min=1.0, max=20.0, step=0.1, value=10.0,\n",
    "                            description=\"L (m)\"),\n",
    "    F = widgets.FloatSlider(min=1.0, max=10.0, step=0.05, value=3.0,\n",
    "                            description=\"F/#\"),\n",
    "    dz = widgets.FloatSlider(min=-1000, max=1000, step=10, value=800.0,\n",
    "                             description=\"dz ($\\\\mu m$)\"),\n",
    "    theta_x = widgets.FloatSlider(min=-1.75, max=1.75, step=0.05, value=0.0,\n",
    "                                  description=\"$\\\\theta_x (deg)$\"),\n",
    "    theta_y = widgets.FloatSlider(min=-1.75, max=1.75, step=0.05, value=0.0,\n",
    "                                  description=\"$\\\\theta_y (deg)$\")\n",
    ")\n",
    "def zernike(L, F, dz, theta_x, theta_y):\n",
    "    telescope = makeTelescope(L, F, dz*1e-6)\n",
    "    wavelength = 750e-9\n",
    "    z = batoid.zernikeGQ(\n",
    "        telescope, np.deg2rad(theta_x), np.deg2rad(theta_y),\n",
    "        wavelength, jmax=22, rings=10\n",
    "    )\n",
    "    for i in range(1, len(z)//2+1):\n",
    "        print(\"{:6d}   {:6.3f}      {:6d}  {:6.3f}\".format(i, z[i], i+11, z[i+11]))\n",
    "\n",
    "    print(\"a4 analytic: {:6.3f}\".format(a4coef(L, F, dz*1e-6, wavelength)))\n",
    "    print(\"a11 analytic: {:6.3f}\".format(a11coef(L, F, dz*1e-6, wavelength)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.8-final"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
