{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([0.8645785 -0.09823784j, 0.85954376-0.10151559j,\n",
       "        0.85534282-0.10389085j, 0.85223139-0.10548823j,\n",
       "        0.85032448-0.10640486j, 0.84968251-0.10670324j,\n",
       "        0.85032448-0.10640486j, 0.85223139-0.10548823j,\n",
       "        0.85534282-0.10389085j, 0.85954376-0.10151559j,\n",
       "        0.8645785 -0.09823784j]),\n",
       " array([0.58060059-0.38299298j, 0.5812387 -0.39895514j,\n",
       "        0.58112332-0.41153593j, 0.58070618-0.42059005j,\n",
       "        0.58031978-0.42604352j, 0.58016811-0.42786419j,\n",
       "        0.58031978-0.42604352j, 0.58070618-0.42059005j,\n",
       "        0.58112332-0.41153593j, 0.5812387 -0.39895514j,\n",
       "        0.58060059-0.38299298j]))"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# matching the mixer LO input and RF output to 50 ohms using the S11/S22 parameters\n",
    "# calculated using Qucs\n",
    "\n",
    "import qucs.qucsdata as qd\n",
    "data = qd.QucsData('bfu520_mixer.dat').data\n",
    "\n",
    "\n",
    "import numpy as np\n",
    "# find the index closest to 915 MHz\n",
    "freqs = data['frequency']\n",
    "idx = np.abs(freqs - 915e+6).argmin()\n",
    "\n",
    "s11s = data['S[1,1]']\n",
    "s22s = data['S[2,2]']\n",
    "\n",
    "s11s[idx,:], s22s[idx,:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(407.8826087843155-328.42259033407754j)\n",
      "834.9901269321724j\n",
      "(672.324866234869+0j)\n",
      "1.452380394909119e-07\n",
      "407.8826087843155 152.45788592627554 133.76894422554054\n",
      "5.712576904340215e-08 1.3003005258265486e-12 2.651849853388749e-08\n"
     ]
    }
   ],
   "source": [
    "s11 = np.mean(s11s, axis=1)\n",
    "s22 = np.mean(s22s, axis=1)\n",
    "#print(s11)\n",
    "\n",
    "import skrf.network as net\n",
    "\n",
    "# conjugate match the source\n",
    "z_s = net.s2z(np.array([[[s11[idx]]]]))[0, 0, 0]\n",
    "print(z_s)\n",
    "\n",
    "# so it looks like it'll need a large series inductor to compensate the imaginary part, followed by a standard \n",
    "# L match to 50 ohms\n",
    "l_series_s = -np.imag(z_s)/(2*np.pi*915e+6)\n",
    "\n",
    "# how hard would it be to remove the imaginary part using a shunt element?\n",
    "print(1j/np.imag(1/z_s))\n",
    "print(1/(1/z_s + 1/(1j/np.imag(1/z_s))))\n",
    "print(1/(np.imag(1/z_s)*2*np.pi*915e+6))\n",
    "\n",
    "# okay, 130 nH is pretty big so I'm going to go with the smaller series option\n",
    "\n",
    "r_s = np.real(z_s)\n",
    "q_s = np.sqrt((r_s - 50.)/50.)\n",
    "\n",
    "x_1_s = r_s/q_s\n",
    "x_2_s = q_s * 50.\n",
    "print(r_s, x_1_s, x_2_s)\n",
    "\n",
    "# let's go with a shunt capacitor followed by an inductor\n",
    "l_series_s2 = x_1_s/(2*np.pi*915e+6)\n",
    "c_shunt_s = 1/(2*np.pi*915e+6*x_2_s)\n",
    "print(l_series_s, c_shunt_s, l_series_s2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(407.8826087843155+0j) (39.61039510850523-120.77834197894384j) (39.61039510850523+31.679543947331695j)\n"
     ]
    }
   ],
   "source": [
    "# double check\n",
    "\n",
    "z_1 = z_s + 2j*np.pi*l_series_s*915e+6\n",
    "z_2 = 1/(1/z_1 + 1/(1/(2j*np.pi*915e+6*c_shunt_s)))\n",
    "z_3 = z_2 + 2j*np.pi*915e+6*l_series_s2\n",
    "\n",
    "print(z_1, z_2, z_3)\n",
    "\n",
    "# TODO maybe simulate it using scikit-rf network stuff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(89.46617486489218-105.51717177278026j)\n",
      "1.83536387636225e-08 3.154815993634542e-08\n",
      "(213.91402966297977+0j)\n",
      "213.91402966297977 811.0129787222926 52.7523073675072\n",
      "2.5782248342053757e-08 6.594586557283782e-12\n"
     ]
    }
   ],
   "source": [
    "# time to conjugate match the output\n",
    "#z_l = net.s2z(np.array([[[s22[idx]]]]))[0, 0, 0]\n",
    "z_l = net.s2z(np.array([[[0.544 - 0.345j]]]))[0, 0, 0]\n",
    "\n",
    "print(z_l)\n",
    "\n",
    "# series inductor or shunt inductor to cancel out the imaginary impedance? let's compare values like before\n",
    "z_series_l = -np.imag(z_l)/(2*np.pi*915e+6)\n",
    "z_shunt_l = 1/(np.imag(1/z_l))/(2*np.pi*915e+6)\n",
    "\n",
    "print(z_series_l, z_shunt_l)\n",
    "print(1/(1/z_l + 1/(2j*np.pi*915e+6*z_shunt_l)))\n",
    "\n",
    "# so either a pair of 15 nH series inductors or a 47 nH shunt; let's see how to the L section looks \n",
    "# before deciding here\n",
    "\n",
    "#r_l = np.real(z_l)\n",
    "r_l = np.real(1/(1/z_l + 1/(2j*np.pi*915e+6*z_shunt_l)))\n",
    "q_l = np.sqrt((r_l - 200.)/200.)\n",
    "\n",
    "x_1_l = r_l/q_l\n",
    "x_2_l = q_l * 200.\n",
    "print(r_l, x_1_l, x_2_l)\n",
    "\n",
    "# let's give the smaller impedance to the capacitor, so it'll be a shunt inductor\n",
    "l_shunt_l = x_1_l/(2*np.pi*915e+6)\n",
    "c_series_l = 1/(2*np.pi*915e+6*x_2_l)\n",
    "l_shunt_total_l = 1/(1/l_shunt_l + 1/z_shunt_l)\n",
    "\n",
    "print(l_shunt_total_l, 2*c_series_l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}