{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0056702d",
   "metadata": {},
   "source": [
    "# Getting started"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "053cf91e",
   "metadata": {},
   "source": [
    "This tutorial introduces some basic concepts required to use this new version of PolSARpro in python.\n",
    "\n",
    "It is important to note that the toolbox relies on Xarray. Here we only describe the basics required to run PolSARpro and refer the reader to https://docs.xarray.dev/en/stable/ for more details."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1df4ba39",
   "metadata": {},
   "source": [
    "## Loading data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2c7b602",
   "metadata": {},
   "source": [
    "First we need to import some data. The demo dataset (TODO: host the data somewhere) has been prepared using SNAP and exported in the NetCDF-BEAM. NetCDF is the format recommended by Xarray as they the same data model.\n",
    "\n",
    "Let's first open the data using the `open_netcdf_beam` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7245ed40",
   "metadata": {},
   "outputs": [],
   "source": [
    "from polsarpro.io import open_netcdf_beam\n",
    "from pathlib import Path\n",
    "\n",
    "# change to your data path\n",
    "data_path = Path(\"/data/psp/test_files/SAN_FRANCISCO_ALOS1_slc.nc\")\n",
    "out_path =  Path(\"/data/psp/res\")\n",
    "S = open_netcdf_beam(data_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c3ed740",
   "metadata": {},
   "source": [
    "### Note\n",
    "\n",
    "Currently, this function is able to recognize and open the following data types: Sinclair matrix `S`, covariance matrices `C3`, `C4` and `C2` as well as coherency matrices `T3` and `T4`. Preparation of polarimetric data using SNAP is out of the scope of this tutorial and may be found here: https://step.esa.int/docs/tutorials/S1TBX%20Polarimetry%20with%20Radarsat-2%20Tutorial_v2.pdf \n",
    "\n",
    "Once the data has been prepared in SNAP, it should be exported in NetCDF-BEAM format from the `File > Export` menu to be opened in PolSARpro.  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80d749ae",
   "metadata": {},
   "source": [
    "## Inspect data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b703e35",
   "metadata": {},
   "source": [
    "The variable `S` has been recognized by the reader as a 2x2 Sinclair matrix. It has been imported in a data structure called `xarray.Dataset`. \n",
    "In a jupyter notebook it may be inspected as:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2089c525",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(S)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c7a5ff66",
   "metadata": {},
   "source": [
    "Each polarimetric channel is represented by a data variable and may be accessed using the following dot notation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "067e8d24",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Access to the hh polarization channel\n",
    "print(S.hh)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "834456d5",
   "metadata": {},
   "source": [
    "## Convert S to T3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "058017ee",
   "metadata": {},
   "source": [
    "Each variable is a dask array divided into smaller chunks, enabling parallel processing.\n",
    "Please note that the data is not loaded into memory at this point. This is called lazy loading and allows to execute processing only when the result is required.\n",
    "\n",
    "More information on lazy operations may be found here:https://docs.xarray.dev/en/latest/internals/internal-design.html#lazy-indexing-classes\n",
    "\n",
    "To convert the S matrix to other types, we may use utility functions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ced6ed3a",
   "metadata": {},
   "outputs": [],
   "source": [
    "from polsarpro.util import S_to_T3\n",
    "\n",
    "T3 = S_to_T3(S)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "560123e5",
   "metadata": {},
   "source": [
    "Let's now look at this new variable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "efd30af2",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(T3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d842b60b",
   "metadata": {},
   "source": [
    "The output has been automatically converted to a new polarimetric type `T3` representing the coherency matrix. Now the elements of the matrix are accessed as:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d743b0cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(T3.m12)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5268e0e",
   "metadata": {},
   "source": [
    "For storage optimization, PolSARpro takes advantage of the Hermitian structure of the matrix and stores only diagonal and upper elements."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f2a36cc4",
   "metadata": {},
   "source": [
    "To ensure its algorithms are applied to valid polarimetric types, PolSARpro looks for a `poltype` \"attribute\" -- which is a kind of metadata attached to the dataset, and may be accessed as:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "604b972d",
   "metadata": {},
   "outputs": [],
   "source": [
    "T3.poltype"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed33aea3",
   "metadata": {},
   "source": [
    "A human readable description may also be accessed as:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eb698709",
   "metadata": {},
   "outputs": [],
   "source": [
    "T3.description"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7145a4db",
   "metadata": {},
   "source": [
    "## Compute the results"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ec4664d",
   "metadata": {},
   "source": [
    "To compute the actual result and load the data into memory, we may simply use:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "976d239a",
   "metadata": {},
   "outputs": [],
   "source": [
    "T3 = T3.compute()\n",
    "print(T3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "05fe5ccd",
   "metadata": {},
   "source": [
    "## Crop, convert and save matrices\n",
    "\n",
    "Now, each variable is a numpy array stored in memory.  \n",
    "\n",
    "Lazy loading allows to define complex processing pipelines without storing intermediate variables in memory. It is even possible to write the result to disk without storing the whole data in memory. For instance one may define:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a3b417f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "from polsarpro.util import boxcar\n",
    "from polsarpro.io import polmat_to_netcdf\n",
    "\n",
    "# crop the data using the isel accessor, re-chunk to avoid errors when writing zarr\n",
    "S_crop = S.isel(y=slice(5000, 12000)).chunk(\"auto\")\n",
    "T3 = S_to_T3(S_crop)\n",
    "\n",
    "# save to a file with a custom function \n",
    "# that preserves chunks and handles complex valued matrices\n",
    "polmat_to_netcdf(boxcar(T3, 5, 5), out_path / \"T3_crop_box_5x5.nc\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50a569e8",
   "metadata": {},
   "source": [
    "## Apply the H/A/Alpha decomposition"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9c1f15c",
   "metadata": {},
   "source": [
    "Now let's apply the H/A/Alpha decomposition to our S matrix and\n",
    "write the result to a NetCDF file:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "62f28093",
   "metadata": {},
   "outputs": [],
   "source": [
    "from polsarpro.decompositions import h_a_alpha\n",
    "from dask.diagnostics import ProgressBar\n",
    "\n",
    "# optional progress bar to monitor the process\n",
    "with ProgressBar():\n",
    "    h_a_alpha(S_crop, boxcar_size=[5, 5]).to_netcdf(out_path / \"h_a_alpha.nc\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da5f1d6e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import xarray as xr\n",
    "# Let's open the file we have written\n",
    "res = xr.open_dataset(out_path / \"h_a_alpha.nc\")\n",
    "print(res)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf357145",
   "metadata": {},
   "source": [
    "As we can see, the new dataset has a specific `poltype` and stores the output parameters into labeled variables. As previously they can be accessed via the dot notation e.g. `res.alpha`.\n",
    "We can now plot the outputs either using matplotlib or xarray plotting capabilities:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "064da891",
   "metadata": {},
   "source": [
    "## Visualize the results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1b33770f",
   "metadata": {},
   "outputs": [],
   "source": [
    "res.alpha.plot.imshow()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a820f14",
   "metadata": {},
   "outputs": [],
   "source": [
    "res.entropy.plot.imshow()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f872fba",
   "metadata": {},
   "outputs": [],
   "source": [
    "res.anisotropy.plot.imshow()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da4efbd7",
   "metadata": {},
   "source": [
    "Additionally, we can plot points in the H/Alpha plane and save the result as an image:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5d0f5089",
   "metadata": {},
   "outputs": [],
   "source": [
    "from polsarpro.util import plot_h_alpha_plane\n",
    "ax, fig = plot_h_alpha_plane(res, bins=400, min_pts=5)\n",
    "fig.savefig(out_path / \"h_a_alpha_plane.png\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "psp",
   "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.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
