{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Dubois surface inversion: Python vs C GUI on Winnip C3 data\n",
    "\n",
    "This notebook loads the precomputed C GUI outputs from `/data/psp/winnip_cpsp/C3`, runs the Python Dubois surface inversion on the same C3 input, and compares the two results numerically."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "from pathlib import Path\n",
    "\n",
    "import numpy as np\n",
    "import xarray as xr\n",
    "from dask.diagnostics import ProgressBar\n",
    "\n",
    "from polsarpro.dev.io import read_C3_psp, read_psp_bin\n",
    "from polsarpro.dev.metrics import summarize_metrics, visualize_errors\n",
    "from polsarpro.physical_inversion import dubois_surface_inversion\n",
    "\n",
    "# Same Dubois parameters as the original notebook.\n",
    "freq_ghz = 1.2575\n",
    "thresh1_db = 0\n",
    "thresh2_db = 0\n",
    "calibration_coeff = 1.0\n",
    "\n",
    "input_test_dir = Path(\"/data/psp/winnip_cpsp/C3\")\n",
    "incidence_angle_file = Path(\"/data/psp/winnip_cpsp/incidence_angle_ml5x5_rad.bin\")\n",
    "file_out = Path(\"/data/psp/res/test_dubois_surface_inversion_winnip_python.nc\")\n",
    "file_out.parent.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "print(f\"Using Dubois frequency: {freq_ghz:.6f} GHz\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load C3 input and C GUI reference outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "C3 = read_C3_psp(input_test_dir)\n",
    "row_dim, col_dim = C3.dims\n",
    "\n",
    "incidence_angle_values = np.fromfile(\n",
    "    incidence_angle_file,\n",
    "    dtype=\"<f4\",\n",
    "    count=C3.sizes[row_dim] * C3.sizes[col_dim],\n",
    ")\n",
    "incidence_angle_values[incidence_angle_values == -10000] = np.nan\n",
    "incidence_angle = xr.DataArray(\n",
    "    incidence_angle_values.reshape(C3.sizes[row_dim], C3.sizes[col_dim]),\n",
    "    dims=(row_dim, col_dim),\n",
    "    coords={row_dim: C3.coords[row_dim], col_dim: C3.coords[col_dim]},\n",
    "    name=\"incidence_angle\",\n",
    ")\n",
    "\n",
    "out_c = {}\n",
    "for name in (\n",
    "    \"dubois_er\",\n",
    "    \"dubois_mv\",\n",
    "    \"dubois_ks\",\n",
    "    \"dubois_mask_out\",\n",
    "    \"dubois_mask_in\",\n",
    "    \"dubois_mask_valid_in_out\",\n",
    "):\n",
    "    out_c[name] = read_psp_bin(input_test_dir / f\"{name}.bin\")\n",
    "\n",
    "print(f\"Loaded C3 input with shape {C3.sizes[row_dim]} x {C3.sizes[col_dim]}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Incidence Angle\n",
    "\n",
    "Plot the multilooked incidence angle raster used by both the Python and C GUI runs.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "incidence_angle_fig = incidence_angle.transpose(*reversed(incidence_angle.dims))\n",
    "\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.imshow(incidence_angle_fig, cmap=\"viridis\", interpolation=\"none\")\n",
    "plt.title(\"Incidence angle (transposed for display)\")\n",
    "plt.axis(\"off\")\n",
    "plt.colorbar(fraction=0.046, pad=0.04, location=\"bottom\")\n",
    "plt.tight_layout()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run the Python inversion"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if file_out.exists():\n",
    "    file_out.unlink()\n",
    "\n",
    "with ProgressBar():\n",
    "    out_py = dubois_surface_inversion(\n",
    "        C3,\n",
    "        incidence_angle=incidence_angle,\n",
    "        freq_ghz=freq_ghz,\n",
    "        thresh1=thresh1_db,\n",
    "        thresh2=thresh2_db,\n",
    "        calibration_coeff=calibration_coeff,\n",
    "    )\n",
    "    out_py.to_netcdf(file_out)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Compare Python and C GUI outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = summarize_metrics(out_py, out_c, short_titles=False, verbose=False)\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Use transposed views for plotting so x and y are swapped in the figures.\n",
    "out_py_fig = out_py.transpose(\"x\", \"y\")\n",
    "out_c_fig = {name: arr.T for name, arr in out_c.items()}\n",
    "\n",
    "visualize_errors(out_py=out_py_fig, out_c=out_c_fig, sub_az=1, sub_rg=1)\n"
   ]
  }
 ],
 "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.12.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
