{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a6ba3eb0-8f27-4ebd-b407-3f25f449c6bf",
   "metadata": {},
   "source": [
    "# Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "bd9299aa-a531-468c-b04b-798b06315f41",
   "metadata": {},
   "outputs": [],
   "source": [
    "# pyright: reportUnknownArgumentType=false, reportCallIssue=false, reportAttributeAccessIssue=false, reportOptionalSubscript=false, reportArgumentType=false\n",
    "from rich.console import Console\n",
    "from rich.table import Table\n",
    "from rich.theme import Theme\n",
    "\n",
    "from finesse.model import Model\n",
    "from finesse.analysis.actions.axes import Noxaxis, Xaxis\n",
    "from finesse.solutions import SeriesSolution\n",
    "from finesse.analysis.actions import (\n",
    "    TemporaryParameters,\n",
    "    Change,\n",
    "    Maximize,\n",
    "    Minimize,\n",
    "    Series,\n",
    "    FrequencyResponse,\n",
    ")\n",
    "from finesse.components import Mirror, SignalGenerator\n",
    "from finesse.detectors import QuantumNoiseDetector\n",
    "\n",
    "from pathlib import Path\n",
    "from typing import NamedTuple\n",
    "import re\n",
    "\n",
    "from matplotlib.axes import Axes\n",
    "from matplotlib.pyplot import figure, show\n",
    "\n",
    "\n",
    "from numpy import linspace, geomspace, pi, angle, where, diff, mean, loadtxt, load\n",
    "from scipy.io.matlab import loadmat\n",
    "\n",
    "from science_signal import Signal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4c038d40-1d01-49cb-9182-a9a0e94d0d40",
   "metadata": {},
   "outputs": [],
   "source": [
    "from gettext import install\n",
    "from logging import getLogger"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5d4f2612-c5ea-4b21-a326-7074022966bc",
   "metadata": {},
   "outputs": [],
   "source": [
    "install(__name__)\n",
    "logger = getLogger(__name__)\n",
    "theme = Theme(\n",
    "    {\n",
    "        \"strong\": \"cyan underline\",\n",
    "        \"result\": \"red bold\",\n",
    "    }\n",
    ")\n",
    "console = Console(theme=theme)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb7d2340-c817-4309-9599-6d58070ff4ab",
   "metadata": {},
   "source": [
    "## Paramètres généraux"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "8fc23eea-145e-4641-93e9-6f8989edca96",
   "metadata": {},
   "outputs": [],
   "source": [
    "C_POWER = 25  # en Whatt\n",
    "C_DARK_FRINGE = 8e-3  # en Whatt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3052aa2b-350e-4eb3-b31c-a4204ab84dac",
   "metadata": {},
   "source": [
    "## Modèle simplifié de Virgo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d32480d0-8525-478a-9af5-b1a1c8b30f1d",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/demagny/codes/python/finesse/finesse-simulation-04/.venv/lib/python3.13/site-packages/pygraphviz/agraph.py:1403: RuntimeWarning: Warning: Illegal value sgd for attribute \"mode\" in graph  - ignored\n",
      "\n",
      "  warnings.warn(b\"\".join(errors).decode(self.encoding), RuntimeWarning)\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"1080pt\" height=\"577pt\" viewBox=\"72.00 72.00 1008.00 504.87\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(0.7 0.7) rotate(0) translate(102.32 717.5)\">\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"0,0 0,-615.17 1330.2,-615.17 1330.2,0 0,0\"/>\n",
       "<!-- laser -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>laser</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"33.8\" cy=\"-262.47\" rx=\"33.6\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"33.8\" y=\"-258.77\" font-family=\"Times,serif\" font-size=\"14.00\">laser</text>\n",
       "</g>\n",
       "<!-- eom1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>eom1</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"144.1\" cy=\"-262.47\" rx=\"36.29\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"144.1\" y=\"-258.77\" font-family=\"Times,serif\" font-size=\"14.00\">eom1</text>\n",
       "</g>\n",
       "<!-- laser&#45;&#45;eom1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>laser--eom1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M67.79,-262.47C80.32,-262.47 94.57,-262.47 107.34,-262.47\"/>\n",
       "</g>\n",
       "<!-- eom2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>eom2</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"255.3\" cy=\"-264.14\" rx=\"36.29\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"255.3\" y=\"-260.44\" font-family=\"Times,serif\" font-size=\"14.00\">eom2</text>\n",
       "</g>\n",
       "<!-- eom1&#45;&#45;eom2 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>eom1--eom2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M180.51,-263.02C192.8,-263.2 206.51,-263.41 218.81,-263.59\"/>\n",
       "</g>\n",
       "<!-- eom3 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>eom3</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"366.1\" cy=\"-275.92\" rx=\"36.29\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"366.1\" y=\"-272.22\" font-family=\"Times,serif\" font-size=\"14.00\">eom3</text>\n",
       "</g>\n",
       "<!-- eom2&#45;&#45;eom3 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>eom2--eom3</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M290.97,-267.93C303.62,-269.28 317.86,-270.79 330.5,-272.13\"/>\n",
       "</g>\n",
       "<!-- eom4 -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>eom4</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"478.16\" cy=\"-288.86\" rx=\"36.29\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"478.16\" y=\"-285.16\" font-family=\"Times,serif\" font-size=\"14.00\">eom4</text>\n",
       "</g>\n",
       "<!-- eom3&#45;&#45;eom4 -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>eom3--eom4</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M401.56,-280.01C414.64,-281.52 429.46,-283.23 442.55,-284.75\"/>\n",
       "</g>\n",
       "<!-- PR_AR -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>PR_AR</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"591.6\" cy=\"-305.98\" rx=\"41.69\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"591.6\" y=\"-302.28\" font-family=\"Times,serif\" font-size=\"14.00\">PR_AR</text>\n",
       "</g>\n",
       "<!-- eom4&#45;&#45;PR_AR -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>eom4--PR_AR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M513.12,-294.13C525.49,-296 539.48,-298.11 552.2,-300.03\"/>\n",
       "</g>\n",
       "<!-- PR -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>PR</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"708.18\" cy=\"-327.51\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"708.18\" y=\"-323.81\" font-family=\"Times,serif\" font-size=\"14.00\">PR</text>\n",
       "</g>\n",
       "<!-- PR&#45;&#45;PR_AR -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>PR--PR_AR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M682.02,-322.68C666.71,-319.85 647.11,-316.23 630.07,-313.08\"/>\n",
       "</g>\n",
       "<!-- BS -->\n",
       "<g id=\"node8\" class=\"node\">\n",
       "<title>BS</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"829.09\" cy=\"-356.31\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"829.09\" y=\"-352.61\" font-family=\"Times,serif\" font-size=\"14.00\">BS</text>\n",
       "</g>\n",
       "<!-- PR&#45;&#45;BS -->\n",
       "<g id=\"edge7\" class=\"edge\">\n",
       "<title>PR--BS</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M733.82,-333.62C754.34,-338.51 782.98,-345.33 803.49,-350.21\"/>\n",
       "</g>\n",
       "<!-- NI_AR -->\n",
       "<g id=\"node9\" class=\"node\">\n",
       "<title>NI_AR</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"939.4\" cy=\"-398.85\" rx=\"39.79\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"939.4\" y=\"-395.15\" font-family=\"Times,serif\" font-size=\"14.00\">NI_AR</text>\n",
       "</g>\n",
       "<!-- BS&#45;&#45;NI_AR -->\n",
       "<g id=\"edge8\" class=\"edge\">\n",
       "<title>BS--NI_AR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M852.49,-365.33C868.93,-371.67 891.08,-380.22 908.91,-387.09\"/>\n",
       "</g>\n",
       "<!-- WI_AR -->\n",
       "<g id=\"node10\" class=\"node\">\n",
       "<title>WI_AR</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"887.61\" cy=\"-279.6\" rx=\"40.89\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"887.61\" y=\"-275.9\" font-family=\"Times,serif\" font-size=\"14.00\">WI_AR</text>\n",
       "</g>\n",
       "<!-- BS&#45;&#45;WI_AR -->\n",
       "<g id=\"edge9\" class=\"edge\">\n",
       "<title>BS--WI_AR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M841.5,-340.05C851.16,-327.38 864.55,-309.84 874.4,-296.91\"/>\n",
       "</g>\n",
       "<!-- SR -->\n",
       "<g id=\"node11\" class=\"node\">\n",
       "<title>SR</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"780.46\" cy=\"-433.66\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"780.46\" y=\"-429.96\" font-family=\"Times,serif\" font-size=\"14.00\">SR</text>\n",
       "</g>\n",
       "<!-- BS&#45;&#45;SR -->\n",
       "<g id=\"edge10\" class=\"edge\">\n",
       "<title>BS--SR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M818.54,-373.1C810.38,-386.07 799.14,-403.95 790.99,-416.91\"/>\n",
       "</g>\n",
       "<!-- SR_AR -->\n",
       "<g id=\"node20\" class=\"node\">\n",
       "<title>SR_AR</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"738.62\" cy=\"-509.94\" rx=\"41.69\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"738.62\" y=\"-506.24\" font-family=\"Times,serif\" font-size=\"14.00\">SR_AR</text>\n",
       "</g>\n",
       "<!-- SR&#45;&#45;SR_AR -->\n",
       "<g id=\"edge19\" class=\"edge\">\n",
       "<title>SR--SR_AR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M771.17,-450.59C764.38,-462.97 755.2,-479.71 748.32,-492.26\"/>\n",
       "</g>\n",
       "<!-- NI -->\n",
       "<g id=\"node12\" class=\"node\">\n",
       "<title>NI</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"1038.5\" cy=\"-445.45\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"1038.5\" y=\"-441.75\" font-family=\"Times,serif\" font-size=\"14.00\">NI</text>\n",
       "</g>\n",
       "<!-- NI&#45;&#45;NI_AR -->\n",
       "<g id=\"edge11\" class=\"edge\">\n",
       "<title>NI--NI_AR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1016.02,-434.87C1001.51,-428.05 982.54,-419.13 967.11,-411.87\"/>\n",
       "</g>\n",
       "<!-- NE -->\n",
       "<g id=\"node13\" class=\"node\">\n",
       "<title>NE</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"1129.3\" cy=\"-493.93\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"1129.3\" y=\"-490.23\" font-family=\"Times,serif\" font-size=\"14.00\">NE</text>\n",
       "</g>\n",
       "<!-- NI&#45;&#45;NE -->\n",
       "<g id=\"edge12\" class=\"edge\">\n",
       "<title>NI--NE</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1060.02,-456.94C1074.49,-464.66 1093.49,-474.81 1107.94,-482.52\"/>\n",
       "</g>\n",
       "<!-- NE_AR -->\n",
       "<g id=\"node14\" class=\"node\">\n",
       "<title>NE_AR</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"1214.25\" cy=\"-543.94\" rx=\"42.79\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"1214.25\" y=\"-540.24\" font-family=\"Times,serif\" font-size=\"14.00\">NE_AR</text>\n",
       "</g>\n",
       "<!-- NE&#45;&#45;NE_AR -->\n",
       "<g id=\"edge13\" class=\"edge\">\n",
       "<title>NE--NE_AR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1149.86,-506.03C1161.75,-513.03 1176.78,-521.88 1189.34,-529.27\"/>\n",
       "</g>\n",
       "<!-- SNEB -->\n",
       "<g id=\"node15\" class=\"node\">\n",
       "<title>SNEB</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"1291.85\" cy=\"-597.17\" rx=\"38.19\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"1291.85\" y=\"-593.47\" font-family=\"Times,serif\" font-size=\"14.00\">SNEB</text>\n",
       "</g>\n",
       "<!-- NE_AR&#45;&#45;SNEB -->\n",
       "<g id=\"edge14\" class=\"edge\">\n",
       "<title>NE_AR--SNEB</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1236.7,-559.34C1247.17,-566.52 1259.59,-575.04 1269.99,-582.18\"/>\n",
       "</g>\n",
       "<!-- WI -->\n",
       "<g id=\"node16\" class=\"node\">\n",
       "<title>WI</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"945.57\" cy=\"-208.64\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"945.57\" y=\"-204.94\" font-family=\"Times,serif\" font-size=\"14.00\">WI</text>\n",
       "</g>\n",
       "<!-- WI&#45;&#45;WI_AR -->\n",
       "<g id=\"edge15\" class=\"edge\">\n",
       "<title>WI--WI_AR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M932.42,-224.74C923.2,-236.03 910.9,-251.09 901.52,-262.57\"/>\n",
       "</g>\n",
       "<!-- WE -->\n",
       "<g id=\"node17\" class=\"node\">\n",
       "<title>WE</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"1002.69\" cy=\"-141.01\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"1002.69\" y=\"-137.31\" font-family=\"Times,serif\" font-size=\"14.00\">WE</text>\n",
       "</g>\n",
       "<!-- WI&#45;&#45;WE -->\n",
       "<g id=\"edge16\" class=\"edge\">\n",
       "<title>WI--WE</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M958.82,-192.95C967.91,-182.18 979.95,-167.93 989.12,-157.08\"/>\n",
       "</g>\n",
       "<!-- WE_AR -->\n",
       "<g id=\"node18\" class=\"node\">\n",
       "<title>WE_AR</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"1061.91\" cy=\"-76.39\" rx=\"44.39\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"1061.91\" y=\"-72.69\" font-family=\"Times,serif\" font-size=\"14.00\">WE_AR</text>\n",
       "</g>\n",
       "<!-- WE&#45;&#45;WE_AR -->\n",
       "<g id=\"edge17\" class=\"edge\">\n",
       "<title>WE--WE_AR</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1017.03,-125.37C1025.79,-115.8 1037.01,-103.56 1046.04,-93.71\"/>\n",
       "</g>\n",
       "<!-- SWEB -->\n",
       "<g id=\"node19\" class=\"node\">\n",
       "<title>SWEB</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"1131.21\" cy=\"-18\" rx=\"40.09\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"1131.21\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">SWEB</text>\n",
       "</g>\n",
       "<!-- WE_AR&#45;&#45;SWEB -->\n",
       "<g id=\"edge18\" class=\"edge\">\n",
       "<title>WE_AR--SWEB</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M1081.21,-60.12C1090.82,-52.03 1102.41,-42.26 1112.01,-34.18\"/>\n",
       "</g>\n",
       "<!-- SDB1 -->\n",
       "<g id=\"node21\" class=\"node\">\n",
       "<title>SDB1</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"702.63\" cy=\"-583.84\" rx=\"37.09\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"702.63\" y=\"-580.14\" font-family=\"Times,serif\" font-size=\"14.00\">SDB1</text>\n",
       "</g>\n",
       "<!-- SR_AR&#45;&#45;SDB1 -->\n",
       "<g id=\"edge20\" class=\"edge\">\n",
       "<title>SR_AR--SDB1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M729.91,-527.83C724.25,-539.45 716.91,-554.53 711.26,-566.11\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib ipympl\n",
    "model_file = Path(\"model.kat\")\n",
    "model = Model()\n",
    "model.phase_config(zero_k00=False, zero_tem00_gouy=True)\n",
    "model.modes(modes=\"off\")  # pyright: ignore[reportUnusedCallResult]\n",
    "model.parse(model_file.read_text())\n",
    "model.lambda0 = model.get(\"wavelength\")\n",
    "model.laser.P = C_POWER\n",
    "model.plot_graph()  # pyright: ignore[reportUnusedCallResult]\n",
    "show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b742cd14-2149-437b-9194-249cf40849b1",
   "metadata": {},
   "outputs": [],
   "source": [
    "result = model.run(\n",
    "    TemporaryParameters(\n",
    "        Series(\n",
    "            Change(\n",
    "                {\n",
    "                    \"SR.misaligned\": True,\n",
    "                    \"PR.misaligned\": True,\n",
    "                    \"eom1.midx\": 0,\n",
    "                    \"eom2.midx\": 0,\n",
    "                    \"eom3.midx\": 0,\n",
    "                    \"eom4.midx\": 0,\n",
    "                }\n",
    "            ),\n",
    "            Maximize(\n",
    "                model.get(\"NE_p1\"),\n",
    "                model.get(\"NORTH_ARM.DC\"),\n",
    "                bounds=[-180, 180],\n",
    "                tol=1e-14,\n",
    "            ),\n",
    "            Maximize(\n",
    "                model.get(\"WE_p1\"),\n",
    "                model.get(\"WEST_ARM.DC\"),\n",
    "                bounds=[-180, 180],\n",
    "                tol=1e-14,\n",
    "            ),\n",
    "            Minimize(\n",
    "                model.get(\"SR_p2\"), model.get(\"MICH.DC\"), bounds=[-180, 180], tol=1e-14\n",
    "            ),\n",
    "            Change(\n",
    "                {\n",
    "                    \"PR.misaligned\": False,\n",
    "                }\n",
    "            ),\n",
    "            Maximize(\n",
    "                model.get(\"PR_p2\"), model.get(\"PRCL.DC\"), bounds=[-180, 180], tol=1e-14\n",
    "            ),\n",
    "            Change(\n",
    "                {\n",
    "                    \"SR.misaligned\": False,\n",
    "                }\n",
    "            ),\n",
    "            Maximize(\n",
    "                model.get(\"B1_DC\"), model.get(\"SRCL.DC\"), bounds=[-180, 180], tol=1e-14\n",
    "            ),\n",
    "            Change(\n",
    "                {\n",
    "                    \"SRCL.DC\": -90,\n",
    "                },\n",
    "                relative=True,\n",
    "            ),\n",
    "        ),\n",
    "        exclude=[\n",
    "            \"NE.phi\",\n",
    "            \"NI.phi\",\n",
    "            \"WE.phi\",\n",
    "            \"WI.phi\",\n",
    "            \"SR.phi\",\n",
    "            \"PR.phi\",\n",
    "            \"NORTH_ARM.DC\",\n",
    "            \"WEST_ARM.DC\",\n",
    "            \"DARM.DC\",\n",
    "            \"MICH.DC\",\n",
    "            \"PRCL.DC\",\n",
    "            \"SRCL.DC\",\n",
    "            \"SR.misaligned\",\n",
    "            \"eom1.midx\",\n",
    "            \"eom2.midx\",\n",
    "            \"eom3.midx\",\n",
    "            \"eom4.midx\",\n",
    "        ],\n",
    "    ),\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "fbc0d68f-9b01-4d52-866c-18d49aedff32",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "ff5543d311194241962ada8509de11c4",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 183236 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 183236 characters]' width=1300.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">Degré de liberté <span style=\"color: #800000; text-decoration-color: #800000; font-weight: bold\">0.00164794921875</span> trouvé en <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold; text-decoration: underline\">14</span><span style=\"color: #008080; text-decoration-color: #008080; text-decoration: underline\"> pas</span> pour avoir une puissance de <span style=\"color: #800000; text-decoration-color: #800000; font-weight: bold\">0.007914176860517742</span><span style=\"color: #800000; text-decoration-color: #800000; font-weight: bold\"> W</span> sur B1\n",
       "</pre>\n"
      ],
      "text/plain": [
       "Degré de liberté \u001b[1;31m0.00164794921875\u001b[0m trouvé en \u001b[1;4;36m14\u001b[0m\u001b[4;36m pas\u001b[0m pour avoir une puissance de \u001b[1;31m0.007914176860517742\u001b[0m\u001b[1;31m W\u001b[0m sur B1\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def compute_solutions(\n",
    "    model: Model, DOF: str, padding: float, nb: int = 10000\n",
    ") -> SeriesSolution:\n",
    "    return model.run(\n",
    "        Xaxis(\n",
    "            model.get(DOF).DC,\n",
    "            \"lin\",\n",
    "            model.get(DOF).DC - padding,\n",
    "            model.get(DOF).DC + padding,\n",
    "            nb,\n",
    "        )\n",
    "    )\n",
    "\n",
    "\n",
    "def display_ax(\n",
    "    ax: Axes,\n",
    "    solution: SeriesSolution,\n",
    "    model: Model,\n",
    "    DOF: str,\n",
    "    padding: float,\n",
    "    nb: int = 10000,\n",
    ") -> Axes:\n",
    "    x = linspace(model.get(DOF).DC - padding, model.get(DOF).DC + padding, nb + 1)\n",
    "    _ = ax.semilogy(x, solution[\"SR_p2\"], label=\"dark fringe\")\n",
    "    _ = ax.semilogy(x, solution[\"NE_p1\"], label=\"north cavity\")\n",
    "    _ = ax.semilogy(x, solution[\"WE_p1\"], label=\"west cavity\")\n",
    "    _ = ax.vlines(\n",
    "        [model.get(DOF).DC],\n",
    "        min(solution[\"SR_p2\"]),\n",
    "        max(solution[\"NE_p1\"]),\n",
    "        colors=\"red\",\n",
    "    )\n",
    "    _ = ax.set_ylabel(\"power (W)\")\n",
    "    ax.grid()\n",
    "    _ = ax.legend()\n",
    "    return ax\n",
    "\n",
    "\n",
    "class DisplayData(NamedTuple):\n",
    "    DOF: str\n",
    "    padding: float\n",
    "\n",
    "\n",
    "data: list[DisplayData] = [\n",
    "    DisplayData(\"NORTH_ARM\", 10),\n",
    "    DisplayData(\"WEST_ARM\", 10),\n",
    "    DisplayData(\"PRCL\", 10),\n",
    "    DisplayData(\"MICH\", 10),\n",
    "    DisplayData(\"DARM\", 10),\n",
    "    DisplayData(\"CARM\", 10),\n",
    "]\n",
    "\n",
    "Figure = figure(figsize=(13, 10))\n",
    "nb = int(1e4)\n",
    "\n",
    "for i in range(len(data)):\n",
    "    element: DisplayData = data[i]\n",
    "    ax = Figure.add_subplot(3, 2, i + 1)\n",
    "    solution = compute_solutions(model, element.DOF, element.padding, nb)\n",
    "    _ = display_ax(ax, solution, model, element.DOF, element.padding, nb).set_xlabel(\n",
    "        \"{} value\".format(element.DOF)\n",
    "    )\n",
    "show()\n",
    "\n",
    "solution = model.run(Noxaxis())\n",
    "result = solution[\"B1_DC\"]\n",
    "start, stop, nb = 0, 1, 0\n",
    "while (abs(result - C_DARK_FRINGE) > 1e-4) and (nb < 100):\n",
    "    nb += 1\n",
    "    temp = start + (stop - start) / 2\n",
    "\n",
    "    model.DARM.DC = temp\n",
    "    solution = model.run(Noxaxis())\n",
    "    result = solution[\"B1_DC\"]\n",
    "    if result > C_DARK_FRINGE:\n",
    "        stop = temp\n",
    "    else:\n",
    "        start = temp\n",
    "console.print(\n",
    "    \"Degré de liberté [result]{dof}[/result] trouvé en [strong]{nb} pas[/strong] pour avoir une puissance de [result]{result} W[/result] sur B1\".format(\n",
    "        nb=nb, dof=model.DARM.DC, result=result\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "66c9be03-cedc-4d07-acbd-3269f3143cd4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-style: italic\">             Puissances dans l'interferomètre              </span>\n",
       "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> position                         </span>┃<span style=\"font-weight: bold\"> puissance (W)        </span>┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Injection                        </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 25.0                 </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> PR                               </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 3.5170290886624462   </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> cavité de recyclage de puissance </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 964.4848027884494    </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> cavité ouest                     </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 135149.08955077862   </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> cavité nord                      </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 133050.4589467552    </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> frange noire                     </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 0.007915300832119847 </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> SNEB                             </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 0.5971887081919476   </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> SWEB                             </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 0.5810707836915688   </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> SDB1                             </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 0.007914184774702517 </span>│\n",
       "└──────────────────────────────────┴──────────────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[3m             Puissances dans l'interferomètre              \u001b[0m\n",
       "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mposition                        \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mpuissance (W)       \u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│\u001b[37m \u001b[0m\u001b[37mInjection                       \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m25.0                \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mPR                              \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m3.5170290886624462  \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mcavité de recyclage de puissance\u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m964.4848027884494   \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mcavité ouest                    \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m135149.08955077862  \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mcavité nord                     \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m133050.4589467552   \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mfrange noire                    \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m0.007915300832119847\u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mSNEB                            \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m0.5971887081919476  \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mSWEB                            \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m0.5810707836915688  \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mSDB1                            \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m0.007914184774702517\u001b[0m\u001b[36m \u001b[0m│\n",
       "└──────────────────────────────────┴──────────────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-style: italic\">       DOF dans l'interferomètre        </span>\n",
       "┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> nom        </span>┃<span style=\"font-weight: bold\"> valeur                  </span>┃\n",
       "┡━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Bras nord  </span>│<span style=\"color: #800080; text-decoration-color: #800080\"> 6.592588499188424e-06   </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Bras ouest </span>│<span style=\"color: #800080; text-decoration-color: #800080\"> -5.8479547500610346e-05 </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> PR         </span>│<span style=\"color: #800080; text-decoration-color: #800080\"> -44.946681098699614     </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> SR         </span>│<span style=\"color: #800080; text-decoration-color: #800080\"> -135.09400848257525     </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> MICH       </span>│<span style=\"color: #800080; text-decoration-color: #800080\"> -89.79029219055182      </span>│\n",
       "└────────────┴─────────────────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[3m       DOF dans l'interferomètre        \u001b[0m\n",
       "┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mnom       \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mvaleur                 \u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│\u001b[37m \u001b[0m\u001b[37mBras nord \u001b[0m\u001b[37m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m6.592588499188424e-06  \u001b[0m\u001b[35m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mBras ouest\u001b[0m\u001b[37m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m-5.8479547500610346e-05\u001b[0m\u001b[35m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mPR        \u001b[0m\u001b[37m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m-44.946681098699614    \u001b[0m\u001b[35m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mSR        \u001b[0m\u001b[37m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m-135.09400848257525    \u001b[0m\u001b[35m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mMICH      \u001b[0m\u001b[37m \u001b[0m│\u001b[35m \u001b[0m\u001b[35m-89.79029219055182     \u001b[0m\u001b[35m \u001b[0m│\n",
       "└────────────┴─────────────────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> nom                   </span>┃<span style=\"font-weight: bold\"> valeur                          </span>┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> FSR                   </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 49968.74091606107               </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Loss                  </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 0.013848722846499961            </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Finesse               </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 450.5516190359727               </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> FWHM                  </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 110.90569605093683              </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Storage time          </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 0.0028700950223295757           </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Pole                  </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 55.45284802546841               </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Round trip length     </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> 5999.6                          </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Waist size            </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> [0.00968668 0.00968668]         </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Waist position        </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> [-1363.71492094 -1363.71492094] </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Stability (m-factor)  </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> [0.7409226 0.7409226]           </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Stability (g-factor)  </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> [0.8704613 0.8704613]           </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Round trip gouy phase </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> [317.81006617 317.81006617]     </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Mode separation       </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> [5856.04964666 5856.04964666]   </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Resolution            </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> [52.80206387 52.80206387]       </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Stable                </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> True                            </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> Critically stable     </span>│<span style=\"color: #008080; text-decoration-color: #008080\"> False                           </span>│\n",
       "└───────────────────────┴─────────────────────────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mnom                  \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mvaleur                         \u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│\u001b[37m \u001b[0m\u001b[37mFSR                  \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m49968.74091606107              \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mLoss                 \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m0.013848722846499961           \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mFinesse              \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m450.5516190359727              \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mFWHM                 \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m110.90569605093683             \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mStorage time         \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m0.0028700950223295757          \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mPole                 \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m55.45284802546841              \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mRound trip length    \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m5999.6                         \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mWaist size           \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m[0.00968668 0.00968668]        \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mWaist position       \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m[-1363.71492094 -1363.71492094]\u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mStability (m-factor) \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m[0.7409226 0.7409226]          \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mStability (g-factor) \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m[0.8704613 0.8704613]          \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mRound trip gouy phase\u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m[317.81006617 317.81006617]    \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mMode separation      \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m[5856.04964666 5856.04964666]  \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mResolution           \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36m[52.80206387 52.80206387]      \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mStable               \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36mTrue                           \u001b[0m\u001b[36m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mCritically stable    \u001b[0m\u001b[37m \u001b[0m│\u001b[36m \u001b[0m\u001b[36mFalse                          \u001b[0m\u001b[36m \u001b[0m│\n",
       "└───────────────────────┴─────────────────────────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "solution = model.run(Noxaxis())\n",
    "console = Console()\n",
    "table = Table(title=\"Puissances dans l'interferomètre\")\n",
    "table.add_column(\"position\", justify=\"left\", style=\"white\")\n",
    "table.add_column(\"puissance (W)\", justify=\"left\", style=\"cyan\")\n",
    "\n",
    "table.add_row(\"Injection\", str(model.get(\"laser\").P.eval()))\n",
    "table.add_row(\"PR\", str(solution[\"PR_p1\"]))\n",
    "table.add_row(\"cavité de recyclage de puissance\", str(solution[\"PR_p2\"]))\n",
    "table.add_row(\"cavité ouest\", str(solution[\"WE_p1\"]))\n",
    "table.add_row(\"cavité nord\", str(solution[\"NE_p1\"]))\n",
    "table.add_row(\"frange noire\", str(solution[\"SR_p2\"]))\n",
    "table.add_row(\"SNEB\", str(solution[\"SNEB_DC\"]))\n",
    "table.add_row(\"SWEB\", str(solution[\"SWEB_DC\"]))\n",
    "table.add_row(\"SDB1\", str(solution[\"SDB1_DC\"]))\n",
    "\n",
    "console.print(table)\n",
    "\n",
    "table = Table(title=\"DOF dans l'interferomètre\")\n",
    "table.add_column(\"nom\", justify=\"left\", style=\"white\")\n",
    "table.add_column(\"valeur\", justify=\"left\", style=\"magenta\")\n",
    "\n",
    "table.add_row(\"Bras nord\", str(model.get(\"NORTH_ARM.DC\")))\n",
    "table.add_row(\"Bras ouest\", str(model.get(\"WEST_ARM.DC\")))\n",
    "table.add_row(\"PR\", str(model.get(\"PRCL.DC\")))\n",
    "table.add_row(\"SR\", str(model.get(\"SRCL.DC\")))\n",
    "table.add_row(\"MICH\", str(model.get(\"MICH.DC\")))\n",
    "\n",
    "console.print(table)\n",
    "\n",
    "console = Console(theme=theme)\n",
    "table = Table(title=\"\")\n",
    "table.add_column(\"nom\", justify=\"left\", style=\"white\")\n",
    "table.add_column(\"valeur\", justify=\"left\", style=\"cyan\")\n",
    "for i in range(1, model.west_arm.info_parameter_table().table.shape[0]):\n",
    "    table.add_row(\n",
    "        str(model.west_arm.info_parameter_table().table[i, 0]),\n",
    "        str(model.west_arm.info_parameter_table().table[i, 1]),\n",
    "    )\n",
    "console.print(table)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "7fde067a-52b7-4798-8bd6-0890e27f33e2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c1020b84332a40c1b0adcd3b985a2ec3",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 117088 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 117088 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/demagny/codes/python/finesse/finesse-simulation-04/.venv/lib/python3.13/site-packages/finesse/analysis/actions/base.py:157: UserWarning: Signal frequency (fsig) was set to None but simulation needs it. Setting default value of 1 Hz\n",
      "  self.__sim.__enter__()\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">Le <span style=\"color: #008080; text-decoration-color: #008080; text-decoration: underline\">pôle</span> de la fonction de transfert <span style=\"color: #008080; text-decoration-color: #008080; text-decoration: underline\">DARM</span> est à <span style=\"color: #800000; text-decoration-color: #800000; font-weight: bold\">445.2</span> Hz\n",
       "</pre>\n"
      ],
      "text/plain": [
       "Le \u001b[4;36mpôle\u001b[0m de la fonction de transfert \u001b[4;36mDARM\u001b[0m est à \u001b[1;31m445.2\u001b[0m Hz\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-style: italic\">             Position des différents miroirs              </span>\n",
       "┏━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> miroir </span>┃<span style=\"font-weight: bold\"> offset (°)          </span>┃<span style=\"font-weight: bold\"> offset (m)              </span>┃\n",
       "┡━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> NE     </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> 44.894328713255035  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> 2.653753652827965e-07   </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> NE_AR  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> 44.894328713255035  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> 2.653753652827965e-07   </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> NI     </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> 44.89514609527591   </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> 2.6538019691874205e-07  </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> NI_AR  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> 44.89514609527591   </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> 2.6538019691874205e-07  </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> WE     </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -44.894380600214035 </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -2.653756719923763e-07  </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> WE_AR  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -44.894380600214035 </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -2.653756719923763e-07  </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> WI     </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -44.89514609527591  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -2.6538019691874205e-07 </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> WI_AR  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -44.89514609527591  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -2.6538019691874205e-07 </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> PR     </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -44.946681098699614 </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -2.656848260500911e-07  </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> PR_AR  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -44.946681098699614 </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -2.656848260500911e-07  </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> SR     </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -135.09400848257525 </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -7.985556945858894e-07  </span>│\n",
       "│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> SR_AR  </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -135.09400848257525 </span>│<span style=\"color: #c0c0c0; text-decoration-color: #c0c0c0\"> -7.985556945858894e-07  </span>│\n",
       "└────────┴─────────────────────┴─────────────────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[3m             Position des différents miroirs              \u001b[0m\n",
       "┏━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mmiroir\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1moffset (°)         \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1moffset (m)             \u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│\u001b[37m \u001b[0m\u001b[37mNE    \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m44.894328713255035 \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m2.653753652827965e-07  \u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mNE_AR \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m44.894328713255035 \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m2.653753652827965e-07  \u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mNI    \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m44.89514609527591  \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m2.6538019691874205e-07 \u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mNI_AR \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m44.89514609527591  \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m2.6538019691874205e-07 \u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mWE    \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-44.894380600214035\u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-2.653756719923763e-07 \u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mWE_AR \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-44.894380600214035\u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-2.653756719923763e-07 \u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mWI    \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-44.89514609527591 \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-2.6538019691874205e-07\u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mWI_AR \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-44.89514609527591 \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-2.6538019691874205e-07\u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mPR    \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-44.946681098699614\u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-2.656848260500911e-07 \u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mPR_AR \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-44.946681098699614\u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-2.656848260500911e-07 \u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mSR    \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-135.09400848257525\u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-7.985556945858894e-07 \u001b[0m\u001b[37m \u001b[0m│\n",
       "│\u001b[37m \u001b[0m\u001b[37mSR_AR \u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-135.09400848257525\u001b[0m\u001b[37m \u001b[0m│\u001b[37m \u001b[0m\u001b[37m-7.985556945858894e-07 \u001b[0m\u001b[37m \u001b[0m│\n",
       "└────────┴─────────────────────┴─────────────────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def get_QNLS(\n",
    "    model: Model, start: int = 5, stop: int = 1000, nb: int = 100\n",
    ") -> SeriesSolution:\n",
    "    new_model = model.deepcopy()\n",
    "    new_model.fsig.f = 1\n",
    "    new_model.add(SignalGenerator(\"darmx\", new_model.space_NI_NE.h, 1, 0))\n",
    "    new_model.add(SignalGenerator(\"darmy\", new_model.space_WI_WE.h, 1, 180))\n",
    "    new_model.add(QuantumNoiseDetector(\"NSR_with_RP\", new_model.SR.p2.o, True))\n",
    "    return new_model.run(Xaxis(new_model.get(\"fsig.f\"), \"log\", start, stop, nb))\n",
    "\n",
    "\n",
    "model._settings.phase_config.zero_k00 = False\n",
    "\n",
    "solution = get_QNLS(model, 5, 5000, 10000)\n",
    "\n",
    "\n",
    "def dumb_parse(value: str = \"\"):\n",
    "    regex = re.compile(\"\\\\((\\\\d+\\\\.\\\\d+e[+-]\\\\d{2})([+-]\\\\d+\\\\.\\\\d+e[+-]\\\\d{2})j\\\\)\")\n",
    "    result = re.search(regex, value)\n",
    "    if result:\n",
    "        return float(result.groups()[0]) + 1j * float(result.groups()[1])\n",
    "    raise Exception(value)\n",
    "\n",
    "\n",
    "QNLS = load(\"sensitivities/finesse-virgo.npy\")\n",
    "current_O4_sensitivity_ASD = loadtxt(\"sensitivities/O4_nominal_reference.txt\")\n",
    "\n",
    "Figure = figure(figsize=(14, 5))\n",
    "_ = Figure.gca().loglog(\n",
    "    solution.x1, abs(solution[\"NSR_with_RP\"]), label=\"this lock process\"\n",
    ")\n",
    "_ = Figure.gca().loglog(\n",
    "    QNLS[0],\n",
    "    QNLS[1],\n",
    "    label=\"packaged lock process\",\n",
    ")\n",
    "_ = Figure.gca().loglog(\n",
    "    current_O4_sensitivity_ASD[0],\n",
    "    abs(current_O4_sensitivity_ASD[1]),\n",
    "    label=\"current nominal sensitivity during O4\",\n",
    ")\n",
    "_ = Figure.gca().legend()\n",
    "Figure.gca().grid(True, \"both\", \"both\")\n",
    "show()\n",
    "\n",
    "solution = model.run(FrequencyResponse(geomspace(5, 10000, 1000), [\"DARM\"], [\"B1.I\"]))\n",
    "maximum_amplitude_step: float = max(abs(diff(angle(solution[\"B1.I\", \"DARM\"]))))\n",
    "pole_index = round(\n",
    "    mean(\n",
    "        where(\n",
    "            abs(angle(solution[\"B1.I\", \"DARM\"]) + pi / 4) < maximum_amplitude_step * 2\n",
    "        )\n",
    "    )\n",
    ")  # find the index where the curve is the closest to -45°\n",
    "console.print(\n",
    "    \"Le [strong]pôle[/strong] de la fonction de transfert [strong]DARM[/strong] est à [result]{:.1f}[/result] Hz\".format(\n",
    "        solution.f[pole_index]\n",
    "    )\n",
    ")\n",
    "\n",
    "table = Table(title=\"Position des différents miroirs\")\n",
    "table.add_column(\"miroir\", justify=\"left\", style=\"white\")\n",
    "table.add_column(\"offset (°)\", justify=\"left\", style=\"white\")\n",
    "table.add_column(\"offset (m)\", justify=\"left\", style=\"white\")\n",
    "\n",
    "for name in [\n",
    "    \"NE\",\n",
    "    \"NE_AR\",\n",
    "    \"NI\",\n",
    "    \"NI_AR\",\n",
    "    \"WE\",\n",
    "    \"WE_AR\",\n",
    "    \"WI\",\n",
    "    \"WI_AR\",\n",
    "    \"PR\",\n",
    "    \"PR_AR\",\n",
    "    \"SR\",\n",
    "    \"SR_AR\",\n",
    "]:\n",
    "    element: Mirror = model.get(name)\n",
    "    table.add_row(\n",
    "        str(element.name),\n",
    "        str(element.phi.eval()),\n",
    "        str(element.phi.eval() * model.lambda0 / 180),\n",
    "    )\n",
    "\n",
    "console.print(table)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd5ff122-8d97-43f2-982a-084ee984b827",
   "metadata": {},
   "source": [
    "## Comparaison avec Optickle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "fd3b1078-0fd6-4e1b-9e55-b231d9464bdf",
   "metadata": {},
   "outputs": [],
   "source": [
    "model.SNEB.phi = model.NE.phi - 45\n",
    "model.SWEB.phi = model.WE.phi - 45\n",
    "model.SDB1.phi = model.SR.phi + 45\n",
    "\n",
    "B1_detector = \"B1_DDC.DC\"\n",
    "\n",
    "quad_tf: dict[str, SeriesSolution] = dict()\n",
    "in_tf: dict[str, SeriesSolution] = dict()\n",
    "\n",
    "for bench_name in [\"SNEB\", \"SWEB\", \"SDB1\"]:\n",
    "    quad_tf[bench_name] = model.run(\n",
    "        FrequencyResponse(\n",
    "            geomspace(5, 10000, 1000), [\"{}_z\".format(bench_name)], [B1_detector]\n",
    "        )\n",
    "    )\n",
    "\n",
    "quad_tf[\"DARM\"] = model.run(\n",
    "    FrequencyResponse(geomspace(5, 10000, 1000), [\"DARM\"], [B1_detector])\n",
    ")\n",
    "\n",
    "model.SNEB.phi = model.NE.phi\n",
    "model.SWEB.phi = model.WE.phi\n",
    "model.SDB1.phi = model.SR.phi\n",
    "\n",
    "for bench_name in [\"SNEB\", \"SWEB\", \"SDB1\"]:\n",
    "    in_tf[bench_name] = model.run(\n",
    "        FrequencyResponse(\n",
    "            geomspace(5, 10000, 1000), [\"{}_z\".format(bench_name)], [B1_detector]\n",
    "        )\n",
    "    )\n",
    "\n",
    "in_tf[\"DARM\"] = model.run(\n",
    "    FrequencyResponse(geomspace(5, 10000, 1000), [\"DARM\"], [B1_detector])\n",
    ")\n",
    "\n",
    "modelisation_file = Path(\"scatterCoupling_25_8.mat\")\n",
    "\n",
    "modelisation_data = loadmat(modelisation_file)\n",
    "coupling_data: dict[str, list[Signal]] = dict()\n",
    "old_couplings = [\"SNEB\", \"SWEB\", \"SDB1\"]\n",
    "for coupling in old_couplings:\n",
    "    coupling_data[coupling] = [\n",
    "        Signal(\n",
    "            modelisation_data[\"freq\"][0],\n",
    "            abs(values),\n",
    "        )\n",
    "        for values in modelisation_data[\"{}coupling\".format(coupling)]\n",
    "    ]\n",
    "DARMcoupling = Signal(\n",
    "    modelisation_data[\"freq\"][0],\n",
    "    modelisation_data[\"DARMmat\"][0],\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be43f8b2-eddf-4dfc-a342-a54017b571f6",
   "metadata": {},
   "source": [
    "### En fonction de la phase"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "61c3d4e0-b8bc-48e0-83cd-5675c62feba1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7eb7037896e2429abf9c0a777e862711",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 75744 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 75744 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f894b4f4ab7a425682a04c23fbaf1f15",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 73752 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 73752 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b0c7d4a9072142f6a32807ebe02e493c",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 86280 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 86280 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "23e07dce0d2e47c2a0cd5b8c1bef8f9d",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 95300 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 95300 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "842595d6273646daadde415bc801ab3e",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 97708 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 97708 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "Figure = figure(figsize=(14, 5))\n",
    "_ = Figure.suptitle(\"Comparaison du module des fonctions de transfert pour DARM\")\n",
    "ax = Figure.add_subplot(1, 2, 1)\n",
    "_ = ax.loglog(quad_tf[\"DARM\"].f, abs(quad_tf[\"DARM\"][B1_detector, \"DARM\"]), label=\"Finesse\")\n",
    "_ = ax.loglog(DARMcoupling.x, abs(DARMcoupling.y), label=\"Optickle\")\n",
    "_ = ax.set_title(\"En quadrature de phase\")\n",
    "_ = ax.legend()\n",
    "ax.grid(True, \"both\", \"both\")\n",
    "ax = Figure.add_subplot(1, 2, 2)\n",
    "_ = ax.loglog(in_tf[\"DARM\"].f, abs(in_tf[\"DARM\"][B1_detector, \"DARM\"]), label=\"Finesse\")\n",
    "_ = ax.loglog(DARMcoupling.x, abs(DARMcoupling.y), label=\"Optickle\")\n",
    "_ = ax.set_title(\"En phase\")\n",
    "_ = ax.legend()\n",
    "ax.grid(True, \"both\", \"both\")\n",
    "\n",
    "Figure = figure(figsize=(14, 5))\n",
    "_ = Figure.suptitle(\"Comparaison de la phase des fonctions de transfert pour DARM\")\n",
    "ax = Figure.add_subplot(1, 2, 1)\n",
    "_ = ax.semilogx(quad_tf[\"DARM\"].f, angle(quad_tf[\"DARM\"][B1_detector, \"DARM\"]) * 180/pi, label=\"Finesse\")\n",
    "_ = ax.semilogx(DARMcoupling.x, angle(DARMcoupling.y) * 180/pi - 180, label=\"Optickle\")\n",
    "_ = ax.set_title(\"En quadrature de phase\")\n",
    "_ = ax.hlines([-45], min(quad_tf[\"DARM\"].f), max(quad_tf[\"DARM\"].f), colors = 'red')\n",
    "_ = ax.legend()\n",
    "ax.grid(True, \"both\", \"both\")\n",
    "ax = Figure.add_subplot(1, 2, 2)\n",
    "_ = ax.semilogx(in_tf[\"DARM\"].f, angle(in_tf[\"DARM\"][B1_detector, \"DARM\"]) * 180/pi, label=\"Finesse\")\n",
    "_ = ax.semilogx(DARMcoupling.x, angle(DARMcoupling.y) * 180/pi - 180, label=\"Optickle\")\n",
    "_ = ax.set_title(\"En phase\")\n",
    "_ = ax.hlines([-45], min(quad_tf[\"DARM\"].f), max(quad_tf[\"DARM\"].f), colors = 'red')\n",
    "_ = ax.legend()\n",
    "ax.grid(True, \"both\", \"both\")\n",
    "\n",
    "for bench_name in [\"SNEB\", \"SWEB\", \"SDB1\"]:\n",
    "    in_index = 0\n",
    "    if bench_name == \"SDB1\":\n",
    "        in_index = 0\n",
    "    quad_index = (1 + in_index) % 2\n",
    "    Figure = figure(figsize=(14, 5))\n",
    "    _ = Figure.suptitle(\n",
    "        \"Comparaison du module des fonctions de transfert pour {}\".format(bench_name)\n",
    "    )\n",
    "    ax = Figure.add_subplot(1, 2, 1)\n",
    "    _ = ax.loglog(\n",
    "        quad_tf[bench_name].f,\n",
    "        abs(quad_tf[bench_name][B1_detector, \"{}_z\".format(bench_name)])\n",
    "        / abs(quad_tf[\"DARM\"][B1_detector, \"DARM\"])\n",
    "        / model.space_NI_NE.L.eval(),\n",
    "        label=\"Finesse\",\n",
    "    )\n",
    "    _ = ax.loglog(\n",
    "        coupling_data[bench_name][quad_index].x,\n",
    "        abs(coupling_data[bench_name][quad_index].y),\n",
    "        label=\"Optickle\",\n",
    "    )\n",
    "    _ = ax.set_title(\"En Quadrature de phase\")\n",
    "    _ = ax.legend()\n",
    "    ax.grid(True, \"both\", \"both\")\n",
    "    ax = Figure.add_subplot(1, 2, 2)\n",
    "    _ = ax.loglog(\n",
    "        in_tf[bench_name].f,\n",
    "        abs(in_tf[bench_name][B1_detector, \"{}_z\".format(bench_name)])\n",
    "        / abs(in_tf[\"DARM\"][B1_detector, \"DARM\"])\n",
    "        / model.space_NI_NE.L.eval(),\n",
    "        label=\"Finesse\",\n",
    "    )\n",
    "    _ = ax.loglog(\n",
    "        coupling_data[bench_name][in_index].x,\n",
    "        abs(coupling_data[bench_name][in_index].y),\n",
    "        label=\"Optickle\",\n",
    "    )\n",
    "    _ = ax.set_title(\"En phase\")\n",
    "    _ = ax.legend()\n",
    "    ax.grid(True, \"both\", \"both\")\n",
    "    console.print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "11606546-2606-404c-a75e-6e434d19084b",
   "metadata": {},
   "source": [
    "### En fonction de la simulation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "88002141-6a42-4ae0-a614-4c2b8dd336ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "6fd8318848a141d59b5173627646b6f0",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 81948 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 81948 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7eec62ae8aa7447dbffa044be238ae8d",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 83416 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 83416 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a9bb6fd944154845a5df1641d69a7080",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 108896 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 108896 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for bench_name in [\"SNEB\", \"SWEB\", \"SDB1\"]:\n",
    "    in_index = 0\n",
    "    if bench_name == \"SDB1\":\n",
    "        in_index = 1\n",
    "    quad_index = (1 + in_index) % 2\n",
    "    Figure = figure(figsize=(14, 5))\n",
    "    _ = Figure.suptitle(\n",
    "        \"Comparaison des fonctions de transfert pour {}\".format(bench_name)\n",
    "    )\n",
    "    ax = Figure.add_subplot(1, 2, 1)\n",
    "    _ = ax.loglog(\n",
    "        quad_tf[bench_name].f,\n",
    "        abs(quad_tf[bench_name][B1_detector, \"{}_z\".format(bench_name)])\n",
    "        / abs(quad_tf[\"DARM\"][B1_detector, \"DARM\"])\n",
    "        / model.space_NI_NE.L.eval(),\n",
    "        label=\"Quadrature de phase\",\n",
    "    )\n",
    "    _ = ax.loglog(\n",
    "        in_tf[bench_name].f,\n",
    "        abs(in_tf[bench_name][B1_detector, \"{}_z\".format(bench_name)])\n",
    "        / abs(in_tf[\"DARM\"][B1_detector, \"DARM\"])\n",
    "        / model.space_NI_NE.L.eval(),\n",
    "        label=\"En phase\",\n",
    "    )\n",
    "    _ = ax.set_title(\"Finesse\")\n",
    "    _ = ax.legend()\n",
    "    ax.grid(True, \"both\", \"both\")\n",
    "    ax = Figure.add_subplot(1, 2, 2)\n",
    "    _ = ax.loglog(\n",
    "        coupling_data[bench_name][quad_index].x,\n",
    "        abs(coupling_data[bench_name][quad_index].y),\n",
    "        label=\"Quadrature de phase\",\n",
    "    )\n",
    "    _ = ax.loglog(\n",
    "        coupling_data[bench_name][in_index].x,\n",
    "        abs(coupling_data[bench_name][in_index].y),\n",
    "        label=\"En phase\",\n",
    "    )\n",
    "    _ = ax.set_title(\"Optickle\")\n",
    "    _ = ax.legend()\n",
    "    ax.grid(True, \"both\", \"both\")\n",
    "    show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c70d12b-b5ae-44b7-b0d3-6f054b697300",
   "metadata": {},
   "source": [
    "### En fonction du module/phase"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "cb1fd40c-83bb-4dc3-b259-7dd3a08d3b6b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "25be9b349a6a4c059eab614015b86812",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 82992 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 82992 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "fd09e54290c74e5abb59b4a289d65025",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 83796 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 83796 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "66dfd09c72aa4febb1b2efc8e8356996",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "[encoded data, 94780 characters]",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Figure\n",
       "                </div>\n",
       "                <img src='data:image/png;base64,[encoded data, 94780 characters]' width=1400.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for bench_name in [\"SNEB\", \"SWEB\", \"SDB1\"]:\n",
    "    Figure = figure(figsize=(14, 5))\n",
    "    _ = Figure.suptitle(\n",
    "        \"Comparaison des fonctions de transfert pour {}\".format(bench_name)\n",
    "    )\n",
    "    ax = Figure.add_subplot(1, 2, 1)\n",
    "    _ = ax.loglog(\n",
    "        quad_tf[bench_name].f,\n",
    "        abs(quad_tf[bench_name][B1_detector, \"{}_z\".format(bench_name)])\n",
    "        / abs(quad_tf[\"DARM\"][B1_detector, \"DARM\"])\n",
    "        / model.space_NI_NE.L.eval(),\n",
    "        label=\"Quadrature de phase\",\n",
    "    )\n",
    "    _ = ax.loglog(\n",
    "        in_tf[bench_name].f,\n",
    "        abs(in_tf[bench_name][B1_detector, \"{}_z\".format(bench_name)])\n",
    "        / abs(in_tf[\"DARM\"][B1_detector, \"DARM\"])\n",
    "        / model.space_NI_NE.L.eval(),\n",
    "        label=\"En phase\",\n",
    "    )\n",
    "    _ = ax.set_title(\"Module\")\n",
    "    _ = ax.legend()\n",
    "    ax.grid(True, \"both\", \"both\")\n",
    "    ax = Figure.add_subplot(1, 2, 2)\n",
    "    _ = ax.semilogx(\n",
    "        quad_tf[bench_name].f,\n",
    "        angle(quad_tf[bench_name][B1_detector, \"{}_z\".format(bench_name)]) * 180 / pi,\n",
    "        label=\"Quadrature de phase\",\n",
    "    )\n",
    "    _ = ax.semilogx(\n",
    "        in_tf[bench_name].f,\n",
    "        angle(in_tf[bench_name][B1_detector, \"{}_z\".format(bench_name)]) * 180 / pi,\n",
    "        label=\"En phase\",\n",
    "    )\n",
    "    _ = ax.set_title(\"Finesse\")\n",
    "    _ = ax.legend()\n",
    "    ax.grid(True, \"both\", \"both\")\n",
    "    show()"
   ]
  }
 ],
 "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.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
