{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "dd7a79da",
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.ticker as mtick\n",
    "\n",
    "import scipy\n",
    "from scipy.signal import savgol_filter\n",
    "from scipy.optimize import curve_fit\n",
    "\n",
    "from Analyzer import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0da7ff81",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 903920 characters]",
      "text/plain": [
       "<Figure size 1800x1200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "data = cv2.imread(\"ss.png\",cv2.IMREAD_GRAYSCALE)\n",
    "\n",
    "fig = plt.figure(figsize=(18,12))\n",
    "\n",
    "plt.imshow(data,origin='lower',cmap='gray')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d550c6fd",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x216d1fcd7c0>]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 1621532 characters]",
      "text/plain": [
       "<Figure size 1800x1200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 958840 characters]",
      "text/plain": [
       "<Figure size 1800x1000 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 345356 characters]",
      "text/plain": [
       "<Figure size 1800x1000 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "shape   = data.shape[0]\n",
    "R_max   = 300\n",
    "N_theta = 300\n",
    "theta   = np.linspace(0, 2*np.pi, N_theta) \n",
    "N_radii = 120\n",
    "radii   = R_max*1/1.05**np.arange(1, N_radii) ## we take a logarithmic range of radii\n",
    "\n",
    "N_p     = 36      # angular frequency (number of dark (bright) lines)\n",
    "\n",
    "# center of the target (determined manually)\n",
    "x_c     = 345\n",
    "y_c     = 335\n",
    "\n",
    "plt.figure(figsize=(18,12))\n",
    "plt.imshow(data, origin='lower')\n",
    "for r in radii:\n",
    "\n",
    "    freq = get_freq(r, N_p)\n",
    "    I,x,y = get_line(data,theta,r,x_c,y_c)\n",
    "    plt.plot(x,y)\n",
    "\n",
    "r      = radii[10]\n",
    "I,x,y  = get_line(data,theta,r,x_c,y_c)\n",
    "\n",
    "p0     = [(I.max()-I.min())/2, (I.max() -(I.max()-I.min())/2)/5, -(I.max()-I.min())/2 ]\n",
    "m,popt = fit_sinusoid(I,theta,p0)\n",
    "\n",
    "plt.figure(figsize=(18,10)) \n",
    "plt.imshow(data)\n",
    "ax = plt.gca() \n",
    "ax.set_aspect(1) \n",
    "plt.plot(x,y)\n",
    "\n",
    "\n",
    "plt.figure(figsize=(18,10))\n",
    "plt.plot(theta,I)\n",
    "xnew = np.linspace(0,theta.max(),1000)\n",
    "ynew = sinusoidal(xnew,*popt)\n",
    "plt.plot(xnew,ynew)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "c457fdba",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Karthik\\AppData\\Local\\Temp\\ipykernel_13568\\853626961.py:77: RuntimeWarning: invalid value encountered in arccos\n",
      "  phi = np.arccos(freq_all/freq_c)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x216e5ec6760>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 521804 characters]",
      "text/plain": [
       "<Figure size 6000x4200 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "lines = np.zeros((N_radii,2))\n",
    "n=0\n",
    "for r in radii:\n",
    "\n",
    "    freq = N_p/(2*np.pi*r)\n",
    "    I,x,y = get_line(data,theta,r,x_c,y_c)\n",
    "\n",
    "    if freq<0.45:\n",
    "        yhat = savgol_filter(I, 11, 2)\n",
    "    elif freq>=0.45:\n",
    "        yhat = savgol_filter(I, 15, 2) \n",
    "\n",
    "    maximums = scipy.signal.argrelextrema(yhat, np.greater,order=2)\n",
    "    minimums = scipy.signal.argrelextrema(yhat, np.less,order=2)\n",
    "\n",
    "\n",
    "    m = (I[maximums].mean() - I[minimums].mean())/(I[maximums].mean() + I[minimums].mean())\n",
    "\n",
    "    lines[n][0] = freq; lines[n][1] = m\n",
    "\n",
    "    n=n+1\n",
    "\n",
    "plt.clf()\n",
    "figure=plt.figure(figsize=(20,14),dpi=300)\n",
    "ax = figure.add_subplot(111)\n",
    "ax.set_xlabel('Cycles/pixel',fontsize=24)\n",
    "ax.set_ylabel('MTF',fontsize=24)\n",
    "# major_ticks = np.arange(0, 2,0.5)\n",
    "# minor_ticks = np.arange(0, 2, 0.1)\n",
    "# major_ticks_y = np.arange(0, 1.8,0.2)\n",
    "# minor_ticks_y = np.arange(0, 1.8, 0.05)\n",
    "# ax.set_xticks(major_ticks)\n",
    "# ax.set_xticks(minor_ticks, minor = True)\n",
    "# ax.set_yticks(major_ticks_y)\n",
    "# ax.set_yticks(minor_ticks_y, minor = True)\n",
    "ax.tick_params(axis = 'both', which = 'major', length=6, width=1,labelsize = 22)\n",
    "ax.tick_params(axis = 'both', which = 'minor', length=3, width=1,labelsize=22)\n",
    "\n",
    "\n",
    "freq_all = lines[:,0]\n",
    "M_all = lines[:,1]\n",
    "\n",
    "# remove last outlier point\n",
    "freq_all =freq_all[:-1]#/ 0.5\n",
    "M_all = M_all[:-1]\n",
    "#M_all =M_all/M_all.max()\n",
    "\n",
    "## fit MTF with a gaussian\n",
    "p0_g = [1,0,0.5]\n",
    "popt, pcov = curve_fit(Gaussian,freq_all[:100],M_all[:100],p0_g,maxfev=8000)\n",
    "xnew = np.linspace(0,2,1000)\n",
    "ynew = Gaussian(xnew,*popt)\n",
    "\n",
    "## perfect MTF (circular aperture, no aberrations):\n",
    "\n",
    "# D = \n",
    "# f = \n",
    "# f_stop = f/D\n",
    "\n",
    "NA = 0.6\n",
    "lam = 532*10**(-6)\n",
    "\n",
    "#in pixels\n",
    "# freq_c = 1/(lam * f_stop * 100)\n",
    "\n",
    "freq_c = (2*NA)/(lam * 100)\n",
    "\n",
    "#in arcsec\n",
    "#freq_c = D/(1.22*lam*206265)\n",
    "\n",
    "## plot results\n",
    "plt.plot(freq_all,M_all,label='Dark subtracted star modulation')\n",
    "plt.plot(xnew,ynew,'r',label='Gaussian fit')\n",
    "plt.axhline(y=0,linestyle='dashed',color='red')\n",
    "\n",
    "freq_all = np.arange(0.02, 2*freq_c, 0.01)\n",
    "phi = np.arccos(freq_all/freq_c)\n",
    "MTF_p = (2/np.pi)*(phi - (np.cos(phi))*np.sin(phi))\n",
    "plt.plot(freq_all,MTF_p,label='Theoretical MTF for circular aperture',color='darkcyan',linestyle='-.',linewidth=3)\n",
    "\n",
    "ax.legend(loc='best',fancybox=True, handlelength=4,fontsize=22)\n",
    "# ax.set_xlim(0,0.7)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
