From 5ec5f6922ce6321b4a8a5f323f01de72bc1f4f8e Mon Sep 17 00:00:00 2001 From: Hadrien Mariaccia <hadrienmariaccia@gmail.com> Date: Tue, 9 Apr 2024 10:32:36 +0200 Subject: [PATCH] clean doc --- .github/workflows/documentation.yml | 27 + docs/.buildinfo | 4 - docs/Makefile | 20 - docs/_modules/deepdespeckling/denoiser.html | 188 --- .../_modules/deepdespeckling/despeckling.html | 256 ---- .../merlin/merlin_denoiser.html | 396 ------- docs/_modules/deepdespeckling/model.html | 240 ---- .../sar2sar/sar2sar_denoiser.html | 320 ----- .../deepdespeckling/utils/load_cosar.html | 183 --- .../_modules/deepdespeckling/utils/utils.html | 728 ------------ docs/_modules/index.html | 105 -- docs/_sources/index.rst.txt | 22 - docs/_sources/modules.rst.txt | 72 -- docs/_static/alabaster.css | 708 ----------- docs/_static/basic.css | 925 --------------- docs/_static/custom.css | 1 - docs/_static/doctools.js | 156 --- docs/_static/documentation_options.js | 13 - docs/_static/file.png | Bin 286 -> 0 bytes docs/_static/language_data.js | 199 ---- docs/_static/minus.png | Bin 90 -> 0 bytes docs/_static/plus.png | Bin 90 -> 0 bytes docs/_static/pygments.css | 84 -- docs/_static/searchtools.js | 574 --------- docs/_static/sphinx_highlight.js | 154 --- docs/build/doctrees/environment.pickle | Bin 551506 -> 0 bytes docs/build/doctrees/index.doctree | Bin 5034 -> 0 bytes docs/build/doctrees/modules.doctree | Bin 334144 -> 0 bytes docs/genindex.html | 389 ------- docs/index.html | 172 --- docs/make.bat | 35 - docs/modules.html | 1033 ----------------- docs/objects.inv | Bin 809 -> 0 bytes docs/py-modindex.html | 153 --- docs/search.html | 122 -- docs/searchindex.js | 1 - 36 files changed, 27 insertions(+), 7253 deletions(-) create mode 100644 .github/workflows/documentation.yml delete mode 100644 docs/.buildinfo delete mode 100644 docs/Makefile delete mode 100644 docs/_modules/deepdespeckling/denoiser.html delete mode 100644 docs/_modules/deepdespeckling/despeckling.html delete mode 100644 docs/_modules/deepdespeckling/merlin/merlin_denoiser.html delete mode 100644 docs/_modules/deepdespeckling/model.html delete mode 100644 docs/_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html delete mode 100644 docs/_modules/deepdespeckling/utils/load_cosar.html delete mode 100644 docs/_modules/deepdespeckling/utils/utils.html delete mode 100644 docs/_modules/index.html delete mode 100644 docs/_sources/index.rst.txt delete mode 100644 docs/_sources/modules.rst.txt delete mode 100644 docs/_static/alabaster.css delete mode 100644 docs/_static/basic.css delete mode 100644 docs/_static/custom.css delete mode 100644 docs/_static/doctools.js delete mode 100644 docs/_static/documentation_options.js delete mode 100644 docs/_static/file.png delete mode 100644 docs/_static/language_data.js delete mode 100644 docs/_static/minus.png delete mode 100644 docs/_static/plus.png delete mode 100644 docs/_static/pygments.css delete mode 100644 docs/_static/searchtools.js delete mode 100644 docs/_static/sphinx_highlight.js delete mode 100644 docs/build/doctrees/environment.pickle delete mode 100644 docs/build/doctrees/index.doctree delete mode 100644 docs/build/doctrees/modules.doctree delete mode 100644 docs/genindex.html delete mode 100644 docs/index.html delete mode 100644 docs/make.bat delete mode 100644 docs/modules.html delete mode 100644 docs/objects.inv delete mode 100644 docs/py-modindex.html delete mode 100644 docs/search.html delete mode 100644 docs/searchindex.js diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000..56cd0de --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,27 @@ +name: documentation + +on: [push, pull_request, workflow_dispatch] + +permissions: + contents: write + +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - name: Install dependencies + run: | + pip install sphinx sphinx_rtd_theme myst_parser + - name: Sphinx build + run: | + sphinx-build doc _build + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + with: + publish_branch: documentation_page + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: _build/ + force_orphan: true \ No newline at end of file diff --git a/docs/.buildinfo b/docs/.buildinfo deleted file mode 100644 index f329a33..0000000 --- a/docs/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: a0064967e4db7d108cafad9366e2bc15 -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d0c3cbf..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_modules/deepdespeckling/denoiser.html b/docs/_modules/deepdespeckling/denoiser.html deleted file mode 100644 index b22fcda..0000000 --- a/docs/_modules/deepdespeckling/denoiser.html +++ /dev/null @@ -1,188 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="../../"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>deepdespeckling.denoiser — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="../../_static/alabaster.css?v=12dfc556" /> - <script src="../../_static/documentation_options.js?v=cb255500"></script> - <script src="../../_static/doctools.js?v=888ff710"></script> - <script src="../../_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="../../genindex.html" /> - <link rel="search" title="Search" href="../../search.html" /> - - <link rel="stylesheet" href="../../_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <h1>Source code for deepdespeckling.denoiser</h1><div class="highlight"><pre> -<span></span><span class="kn">import</span> <span class="nn">logging</span> -<span class="kn">import</span> <span class="nn">torch</span> -<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span> - - -<div class="viewcode-block" id="Denoiser"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.denoiser.Denoiser">[docs]</a> -<span class="k">class</span> <span class="nc">Denoiser</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Class to share parameters beyond denoising functions</span> -<span class="sd"> """</span> - - <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="bp">self</span><span class="o">.</span><span class="n">device</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_device</span><span class="p">()</span> - -<div class="viewcode-block" id="Denoiser.get_device"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.denoiser.Denoiser.get_device">[docs]</a> - <span class="k">def</span> <span class="nf">get_device</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Get torch device to use depending on gpu's availability</span> - -<span class="sd"> Returns:</span> -<span class="sd"> device (str): device to be used by torch</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="n">torch</span><span class="o">.</span><span class="n">backends</span><span class="o">.</span><span class="n">mps</span><span class="o">.</span><span class="n">is_available</span><span class="p">()</span> <span class="ow">and</span> <span class="n">torch</span><span class="o">.</span><span class="n">backends</span><span class="o">.</span><span class="n">mps</span><span class="o">.</span><span class="n">is_built</span><span class="p">():</span> - <span class="n">device</span> <span class="o">=</span> <span class="s2">"mps"</span> - <span class="k">elif</span> <span class="n">torch</span><span class="o">.</span><span class="n">cuda</span><span class="o">.</span><span class="n">is_available</span><span class="p">():</span> - <span class="n">device</span> <span class="o">=</span> <span class="s2">"cuda:0"</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">device</span> <span class="o">=</span> <span class="s2">"cpu"</span> - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">device</span><span class="si">}</span><span class="s2"> device is used by torch"</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">device</span></div> - - -<div class="viewcode-block" id="Denoiser.initialize_axis_range"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.denoiser.Denoiser.initialize_axis_range">[docs]</a> - <span class="k">def</span> <span class="nf">initialize_axis_range</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_axis_dim</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="nb">list</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Initialize the convolution range for x or y axis</span> - -<span class="sd"> Args:</span> -<span class="sd"> image_axis_dim (int): axis size</span> -<span class="sd"> patch_size (int): patch size</span> -<span class="sd"> stride_size (int): stride size</span> - -<span class="sd"> Returns:</span> -<span class="sd"> axis_range (list) : pixel borders of each convolution</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="n">image_axis_dim</span> <span class="o">==</span> <span class="n">patch_size</span><span class="p">:</span> - <span class="n">axis_range</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">]))</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">axis_range</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span> - <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">image_axis_dim</span> <span class="o">-</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">))</span> - <span class="k">if</span> <span class="p">(</span><span class="n">axis_range</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">)</span> <span class="o"><</span> <span class="n">image_axis_dim</span><span class="p">:</span> - <span class="n">axis_range</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span> - <span class="nb">range</span><span class="p">(</span><span class="n">image_axis_dim</span> <span class="o">-</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">image_axis_dim</span> <span class="o">-</span> <span class="n">patch_size</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span> - - <span class="k">return</span> <span class="n">axis_range</span></div> - - -<div class="viewcode-block" id="Denoiser.save_despeckled_images"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.denoiser.Denoiser.save_despeckled_images">[docs]</a> - <span class="k">def</span> <span class="nf">save_despeckled_images</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="k">raise</span> <span class="ne">NotImplementedError</span></div> - - -<div class="viewcode-block" id="Denoiser.denoise_image_kernel"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.denoiser.Denoiser.denoise_image_kernel">[docs]</a> - <span class="k">def</span> <span class="nf">denoise_image_kernel</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="k">raise</span> <span class="ne">NotImplementedError</span></div> - - -<div class="viewcode-block" id="Denoiser.preprocess_denoised_image"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.denoiser.Denoiser.preprocess_denoised_image">[docs]</a> - <span class="k">def</span> <span class="nf">preprocess_denoised_image</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="k">raise</span> <span class="ne">NotImplementedError</span></div> - - -<div class="viewcode-block" id="Denoiser.denoise_image"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.denoiser.Denoiser.denoise_image">[docs]</a> - <span class="k">def</span> <span class="nf">denoise_image</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="k">raise</span> <span class="ne">NotImplementedError</span></div> - - -<div class="viewcode-block" id="Denoiser.denoise_images"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.denoiser.Denoiser.denoise_images">[docs]</a> - <span class="k">def</span> <span class="nf">denoise_images</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="k">raise</span> <span class="ne">NotImplementedError</span></div> -</div> - -</pre></div> - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="../../index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="../../modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="../../index.html">Documentation overview</a><ul> - <li><a href="../index.html">Module code</a><ul> - </ul></li> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="../../search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/_modules/deepdespeckling/despeckling.html b/docs/_modules/deepdespeckling/despeckling.html deleted file mode 100644 index ac535a3..0000000 --- a/docs/_modules/deepdespeckling/despeckling.html +++ /dev/null @@ -1,256 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="../../"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>deepdespeckling.despeckling — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="../../_static/alabaster.css?v=12dfc556" /> - <script src="../../_static/documentation_options.js?v=cb255500"></script> - <script src="../../_static/doctools.js?v=888ff710"></script> - <script src="../../_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="../../genindex.html" /> - <link rel="search" title="Search" href="../../search.html" /> - - <link rel="stylesheet" href="../../_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <h1>Source code for deepdespeckling.despeckling</h1><div class="highlight"><pre> -<span></span><span class="kn">import</span> <span class="nn">logging</span> -<span class="kn">import</span> <span class="nn">os</span> -<span class="kn">from</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="n">glob</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.denoiser</span> <span class="kn">import</span> <span class="n">Denoiser</span> - -<span class="kn">from</span> <span class="nn">deepdespeckling.merlin.merlin_denoiser</span> <span class="kn">import</span> <span class="n">MerlinDenoiser</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.sar2sar.sar2sar_denoiser</span> <span class="kn">import</span> <span class="n">Sar2SarDenoiser</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.utils.constants</span> <span class="kn">import</span> <span class="n">PATCH_SIZE</span><span class="p">,</span> <span class="n">STRIDE_SIZE</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.utils.utils</span> <span class="kn">import</span> <span class="p">(</span><span class="n">crop_image</span><span class="p">,</span> <span class="n">get_cropping_coordinates</span><span class="p">,</span> <span class="n">load_sar_image</span><span class="p">,</span> <span class="n">preprocess_and_store_sar_images_from_coordinates</span><span class="p">,</span> - <span class="n">create_empty_folder_in_directory</span><span class="p">,</span> <span class="n">preprocess_and_store_sar_images</span><span class="p">)</span> - - -<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span> - - -<div class="viewcode-block" id="get_denoiser"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.despeckling.get_denoiser">[docs]</a> -<span class="k">def</span> <span class="nf">get_denoiser</span><span class="p">(</span><span class="n">model_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">symetrise</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="n">Denoiser</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Get the right denoiser object from the model name</span> - -<span class="sd"> Args:</span> -<span class="sd"> model_name (str): model name to be use for despeckling </span> -<span class="sd"> symetrise (bool) : if using spotlight or stripmap model, if True, will symetrise the real and </span> -<span class="sd"> imaginary parts of the noisy image. Defaults to True</span> - -<span class="sd"> Returns:</span> -<span class="sd"> denoiser (Denoiser): the right denoiser, Sar2SarDenoiser or MerlinDenoiser</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="n">model_name</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"spotlight"</span><span class="p">,</span> <span class="s2">"stripmap"</span><span class="p">]:</span> - <span class="n">denoiser</span> <span class="o">=</span> <span class="n">MerlinDenoiser</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="n">model_name</span><span class="p">,</span> <span class="n">symetrise</span><span class="o">=</span><span class="n">symetrise</span><span class="p">)</span> - <span class="k">elif</span> <span class="n">model_name</span> <span class="o">==</span> <span class="s2">"sar2sar"</span><span class="p">:</span> - <span class="n">denoiser</span> <span class="o">=</span> <span class="n">Sar2SarDenoiser</span><span class="p">()</span> - <span class="k">else</span><span class="p">:</span> - <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"The model name doesn't refer to an existing model "</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">denoiser</span></div> - - - -<div class="viewcode-block" id="despeckle"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.despeckling.despeckle">[docs]</a> -<span class="k">def</span> <span class="nf">despeckle</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">destination_directory_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">model_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"spotlight"</span><span class="p">,</span> - <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">PATCH_SIZE</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">STRIDE_SIZE</span><span class="p">,</span> <span class="n">symetrise</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Despeckle coSAR images using trained MERLIN (spotlight or stripmap weights) or SAR2SAR</span> - -<span class="sd"> Args:</span> -<span class="sd"> sar_images_path (str): path of sar images</span> -<span class="sd"> destination_directory_path (str): path of folder in which results will be stored</span> -<span class="sd"> model_name (str): model name, either "spotlight" or "stripmap" to select MERLIN model on the </span> -<span class="sd"> right cosar image format or "sar2sar" for SAR2SAR model. Default to "spotlight"</span> -<span class="sd"> patch_size (int): patch size. Defaults to constant PATCH_SIZE.</span> -<span class="sd"> stride_size (int): stride size. Defaults to constant STRIDE_SIZE.</span> -<span class="sd"> symetrise (bool) : if using spotlight or stripmap model, if True, will symetrise the real and </span> -<span class="sd"> imaginary parts of the noisy image. Defaults to True</span> -<span class="sd"> """</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"""Despeckling entire images using </span><span class="si">{</span><span class="n">model_name</span><span class="si">}</span><span class="s2"> weights"""</span><span class="p">)</span> - - <span class="n">processed_images_path</span> <span class="o">=</span> <span class="n">create_empty_folder_in_directory</span><span class="p">(</span><span class="n">destination_directory_path</span><span class="o">=</span><span class="n">destination_directory_path</span><span class="p">,</span> - <span class="n">folder_name</span><span class="o">=</span><span class="s2">"processed_images"</span><span class="p">)</span> - <span class="n">preprocess_and_store_sar_images</span><span class="p">(</span> - <span class="n">sar_images_path</span><span class="o">=</span><span class="n">sar_images_path</span><span class="p">,</span> <span class="n">processed_images_path</span><span class="o">=</span><span class="n">processed_images_path</span><span class="p">,</span> <span class="n">model_name</span><span class="o">=</span><span class="n">model_name</span><span class="p">)</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"Starting inference.. Collecting data from </span><span class="si">{</span><span class="n">sar_images_path</span><span class="si">}</span><span class="s2"> and storing test results in </span><span class="si">{</span><span class="n">destination_directory_path</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> - - <span class="n">denoiser</span> <span class="o">=</span> <span class="n">get_denoiser</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="n">model_name</span><span class="p">,</span> <span class="n">symetrise</span><span class="o">=</span><span class="n">symetrise</span><span class="p">)</span> - <span class="n">denoiser</span><span class="o">.</span><span class="n">denoise_images</span><span class="p">(</span><span class="n">images_to_denoise_path</span><span class="o">=</span><span class="n">processed_images_path</span><span class="p">,</span> <span class="n">save_dir</span><span class="o">=</span><span class="n">destination_directory_path</span><span class="p">,</span> - <span class="n">patch_size</span><span class="o">=</span><span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="o">=</span><span class="n">stride_size</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="despeckle_from_coordinates"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.despeckling.despeckle_from_coordinates">[docs]</a> -<span class="k">def</span> <span class="nf">despeckle_from_coordinates</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">coordinates_dict</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span> <span class="n">destination_directory_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">model_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"spotlight"</span><span class="p">,</span> - <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">PATCH_SIZE</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">STRIDE_SIZE</span><span class="p">,</span> <span class="n">symetrise</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Despeckle specified area with coordinates in coSAR images using trained MERLIN (spotlight or stripmap weights)</span> - -<span class="sd"> Args:</span> -<span class="sd"> sar_images_path (str): path of sar images</span> -<span class="sd"> coordinates_dict (dict): dictionary containing pixel boundaries of the area to despeckle (x_start, x_end, y_start, y_end)</span> -<span class="sd"> destination_directory_path (str): path of folder in which results will be stored</span> -<span class="sd"> model_name (str): model name, either "spotlight" or "stripmap" to select MERLIN model on the </span> -<span class="sd"> right cosar image format or "sar2sar" for SAR2SAR model. Default to "spotlight"</span> -<span class="sd"> patch_size (int): patch size. Defaults to constant PATCH_SIZE.</span> -<span class="sd"> stride_size (int): stride size. Defaults to constant STRIDE_SIZE.</span> -<span class="sd"> symetrise (bool) : if using spotlight or stripmap model, if True, will symetrise the real and </span> -<span class="sd"> imaginary parts of the noisy image. Defaults to True</span> -<span class="sd"> """</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"""Despeckling images from coordinates using </span><span class="si">{</span><span class="n">model_name</span><span class="si">}</span><span class="s2"> weights"""</span><span class="p">)</span> - - <span class="n">processed_images_path</span> <span class="o">=</span> <span class="n">create_empty_folder_in_directory</span><span class="p">(</span><span class="n">destination_directory_path</span><span class="o">=</span><span class="n">destination_directory_path</span><span class="p">,</span> - <span class="n">folder_name</span><span class="o">=</span><span class="s2">"processed_images"</span><span class="p">)</span> - <span class="n">preprocess_and_store_sar_images_from_coordinates</span><span class="p">(</span><span class="n">sar_images_path</span><span class="o">=</span><span class="n">sar_images_path</span><span class="p">,</span> <span class="n">processed_images_path</span><span class="o">=</span><span class="n">processed_images_path</span><span class="p">,</span> - <span class="n">coordinates_dict</span><span class="o">=</span><span class="n">coordinates_dict</span><span class="p">,</span> <span class="n">model_name</span><span class="o">=</span><span class="n">model_name</span><span class="p">)</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"Starting inference.. Collecting data from </span><span class="si">{</span><span class="n">sar_images_path</span><span class="si">}</span><span class="s2"> and storing test results in </span><span class="si">{</span><span class="n">destination_directory_path</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> - - <span class="n">denoiser</span> <span class="o">=</span> <span class="n">get_denoiser</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="n">model_name</span><span class="p">,</span> <span class="n">symetrise</span><span class="o">=</span><span class="n">symetrise</span><span class="p">)</span> - <span class="n">denoiser</span><span class="o">.</span><span class="n">denoise_images</span><span class="p">(</span><span class="n">images_to_denoise_path</span><span class="o">=</span><span class="n">processed_images_path</span><span class="p">,</span> <span class="n">save_dir</span><span class="o">=</span><span class="n">destination_directory_path</span><span class="p">,</span> - <span class="n">patch_size</span><span class="o">=</span><span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="o">=</span><span class="n">stride_size</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="despeckle_from_crop"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.despeckling.despeckle_from_crop">[docs]</a> -<span class="k">def</span> <span class="nf">despeckle_from_crop</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">destination_directory_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">model_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"spotlight"</span><span class="p">,</span> - <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">PATCH_SIZE</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">STRIDE_SIZE</span><span class="p">,</span> <span class="n">fixed</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">symetrise</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Despeckle specified area with an integrated cropping tool (made with OpenCV) in coSAR images using trained MERLIN (spotlight or stripmap weights)</span> - -<span class="sd"> Args:</span> -<span class="sd"> sar_images_path (str): path of sar images</span> -<span class="sd"> destination_directory_path (str): path of folder in which results will be stored</span> -<span class="sd"> patch_size (int): patch size. Defaults to constant PATCH_SIZE.</span> -<span class="sd"> stride_size (int): stride size. Defaults to constant STRIDE_SIZE.</span> -<span class="sd"> model_name (str): model name, either "spotlight" or "stripmap" to select MERLIN model on the </span> -<span class="sd"> right cosar image format or "sar2sar" for SAR2SAR model. Default to "spotlight"</span> -<span class="sd"> fixed (bool) : If True, crop size is limited to 256*256. Defaults to True</span> -<span class="sd"> symetrise (bool) : if using spotlight or stripmap model, if True, will symetrise the real and </span> -<span class="sd"> imaginary parts of the noisy image. Defaults to True</span> -<span class="sd"> """</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"""Cropping and despeckling images using </span><span class="si">{</span><span class="n">model_name</span><span class="si">}</span><span class="s2"> weights"""</span><span class="p">)</span> - - <span class="n">processed_images_path</span> <span class="o">=</span> <span class="n">create_empty_folder_in_directory</span><span class="p">(</span><span class="n">destination_directory_path</span><span class="o">=</span><span class="n">destination_directory_path</span><span class="p">,</span> - <span class="n">folder_name</span><span class="o">=</span><span class="s2">"processed_images"</span><span class="p">)</span> - - <span class="n">ext</span> <span class="o">=</span> <span class="s2">"cos"</span> <span class="k">if</span> <span class="n">model_name</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"spotlight"</span><span class="p">,</span> <span class="s2">"stripmap"</span><span class="p">]</span> <span class="k">else</span> <span class="s2">"tiff"</span> - <span class="n">images_paths</span> <span class="o">=</span> <span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"*.</span><span class="si">{</span><span class="n">ext</span><span class="si">}</span><span class="s2">"</span><span class="p">))</span> <span class="o">+</span> \ - <span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">,</span> <span class="s2">"*.npy"</span><span class="p">))</span> - - <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">image_path</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">images_paths</span><span class="p">):</span> - <span class="c1"># Load image for cropping</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">load_sar_image</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span> - - <span class="c1"># Get cropping coordinates from the first image of the list of images to crop and despeckle</span> - <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> - <span class="n">cropping_coordinates</span> <span class="o">=</span> <span class="n">get_cropping_coordinates</span><span class="p">(</span> - <span class="n">image</span><span class="o">=</span><span class="n">image</span><span class="p">,</span> <span class="n">fixed</span><span class="o">=</span><span class="n">fixed</span><span class="p">,</span> <span class="n">destination_directory_path</span><span class="o">=</span><span class="n">destination_directory_path</span><span class="p">,</span> <span class="n">model_name</span><span class="o">=</span><span class="n">model_name</span><span class="p">)</span> - - <span class="c1"># Crop image using stored cropping coordinates and store it in processed_images_path</span> - <span class="n">crop_image</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="n">image_path</span><span class="p">,</span> <span class="n">cropping_coordinates</span><span class="p">,</span> <span class="n">model_name</span><span class="p">,</span> - <span class="n">processed_images_path</span><span class="p">)</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"Starting inference.. Collecting data from </span><span class="si">{</span><span class="n">sar_images_path</span><span class="si">}</span><span class="s2"> and storing results in </span><span class="si">{</span><span class="n">destination_directory_path</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> - - <span class="n">denoiser</span> <span class="o">=</span> <span class="n">get_denoiser</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="n">model_name</span><span class="p">,</span> <span class="n">symetrise</span><span class="o">=</span><span class="n">symetrise</span><span class="p">)</span> - <span class="n">denoiser</span><span class="o">.</span><span class="n">denoise_images</span><span class="p">(</span><span class="n">images_to_denoise_path</span><span class="o">=</span><span class="n">processed_images_path</span><span class="p">,</span> <span class="n">save_dir</span><span class="o">=</span><span class="n">destination_directory_path</span><span class="p">,</span> - <span class="n">patch_size</span><span class="o">=</span><span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="o">=</span><span class="n">stride_size</span><span class="p">)</span></div> - -</pre></div> - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="../../index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="../../modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="../../index.html">Documentation overview</a><ul> - <li><a href="../index.html">Module code</a><ul> - </ul></li> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="../../search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/_modules/deepdespeckling/merlin/merlin_denoiser.html b/docs/_modules/deepdespeckling/merlin/merlin_denoiser.html deleted file mode 100644 index 1f3ffc0..0000000 --- a/docs/_modules/deepdespeckling/merlin/merlin_denoiser.html +++ /dev/null @@ -1,396 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="../../../"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>deepdespeckling.merlin.merlin_denoiser — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css?v=12dfc556" /> - <script src="../../../_static/documentation_options.js?v=cb255500"></script> - <script src="../../../_static/doctools.js?v=888ff710"></script> - <script src="../../../_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="../../../genindex.html" /> - <link rel="search" title="Search" href="../../../search.html" /> - - <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <h1>Source code for deepdespeckling.merlin.merlin_denoiser</h1><div class="highlight"><pre> -<span></span><span class="kn">from</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="n">glob</span> -<span class="kn">import</span> <span class="nn">logging</span> -<span class="kn">from</span> <span class="nn">pathlib</span> <span class="kn">import</span> <span class="n">Path</span> -<span class="kn">import</span> <span class="nn">torch</span> -<span class="kn">import</span> <span class="nn">os</span> -<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span> -<span class="kn">from</span> <span class="nn">tqdm</span> <span class="kn">import</span> <span class="n">tqdm</span> - -<span class="kn">from</span> <span class="nn">deepdespeckling.denoiser</span> <span class="kn">import</span> <span class="n">Denoiser</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.model</span> <span class="kn">import</span> <span class="n">Model</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.utils.constants</span> <span class="kn">import</span> <span class="n">M</span><span class="p">,</span> <span class="n">m</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.utils.utils</span> <span class="kn">import</span> <span class="p">(</span><span class="n">denormalize_sar_image</span><span class="p">,</span> <span class="n">load_sar_image</span><span class="p">,</span> <span class="n">save_image_to_npy_and_png</span><span class="p">,</span> - <span class="n">symetrise_real_and_imaginary_parts</span><span class="p">,</span> <span class="n">create_empty_folder_in_directory</span><span class="p">)</span> - -<span class="n">current_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="vm">__file__</span><span class="p">)</span> - - -<div class="viewcode-block" id="MerlinDenoiser"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser">[docs]</a> -<span class="k">class</span> <span class="nc">MerlinDenoiser</span><span class="p">(</span><span class="n">Denoiser</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Class to share parameters beyond denoising functions</span> -<span class="sd"> """</span> - - <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">model_name</span><span class="p">,</span> <span class="n">symetrise</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Initialize MerlinDenoiser class</span> - -<span class="sd"> Args:</span> -<span class="sd"> model_name (str): name to be used, can be "spotlight" or "stripmap"</span> -<span class="sd"> """</span> - <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">params</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">model_name</span> <span class="o">=</span> <span class="n">model_name</span> - <span class="bp">self</span><span class="o">.</span><span class="n">symetrise</span> <span class="o">=</span> <span class="n">symetrise</span> - <span class="bp">self</span><span class="o">.</span><span class="n">weights_path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">init_model_weights_path</span><span class="p">()</span> - -<div class="viewcode-block" id="MerlinDenoiser.init_model_weights_path"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.init_model_weights_path">[docs]</a> - <span class="k">def</span> <span class="nf">init_model_weights_path</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Get model weights path from model name</span> - -<span class="sd"> Returns:</span> -<span class="sd"> model_weights_path (str): the path of the weights of the specified model</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">model_name</span> <span class="o">==</span> <span class="s2">"spotlight"</span><span class="p">:</span> - <span class="n">model_weights_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> - <span class="n">current_dir</span><span class="p">,</span> <span class="s2">"saved_models/spotlight.pth"</span><span class="p">)</span> - <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">model_name</span> <span class="o">==</span> <span class="s2">"stripmap"</span><span class="p">:</span> - <span class="n">model_weights_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> - <span class="n">current_dir</span><span class="p">,</span> <span class="s2">"saved_models/stripmap.pth"</span><span class="p">)</span> - <span class="k">else</span><span class="p">:</span> - <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span> - <span class="s2">"The model name doesn't refer to an existing model "</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">model_weights_path</span></div> - - -<div class="viewcode-block" id="MerlinDenoiser.load_model"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.load_model">[docs]</a> - <span class="k">def</span> <span class="nf">load_model</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="n">Model</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Load model with given weights </span> - -<span class="sd"> Args:</span> -<span class="sd"> weights_path (str): path to weights </span> -<span class="sd"> patch_size (int): patch size</span> - -<span class="sd"> Returns:</span> -<span class="sd"> model (Model): model loaded with stored weights</span> -<span class="sd"> """</span> - <span class="n">model</span> <span class="o">=</span> <span class="n">Model</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">device</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">),</span> - <span class="n">height</span><span class="o">=</span><span class="n">patch_size</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="n">patch_size</span><span class="p">)</span> - <span class="n">model</span><span class="o">.</span><span class="n">load_state_dict</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">load</span><span class="p">(</span> - <span class="bp">self</span><span class="o">.</span><span class="n">weights_path</span><span class="p">,</span> <span class="n">map_location</span><span class="o">=</span><span class="n">torch</span><span class="o">.</span><span class="n">device</span><span class="p">(</span><span class="s2">"cpu"</span><span class="p">)))</span> - - <span class="k">return</span> <span class="n">model</span></div> - - -<div class="viewcode-block" id="MerlinDenoiser.save_despeckled_images"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.save_despeckled_images">[docs]</a> - <span class="k">def</span> <span class="nf">save_despeckled_images</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">despeckled_images</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span> <span class="n">image_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">save_dir</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Save full, real and imaginary part of noisy and denoised image stored in a dictionary in png to a given folder</span> - -<span class="sd"> Args:</span> -<span class="sd"> despeckled_images (dict): dictionary containing full, real and imaginary parts of noisy and denoised image</span> -<span class="sd"> image_name (str): name of the image</span> -<span class="sd"> save_dir (str): path to the folder where to save the png images</span> -<span class="sd"> """</span> - <span class="n">threshold</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span> - <span class="n">despeckled_images</span><span class="p">[</span><span class="s2">"noisy"</span><span class="p">][</span><span class="s2">"full"</span><span class="p">])</span> <span class="o">+</span> <span class="mi">3</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">std</span><span class="p">(</span><span class="n">despeckled_images</span><span class="p">[</span><span class="s2">"noisy"</span><span class="p">][</span><span class="s2">"full"</span><span class="p">])</span> - <span class="n">image_name</span> <span class="o">=</span> <span class="n">image_name</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\\</span><span class="s1">'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> - - <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">despeckled_images</span><span class="p">:</span> - <span class="n">create_empty_folder_in_directory</span><span class="p">(</span><span class="n">save_dir</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span> - <span class="k">for</span> <span class="n">key2</span> <span class="ow">in</span> <span class="n">despeckled_images</span><span class="p">[</span><span class="n">key</span><span class="p">]:</span> - <span class="n">save_image_to_npy_and_png</span><span class="p">(</span> - <span class="n">despeckled_images</span><span class="p">[</span><span class="n">key</span><span class="p">][</span><span class="n">key2</span><span class="p">],</span> <span class="n">save_dir</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"/</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">_</span><span class="si">{</span><span class="n">key2</span><span class="si">}</span><span class="s2">_"</span><span class="p">,</span> <span class="n">image_name</span><span class="p">,</span> <span class="n">threshold</span><span class="p">)</span></div> - - -<div class="viewcode-block" id="MerlinDenoiser.denoise_image_kernel"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image_kernel">[docs]</a> - <span class="k">def</span> <span class="nf">denoise_image_kernel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">noisy_image</span><span class="p">:</span> <span class="n">torch</span><span class="o">.</span><span class="n">tensor</span><span class="p">,</span> <span class="n">denoised_image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">x</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> - <span class="n">model</span><span class="p">:</span> <span class="n">Model</span><span class="p">,</span> <span class="n">normalisation_kernel</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Denoise a subpart of a given symetrised noisy image delimited by x, y and patch_size using a given model</span> - -<span class="sd"> Args:</span> -<span class="sd"> noisy_image (torch tensor): symetrised noisy image to denoise</span> -<span class="sd"> denoised_image (numpy array): symetrised partially denoised image</span> -<span class="sd"> x (int): x coordinate of current kernel to denoise</span> -<span class="sd"> y (int): y coordinate of current kernel to denoise</span> -<span class="sd"> patch_size (int): patch size</span> -<span class="sd"> model (Model): trained model with loaded weights </span> -<span class="sd"> normalisation_kernel (bool, optional): Determine if. Defaults to False.</span> - -<span class="sd"> Returns:</span> -<span class="sd"> denoised_image (numpy array): image denoised in the given coordinates and the ones already iterated</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="ow">not</span> <span class="n">normalisation_kernel</span><span class="p">:</span> - - <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span> <span class="o">!=</span> <span class="s1">'cpu'</span><span class="p">:</span> - <span class="n">tmp_clean_image</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">forward</span><span class="p">(</span> - <span class="n">noisy_image</span><span class="p">)</span><span class="o">.</span><span class="n">cpu</span><span class="p">()</span><span class="o">.</span><span class="n">detach</span><span class="p">()</span><span class="o">.</span><span class="n">numpy</span><span class="p">()</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">tmp_clean_image</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">forward</span><span class="p">(</span> - <span class="n">noisy_image</span><span class="p">)</span><span class="o">.</span><span class="n">detach</span><span class="p">()</span><span class="o">.</span><span class="n">numpy</span><span class="p">()</span> - - <span class="n">tmp_clean_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">moveaxis</span><span class="p">(</span><span class="n">tmp_clean_image</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> - <span class="n">denoised_image</span><span class="p">[:,</span> <span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">denoised_image</span><span class="p">[:,</span> <span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> - <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> - <span class="p">:]</span> <span class="o">+</span> <span class="n">tmp_clean_image</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">denoised_image</span><span class="p">[:,</span> <span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">denoised_image</span><span class="p">[:,</span> <span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> - <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> - <span class="p">:]</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> - <span class="k">return</span> <span class="n">denoised_image</span></div> - - -<div class="viewcode-block" id="MerlinDenoiser.preprocess_noisy_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_noisy_image">[docs]</a> - <span class="k">def</span> <span class="nf">preprocess_noisy_image</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">noisy_image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">]:</span> -<span class="w"> </span><span class="sd">"""preprocess a given noisy image and generates its real and imaginary parts</span> - -<span class="sd"> Args:</span> -<span class="sd"> noisy_image (numpy array): noisy image</span> - -<span class="sd"> Returns:</span> -<span class="sd"> noisy_image, noisy_image_real_part, noisy_image_imaginary_part (numpy array, numpy array, numpy array): </span> -<span class="sd"> preprocessed noisy image, real part of noisy image, imaginary part of noisy image</span> -<span class="sd"> """</span> - <span class="n">noisy_image_real_part</span> <span class="o">=</span> <span class="p">(</span><span class="n">noisy_image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">])</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">noisy_image</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">noisy_image</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> - <span class="n">noisy_image</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span> - <span class="n">noisy_image_imaginary_part</span> <span class="o">=</span> <span class="p">(</span><span class="n">noisy_image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="p">:,</span> <span class="mi">1</span><span class="p">])</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">noisy_image</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">noisy_image</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> - <span class="n">noisy_image</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span> - <span class="n">noisy_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span> - <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">noisy_image_real_part</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">+</span> <span class="n">noisy_image_imaginary_part</span> <span class="o">**</span> <span class="mi">2</span><span class="p">))</span> - - <span class="k">return</span> <span class="n">noisy_image</span><span class="p">,</span> <span class="n">noisy_image_real_part</span><span class="p">,</span> <span class="n">noisy_image_imaginary_part</span></div> - - -<div class="viewcode-block" id="MerlinDenoiser.preprocess_denoised_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_denoised_image">[docs]</a> - <span class="k">def</span> <span class="nf">preprocess_denoised_image</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">denoised_image_real_part</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">denoised_image_imaginary_part</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">count_image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">]:</span> -<span class="w"> </span><span class="sd">"""Preprocess given denoised real and imaginary parts of an image, and build the full denoised image</span> - -<span class="sd"> Args:</span> -<span class="sd"> denoised_image_real_part (numpy array): real part of a denoised image</span> -<span class="sd"> denoised_image_imaginary_part (numpy array): imaginary part of a denoised image</span> -<span class="sd"> count_image (numpy array): normalisation image used for denormalisation</span> - -<span class="sd"> Returns:</span> -<span class="sd"> denoised_image, denoised_image_real_part, denoised_image_imaginary_part (numpy array, numpy array, numpy array): </span> -<span class="sd"> processed denoised full image, processed denoised image real part, processed denoised image imaginary part</span> -<span class="sd"> """</span> - <span class="n">denoised_image_real_part</span> <span class="o">=</span> <span class="n">denormalize_sar_image</span><span class="p">(</span> - <span class="n">denoised_image_real_part</span> <span class="o">/</span> <span class="n">count_image</span><span class="p">)</span> - <span class="n">denoised_image_imaginary_part</span> <span class="o">=</span> <span class="n">denormalize_sar_image</span><span class="p">(</span> - <span class="n">denoised_image_imaginary_part</span> <span class="o">/</span> <span class="n">count_image</span><span class="p">)</span> - - <span class="c1"># combine the two estimation</span> - <span class="n">output_clean_image</span> <span class="o">=</span> <span class="mf">0.5</span> <span class="o">*</span> <span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">square</span><span class="p">(</span> - <span class="n">denoised_image_real_part</span><span class="p">)</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">square</span><span class="p">(</span><span class="n">denoised_image_imaginary_part</span><span class="p">))</span> - - <span class="n">denoised_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span><span class="n">output_clean_image</span><span class="p">))</span> - - <span class="k">return</span> <span class="n">denoised_image</span><span class="p">,</span> <span class="n">denoised_image_real_part</span><span class="p">,</span> <span class="n">denoised_image_imaginary_part</span></div> - - -<div class="viewcode-block" id="MerlinDenoiser.denoise_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image">[docs]</a> - <span class="k">def</span> <span class="nf">denoise_image</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">noisy_image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="nb">dict</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Preprocess and denoise a coSAR image using given model weights</span> - -<span class="sd"> Args:</span> -<span class="sd"> noisy_image (numpy array): numpy array containing the noisy image to despeckle </span> -<span class="sd"> patch_size (int): size of the patch of the convolution</span> -<span class="sd"> stride_size (int): number of pixels between one convolution to the next</span> - -<span class="sd"> Returns:</span> -<span class="sd"> despeckled_image (dict): noisy and denoised images</span> -<span class="sd"> """</span> - <span class="n">noisy_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">noisy_image</span><span class="p">)</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span> - <span class="mi">1</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">noisy_image</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">noisy_image</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span> - - <span class="c1"># Pad the image</span> - <span class="n">image_height</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">noisy_image</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> - <span class="n">image_width</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">noisy_image</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> - - <span class="n">noisy_image</span><span class="p">,</span> <span class="n">noisy_image_real_part</span><span class="p">,</span> <span class="n">noisy_image_imaginary_part</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">preprocess_noisy_image</span><span class="p">(</span> - <span class="n">noisy_image</span><span class="p">)</span> - - <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">load_model</span><span class="p">(</span><span class="n">patch_size</span><span class="o">=</span><span class="n">patch_size</span><span class="p">)</span> - - <span class="n">count_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">noisy_image_real_part</span><span class="o">.</span><span class="n">shape</span><span class="p">)</span> - <span class="n">denoised_image_real_part</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">noisy_image_real_part</span><span class="o">.</span><span class="n">shape</span><span class="p">)</span> - <span class="n">denoised_image_imaginary_part</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="n">noisy_image_real_part</span><span class="o">.</span><span class="n">shape</span><span class="p">)</span> - - <span class="n">x_range</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialize_axis_range</span><span class="p">(</span> - <span class="n">image_height</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">)</span> - <span class="n">y_range</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialize_axis_range</span><span class="p">(</span> - <span class="n">image_width</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">)</span> - - <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">tqdm</span><span class="p">(</span><span class="n">x_range</span><span class="p">):</span> - <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">y_range</span><span class="p">:</span> - <span class="n">real_to_denoise</span> <span class="o">=</span> <span class="n">noisy_image_real_part</span><span class="p">[:,</span> - <span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="p">:]</span> - <span class="n">imag_to_denoise</span> <span class="o">=</span> <span class="n">noisy_image_imaginary_part</span><span class="p">[:,</span> - <span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="p">:]</span> - <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">symetrise</span><span class="p">:</span> - <span class="n">real_to_denoise</span><span class="p">,</span> <span class="n">imag_to_denoise</span> <span class="o">=</span> <span class="n">symetrise_real_and_imaginary_parts</span><span class="p">(</span> - <span class="n">real_to_denoise</span><span class="p">,</span> <span class="n">imag_to_denoise</span><span class="p">)</span> - - <span class="n">real_to_denoise</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">tensor</span><span class="p">(</span> - <span class="n">real_to_denoise</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">torch</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span> - <span class="n">imag_to_denoise</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">tensor</span><span class="p">(</span> - <span class="n">imag_to_denoise</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">torch</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span> - - <span class="n">real_to_denoise</span> <span class="o">=</span> <span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">square</span><span class="p">(</span> - <span class="n">real_to_denoise</span><span class="p">)</span><span class="o">+</span><span class="mf">1e-3</span><span class="p">)</span><span class="o">-</span><span class="mi">2</span><span class="o">*</span><span class="n">m</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="p">(</span><span class="n">M</span><span class="o">-</span><span class="n">m</span><span class="p">))</span> - <span class="n">imag_to_denoise</span> <span class="o">=</span> <span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">square</span><span class="p">(</span> - <span class="n">imag_to_denoise</span><span class="p">)</span><span class="o">+</span><span class="mf">1e-3</span><span class="p">)</span><span class="o">-</span><span class="mi">2</span><span class="o">*</span><span class="n">m</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="p">(</span><span class="n">M</span><span class="o">-</span><span class="n">m</span><span class="p">))</span> - - <span class="n">denoised_image_real_part</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">denoise_image_kernel</span><span class="p">(</span> - <span class="n">real_to_denoise</span><span class="p">,</span> <span class="n">denoised_image_real_part</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">model</span><span class="p">)</span> - <span class="n">denoised_image_imaginary_part</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">denoise_image_kernel</span><span class="p">(</span> - <span class="n">imag_to_denoise</span><span class="p">,</span> <span class="n">denoised_image_imaginary_part</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">model</span><span class="p">)</span> - <span class="n">count_image</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">denoise_image_kernel</span><span class="p">(</span> - <span class="n">imag_to_denoise</span><span class="p">,</span> <span class="n">count_image</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">model</span><span class="p">,</span> <span class="n">normalisation_kernel</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> - - <span class="n">denoised_image</span><span class="p">,</span> <span class="n">denoised_image_real_part</span><span class="p">,</span> <span class="n">denoised_image_imaginary_part</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">preprocess_denoised_image</span><span class="p">(</span> - <span class="n">denoised_image_real_part</span><span class="p">,</span> <span class="n">denoised_image_imaginary_part</span><span class="p">,</span> <span class="n">count_image</span><span class="p">)</span> - - <span class="n">despeckled_image</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"noisy"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"full"</span><span class="p">:</span> <span class="n">noisy_image</span><span class="p">,</span> - <span class="s2">"real"</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span><span class="n">noisy_image_real_part</span><span class="p">),</span> - <span class="s2">"imaginary"</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span><span class="n">noisy_image_imaginary_part</span><span class="p">)</span> - <span class="p">},</span> - <span class="s2">"denoised"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"full"</span><span class="p">:</span> <span class="n">denoised_image</span><span class="p">,</span> - <span class="s2">"from_real"</span><span class="p">:</span> <span class="n">denoised_image_real_part</span><span class="p">,</span> - <span class="s2">"from_imaginary"</span><span class="p">:</span> <span class="n">denoised_image_imaginary_part</span> - <span class="p">}</span> - <span class="p">}</span> - - <span class="k">return</span> <span class="n">despeckled_image</span></div> - - -<div class="viewcode-block" id="MerlinDenoiser.denoise_images"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_images">[docs]</a> - <span class="k">def</span> <span class="nf">denoise_images</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">images_to_denoise_path</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">save_dir</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> - <span class="n">stride_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Iterate over a directory of coSAR images and store the denoised images in a directory</span> - -<span class="sd"> Args:</span> -<span class="sd"> images_to_denoise_path (list): a list of paths of npy images to denoise</span> -<span class="sd"> save_dir (str): repository to save sar images, real images and noisy images</span> -<span class="sd"> patch_size (int): size of the patch of the convolution</span> -<span class="sd"> stride_size (int): number of pixels between one convolution to the next</span> -<span class="sd"> """</span> - - <span class="n">images_to_denoise_paths</span> <span class="o">=</span> <span class="n">glob</span><span class="p">((</span><span class="n">images_to_denoise_path</span> <span class="o">+</span> <span class="s1">'/*.npy'</span><span class="p">))</span> - - <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">images_to_denoise_paths</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">'No data!'</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Starting denoising images in </span><span class="si">{</span><span class="n">images_to_denoise_paths</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> - - <span class="k">for</span> <span class="n">idx</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">images_to_denoise_paths</span><span class="p">)):</span> - <span class="n">image_name</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">images_to_denoise_paths</span><span class="p">[</span><span class="n">idx</span><span class="p">])</span><span class="o">.</span><span class="n">name</span> - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"Despeckling </span><span class="si">{</span><span class="n">image_name</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> - - <span class="n">noisy_image_idx</span> <span class="o">=</span> <span class="n">load_sar_image</span><span class="p">(</span> - <span class="n">images_to_denoise_paths</span><span class="p">[</span><span class="n">idx</span><span class="p">])</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span> - <span class="n">despeckled_images</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">denoise_image</span><span class="p">(</span> - <span class="n">noisy_image_idx</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">)</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"Saving despeckled images in </span><span class="si">{</span><span class="n">save_dir</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">save_despeckled_images</span><span class="p">(</span> - <span class="n">despeckled_images</span><span class="p">,</span> <span class="n">image_name</span><span class="p">,</span> <span class="n">save_dir</span><span class="p">)</span></div> -</div> - -</pre></div> - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="../../../index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="../../../index.html">Documentation overview</a><ul> - <li><a href="../../index.html">Module code</a><ul> - </ul></li> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="../../../search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/_modules/deepdespeckling/model.html b/docs/_modules/deepdespeckling/model.html deleted file mode 100644 index f9b011e..0000000 --- a/docs/_modules/deepdespeckling/model.html +++ /dev/null @@ -1,240 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="../../"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>deepdespeckling.model — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="../../_static/alabaster.css?v=12dfc556" /> - <script src="../../_static/documentation_options.js?v=cb255500"></script> - <script src="../../_static/doctools.js?v=888ff710"></script> - <script src="../../_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="../../genindex.html" /> - <link rel="search" title="Search" href="../../search.html" /> - - <link rel="stylesheet" href="../../_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <h1>Source code for deepdespeckling.model</h1><div class="highlight"><pre> -<span></span><span class="kn">import</span> <span class="nn">torch</span> -<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span> - - -<div class="viewcode-block" id="Model"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.model.Model">[docs]</a> -<span class="k">class</span> <span class="nc">Model</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Module</span><span class="p">):</span> - - <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">device</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span> - <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span> - - <span class="bp">self</span><span class="o">.</span><span class="n">device</span> <span class="o">=</span> <span class="n">device</span> - - <span class="bp">self</span><span class="o">.</span><span class="n">height</span> <span class="o">=</span> <span class="n">height</span> - <span class="bp">self</span><span class="o">.</span><span class="n">width</span> <span class="o">=</span> <span class="n">width</span> - - <span class="bp">self</span><span class="o">.</span><span class="n">pool</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">MaxPool2d</span><span class="p">(</span><span class="n">kernel_size</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">stride</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">LeakyReLU</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span> - - <span class="bp">self</span><span class="o">.</span><span class="n">enc0</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">enc1</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">enc2</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">enc3</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">enc4</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">enc5</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">enc6</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">48</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - - <span class="bp">self</span><span class="o">.</span><span class="n">dec5</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec5b</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec4</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">144</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec4b</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec3</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">144</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec3b</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec2</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">144</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec2b</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">96</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec1a</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">97</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">64</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec1b</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">64</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">32</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">dec1</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">Conv2d</span><span class="p">(</span><span class="n">in_channels</span><span class="o">=</span><span class="mi">32</span><span class="p">,</span> <span class="n">out_channels</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">kernel_size</span><span class="o">=</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">stride</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> - <span class="n">padding</span><span class="o">=</span><span class="s1">'same'</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - - <span class="bp">self</span><span class="o">.</span><span class="n">upscale2d</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">nn</span><span class="o">.</span><span class="n">UpsamplingNearest2d</span><span class="p">(</span><span class="n">scale_factor</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> - -<div class="viewcode-block" id="Model.forward"> -<a class="viewcode-back" href="../../modules.html#deepdespeckling.model.Model.forward">[docs]</a> - <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">""" Defines a class for an autoencoder algorithm for an object (image) x</span> - -<span class="sd"> An autoencoder is a specific type of feedforward neural networks where the</span> -<span class="sd"> input is the same as the</span> -<span class="sd"> output. It compresses the input into a lower-dimensional code and then </span> -<span class="sd"> reconstruct the output from this representattion. It is a dimensionality </span> -<span class="sd"> reduction algorithm</span> - -<span class="sd"> Parameters</span> -<span class="sd"> ----------</span> -<span class="sd"> x : np.array</span> -<span class="sd"> a numpy array containing image </span> - -<span class="sd"> Returns</span> -<span class="sd"> ----------</span> -<span class="sd"> x-n : np.array</span> -<span class="sd"> a numpy array containing the denoised image i.e the image itself minus the noise</span> - -<span class="sd"> """</span> - <span class="n">x</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">height</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">width</span><span class="p">])</span> - <span class="c1"># x = torch.permute(x, (0, 3, 1, 2))</span> - <span class="n">skips</span> <span class="o">=</span> <span class="p">[</span><span class="n">x</span><span class="p">]</span> - - <span class="n">n</span> <span class="o">=</span> <span class="n">x</span> - - <span class="c1"># ENCODER</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">enc0</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">enc1</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pool</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">skips</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">enc2</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pool</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">skips</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">enc3</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pool</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">skips</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">enc4</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pool</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">skips</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">enc5</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pool</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">enc6</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - - <span class="c1"># DECODER</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">upscale2d</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">cat</span><span class="p">((</span><span class="n">n</span><span class="p">,</span> <span class="n">skips</span><span class="o">.</span><span class="n">pop</span><span class="p">()),</span> <span class="n">dim</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec5</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec5b</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">upscale2d</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">cat</span><span class="p">((</span><span class="n">n</span><span class="p">,</span> <span class="n">skips</span><span class="o">.</span><span class="n">pop</span><span class="p">()),</span> <span class="n">dim</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec4</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec4b</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">upscale2d</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">cat</span><span class="p">((</span><span class="n">n</span><span class="p">,</span> <span class="n">skips</span><span class="o">.</span><span class="n">pop</span><span class="p">()),</span> <span class="n">dim</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec3</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec3b</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">upscale2d</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">cat</span><span class="p">((</span><span class="n">n</span><span class="p">,</span> <span class="n">skips</span><span class="o">.</span><span class="n">pop</span><span class="p">()),</span> <span class="n">dim</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec2</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec2b</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">upscale2d</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">cat</span><span class="p">((</span><span class="n">n</span><span class="p">,</span> <span class="n">skips</span><span class="o">.</span><span class="n">pop</span><span class="p">()),</span> <span class="n">dim</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec1a</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">leaky</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dec1b</span><span class="p">(</span><span class="n">n</span><span class="p">))</span> - - <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">dec1</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">x</span> <span class="o">-</span> <span class="n">n</span></div> -</div> - -</pre></div> - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="../../index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="../../modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="../../index.html">Documentation overview</a><ul> - <li><a href="../index.html">Module code</a><ul> - </ul></li> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="../../search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html b/docs/_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html deleted file mode 100644 index 65cda37..0000000 --- a/docs/_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html +++ /dev/null @@ -1,320 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="../../../"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>deepdespeckling.sar2sar.sar2sar_denoiser — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css?v=12dfc556" /> - <script src="../../../_static/documentation_options.js?v=cb255500"></script> - <script src="../../../_static/doctools.js?v=888ff710"></script> - <script src="../../../_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="../../../genindex.html" /> - <link rel="search" title="Search" href="../../../search.html" /> - - <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <h1>Source code for deepdespeckling.sar2sar.sar2sar_denoiser</h1><div class="highlight"><pre> -<span></span><span class="kn">from</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="n">glob</span> -<span class="kn">import</span> <span class="nn">logging</span> -<span class="kn">import</span> <span class="nn">os</span> -<span class="kn">from</span> <span class="nn">pathlib</span> <span class="kn">import</span> <span class="n">Path</span> -<span class="kn">import</span> <span class="nn">torch</span> -<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span> -<span class="kn">from</span> <span class="nn">tqdm</span> <span class="kn">import</span> <span class="n">tqdm</span> - -<span class="kn">from</span> <span class="nn">deepdespeckling.denoiser</span> <span class="kn">import</span> <span class="n">Denoiser</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.model</span> <span class="kn">import</span> <span class="n">Model</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.utils.constants</span> <span class="kn">import</span> <span class="n">M</span><span class="p">,</span> <span class="n">m</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.utils.utils</span> <span class="kn">import</span> <span class="p">(</span><span class="n">denormalize_sar_image</span><span class="p">,</span> <span class="n">load_sar_image</span><span class="p">,</span> <span class="n">normalize_sar_image</span><span class="p">,</span> <span class="n">save_image_to_npy_and_png</span><span class="p">,</span> - <span class="n">create_empty_folder_in_directory</span><span class="p">)</span> - -<span class="n">current_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="vm">__file__</span><span class="p">)</span> - - -<div class="viewcode-block" id="Sar2SarDenoiser"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser">[docs]</a> -<span class="k">class</span> <span class="nc">Sar2SarDenoiser</span><span class="p">(</span><span class="n">Denoiser</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Class to share parameters beyond denoising functions</span> -<span class="sd"> """</span> - - <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">):</span> - <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">params</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">weights_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span> - <span class="n">current_dir</span><span class="p">,</span> <span class="s2">"saved_model/sar2sar.pth"</span><span class="p">)</span> - <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">weights_path</span><span class="p">)</span> - -<div class="viewcode-block" id="Sar2SarDenoiser.load_model"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.load_model">[docs]</a> - <span class="k">def</span> <span class="nf">load_model</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="n">Model</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Load model with given weights </span> - -<span class="sd"> Args:</span> -<span class="sd"> weights_path (str): path to weights </span> -<span class="sd"> patch_size (int): patch size</span> - -<span class="sd"> Returns:</span> -<span class="sd"> model (Model): model loaded with stored weights</span> -<span class="sd"> """</span> - <span class="n">model</span> <span class="o">=</span> <span class="n">Model</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">device</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">),</span> - <span class="n">height</span><span class="o">=</span><span class="n">patch_size</span><span class="p">,</span> <span class="n">width</span><span class="o">=</span><span class="n">patch_size</span><span class="p">)</span> - <span class="n">model</span><span class="o">.</span><span class="n">load_state_dict</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">load</span><span class="p">(</span> - <span class="bp">self</span><span class="o">.</span><span class="n">weights_path</span><span class="p">,</span> <span class="n">map_location</span><span class="o">=</span><span class="n">torch</span><span class="o">.</span><span class="n">device</span><span class="p">(</span><span class="s2">"cpu"</span><span class="p">))[</span><span class="s1">'model_state_dict'</span><span class="p">])</span> - - <span class="k">return</span> <span class="n">model</span></div> - - -<div class="viewcode-block" id="Sar2SarDenoiser.save_despeckled_images"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.save_despeckled_images">[docs]</a> - <span class="k">def</span> <span class="nf">save_despeckled_images</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">despeckled_images</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span> <span class="n">image_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">save_dir</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Save full, real and imaginary part of noisy and denoised image stored in a dictionary in png to a given folder</span> - -<span class="sd"> Args:</span> -<span class="sd"> despeckled_images (dict): dictionary containing noisy and denoised image</span> -<span class="sd"> image_name (str): name of the image</span> -<span class="sd"> save_dir (str): path to the folder where to save the png images</span> -<span class="sd"> """</span> - <span class="n">threshold</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span> - <span class="n">despeckled_images</span><span class="p">[</span><span class="s2">"noisy"</span><span class="p">])</span> <span class="o">+</span> <span class="mi">3</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">std</span><span class="p">(</span><span class="n">despeckled_images</span><span class="p">[</span><span class="s2">"noisy"</span><span class="p">])</span> - <span class="n">image_name</span> <span class="o">=</span> <span class="n">image_name</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\\</span><span class="s1">'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> - - <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">despeckled_images</span><span class="p">:</span> - <span class="n">create_empty_folder_in_directory</span><span class="p">(</span><span class="n">save_dir</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span> - <span class="n">save_image_to_npy_and_png</span><span class="p">(</span> - <span class="n">despeckled_images</span><span class="p">[</span><span class="n">key</span><span class="p">],</span> <span class="n">save_dir</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"/</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">/</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">_"</span><span class="p">,</span> <span class="n">image_name</span><span class="p">,</span> <span class="n">threshold</span><span class="p">)</span></div> - - -<div class="viewcode-block" id="Sar2SarDenoiser.denoise_image_kernel"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image_kernel">[docs]</a> - <span class="k">def</span> <span class="nf">denoise_image_kernel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">noisy_image_kernel</span><span class="p">:</span> <span class="n">torch</span><span class="o">.</span><span class="n">tensor</span><span class="p">,</span> <span class="n">denoised_image_kernel</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">x</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">model</span><span class="p">:</span> <span class="n">Model</span><span class="p">,</span> <span class="n">normalisation_kernel</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Denoise a subpart of a given symetrised noisy image delimited by x, y and patch_size using a given model</span> - -<span class="sd"> Args:</span> -<span class="sd"> noisy_image_kernel (torch tensor): part of the noisy image to denoise </span> -<span class="sd"> denoised_image_kernel (numpy array): part of the partially denoised image</span> -<span class="sd"> x (int): x coordinate of current kernel to denoise</span> -<span class="sd"> y (int): y coordinate of current kernel to denoise</span> -<span class="sd"> patch_size (int): patch size</span> -<span class="sd"> model (Model): trained model with loaded weights </span> -<span class="sd"> normalisation_kernel (bool, optional): Determine if. Defaults to False.</span> - -<span class="sd"> Returns:</span> -<span class="sd"> denoised_image_kernel (numpy array): image denoised in the given coordinates and the ones already iterated</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="ow">not</span> <span class="n">normalisation_kernel</span><span class="p">:</span> - - <span class="k">with</span> <span class="n">torch</span><span class="o">.</span><span class="n">no_grad</span><span class="p">():</span> - <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span> <span class="o">!=</span> <span class="s1">'cpu'</span><span class="p">:</span> - <span class="n">tmp_clean_image</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">forward</span><span class="p">(</span> - <span class="n">noisy_image_kernel</span><span class="p">)</span><span class="o">.</span><span class="n">cpu</span><span class="p">()</span><span class="o">.</span><span class="n">numpy</span><span class="p">()</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">tmp_clean_image</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">forward</span><span class="p">(</span> - <span class="n">noisy_image_kernel</span><span class="p">)</span><span class="o">.</span><span class="n">numpy</span><span class="p">()</span> - - <span class="n">tmp_clean_image</span> <span class="o">=</span> <span class="n">denormalize_sar_image</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span> - <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">tmp_clean_image</span><span class="p">)))</span> - - <span class="n">denoised_image_kernel</span><span class="p">[</span><span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">]</span> <span class="o">=</span> <span class="n">denoised_image_kernel</span><span class="p">[</span><span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> - <span class="n">patch_size</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">]</span> <span class="o">+</span> <span class="n">tmp_clean_image</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">denoised_image_kernel</span><span class="p">[</span><span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">]</span> <span class="o">=</span> <span class="n">denoised_image_kernel</span><span class="p">[</span><span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> - <span class="n">patch_size</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">]</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="n">patch_size</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">))</span> - - <span class="k">return</span> <span class="n">denoised_image_kernel</span></div> - - -<div class="viewcode-block" id="Sar2SarDenoiser.denormalize_sar_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denormalize_sar_image">[docs]</a> - <span class="k">def</span> <span class="nf">denormalize_sar_image</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Denormalize a sar image stored in a numpy array</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy array): a sar image</span> - -<span class="sd"> Raises:</span> -<span class="sd"> TypeError: raise an error if the image file is not a numpy array</span> - -<span class="sd"> Returns:</span> -<span class="sd"> (numpy array): the image denormalized</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span> - <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Please provide a numpy array'</span><span class="p">)</span> - <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">((</span><span class="n">np</span><span class="o">.</span><span class="n">clip</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span><span class="n">image</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">image</span><span class="o">.</span><span class="n">max</span><span class="p">()))</span><span class="o">*</span><span class="p">(</span><span class="n">M</span><span class="o">-</span><span class="n">m</span><span class="p">)</span><span class="o">+</span><span class="n">m</span><span class="p">)</span></div> - - -<div class="viewcode-block" id="Sar2SarDenoiser.denoise_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image">[docs]</a> - <span class="k">def</span> <span class="nf">denoise_image</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">noisy_image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="nb">dict</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Preprocess and denoise a coSAR image using given model weights</span> - -<span class="sd"> Args:</span> -<span class="sd"> noisy_image (numpy array): numpy array containing the noisy image to despeckle </span> -<span class="sd"> patch_size (int): size of the patch of the convolution</span> -<span class="sd"> stride_size (int): number of pixels between one convolution to the next</span> - -<span class="sd"> Returns:</span> -<span class="sd"> output_image (numpy array): denoised image</span> -<span class="sd"> """</span> - <span class="n">noisy_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">noisy_image</span><span class="p">)</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span> - <span class="mi">1</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">noisy_image</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">noisy_image</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span> - - <span class="n">noisy_image</span> <span class="o">=</span> <span class="n">normalize_sar_image</span><span class="p">(</span><span class="n">noisy_image</span><span class="p">)</span> - - <span class="n">noisy_image</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">tensor</span><span class="p">(</span> - <span class="n">noisy_image</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">torch</span><span class="o">.</span><span class="n">float</span><span class="p">)</span> - - <span class="c1"># Pad the image</span> - <span class="n">image_height</span> <span class="o">=</span> <span class="n">noisy_image</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> - <span class="n">image_width</span> <span class="o">=</span> <span class="n">noisy_image</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> - - <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">load_model</span><span class="p">(</span><span class="n">patch_size</span><span class="o">=</span><span class="n">patch_size</span><span class="p">)</span> - - <span class="n">count_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">image_height</span><span class="p">,</span> <span class="n">image_width</span><span class="p">))</span> - <span class="n">denoised_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">image_height</span><span class="p">,</span> <span class="n">image_width</span><span class="p">))</span> - - <span class="n">x_range</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialize_axis_range</span><span class="p">(</span> - <span class="n">image_height</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">)</span> - <span class="n">y_range</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialize_axis_range</span><span class="p">(</span> - <span class="n">image_width</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">)</span> - - <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">tqdm</span><span class="p">(</span><span class="n">x_range</span><span class="p">):</span> - <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">y_range</span><span class="p">:</span> - <span class="n">noisy_image_kernel</span> <span class="o">=</span> <span class="n">noisy_image</span><span class="p">[:,</span> - <span class="n">x</span><span class="p">:</span><span class="n">x</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span><span class="n">y</span> <span class="o">+</span> <span class="n">patch_size</span><span class="p">,</span> <span class="p">:]</span> - <span class="n">noisy_image_kernel</span> <span class="o">=</span> <span class="n">noisy_image_kernel</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">)</span> - - <span class="n">denoised_image</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">denoise_image_kernel</span><span class="p">(</span> - <span class="n">noisy_image_kernel</span><span class="p">,</span> <span class="n">denoised_image</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">model</span><span class="p">)</span> - <span class="n">count_image</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">denoise_image_kernel</span><span class="p">(</span> - <span class="n">noisy_image_kernel</span><span class="p">,</span> <span class="n">count_image</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">model</span><span class="p">,</span> <span class="n">normalisation_kernel</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> - - <span class="n">denoised_image</span> <span class="o">=</span> <span class="n">denoised_image</span> <span class="o">/</span> <span class="n">count_image</span> - - <span class="n">noisy_image_denormalized</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">denormalize_sar_image</span><span class="p">(</span> - <span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">noisy_image</span><span class="o">.</span><span class="n">cpu</span><span class="p">()</span><span class="o">.</span><span class="n">numpy</span><span class="p">())))</span> - - <span class="n">despeckled_image</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"noisy"</span><span class="p">:</span> <span class="n">noisy_image_denormalized</span><span class="p">,</span> - <span class="s2">"denoised"</span><span class="p">:</span> <span class="n">denoised_image</span> - <span class="p">}</span> - - <span class="k">return</span> <span class="n">despeckled_image</span></div> - - -<div class="viewcode-block" id="Sar2SarDenoiser.denoise_images"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_images">[docs]</a> - <span class="k">def</span> <span class="nf">denoise_images</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">images_to_denoise_path</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">save_dir</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> - <span class="n">stride_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Iterate over a directory of coSAR images and store the denoised images in a directory</span> - -<span class="sd"> Args:</span> -<span class="sd"> images_to_denoise_path (list): a list of paths of npy images to denoise</span> -<span class="sd"> save_dir (str): repository to save sar images, real images and noisy images</span> -<span class="sd"> patch_size (int): size of the patch of the convolution</span> -<span class="sd"> stride_size (int): number of pixels between one convolution to the next</span> -<span class="sd"> """</span> - - <span class="n">images_to_denoise_paths</span> <span class="o">=</span> <span class="n">glob</span><span class="p">((</span><span class="n">images_to_denoise_path</span> <span class="o">+</span> <span class="s1">'/*.npy'</span><span class="p">))</span> - - <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">images_to_denoise_paths</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">'No data!'</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Starting denoising images in </span><span class="si">{</span><span class="n">images_to_denoise_paths</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> - - <span class="k">for</span> <span class="n">idx</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">images_to_denoise_paths</span><span class="p">)):</span> - <span class="n">image_name</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">images_to_denoise_paths</span><span class="p">[</span><span class="n">idx</span><span class="p">])</span><span class="o">.</span><span class="n">name</span> - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"Despeckling </span><span class="si">{</span><span class="n">image_name</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> - - <span class="n">noisy_image_idx</span> <span class="o">=</span> <span class="n">load_sar_image</span><span class="p">(</span> - <span class="n">images_to_denoise_paths</span><span class="p">[</span><span class="n">idx</span><span class="p">])</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span> - <span class="n">despeckled_images</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">denoise_image</span><span class="p">(</span> - <span class="n">noisy_image_idx</span><span class="p">,</span> <span class="n">patch_size</span><span class="p">,</span> <span class="n">stride_size</span><span class="p">)</span> - - <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span> - <span class="sa">f</span><span class="s2">"Saving despeckled images in </span><span class="si">{</span><span class="n">save_dir</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">save_despeckled_images</span><span class="p">(</span> - <span class="n">despeckled_images</span><span class="p">,</span> <span class="n">image_name</span><span class="p">,</span> <span class="n">save_dir</span><span class="p">)</span></div> -</div> - -</pre></div> - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="../../../index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="../../../index.html">Documentation overview</a><ul> - <li><a href="../../index.html">Module code</a><ul> - </ul></li> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="../../../search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/_modules/deepdespeckling/utils/load_cosar.html b/docs/_modules/deepdespeckling/utils/load_cosar.html deleted file mode 100644 index 7c48800..0000000 --- a/docs/_modules/deepdespeckling/utils/load_cosar.html +++ /dev/null @@ -1,183 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="../../../"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>deepdespeckling.utils.load_cosar — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css?v=12dfc556" /> - <script src="../../../_static/documentation_options.js?v=cb255500"></script> - <script src="../../../_static/doctools.js?v=888ff710"></script> - <script src="../../../_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="../../../genindex.html" /> - <link rel="search" title="Search" href="../../../search.html" /> - - <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <h1>Source code for deepdespeckling.utils.load_cosar</h1><div class="highlight"><pre> -<span></span><span class="kn">import</span> <span class="nn">struct</span> -<span class="kn">from</span> <span class="nn">osgeo</span> <span class="kn">import</span> <span class="n">gdal</span> -<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span> - - -<div class="viewcode-block" id="cos2mat"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.load_cosar.cos2mat">[docs]</a> -<span class="k">def</span> <span class="nf">cos2mat</span><span class="p">(</span><span class="n">path_to_cosar_image</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Convert a CoSAR imge to a numpy array of size [ncolumns,nlines,2]</span> - -<span class="sd"> Args:</span> -<span class="sd"> path_to_cosar_image (str): path to the image which is a cos file</span> - -<span class="sd"> Returns:</span> -<span class="sd"> numpy array : the image in a numpy array</span> -<span class="sd"> """</span> - - <span class="nb">print</span><span class="p">(</span><span class="s1">'Converting CoSAR to numpy array of size [ncolumns,nlines,2]'</span><span class="p">)</span> - - <span class="k">try</span><span class="p">:</span> - <span class="n">fin</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">path_to_cosar_image</span><span class="p">,</span> <span class="s1">'rb'</span><span class="p">)</span> - <span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span> - <span class="n">legx</span> <span class="o">=</span> <span class="n">path_to_cosar_image</span> <span class="o">+</span> <span class="s1">': it is a not openable file'</span> - <span class="nb">print</span><span class="p">(</span><span class="n">legx</span><span class="p">)</span> - <span class="nb">print</span><span class="p">(</span><span class="sa">u</span><span class="s1">'failed to call cos2mat'</span><span class="p">)</span> - <span class="k">return</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span> - - <span class="n">ibib</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">">i"</span><span class="p">,</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">irsri</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">">i"</span><span class="p">,</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">irs</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">">i"</span><span class="p">,</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">ias</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">">i"</span><span class="p">,</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">ibi</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">">i"</span><span class="p">,</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">irtnb</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">">i"</span><span class="p">,</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">itnl</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">">i"</span><span class="p">,</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span> - - <span class="n">nlig</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">">i"</span><span class="p">,</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">ncoltot</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">irtnb</span> <span class="o">/</span> <span class="mi">4</span><span class="p">)</span> - <span class="n">ncol</span> <span class="o">=</span> <span class="n">ncoltot</span> <span class="o">-</span> <span class="mi">2</span> - <span class="n">nlig</span> <span class="o">=</span> <span class="n">ias</span> - - <span class="nb">print</span><span class="p">(</span><span class="sa">u</span><span class="s1">'Reading image in CoSAR format. ncolumns=</span><span class="si">%d</span><span class="s1"> nlines=</span><span class="si">%d</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">ncol</span><span class="p">,</span> <span class="n">nlig</span><span class="p">))</span> - - <span class="n">firm</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="mi">4</span> <span class="o">*</span> <span class="n">ncoltot</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">byte</span><span class="p">())</span> - <span class="n">imgcxs</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">empty</span><span class="p">([</span><span class="n">nlig</span><span class="p">,</span> <span class="n">ncol</span><span class="p">],</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">complex64</span><span class="p">())</span> - - <span class="n">fin</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> - <span class="n">firm</span> <span class="o">=</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span> <span class="o">*</span> <span class="n">ncoltot</span><span class="p">)</span> - <span class="n">firm</span> <span class="o">=</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span> <span class="o">*</span> <span class="n">ncoltot</span><span class="p">)</span> - <span class="n">firm</span> <span class="o">=</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span> <span class="o">*</span> <span class="n">ncoltot</span><span class="p">)</span> - <span class="n">firm</span> <span class="o">=</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span> <span class="o">*</span> <span class="n">ncoltot</span><span class="p">)</span> - - <span class="k">for</span> <span class="n">iut</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">nlig</span><span class="p">):</span> - <span class="n">firm</span> <span class="o">=</span> <span class="n">fin</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span> <span class="o">*</span> <span class="n">ncoltot</span><span class="p">)</span> - <span class="n">imgligne</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">ncoltot</span><span class="p">,</span> <span class="s1">'>h'</span><span class="p">,</span> <span class="n">firm</span><span class="p">)</span> - <span class="n">imgcxs</span><span class="p">[</span><span class="n">iut</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">imgligne</span><span class="p">[</span><span class="mi">4</span><span class="p">:</span><span class="mi">2</span> <span class="o">*</span> <span class="n">ncoltot</span><span class="p">:</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> \ - <span class="mi">1</span><span class="n">j</span> <span class="o">*</span> <span class="n">imgligne</span><span class="p">[</span><span class="mi">5</span><span class="p">:</span><span class="mi">2</span> <span class="o">*</span> <span class="n">ncoltot</span><span class="p">:</span><span class="mi">2</span><span class="p">]</span> - - <span class="nb">print</span><span class="p">(</span><span class="s1">'[:,:,0] contains the real part of the SLC image data'</span><span class="p">)</span> - <span class="nb">print</span><span class="p">(</span><span class="s1">'[:,:,1] contains the imaginary part of the SLC image data'</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">stack</span><span class="p">((</span><span class="n">np</span><span class="o">.</span><span class="n">real</span><span class="p">(</span><span class="n">imgcxs</span><span class="p">),</span> <span class="n">np</span><span class="o">.</span><span class="n">imag</span><span class="p">(</span><span class="n">imgcxs</span><span class="p">)),</span> <span class="n">axis</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="load_tiff_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.load_cosar.load_tiff_image">[docs]</a> -<span class="k">def</span> <span class="nf">load_tiff_image</span><span class="p">(</span><span class="n">path_to_tiff_image</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Load a tiff image in a numpy array using gdal library</span> - -<span class="sd"> Args:</span> -<span class="sd"> path_to_tiff_image (str): path to a tiff image</span> - -<span class="sd"> Returns:</span> -<span class="sd"> (numpy array): numpy array containing the tiff image</span> -<span class="sd"> """</span> - <span class="n">dataset</span> <span class="o">=</span> <span class="n">gdal</span><span class="o">.</span><span class="n">Open</span><span class="p">(</span><span class="n">path_to_tiff_image</span><span class="p">)</span> - - <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">dataset</span><span class="o">.</span><span class="n">RasterCount</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span> - <span class="n">band</span> <span class="o">=</span> <span class="n">dataset</span><span class="o">.</span><span class="n">GetRasterBand</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> - <span class="n">array</span> <span class="o">=</span> <span class="n">band</span><span class="o">.</span><span class="n">ReadAsArray</span><span class="p">()</span> - - <span class="k">return</span> <span class="n">array</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span></div> - -</pre></div> - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="../../../index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="../../../index.html">Documentation overview</a><ul> - <li><a href="../../index.html">Module code</a><ul> - </ul></li> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="../../../search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/_modules/deepdespeckling/utils/utils.html b/docs/_modules/deepdespeckling/utils/utils.html deleted file mode 100644 index b9938e2..0000000 --- a/docs/_modules/deepdespeckling/utils/utils.html +++ /dev/null @@ -1,728 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="../../../"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>deepdespeckling.utils.utils — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css?v=12dfc556" /> - <script src="../../../_static/documentation_options.js?v=cb255500"></script> - <script src="../../../_static/doctools.js?v=888ff710"></script> - <script src="../../../_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="../../../genindex.html" /> - <link rel="search" title="Search" href="../../../search.html" /> - - <link rel="stylesheet" href="../../../_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <h1>Source code for deepdespeckling.utils.utils</h1><div class="highlight"><pre> -<span></span><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span> -<span class="kn">import</span> <span class="nn">cv2</span> -<span class="kn">import</span> <span class="nn">os</span> -<span class="kn">from</span> <span class="nn">PIL</span> <span class="kn">import</span> <span class="n">Image</span> -<span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">signal</span> -<span class="kn">from</span> <span class="nn">pathlib</span> <span class="kn">import</span> <span class="n">Path</span> -<span class="kn">from</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="n">glob</span> - -<span class="kn">from</span> <span class="nn">deepdespeckling.utils.load_cosar</span> <span class="kn">import</span> <span class="n">cos2mat</span><span class="p">,</span> <span class="n">load_tiff_image</span> -<span class="kn">from</span> <span class="nn">deepdespeckling.utils.constants</span> <span class="kn">import</span> <span class="n">M</span><span class="p">,</span> <span class="n">m</span> - - -<div class="viewcode-block" id="normalize_sar_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.normalize_sar_image">[docs]</a> -<span class="k">def</span> <span class="nf">normalize_sar_image</span><span class="p">(</span><span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""normalize a sar image store in a numpy array</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy array): the image to be normalized</span> - -<span class="sd"> Returns:</span> -<span class="sd"> (numpy array): normalized image</span> -<span class="sd"> """</span> - <span class="k">return</span> <span class="p">((</span><span class="n">np</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">clip</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">image</span><span class="o">.</span><span class="n">max</span><span class="p">())</span><span class="o">+</span><span class="mf">1e-6</span><span class="p">)</span><span class="o">-</span><span class="n">m</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="n">M</span><span class="o">-</span><span class="n">m</span><span class="p">))</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="denormalize_sar_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.denormalize_sar_image">[docs]</a> -<span class="k">def</span> <span class="nf">denormalize_sar_image</span><span class="p">(</span><span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Denormalize a sar image store in a numpy array</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy array): a sar image</span> - -<span class="sd"> Raises:</span> -<span class="sd"> TypeError: raise an error if the image file is not a numpy array</span> - -<span class="sd"> Returns:</span> -<span class="sd"> (numpy array): the image denormalized</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span> - <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Please provide a numpy array'</span><span class="p">)</span> - <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">((</span><span class="n">M</span> <span class="o">-</span> <span class="n">m</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span><span class="n">image</span><span class="p">))</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="s1">'float32'</span><span class="p">)</span> <span class="o">+</span> <span class="n">m</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="denormalize_sar_image_sar2sar"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.denormalize_sar_image_sar2sar">[docs]</a> -<span class="k">def</span> <span class="nf">denormalize_sar_image_sar2sar</span><span class="p">(</span><span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Denormalize a sar image store i a numpy array</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy array): a sar image</span> - -<span class="sd"> Raises:</span> -<span class="sd"> TypeError: raise an error if the image file is not a numpy array</span> - -<span class="sd"> Returns:</span> -<span class="sd"> (numpy array): the image denormalized</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span> - <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Please provide a numpy array'</span><span class="p">)</span> - <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">((</span><span class="n">np</span><span class="o">.</span><span class="n">clip</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span><span class="n">image</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">image</span><span class="o">.</span><span class="n">max</span><span class="p">()))</span><span class="o">*</span><span class="p">(</span><span class="n">M</span><span class="o">-</span><span class="n">m</span><span class="p">)</span><span class="o">+</span><span class="n">m</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="load_sar_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.load_sar_image">[docs]</a> -<span class="k">def</span> <span class="nf">load_sar_image</span><span class="p">(</span><span class="n">image_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Load a SAR image in a numpy array, use cos2mat function if the file is a cos file, </span> -<span class="sd"> load_tiff_image if the file is a tiff file</span> - -<span class="sd"> Args:</span> -<span class="sd"> image_path (str) : absolute path to a SAR image (cos or npy file)</span> - -<span class="sd"> Returns:</span> -<span class="sd"> image (numpy array) : the image of dimension [ncolumns,nlines,2]</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="n">Path</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span><span class="o">.</span><span class="n">suffix</span> <span class="o">==</span> <span class="s2">".npy"</span><span class="p">:</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span> - <span class="k">elif</span> <span class="n">Path</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span><span class="o">.</span><span class="n">suffix</span> <span class="o">==</span> <span class="s2">".cos"</span><span class="p">:</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">cos2mat</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span> - <span class="k">elif</span> <span class="n">Path</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span><span class="o">.</span><span class="n">suffix</span> <span class="o">==</span> <span class="s2">".tiff"</span><span class="p">:</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">load_tiff_image</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span> - <span class="k">else</span><span class="p">:</span> - <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"the image should be a cos, npy or tiff file"</span><span class="p">)</span> - <span class="k">return</span> <span class="n">image</span></div> - - - -<div class="viewcode-block" id="load_sar_images"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.load_sar_images">[docs]</a> -<span class="k">def</span> <span class="nf">load_sar_images</span><span class="p">(</span><span class="n">file_list</span><span class="p">):</span> -<span class="w"> </span><span class="sd">""" Description</span> -<span class="sd"> ----------</span> -<span class="sd"> Loads files , resize them and append them into a list called data</span> - -<span class="sd"> Parameters</span> -<span class="sd"> ----------</span> -<span class="sd"> filelist : a path to a folder containing the images</span> - -<span class="sd"> Returns</span> -<span class="sd"> ----------</span> -<span class="sd"> A list of images</span> - -<span class="sd"> """</span> - <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file_list</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">file_list</span><span class="p">)</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">image</span><span class="p">)</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span> - <span class="mi">1</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span> - <span class="k">return</span> <span class="n">image</span> - <span class="n">data</span> <span class="o">=</span> <span class="p">[]</span> - <span class="k">for</span> <span class="n">file</span> <span class="ow">in</span> <span class="n">file_list</span><span class="p">:</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> - <span class="n">data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">image</span><span class="p">)</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span> - <span class="mi">1</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">np</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="mi">2</span><span class="p">))</span> - <span class="k">return</span> <span class="n">data</span></div> - - - -<div class="viewcode-block" id="create_empty_folder_in_directory"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.create_empty_folder_in_directory">[docs]</a> -<span class="k">def</span> <span class="nf">create_empty_folder_in_directory</span><span class="p">(</span><span class="n">destination_directory_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">folder_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"processed_images"</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Create an empty folder in a given directory</span> - -<span class="sd"> Args:</span> -<span class="sd"> destination_directory_path (str): path pf the directory in which an empty folder is created if it doest not exist yet</span> -<span class="sd"> folder_name (str, optional): name of the folder to create. Defaults to "processed_images".</span> - -<span class="sd"> Returns:</span> -<span class="sd"> processed_images_path: path of the created empty folder</span> -<span class="sd"> """</span> - <span class="n">processed_images_path</span> <span class="o">=</span> <span class="n">destination_directory_path</span> <span class="o">+</span> <span class="sa">f</span><span class="s1">'/</span><span class="si">{</span><span class="n">folder_name</span><span class="si">}</span><span class="s1">'</span> - <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">processed_images_path</span><span class="p">):</span> - <span class="n">os</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">processed_images_path</span><span class="p">)</span> - <span class="k">return</span> <span class="n">processed_images_path</span></div> - - - -<div class="viewcode-block" id="preprocess_and_store_sar_images"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.preprocess_and_store_sar_images">[docs]</a> -<span class="k">def</span> <span class="nf">preprocess_and_store_sar_images</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">processed_images_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">model_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"spotlight"</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Convert coSAR images to numpy arrays and store it in a specified path</span> - -<span class="sd"> Args:</span> -<span class="sd"> sar_images_path (str): path of a folder containing coSAR images to be converted in numpy array</span> -<span class="sd"> processed_images_path (str): path of the folder where converted images are stored</span> -<span class="sd"> model_name (str): model name to be use for despeckling </span> -<span class="sd"> """</span> - <span class="n">ext</span> <span class="o">=</span> <span class="s2">"cos"</span> <span class="k">if</span> <span class="n">model_name</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"spotlight"</span><span class="p">,</span> <span class="s2">"stripmap"</span><span class="p">]</span> <span class="k">else</span> <span class="s2">"tiff"</span> - <span class="n">images_paths</span> <span class="o">=</span> <span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">,</span> <span class="s2">"*.npy"</span><span class="p">))</span> <span class="o">+</span> \ - <span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"*.</span><span class="si">{</span><span class="n">ext</span><span class="si">}</span><span class="s2">"</span><span class="p">))</span> - <span class="k">for</span> <span class="n">image_path</span> <span class="ow">in</span> <span class="n">images_paths</span><span class="p">:</span> - <span class="n">imagename</span> <span class="o">=</span> <span class="n">image_path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> - <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">processed_images_path</span> <span class="o">+</span> <span class="s1">'/'</span> <span class="o">+</span> <span class="n">imagename</span> <span class="o">+</span> <span class="s1">'.npy'</span><span class="p">):</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">load_sar_image</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span> - <span class="n">np</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">processed_images_path</span> <span class="o">+</span> <span class="s1">'/'</span> <span class="o">+</span> <span class="n">imagename</span> <span class="o">+</span> <span class="s1">'.npy'</span><span class="p">,</span> <span class="n">image</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="preprocess_and_store_sar_images_from_coordinates"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.preprocess_and_store_sar_images_from_coordinates">[docs]</a> -<span class="k">def</span> <span class="nf">preprocess_and_store_sar_images_from_coordinates</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">processed_images_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">coordinates_dict</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span> <span class="n">model_name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">"spotlight"</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Convert specified areas of coSAR images to numpy arrays and store it in a specified path</span> - -<span class="sd"> Args:</span> -<span class="sd"> sar_images_path (str): path of a folder containing coSAR images to be converted in numpy array</span> -<span class="sd"> processed_images_path (str): path of the folder where converted images are stored</span> -<span class="sd"> coordinates_dict (dict): dictionary containing pixel boundaries of the area to despeckle (x_start, x_end, y_start, y_end)</span> -<span class="sd"> model_name (str): model name to be use for despeckling. Default to "spotlight"</span> -<span class="sd"> """</span> - <span class="n">x_start</span> <span class="o">=</span> <span class="n">coordinates_dict</span><span class="p">[</span><span class="s2">"x_start"</span><span class="p">]</span> - <span class="n">x_end</span> <span class="o">=</span> <span class="n">coordinates_dict</span><span class="p">[</span><span class="s2">"x_end"</span><span class="p">]</span> - <span class="n">y_start</span> <span class="o">=</span> <span class="n">coordinates_dict</span><span class="p">[</span><span class="s2">"y_start"</span><span class="p">]</span> - <span class="n">y_end</span> <span class="o">=</span> <span class="n">coordinates_dict</span><span class="p">[</span><span class="s2">"y_end"</span><span class="p">]</span> - - <span class="n">ext</span> <span class="o">=</span> <span class="s2">"cos"</span> <span class="k">if</span> <span class="n">model_name</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"spotlight"</span><span class="p">,</span> <span class="s2">"stripmap"</span><span class="p">]</span> <span class="k">else</span> <span class="s2">"tiff"</span> - - <span class="n">images_paths</span> <span class="o">=</span> <span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">,</span> <span class="s2">"*.npy"</span><span class="p">))</span> <span class="o">+</span> \ - <span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sar_images_path</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"*.</span><span class="si">{</span><span class="n">ext</span><span class="si">}</span><span class="s2">"</span><span class="p">))</span> - <span class="k">for</span> <span class="n">image_path</span> <span class="ow">in</span> <span class="n">images_paths</span><span class="p">:</span> - <span class="n">imagename</span> <span class="o">=</span> <span class="n">image_path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> - <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">processed_images_path</span> <span class="o">+</span> <span class="s1">'/'</span> <span class="o">+</span> <span class="n">imagename</span> <span class="o">+</span> <span class="s1">'.npy'</span><span class="p">):</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">load_sar_image</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span> - <span class="k">if</span> <span class="n">ext</span> <span class="o">==</span> <span class="s2">"cos"</span><span class="p">:</span> - <span class="n">np</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">processed_images_path</span> <span class="o">+</span> <span class="s1">'/'</span> <span class="o">+</span> <span class="n">imagename</span> <span class="o">+</span> - <span class="s1">'.npy'</span><span class="p">,</span> <span class="n">image</span><span class="p">[</span><span class="n">x_start</span><span class="p">:</span><span class="n">x_end</span><span class="p">,</span> <span class="n">y_start</span><span class="p">:</span><span class="n">y_end</span><span class="p">,</span> <span class="p">:])</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">np</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">processed_images_path</span> <span class="o">+</span> <span class="s1">'/'</span> <span class="o">+</span> <span class="n">imagename</span> <span class="o">+</span> - <span class="s1">'.npy'</span><span class="p">,</span> <span class="n">image</span><span class="p">[</span><span class="n">x_start</span><span class="p">:</span><span class="n">x_end</span><span class="p">,</span> <span class="n">y_start</span><span class="p">:</span><span class="n">y_end</span><span class="p">])</span></div> - - - -<div class="viewcode-block" id="get_maximum_patch_size"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.get_maximum_patch_size">[docs]</a> -<span class="k">def</span> <span class="nf">get_maximum_patch_size</span><span class="p">(</span><span class="n">kernel_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">patch_bound</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Get maximum manifold of a number lower than a bound</span> - -<span class="sd"> Args:</span> -<span class="sd"> kernel_size (int): the kernel size of the trained model</span> -<span class="sd"> patch_bound (int): the maximum bound of the kernel size</span> - -<span class="sd"> Returns:</span> -<span class="sd"> maximum_patch_size (int) : the maximum patch size</span> -<span class="sd"> """</span> - <span class="n">k</span> <span class="o">=</span> <span class="mi">1</span> - - <span class="k">while</span> <span class="n">kernel_size</span> <span class="o">*</span> <span class="n">k</span> <span class="o"><</span> <span class="n">patch_bound</span><span class="p">:</span> - <span class="n">k</span> <span class="o">=</span> <span class="n">k</span> <span class="o">*</span> <span class="mi">2</span> - - <span class="n">maximum_patch_size</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">kernel_size</span> <span class="o">*</span> <span class="p">(</span><span class="n">k</span><span class="o">/</span><span class="mi">2</span><span class="p">))</span> - - <span class="k">return</span> <span class="n">maximum_patch_size</span></div> - - - -<div class="viewcode-block" id="get_maximum_patch_size_from_image_dimensions"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.get_maximum_patch_size_from_image_dimensions">[docs]</a> -<span class="k">def</span> <span class="nf">get_maximum_patch_size_from_image_dimensions</span><span class="p">(</span><span class="n">kernel_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">height</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">width</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Get the maximum patch size from the width and heigth and the kernel size of the model we use</span> - -<span class="sd"> Args:</span> -<span class="sd"> kernel_size (int): the kernel size of the trained model</span> -<span class="sd"> height (int): the heigth of the image</span> -<span class="sd"> width (int): the width of the image</span> - -<span class="sd"> Returns:</span> -<span class="sd"> maximum_patch_size (int) : the maximum patch size to use for despeckling</span> -<span class="sd"> """</span> - <span class="n">patch_bound</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">height</span><span class="p">,</span> <span class="n">width</span><span class="p">)</span> - - <span class="k">if</span> <span class="n">patch_bound</span> <span class="o"><=</span> <span class="n">kernel_size</span><span class="p">:</span> - <span class="n">maximum_patch_size</span> <span class="o">=</span> <span class="n">kernel_size</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">maximum_patch_size</span> <span class="o">=</span> <span class="n">get_maximum_patch_size</span><span class="p">(</span> - <span class="n">kernel_size</span><span class="o">=</span><span class="n">kernel_size</span><span class="p">,</span> <span class="n">patch_bound</span><span class="o">=</span><span class="n">patch_bound</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">maximum_patch_size</span></div> - - - -<div class="viewcode-block" id="symetrise_real_and_imaginary_parts"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.symetrise_real_and_imaginary_parts">[docs]</a> -<span class="k">def</span> <span class="nf">symetrise_real_and_imaginary_parts</span><span class="p">(</span><span class="n">real_part</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">imag_part</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">)</span> <span class="o">-></span> <span class="nb">tuple</span><span class="p">[</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">]:</span> -<span class="w"> </span><span class="sd">"""Symetrise given real and imaginary parts to ensure MERLIN properties</span> - -<span class="sd"> Args:</span> -<span class="sd"> real_part (numpy array): real part of the noisy image to symetrise</span> -<span class="sd"> imag_part (numpy array): imaginary part of the noisy image to symetrise </span> - -<span class="sd"> Returns:</span> -<span class="sd"> np.real(ima2), np.imag(ima2) (numpy array, numpy array): symetrised real and imaginary parts of a noisy image</span> -<span class="sd"> """</span> - <span class="n">S</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">fftshift</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">fft2</span><span class="p">(</span> - <span class="n">real_part</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="p">:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="n">j</span> <span class="o">*</span> <span class="n">imag_part</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="p">:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]))</span> - <span class="n">p</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">S</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> <span class="c1"># azimut (ncol)</span> - <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">S</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span> - <span class="n">p</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="p">:]))</span> - <span class="n">sp</span> <span class="o">=</span> <span class="n">p</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> - <span class="n">c</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">real</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">ifft</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">fft</span><span class="p">(</span><span class="n">p</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">conjugate</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">fft</span><span class="p">(</span><span class="n">sp</span><span class="p">))))</span> - <span class="n">d1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">unravel_index</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">argmax</span><span class="p">(),</span> <span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> - <span class="n">d1</span> <span class="o">=</span> <span class="n">d1</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">shift_az_1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">round</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="n">d1</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span> <span class="o">%</span> <span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="nb">int</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span> - <span class="n">p2_1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">shift_az_1</span><span class="p">)</span> - <span class="n">shift_az_2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span> - <span class="nb">round</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="n">d1</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span> <span class="o">%</span> <span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="nb">int</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span> - <span class="n">p2_2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">shift_az_2</span><span class="p">)</span> - <span class="n">window</span> <span class="o">=</span> <span class="n">signal</span><span class="o">.</span><span class="n">gaussian</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">std</span><span class="o">=</span><span class="mf">0.2</span> <span class="o">*</span> <span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> - <span class="n">test_1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">window</span> <span class="o">*</span> <span class="n">p2_1</span><span class="p">)</span> - <span class="n">test_2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">window</span> <span class="o">*</span> <span class="n">p2_2</span><span class="p">)</span> - <span class="c1"># make sure the spectrum is symetrized and zeo-Doppler centered</span> - <span class="k">if</span> <span class="n">test_1</span> <span class="o">>=</span> <span class="n">test_2</span><span class="p">:</span> - <span class="n">p2</span> <span class="o">=</span> <span class="n">p2_1</span> - <span class="n">shift_az</span> <span class="o">=</span> <span class="n">shift_az_1</span> <span class="o">/</span> <span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">p2</span> <span class="o">=</span> <span class="n">p2_2</span> - <span class="n">shift_az</span> <span class="o">=</span> <span class="n">shift_az_2</span> <span class="o">/</span> <span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">S2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">shift_az</span> <span class="o">*</span> <span class="n">p</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> - - <span class="n">q</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">S</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span> <span class="c1"># range (nlin)</span> - <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">S</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]):</span> - <span class="n">q</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">S</span><span class="p">[:,</span> <span class="n">j</span><span class="p">]))</span> - <span class="n">sq</span> <span class="o">=</span> <span class="n">q</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> - <span class="c1"># correlation</span> - <span class="n">cq</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">real</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">ifft</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">fft</span><span class="p">(</span><span class="n">q</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">conjugate</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">fft</span><span class="p">(</span><span class="n">sq</span><span class="p">))))</span> - <span class="n">d2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">unravel_index</span><span class="p">(</span><span class="n">cq</span><span class="o">.</span><span class="n">argmax</span><span class="p">(),</span> <span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> - <span class="n">d2</span> <span class="o">=</span> <span class="n">d2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> - <span class="n">shift_range_1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">round</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="n">d2</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span> - <span class="p">)</span> <span class="o">%</span> <span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="nb">int</span><span class="p">(</span><span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span> - <span class="n">q2_1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">shift_range_1</span><span class="p">)</span> - <span class="n">shift_range_2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span> - <span class="nb">round</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="n">d2</span> <span class="o">-</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">/</span> <span class="mi">2</span><span class="p">))</span> <span class="o">%</span> <span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="nb">int</span><span class="p">(</span><span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span> - <span class="n">q2_2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">q</span><span class="p">,</span> <span class="n">shift_range_2</span><span class="p">)</span> - <span class="n">window_r</span> <span class="o">=</span> <span class="n">signal</span><span class="o">.</span><span class="n">gaussian</span><span class="p">(</span><span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">std</span><span class="o">=</span><span class="mf">0.2</span> <span class="o">*</span> <span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> - <span class="n">test_1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">window_r</span> <span class="o">*</span> <span class="n">q2_1</span><span class="p">)</span> - <span class="n">test_2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">window_r</span> <span class="o">*</span> <span class="n">q2_2</span><span class="p">)</span> - <span class="k">if</span> <span class="n">test_1</span> <span class="o">>=</span> <span class="n">test_2</span><span class="p">:</span> - <span class="n">q2</span> <span class="o">=</span> <span class="n">q2_1</span> - <span class="n">shift_range</span> <span class="o">=</span> <span class="n">shift_range_1</span> <span class="o">/</span> <span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">q2</span> <span class="o">=</span> <span class="n">q2_2</span> - <span class="n">shift_range</span> <span class="o">=</span> <span class="n">shift_range_2</span> <span class="o">/</span> <span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> - - <span class="n">Sf</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">roll</span><span class="p">(</span><span class="n">S2</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">shift_range</span> <span class="o">*</span> <span class="n">q</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> - <span class="n">ima2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">ifft2</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">ifftshift</span><span class="p">(</span><span class="n">Sf</span><span class="p">))</span> - - <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">real</span><span class="p">(</span><span class="n">ima2</span><span class="p">),</span> <span class="n">np</span><span class="o">.</span><span class="n">imag</span><span class="p">(</span><span class="n">ima2</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="preprocess_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.preprocess_image">[docs]</a> -<span class="k">def</span> <span class="nf">preprocess_image</span><span class="p">(</span><span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">threshold</span><span class="p">:</span> <span class="nb">float</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Preprocess image by limiting pixel values with a threshold</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy array): image to preprocess</span> -<span class="sd"> threshold (float): pixel value threshold </span> - -<span class="sd"> Returns:</span> -<span class="sd"> image (cv2 Image): image to be saved</span> -<span class="sd"> """</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">clip</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">threshold</span><span class="p">)</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">image</span> <span class="o">/</span> <span class="n">threshold</span> <span class="o">*</span> <span class="mi">255</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">fromarray</span><span class="p">(</span><span class="n">image</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="s1">'float64'</span><span class="p">))</span><span class="o">.</span><span class="n">convert</span><span class="p">(</span><span class="s1">'L'</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">image</span></div> - - - -<div class="viewcode-block" id="save_image_to_png"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.save_image_to_png">[docs]</a> -<span class="k">def</span> <span class="nf">save_image_to_png</span><span class="p">(</span><span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">threshold</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">image_full_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Save a given image to a png file in a given folder</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy array): image to save </span> -<span class="sd"> threshold (float): threshold of pixel values of the image to be saved in png</span> -<span class="sd"> image_full_path (str): full path of the image</span> - -<span class="sd"> Raises:</span> -<span class="sd"> TypeError: if the image is not a numpy array</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span> - <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Please provide a numpy array'</span><span class="p">)</span> - - <span class="n">image</span> <span class="o">=</span> <span class="n">preprocess_image</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="n">threshold</span><span class="o">=</span><span class="n">threshold</span><span class="p">)</span> - <span class="n">image</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">image_full_path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'npy'</span><span class="p">,</span> <span class="s1">'png'</span><span class="p">))</span></div> - - - -<div class="viewcode-block" id="save_image_to_npy_and_png"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.save_image_to_npy_and_png">[docs]</a> -<span class="k">def</span> <span class="nf">save_image_to_npy_and_png</span><span class="p">(</span><span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">save_dir</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">prefix</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">image_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">threshold</span><span class="p">:</span> <span class="nb">float</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Save a given image to npy and png in a given folder</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy array): image to save</span> -<span class="sd"> save_dir (str): path to the folder where to save the image</span> -<span class="sd"> prefix (str): prefix of the image file name</span> -<span class="sd"> image_name (str): name of the image file</span> -<span class="sd"> threshold (float): threshold of image pixel values used for png conversion</span> -<span class="sd"> """</span> - <span class="n">image_full_path</span> <span class="o">=</span> <span class="n">save_dir</span> <span class="o">+</span> <span class="n">prefix</span> <span class="o">+</span> <span class="n">image_name</span> - - <span class="c1"># Save image to npy file</span> - <span class="n">np</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">image_full_path</span><span class="p">,</span> <span class="n">image</span><span class="p">)</span> - - <span class="c1"># Save image to png file</span> - <span class="n">save_image_to_png</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="n">threshold</span><span class="p">,</span> <span class="n">image_full_path</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="compute_psnr"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.compute_psnr">[docs]</a> -<span class="k">def</span> <span class="nf">compute_psnr</span><span class="p">(</span><span class="n">Shat</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">S</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">)</span> <span class="o">-></span> <span class="nb">float</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Compute Peak Signal to Noise Ratio</span> - -<span class="sd"> Args:</span> -<span class="sd"> Shat (numpy array): a SAR amplitude image</span> -<span class="sd"> S (numpy array): a reference SAR image</span> - -<span class="sd"> Returns:</span> -<span class="sd"> res (float): psnr value</span> -<span class="sd"> """</span> - <span class="n">P</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">quantile</span><span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="mf">0.99</span><span class="p">)</span> - <span class="n">res</span> <span class="o">=</span> <span class="mi">10</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">log10</span><span class="p">((</span><span class="n">P</span> <span class="o">**</span> <span class="mi">2</span><span class="p">)</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">Shat</span> <span class="o">-</span> <span class="n">S</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span><span class="p">))</span> - <span class="k">return</span> <span class="n">res</span></div> - - - -<div class="viewcode-block" id="get_cropping_coordinates"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.get_cropping_coordinates">[docs]</a> -<span class="k">def</span> <span class="nf">get_cropping_coordinates</span><span class="p">(</span><span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">destination_directory_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">model_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">fixed</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Launch the crop tool to enable the user to select the subpart of the image to be despeckled</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy aray): full image to be cropped </span> -<span class="sd"> destination_directory_path (str): path of a folder to store the results</span> -<span class="sd"> model_name (str): model name to be use for despeckling. Default to "spotlight"</span> -<span class="sd"> fixed (bool, optional): whether the area of selection has a fixed size of not. Defaults to True.</span> -<span class="sd"> """</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">preprocess_sar_image_for_cropping</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="n">model_name</span><span class="p">)</span> - <span class="n">full_image</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> - <span class="n">cropping</span> <span class="o">=</span> <span class="kc">False</span> - <span class="n">x_start</span><span class="p">,</span> <span class="n">y_start</span><span class="p">,</span> <span class="n">x_end</span><span class="p">,</span> <span class="n">y_end</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span> - - <span class="c1"># CV2 CROPPING IN WINDOW</span> - <span class="k">def</span> <span class="nf">mouse_crop</span><span class="p">(</span><span class="n">event</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">flags</span><span class="p">,</span> <span class="n">param</span><span class="p">):</span> -<span class="w"> </span><span class="sd">""" The callback function of crop() to deal with user's events</span> -<span class="sd"> """</span> - <span class="k">global</span> <span class="n">x_start</span><span class="p">,</span> <span class="n">y_start</span><span class="p">,</span> <span class="n">x_end</span><span class="p">,</span> <span class="n">y_end</span><span class="p">,</span> <span class="n">cropping</span> - <span class="n">cropping</span> <span class="o">=</span> <span class="kc">False</span> - - <span class="k">if</span> <span class="n">event</span> <span class="o">==</span> <span class="n">cv2</span><span class="o">.</span><span class="n">EVENT_LBUTTONDOWN</span><span class="p">:</span> - <span class="n">x_start</span><span class="p">,</span> <span class="n">y_start</span><span class="p">,</span> <span class="n">x_end</span><span class="p">,</span> <span class="n">y_end</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> - <span class="n">cropping</span> <span class="o">=</span> <span class="kc">True</span> - - <span class="c1"># Mouse is Moving</span> - <span class="k">elif</span> <span class="n">event</span> <span class="o">==</span> <span class="n">cv2</span><span class="o">.</span><span class="n">EVENT_MOUSEMOVE</span><span class="p">:</span> - <span class="n">x_end</span><span class="p">,</span> <span class="n">y_end</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> - - <span class="c1"># if the left mouse button was released</span> - <span class="k">elif</span> <span class="n">event</span> <span class="o">==</span> <span class="n">cv2</span><span class="o">.</span><span class="n">EVENT_LBUTTONUP</span><span class="p">:</span> - <span class="c1"># record the ending (x, y) coordinates</span> - <span class="n">x_end</span><span class="p">,</span> <span class="n">y_end</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span> - <span class="k">if</span> <span class="n">fixed</span><span class="p">:</span> - <span class="k">if</span> <span class="n">x_start</span> <span class="o">></span> <span class="n">x_end</span> <span class="ow">and</span> <span class="n">y_start</span> <span class="o">></span> <span class="n">y_end</span><span class="p">:</span> - <span class="n">tempxstart</span> <span class="o">=</span> <span class="n">x_start</span> - <span class="n">tempystart</span> <span class="o">=</span> <span class="n">y_start</span> - - <span class="n">x_start</span> <span class="o">=</span> <span class="n">tempxstart</span> <span class="o">-</span> <span class="mi">32</span> - <span class="n">x_end</span> <span class="o">=</span> <span class="n">tempxstart</span> - - <span class="n">y_start</span> <span class="o">=</span> <span class="n">tempystart</span> <span class="o">-</span> <span class="mi">32</span> - <span class="n">y_end</span> <span class="o">=</span> <span class="n">tempystart</span> - - <span class="k">elif</span> <span class="n">x_start</span> <span class="o">></span> <span class="n">x_end</span> <span class="ow">and</span> <span class="n">y_start</span> <span class="o"><</span> <span class="n">y_end</span><span class="p">:</span> - <span class="n">tempxstart</span> <span class="o">=</span> <span class="n">x_start</span> - <span class="n">tempystart</span> <span class="o">=</span> <span class="n">y_start</span> - - <span class="n">x_start</span> <span class="o">=</span> <span class="n">tempxstart</span> <span class="o">-</span> <span class="mi">32</span> - <span class="n">y_start</span> <span class="o">=</span> <span class="n">tempystart</span> - - <span class="n">x_end</span> <span class="o">=</span> <span class="n">tempxstart</span> - <span class="n">y_end</span> <span class="o">=</span> <span class="n">tempystart</span> <span class="o">+</span> <span class="mi">32</span> - - <span class="k">elif</span> <span class="n">x_start</span> <span class="o"><</span> <span class="n">x_end</span> <span class="ow">and</span> <span class="n">y_start</span> <span class="o">></span> <span class="n">y_end</span><span class="p">:</span> - <span class="n">tempxstart</span> <span class="o">=</span> <span class="n">x_start</span> - <span class="n">tempystart</span> <span class="o">=</span> <span class="n">y_start</span> - - <span class="n">x_start</span> <span class="o">=</span> <span class="n">tempxstart</span> - <span class="n">y_start</span> <span class="o">=</span> <span class="n">tempystart</span> <span class="o">-</span> <span class="mi">32</span> - <span class="n">x_end</span> <span class="o">=</span> <span class="n">tempxstart</span> <span class="o">+</span> <span class="mi">32</span> - <span class="n">y_end</span> <span class="o">=</span> <span class="n">tempystart</span> - - <span class="k">else</span><span class="p">:</span> - <span class="n">x_end</span> <span class="o">=</span> <span class="n">x_start</span> <span class="o">+</span> <span class="mi">32</span> - <span class="n">y_end</span> <span class="o">=</span> <span class="n">y_start</span> <span class="o">+</span> <span class="mi">32</span> - <span class="k">else</span><span class="p">:</span> - <span class="k">if</span> <span class="n">x_start</span> <span class="o">></span> <span class="n">x_end</span> <span class="ow">and</span> <span class="n">y_start</span> <span class="o">></span> <span class="n">y_end</span><span class="p">:</span> - <span class="n">tempx</span> <span class="o">=</span> <span class="n">x_start</span> - <span class="n">x_start</span> <span class="o">=</span> <span class="n">x_end</span> - <span class="n">x_end</span> <span class="o">=</span> <span class="n">tempx</span> - - <span class="n">tempy</span> <span class="o">=</span> <span class="n">y_start</span> - <span class="n">y_start</span> <span class="o">=</span> <span class="n">y_end</span> - <span class="n">y_end</span> <span class="o">=</span> <span class="n">tempy</span> - - <span class="k">elif</span> <span class="n">x_start</span> <span class="o">></span> <span class="n">x_end</span> <span class="ow">and</span> <span class="n">y_start</span> <span class="o"><</span> <span class="n">y_end</span><span class="p">:</span> - <span class="n">tempxstart</span> <span class="o">=</span> <span class="n">x_start</span> - <span class="n">tempystart</span> <span class="o">=</span> <span class="n">y_start</span> - <span class="n">tempxend</span> <span class="o">=</span> <span class="n">x_end</span> - <span class="n">tempyend</span> <span class="o">=</span> <span class="n">y_end</span> - - <span class="n">x_start</span> <span class="o">=</span> <span class="n">tempxend</span> - <span class="n">y_start</span> <span class="o">=</span> <span class="n">tempystart</span> - <span class="n">x_end</span> <span class="o">=</span> <span class="n">tempxstart</span> - <span class="n">y_end</span> <span class="o">=</span> <span class="n">tempyend</span> - - <span class="k">elif</span> <span class="n">x_start</span> <span class="o"><</span> <span class="n">x_end</span> <span class="ow">and</span> <span class="n">y_start</span> <span class="o">></span> <span class="n">y_end</span><span class="p">:</span> - <span class="n">tempxstart</span> <span class="o">=</span> <span class="n">x_start</span> - <span class="n">tempystart</span> <span class="o">=</span> <span class="n">y_start</span> - <span class="n">tempxend</span> <span class="o">=</span> <span class="n">x_end</span> - <span class="n">tempyend</span> <span class="o">=</span> <span class="n">y_end</span> - - <span class="n">x_start</span> <span class="o">=</span> <span class="n">tempxstart</span> - <span class="n">y_start</span> <span class="o">=</span> <span class="n">tempyend</span> - <span class="n">x_end</span> <span class="o">=</span> <span class="n">tempxend</span> - <span class="n">y_end</span> <span class="o">=</span> <span class="n">tempystart</span> - - <span class="c1"># cropping is finished</span> - <span class="n">cv2</span><span class="o">.</span><span class="n">rectangle</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="p">(</span><span class="n">x_start</span><span class="p">,</span> <span class="n">y_start</span><span class="p">),</span> - <span class="p">(</span><span class="n">x_end</span><span class="p">,</span> <span class="n">y_end</span><span class="p">),</span> <span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span> - <span class="n">cropping</span> <span class="o">=</span> <span class="kc">False</span> - - <span class="n">refPoint</span> <span class="o">=</span> <span class="p">[(</span><span class="n">x_start</span><span class="p">,</span> <span class="n">y_start</span><span class="p">),</span> <span class="p">(</span><span class="n">x_end</span><span class="p">,</span> <span class="n">y_end</span><span class="p">)]</span> - - <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">refPoint</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span> <span class="c1"># when two points were found</span> - <span class="n">cropped_image</span> <span class="o">=</span> <span class="n">full_image</span><span class="p">[</span><span class="n">refPoint</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:</span><span class="n">refPoint</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> - <span class="o">*</span> <span class="mi">8</span><span class="p">,</span> <span class="n">refPoint</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:</span><span class="n">refPoint</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">]</span> - <span class="k">if</span> <span class="n">fixed</span><span class="p">:</span> - <span class="n">cropped_image</span> <span class="o">=</span> <span class="n">cv2</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span><span class="n">cropped_image</span><span class="p">,</span> <span class="p">(</span><span class="mi">256</span><span class="p">,</span> <span class="mi">256</span><span class="p">))</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">cropped_image</span> <span class="o">=</span> <span class="n">cv2</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span> - <span class="n">cropped_image</span><span class="p">,</span> <span class="p">(</span><span class="mi">8</span> <span class="o">*</span> <span class="p">(</span><span class="n">x_end</span> <span class="o">-</span> <span class="n">x_start</span><span class="p">),</span> <span class="mi">8</span> <span class="o">*</span> <span class="p">(</span><span class="n">y_end</span> <span class="o">-</span> <span class="n">y_start</span><span class="p">)))</span> - <span class="n">cv2</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="s2">"Cropped"</span><span class="p">,</span> <span class="n">cropped_image</span><span class="p">)</span> - - <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">destination_directory_path</span><span class="o">+</span><span class="s1">'/cropping_coordinates.txt'</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">filehandle</span><span class="p">:</span> - <span class="k">for</span> <span class="n">listitem</span> <span class="ow">in</span> <span class="n">refPoint</span><span class="p">:</span> - <span class="n">filehandle</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">listitem</span><span class="si">}</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span> - - <span class="n">h</span><span class="p">,</span> <span class="n">w</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">shape</span> - <span class="c1"># resizing image</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">cv2</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">w</span> <span class="o">/</span> <span class="mi">8</span><span class="p">),</span> <span class="nb">int</span><span class="p">(</span><span class="n">h</span> <span class="o">/</span> <span class="mi">8</span><span class="p">)))</span> - <span class="n">cv2</span><span class="o">.</span><span class="n">namedWindow</span><span class="p">(</span><span class="s2">"image"</span><span class="p">)</span> - <span class="n">cv2</span><span class="o">.</span><span class="n">setMouseCallback</span><span class="p">(</span><span class="s2">"image"</span><span class="p">,</span> <span class="n">mouse_crop</span><span class="p">)</span> - - <span class="k">while</span> <span class="kc">True</span><span class="p">:</span> - <span class="n">i</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> - <span class="k">if</span> <span class="ow">not</span> <span class="n">cropping</span><span class="p">:</span> - <span class="n">cv2</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="s2">"image"</span><span class="p">,</span> <span class="n">image</span><span class="p">)</span> - <span class="k">elif</span> <span class="n">cropping</span><span class="p">:</span> - <span class="n">cv2</span><span class="o">.</span><span class="n">imshow</span><span class="p">(</span><span class="s2">"image"</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> - <span class="k">if</span> <span class="ow">not</span> <span class="n">fixed</span><span class="p">:</span> - <span class="n">cv2</span><span class="o">.</span><span class="n">rectangle</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="p">(</span><span class="n">x_start</span><span class="p">,</span> <span class="n">y_start</span><span class="p">),</span> - <span class="p">(</span><span class="n">x_end</span><span class="p">,</span> <span class="n">y_end</span><span class="p">),</span> <span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span> - <span class="n">key</span> <span class="o">=</span> <span class="n">cv2</span><span class="o">.</span><span class="n">waitKey</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> - <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="nb">ord</span><span class="p">(</span><span class="s1">'q'</span><span class="p">):</span> - <span class="n">cv2</span><span class="o">.</span><span class="n">destroyAllWindows</span><span class="p">()</span> - <span class="k">return</span> <span class="n">get_cropping_coordinates_from_file</span><span class="p">(</span><span class="n">destination_directory_path</span><span class="o">=</span><span class="n">destination_directory_path</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="get_cropping_coordinates_from_file"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.get_cropping_coordinates_from_file">[docs]</a> -<span class="k">def</span> <span class="nf">get_cropping_coordinates_from_file</span><span class="p">(</span><span class="n">destination_directory_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="nb">list</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Get cropping coordinates from a file where it's stored</span> - -<span class="sd"> Args:</span> -<span class="sd"> destination_directory_path (str): path of the file in which the cropping coordinates are stored</span> - -<span class="sd"> Returns:</span> -<span class="sd"> cropping_coordinates (list): list containing cropping coordinates</span> -<span class="sd"> """</span> - <span class="n">cropping_coordinates</span> <span class="o">=</span> <span class="p">[]</span> - - <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">destination_directory_path</span><span class="o">+</span><span class="s1">'/cropping_coordinates.txt'</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span> <span class="k">as</span> <span class="n">filehandle</span><span class="p">:</span> - <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">filehandle</span><span class="p">:</span> - <span class="c1"># Remove linebreak which is the last character of the string</span> - <span class="n">curr_place</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="n">line</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> - <span class="c1"># Add item to the list</span> - <span class="n">cropping_coordinates</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">curr_place</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">cropping_coordinates</span></div> - - - -<div class="viewcode-block" id="crop_image"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.crop_image">[docs]</a> -<span class="k">def</span> <span class="nf">crop_image</span><span class="p">(</span><span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">image_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">cropping_coordinates</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">model_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">processed_images_path</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span> -<span class="w"> </span><span class="sd">"""Crop an image using given cropping coordinates and store the result in a given folder</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy array): image to be cropped</span> -<span class="sd"> image_path (str): path of the image</span> -<span class="sd"> cropping_coordinates (list): list of coordinates of cropping, format [(x1, y1), (x2, y2)]</span> -<span class="sd"> model_name (str): name of the model (stripmap, spotlight or sar2sar)</span> -<span class="sd"> processed_images_path (str): path of the folder where to store the cropped image in npy format</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="n">model_name</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"spotlight"</span><span class="p">,</span> <span class="s2">"stripmap"</span><span class="p">]:</span> - <span class="n">image_real_part</span> <span class="o">=</span> <span class="n">image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]</span> - <span class="n">image_imaginary_part</span> <span class="o">=</span> <span class="n">image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">1</span><span class="p">]</span> - - <span class="n">cropped_image_real_part</span> <span class="o">=</span> <span class="n">image_real_part</span><span class="p">[</span><span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:</span><span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">,</span> - <span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:</span><span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">]</span> - <span class="n">cropped_image_imaginary_part</span> <span class="o">=</span> <span class="n">image_imaginary_part</span><span class="p">[</span><span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:</span><span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">,</span> - <span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:</span><span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">]</span> - - <span class="n">cropped_image_real_part</span> <span class="o">=</span> <span class="n">cropped_image_real_part</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">cropped_image_real_part</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> - <span class="n">cropped_image_real_part</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span> - <span class="n">cropped_image_imaginary_part</span> <span class="o">=</span> <span class="n">cropped_image_imaginary_part</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">cropped_image_imaginary_part</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> - <span class="n">cropped_image_imaginary_part</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span> - - <span class="n">cropped_image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">concatenate</span><span class="p">(</span> - <span class="p">(</span><span class="n">cropped_image_real_part</span><span class="p">,</span> <span class="n">cropped_image_imaginary_part</span><span class="p">),</span> <span class="n">axis</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">cropped_image</span> <span class="o">=</span> <span class="n">image</span><span class="p">[</span><span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:</span><span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">,</span> - <span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">:</span><span class="n">cropping_coordinates</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">]</span> - - <span class="n">cropped_image</span> <span class="o">=</span> <span class="n">cropped_image</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span> - <span class="n">cropped_image</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">cropped_image</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span> - - <span class="n">image_path_name</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span> - <span class="n">np</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">processed_images_path</span> <span class="o">+</span> <span class="s1">'/'</span> <span class="o">+</span> <span class="n">image_path_name</span><span class="o">.</span><span class="n">stem</span> <span class="o">+</span> - <span class="s1">'_cropped_to_denoise'</span><span class="p">,</span> <span class="n">cropped_image</span><span class="p">)</span></div> - - - -<div class="viewcode-block" id="preprocess_sar_image_for_cropping"> -<a class="viewcode-back" href="../../../modules.html#deepdespeckling.utils.utils.preprocess_sar_image_for_cropping">[docs]</a> -<span class="k">def</span> <span class="nf">preprocess_sar_image_for_cropping</span><span class="p">(</span><span class="n">image</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">model_name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">:</span> -<span class="w"> </span><span class="sd">"""Preprocess image to use the cropping tool</span> - -<span class="sd"> Args:</span> -<span class="sd"> image (numpy array): image from which we get cropping coordinates by using the cropping tool</span> -<span class="sd"> model_name (str): name of the model (stripmap, spotlight or sar2sar)</span> - -<span class="sd"> Returns:</span> -<span class="sd"> image (cv2 image): image preprocessed for cropping</span> -<span class="sd"> """</span> - <span class="k">if</span> <span class="n">model_name</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"spotlight"</span><span class="p">,</span> <span class="s2">"stripmap"</span><span class="p">]:</span> - <span class="n">image_data_real</span> <span class="o">=</span> <span class="n">image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]</span> - <span class="n">image_data_imag</span> <span class="o">=</span> <span class="n">image</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">1</span><span class="p">]</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">squeeze</span><span class="p">(</span> - <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">square</span><span class="p">(</span><span class="n">image_data_real</span><span class="p">)</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">square</span><span class="p">(</span><span class="n">image_data_imag</span><span class="p">)))</span> - - <span class="n">threshold</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">image</span><span class="p">)</span> <span class="o">+</span> <span class="mi">3</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">std</span><span class="p">(</span><span class="n">image</span><span class="p">)</span> - - <span class="n">image</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">clip</span><span class="p">(</span><span class="n">image</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">threshold</span><span class="p">)</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">image</span> <span class="o">/</span> <span class="n">threshold</span> <span class="o">*</span> <span class="mi">255</span> - - <span class="n">image</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">fromarray</span><span class="p">(</span><span class="n">image</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="s1">'float64'</span><span class="p">))</span><span class="o">.</span><span class="n">convert</span><span class="p">(</span><span class="s1">'L'</span><span class="p">)</span> - <span class="n">image</span> <span class="o">=</span> <span class="n">cv2</span><span class="o">.</span><span class="n">cvtColor</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">image</span><span class="p">),</span> <span class="n">cv2</span><span class="o">.</span><span class="n">COLOR_RGB2BGR</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">image</span></div> - -</pre></div> - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="../../../index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="../../../index.html">Documentation overview</a><ul> - <li><a href="../../index.html">Module code</a><ul> - </ul></li> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="../../../search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/_modules/index.html b/docs/_modules/index.html deleted file mode 100644 index 3474cb0..0000000 --- a/docs/_modules/index.html +++ /dev/null @@ -1,105 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="../"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>Overview: module code — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=12dfc556" /> - <script src="../_static/documentation_options.js?v=cb255500"></script> - <script src="../_static/doctools.js?v=888ff710"></script> - <script src="../_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="../genindex.html" /> - <link rel="search" title="Search" href="../search.html" /> - - <link rel="stylesheet" href="../_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <h1>All modules for which code is available</h1> -<ul><li><a href="deepdespeckling/denoiser.html">deepdespeckling.denoiser</a></li> -<li><a href="deepdespeckling/despeckling.html">deepdespeckling.despeckling</a></li> -<li><a href="deepdespeckling/merlin/merlin_denoiser.html">deepdespeckling.merlin.merlin_denoiser</a></li> -<li><a href="deepdespeckling/model.html">deepdespeckling.model</a></li> -<li><a href="deepdespeckling/sar2sar/sar2sar_denoiser.html">deepdespeckling.sar2sar.sar2sar_denoiser</a></li> -<li><a href="deepdespeckling/utils/load_cosar.html">deepdespeckling.utils.load_cosar</a></li> -<li><a href="deepdespeckling/utils/utils.html">deepdespeckling.utils.utils</a></li> -</ul> - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="../index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="../modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="../index.html">Documentation overview</a><ul> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="../search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/_sources/index.rst.txt b/docs/_sources/index.rst.txt deleted file mode 100644 index cc2aca5..0000000 --- a/docs/_sources/index.rst.txt +++ /dev/null @@ -1,22 +0,0 @@ -.. deepdespeckling documentation master file, created by - sphinx-quickstart on Thu Mar 28 11:09:21 2024. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to deepdespeckling's documentation! -=========================================== - -.. toctree:: - :maxdepth: 3 - :caption: Contents: - - modules - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/_sources/modules.rst.txt b/docs/_sources/modules.rst.txt deleted file mode 100644 index 705f7c9..0000000 --- a/docs/_sources/modules.rst.txt +++ /dev/null @@ -1,72 +0,0 @@ -.. toctree:: - :maxdepth: 3 - :caption: Contents: - -deepdespeckling -================= -.. automodule:: deepdespeckling - :members: - :undoc-members: - :show-inheritance: - -denoiser --------- - -.. automodule:: deepdespeckling.denoiser - :members: - :undoc-members: - :show-inheritance: - - -despeckling --------- - -.. automodule:: deepdespeckling.despeckling - :members: - :undoc-members: - :show-inheritance: - - -model --------- - -.. automodule:: deepdespeckling.model - :members: - :undoc-members: - :show-inheritance: - - -merlin_denoiser --------- - -.. automodule:: deepdespeckling.merlin.merlin_denoiser - :members: - :undoc-members: - :show-inheritance: - -sar2sar_denoiser --------- - -.. automodule:: deepdespeckling.sar2sar.sar2sar_denoiser - :members: - :undoc-members: - :show-inheritance: - -utils --------- - -.. automodule:: deepdespeckling.utils.utils - :members: - :undoc-members: - :show-inheritance: - - -load_cosar --------- - -.. automodule:: deepdespeckling.utils.load_cosar - :members: - :undoc-members: - :show-inheritance: - - diff --git a/docs/_static/alabaster.css b/docs/_static/alabaster.css deleted file mode 100644 index e3174bf..0000000 --- a/docs/_static/alabaster.css +++ /dev/null @@ -1,708 +0,0 @@ -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: Georgia, serif; - font-size: 17px; - background-color: #fff; - color: #000; - margin: 0; - padding: 0; -} - - -div.document { - width: 940px; - margin: 30px auto 0 auto; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 220px; -} - -div.sphinxsidebar { - width: 220px; - font-size: 14px; - line-height: 1.5; -} - -hr { - border: 1px solid #B1B4B6; -} - -div.body { - background-color: #fff; - color: #3E4349; - padding: 0 30px 0 30px; -} - -div.body > .section { - text-align: left; -} - -div.footer { - width: 940px; - margin: 20px auto 30px auto; - font-size: 14px; - color: #888; - text-align: right; -} - -div.footer a { - color: #888; -} - -p.caption { - font-family: inherit; - font-size: inherit; -} - - -div.relations { - display: none; -} - - -div.sphinxsidebar { - max-height: 100%; - overflow-y: auto; -} - -div.sphinxsidebar a { - color: #444; - text-decoration: none; - border-bottom: 1px dotted #999; -} - -div.sphinxsidebar a:hover { - border-bottom: 1px solid #999; -} - -div.sphinxsidebarwrapper { - padding: 18px 10px; -} - -div.sphinxsidebarwrapper p.logo { - padding: 0; - margin: -10px 0 0 0px; - text-align: center; -} - -div.sphinxsidebarwrapper h1.logo { - margin-top: -10px; - text-align: center; - margin-bottom: 5px; - text-align: left; -} - -div.sphinxsidebarwrapper h1.logo-name { - margin-top: 0px; -} - -div.sphinxsidebarwrapper p.blurb { - margin-top: 0; - font-style: normal; -} - -div.sphinxsidebar h3, -div.sphinxsidebar h4 { - font-family: Georgia, serif; - color: #444; - font-size: 24px; - font-weight: normal; - margin: 0 0 5px 0; - padding: 0; -} - -div.sphinxsidebar h4 { - font-size: 20px; -} - -div.sphinxsidebar h3 a { - color: #444; -} - -div.sphinxsidebar p.logo a, -div.sphinxsidebar h3 a, -div.sphinxsidebar p.logo a:hover, -div.sphinxsidebar h3 a:hover { - border: none; -} - -div.sphinxsidebar p { - color: #555; - margin: 10px 0; -} - -div.sphinxsidebar ul { - margin: 10px 0; - padding: 0; - color: #000; -} - -div.sphinxsidebar ul li.toctree-l1 > a { - font-size: 120%; -} - -div.sphinxsidebar ul li.toctree-l2 > a { - font-size: 110%; -} - -div.sphinxsidebar input { - border: 1px solid #CCC; - font-family: Georgia, serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 160px; -} - -div.sphinxsidebar .search > div { - display: table-cell; -} - -div.sphinxsidebar hr { - border: none; - height: 1px; - color: #AAA; - background: #AAA; - - text-align: left; - margin-left: 0; - width: 50%; -} - -div.sphinxsidebar .badge { - border-bottom: none; -} - -div.sphinxsidebar .badge:hover { - border-bottom: none; -} - -/* To address an issue with donation coming after search */ -div.sphinxsidebar h3.donation { - margin-top: 10px; -} - -/* -- body styles ----------------------------------------------------------- */ - -a { - color: #004B6B; - text-decoration: underline; -} - -a:hover { - color: #6D4100; - text-decoration: underline; -} - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: Georgia, serif; - font-weight: normal; - margin: 30px 0px 10px 0px; - padding: 0; -} - -div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } -div.body h2 { font-size: 180%; } -div.body h3 { font-size: 150%; } -div.body h4 { font-size: 130%; } -div.body h5 { font-size: 100%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: #DDD; - padding: 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - color: #444; - background: #EAEAEA; -} - -div.body p, div.body dd, div.body li { - line-height: 1.4em; -} - -div.admonition { - margin: 20px 0px; - padding: 10px 30px; - background-color: #EEE; - border: 1px solid #CCC; -} - -div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { - background-color: #FBFBFB; - border-bottom: 1px solid #fafafa; -} - -div.admonition p.admonition-title { - font-family: Georgia, serif; - font-weight: normal; - font-size: 24px; - margin: 0 0 10px 0; - padding: 0; - line-height: 1; -} - -div.admonition p.last { - margin-bottom: 0; -} - -div.highlight { - background-color: #fff; -} - -dt:target, .highlight { - background: #FAF3E8; -} - -div.warning { - background-color: #FCC; - border: 1px solid #FAA; -} - -div.danger { - background-color: #FCC; - border: 1px solid #FAA; - -moz-box-shadow: 2px 2px 4px #D52C2C; - -webkit-box-shadow: 2px 2px 4px #D52C2C; - box-shadow: 2px 2px 4px #D52C2C; -} - -div.error { - background-color: #FCC; - border: 1px solid #FAA; - -moz-box-shadow: 2px 2px 4px #D52C2C; - -webkit-box-shadow: 2px 2px 4px #D52C2C; - box-shadow: 2px 2px 4px #D52C2C; -} - -div.caution { - background-color: #FCC; - border: 1px solid #FAA; -} - -div.attention { - background-color: #FCC; - border: 1px solid #FAA; -} - -div.important { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.note { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.tip { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.hint { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.seealso { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.topic { - background-color: #EEE; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre, tt, code { - font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; - font-size: 0.9em; -} - -.hll { - background-color: #FFC; - margin: 0 -12px; - padding: 0 12px; - display: block; -} - -img.screenshot { -} - -tt.descname, tt.descclassname, code.descname, code.descclassname { - font-size: 0.95em; -} - -tt.descname, code.descname { - padding-right: 0.08em; -} - -img.screenshot { - -moz-box-shadow: 2px 2px 4px #EEE; - -webkit-box-shadow: 2px 2px 4px #EEE; - box-shadow: 2px 2px 4px #EEE; -} - -table.docutils { - border: 1px solid #888; - -moz-box-shadow: 2px 2px 4px #EEE; - -webkit-box-shadow: 2px 2px 4px #EEE; - box-shadow: 2px 2px 4px #EEE; -} - -table.docutils td, table.docutils th { - border: 1px solid #888; - padding: 0.25em 0.7em; -} - -table.field-list, table.footnote { - border: none; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -table.footnote { - margin: 15px 0; - width: 100%; - border: 1px solid #EEE; - background: #FDFDFD; - font-size: 0.9em; -} - -table.footnote + table.footnote { - margin-top: -15px; - border-top: none; -} - -table.field-list th { - padding: 0 0.8em 0 0; -} - -table.field-list td { - padding: 0; -} - -table.field-list p { - margin-bottom: 0.8em; -} - -/* Cloned from - * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 - */ -.field-name { - -moz-hyphens: manual; - -ms-hyphens: manual; - -webkit-hyphens: manual; - hyphens: manual; -} - -table.footnote td.label { - width: .1px; - padding: 0.3em 0 0.3em 0.5em; -} - -table.footnote td { - padding: 0.3em 0.5em; -} - -dl { - margin-left: 0; - margin-right: 0; - margin-top: 0; - padding: 0; -} - -dl dd { - margin-left: 30px; -} - -blockquote { - margin: 0 0 0 30px; - padding: 0; -} - -ul, ol { - /* Matches the 30px from the narrow-screen "li > ul" selector below */ - margin: 10px 0 10px 30px; - padding: 0; -} - -pre { - background: #EEE; - padding: 7px 30px; - margin: 15px 0px; - line-height: 1.3em; -} - -div.viewcode-block:target { - background: #ffd; -} - -dl pre, blockquote pre, li pre { - margin-left: 0; - padding-left: 30px; -} - -tt, code { - background-color: #ecf0f3; - color: #222; - /* padding: 1px 2px; */ -} - -tt.xref, code.xref, a tt { - background-color: #FBFBFB; - border-bottom: 1px solid #fff; -} - -a.reference { - text-decoration: none; - border-bottom: 1px dotted #004B6B; -} - -/* Don't put an underline on images */ -a.image-reference, a.image-reference:hover { - border-bottom: none; -} - -a.reference:hover { - border-bottom: 1px solid #6D4100; -} - -a.footnote-reference { - text-decoration: none; - font-size: 0.7em; - vertical-align: top; - border-bottom: 1px dotted #004B6B; -} - -a.footnote-reference:hover { - border-bottom: 1px solid #6D4100; -} - -a:hover tt, a:hover code { - background: #EEE; -} - - -@media screen and (max-width: 870px) { - - div.sphinxsidebar { - display: none; - } - - div.document { - width: 100%; - - } - - div.documentwrapper { - margin-left: 0; - margin-top: 0; - margin-right: 0; - margin-bottom: 0; - } - - div.bodywrapper { - margin-top: 0; - margin-right: 0; - margin-bottom: 0; - margin-left: 0; - } - - ul { - margin-left: 0; - } - - li > ul { - /* Matches the 30px from the "ul, ol" selector above */ - margin-left: 30px; - } - - .document { - width: auto; - } - - .footer { - width: auto; - } - - .bodywrapper { - margin: 0; - } - - .footer { - width: auto; - } - - .github { - display: none; - } - - - -} - - - -@media screen and (max-width: 875px) { - - body { - margin: 0; - padding: 20px 30px; - } - - div.documentwrapper { - float: none; - background: #fff; - } - - div.sphinxsidebar { - display: block; - float: none; - width: 102.5%; - margin: 50px -30px -20px -30px; - padding: 10px 20px; - background: #333; - color: #FFF; - } - - div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, - div.sphinxsidebar h3 a { - color: #fff; - } - - div.sphinxsidebar a { - color: #AAA; - } - - div.sphinxsidebar p.logo { - display: none; - } - - div.document { - width: 100%; - margin: 0; - } - - div.footer { - display: none; - } - - div.bodywrapper { - margin: 0; - } - - div.body { - min-height: 0; - padding: 0; - } - - .rtd_doc_footer { - display: none; - } - - .document { - width: auto; - } - - .footer { - width: auto; - } - - .footer { - width: auto; - } - - .github { - display: none; - } -} - - -/* misc. */ - -.revsys-inline { - display: none!important; -} - -/* Hide ugly table cell borders in ..bibliography:: directive output */ -table.docutils.citation, table.docutils.citation td, table.docutils.citation th { - border: none; - /* Below needed in some edge cases; if not applied, bottom shadows appear */ - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - - -/* relbar */ - -.related { - line-height: 30px; - width: 100%; - font-size: 0.9rem; -} - -.related.top { - border-bottom: 1px solid #EEE; - margin-bottom: 20px; -} - -.related.bottom { - border-top: 1px solid #EEE; -} - -.related ul { - padding: 0; - margin: 0; - list-style: none; -} - -.related li { - display: inline; -} - -nav#rellinks { - float: right; -} - -nav#rellinks li+li:before { - content: "|"; -} - -nav#breadcrumbs li+li:before { - content: "\00BB"; -} - -/* Hide certain items when printing */ -@media print { - div.related { - display: none; - } -} \ No newline at end of file diff --git a/docs/_static/basic.css b/docs/_static/basic.css deleted file mode 100644 index 4157edf..0000000 --- a/docs/_static/basic.css +++ /dev/null @@ -1,925 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -div.section::after { - display: block; - content: ''; - clear: left; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; - word-wrap: break-word; - overflow-wrap : break-word; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox form.search { - overflow: hidden; -} - -div.sphinxsidebar #searchbox input[type="text"] { - float: left; - width: 80%; - padding: 0.25em; - box-sizing: border-box; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - float: left; - width: 20%; - border-left: none; - padding: 0.25em; - box-sizing: border-box; -} - - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li p.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; - margin-left: auto; - margin-right: auto; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable ul { - margin-top: 0; - margin-bottom: 0; - list-style-type: none; -} - -table.indextable > tbody > tr > td > ul { - padding-left: 0em; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- domain module index --------------------------------------------------- */ - -table.modindextable td { - padding: 2px; - border-collapse: collapse; -} - -/* -- general body styles --------------------------------------------------- */ - -div.body { - min-width: inherit; - max-width: 800px; -} - -div.body p, div.body dd, div.body li, div.body blockquote { - -moz-hyphens: auto; - -ms-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - -a.headerlink { - visibility: hidden; -} - -a:visited { - color: #551A8B; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink, -caption:hover > a.headerlink, -p.caption:hover > a.headerlink, -div.code-block-caption:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, figure.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, figure.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, figure.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -img.align-default, figure.align-default, .figure.align-default { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-default { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar, -aside.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px; - background-color: #ffe; - width: 40%; - float: right; - clear: right; - overflow-x: auto; -} - -p.sidebar-title { - font-weight: bold; -} - -nav.contents, -aside.topic, -div.admonition, div.topic, blockquote { - clear: left; -} - -/* -- topics ---------------------------------------------------------------- */ - -nav.contents, -aside.topic, -div.topic { - border: 1px solid #ccc; - padding: 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- content of sidebars/topics/admonitions -------------------------------- */ - -div.sidebar > :last-child, -aside.sidebar > :last-child, -nav.contents > :last-child, -aside.topic > :last-child, -div.topic > :last-child, -div.admonition > :last-child { - margin-bottom: 0; -} - -div.sidebar::after, -aside.sidebar::after, -nav.contents::after, -aside.topic::after, -div.topic::after, -div.admonition::after, -blockquote::after { - display: block; - content: ''; - clear: both; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - margin-top: 10px; - margin-bottom: 10px; - border: 0; - border-collapse: collapse; -} - -table.align-center { - margin-left: auto; - margin-right: auto; -} - -table.align-default { - margin-left: auto; - margin-right: auto; -} - -table caption span.caption-number { - font-style: italic; -} - -table caption span.caption-text { -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -th > :first-child, -td > :first-child { - margin-top: 0px; -} - -th > :last-child, -td > :last-child { - margin-bottom: 0px; -} - -/* -- figures --------------------------------------------------------------- */ - -div.figure, figure { - margin: 0.5em; - padding: 0.5em; -} - -div.figure p.caption, figcaption { - padding: 0.3em; -} - -div.figure p.caption span.caption-number, -figcaption span.caption-number { - font-style: italic; -} - -div.figure p.caption span.caption-text, -figcaption span.caption-text { -} - -/* -- field list styles ----------------------------------------------------- */ - -table.field-list td, table.field-list th { - border: 0 !important; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.field-name { - -moz-hyphens: manual; - -ms-hyphens: manual; - -webkit-hyphens: manual; - hyphens: manual; -} - -/* -- hlist styles ---------------------------------------------------------- */ - -table.hlist { - margin: 1em 0; -} - -table.hlist td { - vertical-align: top; -} - -/* -- object description styles --------------------------------------------- */ - -.sig { - font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; -} - -.sig-name, code.descname { - background-color: transparent; - font-weight: bold; -} - -.sig-name { - font-size: 1.1em; -} - -code.descname { - font-size: 1.2em; -} - -.sig-prename, code.descclassname { - background-color: transparent; -} - -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - -.sig-param.n { - font-style: italic; -} - -/* C++ specific styling */ - -.sig-inline.c-texpr, -.sig-inline.cpp-texpr { - font-family: unset; -} - -.sig.c .k, .sig.c .kt, -.sig.cpp .k, .sig.cpp .kt { - color: #0033B3; -} - -.sig.c .m, -.sig.cpp .m { - color: #1750EB; -} - -.sig.c .s, .sig.c .sc, -.sig.cpp .s, .sig.cpp .sc { - color: #067D17; -} - - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -:not(li) > ol > li:first-child > :first-child, -:not(li) > ul > li:first-child > :first-child { - margin-top: 0px; -} - -:not(li) > ol > li:last-child > :last-child, -:not(li) > ul > li:last-child > :last-child { - margin-bottom: 0px; -} - -ol.simple ol p, -ol.simple ul p, -ul.simple ol p, -ul.simple ul p { - margin-top: 0; -} - -ol.simple > li:not(:first-child) > p, -ul.simple > li:not(:first-child) > p { - margin-top: 0; -} - -ol.simple p, -ul.simple p { - margin-bottom: 0; -} - -aside.footnote > span, -div.citation > span { - float: left; -} -aside.footnote > span:last-of-type, -div.citation > span:last-of-type { - padding-right: 0.5em; -} -aside.footnote > p { - margin-left: 2em; -} -div.citation > p { - margin-left: 4em; -} -aside.footnote > p:last-of-type, -div.citation > p:last-of-type { - margin-bottom: 0em; -} -aside.footnote > p:last-of-type:after, -div.citation > p:last-of-type:after { - content: ""; - clear: both; -} - -dl.field-list { - display: grid; - grid-template-columns: fit-content(30%) auto; -} - -dl.field-list > dt { - font-weight: bold; - word-break: break-word; - padding-left: 0.5em; - padding-right: 5px; -} - -dl.field-list > dd { - padding-left: 0.5em; - margin-top: 0em; - margin-left: 0em; - margin-bottom: 0em; -} - -dl { - margin-bottom: 15px; -} - -dd > :first-child { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -.sig dd { - margin-top: 0px; - margin-bottom: 0px; -} - -.sig dl { - margin-top: 0px; - margin-bottom: 0px; -} - -dl > dd:last-child, -dl > dd:last-child > :last-child { - margin-bottom: 0; -} - -dt:target, span.highlighted { - background-color: #fbe54e; -} - -rect.highlighted { - fill: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -.classifier:before { - font-style: normal; - margin: 0 0.5em; - content: ":"; - display: inline-block; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -.translated { - background-color: rgba(207, 255, 207, 0.2) -} - -.untranslated { - background-color: rgba(255, 207, 207, 0.2) -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -pre, div[class*="highlight-"] { - clear: both; -} - -span.pre { - -moz-hyphens: none; - -ms-hyphens: none; - -webkit-hyphens: none; - hyphens: none; - white-space: nowrap; -} - -div[class*="highlight-"] { - margin: 1em 0; -} - -td.linenos pre { - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - display: block; -} - -table.highlighttable tbody { - display: block; -} - -table.highlighttable tr { - display: flex; -} - -table.highlighttable td { - margin: 0; - padding: 0; -} - -table.highlighttable td.linenos { - padding-right: 0.5em; -} - -table.highlighttable td.code { - flex: 1; - overflow: hidden; -} - -.highlight .hll { - display: block; -} - -div.highlight pre, -table.highlighttable pre { - margin: 0; -} - -div.code-block-caption + div { - margin-top: 0; -} - -div.code-block-caption { - margin-top: 1em; - padding: 2px 5px; - font-size: small; -} - -div.code-block-caption code { - background-color: transparent; -} - -table.highlighttable td.linenos, -span.linenos, -div.highlight span.gp { /* gp: Generic.Prompt */ - user-select: none; - -webkit-user-select: text; /* Safari fallback only */ - -webkit-user-select: none; /* Chrome/Safari */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* IE10+ */ -} - -div.code-block-caption span.caption-number { - padding: 0.1em 0.3em; - font-style: italic; -} - -div.code-block-caption span.caption-text { -} - -div.literal-block-wrapper { - margin: 1em 0; -} - -code.xref, a code { - background-color: transparent; - font-weight: bold; -} - -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -span.eqno a.headerlink { - position: absolute; - z-index: 1; -} - -div.math:hover a.headerlink { - visibility: visible; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/docs/_static/custom.css b/docs/_static/custom.css deleted file mode 100644 index 2a924f1..0000000 --- a/docs/_static/custom.css +++ /dev/null @@ -1 +0,0 @@ -/* This file intentionally left blank. */ diff --git a/docs/_static/doctools.js b/docs/_static/doctools.js deleted file mode 100644 index d06a71d..0000000 --- a/docs/_static/doctools.js +++ /dev/null @@ -1,156 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Base JavaScript utilities for all Sphinx HTML documentation. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ -"use strict"; - -const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ - "TEXTAREA", - "INPUT", - "SELECT", - "BUTTON", -]); - -const _ready = (callback) => { - if (document.readyState !== "loading") { - callback(); - } else { - document.addEventListener("DOMContentLoaded", callback); - } -}; - -/** - * Small JavaScript module for the documentation. - */ -const Documentation = { - init: () => { - Documentation.initDomainIndexTable(); - Documentation.initOnKeyListeners(); - }, - - /** - * i18n support - */ - TRANSLATIONS: {}, - PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), - LOCALE: "unknown", - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext: (string) => { - const translated = Documentation.TRANSLATIONS[string]; - switch (typeof translated) { - case "undefined": - return string; // no translation - case "string": - return translated; // translation exists - default: - return translated[0]; // (singular, plural) translation tuple exists - } - }, - - ngettext: (singular, plural, n) => { - const translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated !== "undefined") - return translated[Documentation.PLURAL_EXPR(n)]; - return n === 1 ? singular : plural; - }, - - addTranslations: (catalog) => { - Object.assign(Documentation.TRANSLATIONS, catalog.messages); - Documentation.PLURAL_EXPR = new Function( - "n", - `return (${catalog.plural_expr})` - ); - Documentation.LOCALE = catalog.locale; - }, - - /** - * helper function to focus on search bar - */ - focusSearchBar: () => { - document.querySelectorAll("input[name=q]")[0]?.focus(); - }, - - /** - * Initialise the domain index toggle buttons - */ - initDomainIndexTable: () => { - const toggler = (el) => { - const idNumber = el.id.substr(7); - const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); - if (el.src.substr(-9) === "minus.png") { - el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; - toggledRows.forEach((el) => (el.style.display = "none")); - } else { - el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; - toggledRows.forEach((el) => (el.style.display = "")); - } - }; - - const togglerElements = document.querySelectorAll("img.toggler"); - togglerElements.forEach((el) => - el.addEventListener("click", (event) => toggler(event.currentTarget)) - ); - togglerElements.forEach((el) => (el.style.display = "")); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); - }, - - initOnKeyListeners: () => { - // only install a listener if it is really needed - if ( - !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && - !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS - ) - return; - - document.addEventListener("keydown", (event) => { - // bail for input elements - if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; - // bail with special keys - if (event.altKey || event.ctrlKey || event.metaKey) return; - - if (!event.shiftKey) { - switch (event.key) { - case "ArrowLeft": - if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; - - const prevLink = document.querySelector('link[rel="prev"]'); - if (prevLink && prevLink.href) { - window.location.href = prevLink.href; - event.preventDefault(); - } - break; - case "ArrowRight": - if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; - - const nextLink = document.querySelector('link[rel="next"]'); - if (nextLink && nextLink.href) { - window.location.href = nextLink.href; - event.preventDefault(); - } - break; - } - } - - // some keyboard layouts may need Shift to get / - switch (event.key) { - case "/": - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; - Documentation.focusSearchBar(); - event.preventDefault(); - } - }); - }, -}; - -// quick alias for translations -const _ = Documentation.gettext; - -_ready(Documentation.init); diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js deleted file mode 100644 index fef3410..0000000 --- a/docs/_static/documentation_options.js +++ /dev/null @@ -1,13 +0,0 @@ -const DOCUMENTATION_OPTIONS = { - VERSION: '0.3', - LANGUAGE: 'English', - COLLAPSE_INDEX: false, - BUILDER: 'html', - FILE_SUFFIX: '.html', - LINK_SUFFIX: '.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt', - NAVIGATION_WITH_KEYS: false, - SHOW_SEARCH_SUMMARY: true, - ENABLE_SEARCH_SHORTCUTS: true, -}; \ No newline at end of file diff --git a/docs/_static/file.png b/docs/_static/file.png deleted file mode 100644 index a858a410e4faa62ce324d814e4b816fff83a6fb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 286 zcmV+(0pb3MP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0002xNkl<Zcmb`G zgHi?o6ovOGdxdP*AltSE*&JruJwUGI3!FN?xxO>s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHD<M{a4P!N^sPbQKi=?mBx zoos%BSoiGXjr-;%$QixXMOVNSUNp6L0a1Oz&cgu)wqE?07u5I7qrQIu4Fij)Y3c&0 z@0u_#NH6I?Mk(n;dT}d~^J<WkTLqp|RW-hV56tKpXqu)k@V{?amI+5DOlEU@funz+ kySsbM>fiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( diff --git a/docs/_static/language_data.js b/docs/_static/language_data.js deleted file mode 100644 index 250f566..0000000 --- a/docs/_static/language_data.js +++ /dev/null @@ -1,199 +0,0 @@ -/* - * language_data.js - * ~~~~~~~~~~~~~~~~ - * - * This script contains the language-specific data used by searchtools.js, - * namely the list of stopwords, stemmer, scorer and splitter. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; - - -/* Non-minified version is copied as a separate JS file, is available */ - -/** - * Porter Stemmer - */ -var Stemmer = function() { - - var step2list = { - ational: 'ate', - tional: 'tion', - enci: 'ence', - anci: 'ance', - izer: 'ize', - bli: 'ble', - alli: 'al', - entli: 'ent', - eli: 'e', - ousli: 'ous', - ization: 'ize', - ation: 'ate', - ator: 'ate', - alism: 'al', - iveness: 'ive', - fulness: 'ful', - ousness: 'ous', - aliti: 'al', - iviti: 'ive', - biliti: 'ble', - logi: 'log' - }; - - var step3list = { - icate: 'ic', - ative: '', - alize: 'al', - iciti: 'ic', - ical: 'ic', - ful: '', - ness: '' - }; - - var c = "[^aeiou]"; // consonant - var v = "[aeiouy]"; // vowel - var C = c + "[^aeiouy]*"; // consonant sequence - var V = v + "[aeiou]*"; // vowel sequence - - var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 - var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 - var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 - var s_v = "^(" + C + ")?" + v; // vowel in stem - - this.stemWord = function (w) { - var stem; - var suffix; - var firstch; - var origword = w; - - if (w.length < 3) - return w; - - var re; - var re2; - var re3; - var re4; - - firstch = w.substr(0,1); - if (firstch == "y") - w = firstch.toUpperCase() + w.substr(1); - - // Step 1a - re = /^(.+?)(ss|i)es$/; - re2 = /^(.+?)([^s])s$/; - - if (re.test(w)) - w = w.replace(re,"$1$2"); - else if (re2.test(w)) - w = w.replace(re2,"$1$2"); - - // Step 1b - re = /^(.+?)eed$/; - re2 = /^(.+?)(ed|ing)$/; - if (re.test(w)) { - var fp = re.exec(w); - re = new RegExp(mgr0); - if (re.test(fp[1])) { - re = /.$/; - w = w.replace(re,""); - } - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1]; - re2 = new RegExp(s_v); - if (re2.test(stem)) { - w = stem; - re2 = /(at|bl|iz)$/; - re3 = new RegExp("([^aeiouylsz])\\1$"); - re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re2.test(w)) - w = w + "e"; - else if (re3.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - else if (re4.test(w)) - w = w + "e"; - } - } - - // Step 1c - re = /^(.+?)y$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(s_v); - if (re.test(stem)) - w = stem + "i"; - } - - // Step 2 - re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step2list[suffix]; - } - - // Step 3 - re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - suffix = fp[2]; - re = new RegExp(mgr0); - if (re.test(stem)) - w = stem + step3list[suffix]; - } - - // Step 4 - re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; - re2 = /^(.+?)(s|t)(ion)$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - if (re.test(stem)) - w = stem; - } - else if (re2.test(w)) { - var fp = re2.exec(w); - stem = fp[1] + fp[2]; - re2 = new RegExp(mgr1); - if (re2.test(stem)) - w = stem; - } - - // Step 5 - re = /^(.+?)e$/; - if (re.test(w)) { - var fp = re.exec(w); - stem = fp[1]; - re = new RegExp(mgr1); - re2 = new RegExp(meq1); - re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); - if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) - w = stem; - } - re = /ll$/; - re2 = new RegExp(mgr1); - if (re.test(w) && re2.test(w)) { - re = /.$/; - w = w.replace(re,""); - } - - // and turn initial Y back to y - if (firstch == "y") - w = firstch.toLowerCase() + w.substr(1); - return w; - } -} - diff --git a/docs/_static/minus.png b/docs/_static/minus.png deleted file mode 100644 index d96755fdaf8bb2214971e0db9c1fd3077d7c419d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu=nj kDsEF_5m^0CR;1wuP-*O&G^0G}KYk!hp00i_>zopr08q^qX#fBK diff --git a/docs/_static/plus.png b/docs/_static/plus.png deleted file mode 100644 index 7107cec93a979b9a5f64843235a16651d563ce2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu>-2 m3q%Vub%g%s<8sJhVPMczOq}xhg9DJoz~JfX=d#Wzp$Pyb1r*Kz diff --git a/docs/_static/pygments.css b/docs/_static/pygments.css deleted file mode 100644 index 04a4174..0000000 --- a/docs/_static/pygments.css +++ /dev/null @@ -1,84 +0,0 @@ -pre { line-height: 125%; } -td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } -span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } -td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } -span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } -.highlight .hll { background-color: #ffffcc } -.highlight { background: #f8f8f8; } -.highlight .c { color: #8f5902; font-style: italic } /* Comment */ -.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ -.highlight .g { color: #000000 } /* Generic */ -.highlight .k { color: #004461; font-weight: bold } /* Keyword */ -.highlight .l { color: #000000 } /* Literal */ -.highlight .n { color: #000000 } /* Name */ -.highlight .o { color: #582800 } /* Operator */ -.highlight .x { color: #000000 } /* Other */ -.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ -.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ -.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #8f5902 } /* Comment.Preproc */ -.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ -.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #a40000 } /* Generic.Deleted */ -.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ -.highlight .ges { color: #000000 } /* Generic.EmphStrong */ -.highlight .gr { color: #ef2929 } /* Generic.Error */ -.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #888888 } /* Generic.Output */ -.highlight .gp { color: #745334 } /* Generic.Prompt */ -.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ -.highlight .kc { color: #004461; font-weight: bold } /* Keyword.Constant */ -.highlight .kd { color: #004461; font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { color: #004461; font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { color: #004461; font-weight: bold } /* Keyword.Pseudo */ -.highlight .kr { color: #004461; font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #004461; font-weight: bold } /* Keyword.Type */ -.highlight .ld { color: #000000 } /* Literal.Date */ -.highlight .m { color: #990000 } /* Literal.Number */ -.highlight .s { color: #4e9a06 } /* Literal.String */ -.highlight .na { color: #c4a000 } /* Name.Attribute */ -.highlight .nb { color: #004461 } /* Name.Builtin */ -.highlight .nc { color: #000000 } /* Name.Class */ -.highlight .no { color: #000000 } /* Name.Constant */ -.highlight .nd { color: #888888 } /* Name.Decorator */ -.highlight .ni { color: #ce5c00 } /* Name.Entity */ -.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #000000 } /* Name.Function */ -.highlight .nl { color: #f57900 } /* Name.Label */ -.highlight .nn { color: #000000 } /* Name.Namespace */ -.highlight .nx { color: #000000 } /* Name.Other */ -.highlight .py { color: #000000 } /* Name.Property */ -.highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */ -.highlight .nv { color: #000000 } /* Name.Variable */ -.highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */ -.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */ -.highlight .w { color: #f8f8f8 } /* Text.Whitespace */ -.highlight .mb { color: #990000 } /* Literal.Number.Bin */ -.highlight .mf { color: #990000 } /* Literal.Number.Float */ -.highlight .mh { color: #990000 } /* Literal.Number.Hex */ -.highlight .mi { color: #990000 } /* Literal.Number.Integer */ -.highlight .mo { color: #990000 } /* Literal.Number.Oct */ -.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ -.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ -.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ -.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ -.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ -.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ -.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ -.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ -.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ -.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ -.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ -.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ -.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ -.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #000000 } /* Name.Function.Magic */ -.highlight .vc { color: #000000 } /* Name.Variable.Class */ -.highlight .vg { color: #000000 } /* Name.Variable.Global */ -.highlight .vi { color: #000000 } /* Name.Variable.Instance */ -.highlight .vm { color: #000000 } /* Name.Variable.Magic */ -.highlight .il { color: #990000 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/_static/searchtools.js b/docs/_static/searchtools.js deleted file mode 100644 index 7918c3f..0000000 --- a/docs/_static/searchtools.js +++ /dev/null @@ -1,574 +0,0 @@ -/* - * searchtools.js - * ~~~~~~~~~~~~~~~~ - * - * Sphinx JavaScript utilities for the full-text search. - * - * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ -"use strict"; - -/** - * Simple result scoring code. - */ -if (typeof Scorer === "undefined") { - var Scorer = { - // Implement the following function to further tweak the score for each result - // The function takes a result array [docname, title, anchor, descr, score, filename] - // and returns the new score. - /* - score: result => { - const [docname, title, anchor, descr, score, filename] = result - return score - }, - */ - - // query matches the full name of an object - objNameMatch: 11, - // or matches in the last dotted part of the object name - objPartialMatch: 6, - // Additive scores depending on the priority of the object - objPrio: { - 0: 15, // used to be importantResults - 1: 5, // used to be objectResults - 2: -5, // used to be unimportantResults - }, - // Used when the priority is not in the mapping. - objPrioDefault: 0, - - // query found in title - title: 15, - partialTitle: 7, - // query found in terms - term: 5, - partialTerm: 2, - }; -} - -const _removeChildren = (element) => { - while (element && element.lastChild) element.removeChild(element.lastChild); -}; - -/** - * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping - */ -const _escapeRegExp = (string) => - string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string - -const _displayItem = (item, searchTerms, highlightTerms) => { - const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; - const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; - const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; - const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; - const contentRoot = document.documentElement.dataset.content_root; - - const [docName, title, anchor, descr, score, _filename] = item; - - let listItem = document.createElement("li"); - let requestUrl; - let linkUrl; - if (docBuilder === "dirhtml") { - // dirhtml builder - let dirname = docName + "/"; - if (dirname.match(/\/index\/$/)) - dirname = dirname.substring(0, dirname.length - 6); - else if (dirname === "index/") dirname = ""; - requestUrl = contentRoot + dirname; - linkUrl = requestUrl; - } else { - // normal html builders - requestUrl = contentRoot + docName + docFileSuffix; - linkUrl = docName + docLinkSuffix; - } - let linkEl = listItem.appendChild(document.createElement("a")); - linkEl.href = linkUrl + anchor; - linkEl.dataset.score = score; - linkEl.innerHTML = title; - if (descr) { - listItem.appendChild(document.createElement("span")).innerHTML = - " (" + descr + ")"; - // highlight search terms in the description - if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js - highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); - } - else if (showSearchSummary) - fetch(requestUrl) - .then((responseData) => responseData.text()) - .then((data) => { - if (data) - listItem.appendChild( - Search.makeSearchSummary(data, searchTerms) - ); - // highlight search terms in the summary - if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js - highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); - }); - Search.output.appendChild(listItem); -}; -const _finishSearch = (resultCount) => { - Search.stopPulse(); - Search.title.innerText = _("Search Results"); - if (!resultCount) - Search.status.innerText = Documentation.gettext( - "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." - ); - else - Search.status.innerText = _( - `Search finished, found ${resultCount} page(s) matching the search query.` - ); -}; -const _displayNextItem = ( - results, - resultCount, - searchTerms, - highlightTerms, -) => { - // results left, load the summary and display it - // this is intended to be dynamic (don't sub resultsCount) - if (results.length) { - _displayItem(results.pop(), searchTerms, highlightTerms); - setTimeout( - () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), - 5 - ); - } - // search finished, update title and status message - else _finishSearch(resultCount); -}; - -/** - * Default splitQuery function. Can be overridden in ``sphinx.search`` with a - * custom function per language. - * - * The regular expression works by splitting the string on consecutive characters - * that are not Unicode letters, numbers, underscores, or emoji characters. - * This is the same as ``\W+`` in Python, preserving the surrogate pair area. - */ -if (typeof splitQuery === "undefined") { - var splitQuery = (query) => query - .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) - .filter(term => term) // remove remaining empty strings -} - -/** - * Search Module - */ -const Search = { - _index: null, - _queued_query: null, - _pulse_status: -1, - - htmlToText: (htmlString) => { - const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); - htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); - const docContent = htmlElement.querySelector('[role="main"]'); - if (docContent !== undefined) return docContent.textContent; - console.warn( - "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." - ); - return ""; - }, - - init: () => { - const query = new URLSearchParams(window.location.search).get("q"); - document - .querySelectorAll('input[name="q"]') - .forEach((el) => (el.value = query)); - if (query) Search.performSearch(query); - }, - - loadIndex: (url) => - (document.body.appendChild(document.createElement("script")).src = url), - - setIndex: (index) => { - Search._index = index; - if (Search._queued_query !== null) { - const query = Search._queued_query; - Search._queued_query = null; - Search.query(query); - } - }, - - hasIndex: () => Search._index !== null, - - deferQuery: (query) => (Search._queued_query = query), - - stopPulse: () => (Search._pulse_status = -1), - - startPulse: () => { - if (Search._pulse_status >= 0) return; - - const pulse = () => { - Search._pulse_status = (Search._pulse_status + 1) % 4; - Search.dots.innerText = ".".repeat(Search._pulse_status); - if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); - }; - pulse(); - }, - - /** - * perform a search for something (or wait until index is loaded) - */ - performSearch: (query) => { - // create the required interface elements - const searchText = document.createElement("h2"); - searchText.textContent = _("Searching"); - const searchSummary = document.createElement("p"); - searchSummary.classList.add("search-summary"); - searchSummary.innerText = ""; - const searchList = document.createElement("ul"); - searchList.classList.add("search"); - - const out = document.getElementById("search-results"); - Search.title = out.appendChild(searchText); - Search.dots = Search.title.appendChild(document.createElement("span")); - Search.status = out.appendChild(searchSummary); - Search.output = out.appendChild(searchList); - - const searchProgress = document.getElementById("search-progress"); - // Some themes don't use the search progress node - if (searchProgress) { - searchProgress.innerText = _("Preparing search..."); - } - Search.startPulse(); - - // index already loaded, the browser was quick! - if (Search.hasIndex()) Search.query(query); - else Search.deferQuery(query); - }, - - /** - * execute search (requires search index to be loaded) - */ - query: (query) => { - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const titles = Search._index.titles; - const allTitles = Search._index.alltitles; - const indexEntries = Search._index.indexentries; - - // stem the search terms and add them to the correct list - const stemmer = new Stemmer(); - const searchTerms = new Set(); - const excludedTerms = new Set(); - const highlightTerms = new Set(); - const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); - splitQuery(query.trim()).forEach((queryTerm) => { - const queryTermLower = queryTerm.toLowerCase(); - - // maybe skip this "word" - // stopwords array is from language_data.js - if ( - stopwords.indexOf(queryTermLower) !== -1 || - queryTerm.match(/^\d+$/) - ) - return; - - // stem the word - let word = stemmer.stemWord(queryTermLower); - // select the correct list - if (word[0] === "-") excludedTerms.add(word.substr(1)); - else { - searchTerms.add(word); - highlightTerms.add(queryTermLower); - } - }); - - if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js - localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) - } - - // console.debug("SEARCH: searching for:"); - // console.info("required: ", [...searchTerms]); - // console.info("excluded: ", [...excludedTerms]); - - // array of [docname, title, anchor, descr, score, filename] - let results = []; - _removeChildren(document.getElementById("search-progress")); - - const queryLower = query.toLowerCase(); - for (const [title, foundTitles] of Object.entries(allTitles)) { - if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { - for (const [file, id] of foundTitles) { - let score = Math.round(100 * queryLower.length / title.length) - results.push([ - docNames[file], - titles[file] !== title ? `${titles[file]} > ${title}` : title, - id !== null ? "#" + id : "", - null, - score, - filenames[file], - ]); - } - } - } - - // search for explicit entries in index directives - for (const [entry, foundEntries] of Object.entries(indexEntries)) { - if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { - for (const [file, id] of foundEntries) { - let score = Math.round(100 * queryLower.length / entry.length) - results.push([ - docNames[file], - titles[file], - id ? "#" + id : "", - null, - score, - filenames[file], - ]); - } - } - } - - // lookup as object - objectTerms.forEach((term) => - results.push(...Search.performObjectSearch(term, objectTerms)) - ); - - // lookup as search terms in fulltext - results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); - - // let the scorer override scores with a custom scoring function - if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); - - // now sort the results by score (in opposite order of appearance, since the - // display function below uses pop() to retrieve items) and then - // alphabetically - results.sort((a, b) => { - const leftScore = a[4]; - const rightScore = b[4]; - if (leftScore === rightScore) { - // same score: sort alphabetically - const leftTitle = a[1].toLowerCase(); - const rightTitle = b[1].toLowerCase(); - if (leftTitle === rightTitle) return 0; - return leftTitle > rightTitle ? -1 : 1; // inverted is intentional - } - return leftScore > rightScore ? 1 : -1; - }); - - // remove duplicate search results - // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept - let seen = new Set(); - results = results.reverse().reduce((acc, result) => { - let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); - if (!seen.has(resultStr)) { - acc.push(result); - seen.add(resultStr); - } - return acc; - }, []); - - results = results.reverse(); - - // for debugging - //Search.lastresults = results.slice(); // a copy - // console.info("search results:", Search.lastresults); - - // print the results - _displayNextItem(results, results.length, searchTerms, highlightTerms); - }, - - /** - * search for object names - */ - performObjectSearch: (object, objectTerms) => { - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const objects = Search._index.objects; - const objNames = Search._index.objnames; - const titles = Search._index.titles; - - const results = []; - - const objectSearchCallback = (prefix, match) => { - const name = match[4] - const fullname = (prefix ? prefix + "." : "") + name; - const fullnameLower = fullname.toLowerCase(); - if (fullnameLower.indexOf(object) < 0) return; - - let score = 0; - const parts = fullnameLower.split("."); - - // check for different match types: exact matches of full name or - // "last name" (i.e. last dotted part) - if (fullnameLower === object || parts.slice(-1)[0] === object) - score += Scorer.objNameMatch; - else if (parts.slice(-1)[0].indexOf(object) > -1) - score += Scorer.objPartialMatch; // matches in last name - - const objName = objNames[match[1]][2]; - const title = titles[match[0]]; - - // If more than one term searched for, we require other words to be - // found in the name/title/description - const otherTerms = new Set(objectTerms); - otherTerms.delete(object); - if (otherTerms.size > 0) { - const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); - if ( - [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) - ) - return; - } - - let anchor = match[3]; - if (anchor === "") anchor = fullname; - else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; - - const descr = objName + _(", in ") + title; - - // add custom score for some objects according to scorer - if (Scorer.objPrio.hasOwnProperty(match[2])) - score += Scorer.objPrio[match[2]]; - else score += Scorer.objPrioDefault; - - results.push([ - docNames[match[0]], - fullname, - "#" + anchor, - descr, - score, - filenames[match[0]], - ]); - }; - Object.keys(objects).forEach((prefix) => - objects[prefix].forEach((array) => - objectSearchCallback(prefix, array) - ) - ); - return results; - }, - - /** - * search for full-text terms in the index - */ - performTermsSearch: (searchTerms, excludedTerms) => { - // prepare search - const terms = Search._index.terms; - const titleTerms = Search._index.titleterms; - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const titles = Search._index.titles; - - const scoreMap = new Map(); - const fileMap = new Map(); - - // perform the search on the required terms - searchTerms.forEach((word) => { - const files = []; - const arr = [ - { files: terms[word], score: Scorer.term }, - { files: titleTerms[word], score: Scorer.title }, - ]; - // add support for partial matches - if (word.length > 2) { - const escapedWord = _escapeRegExp(word); - Object.keys(terms).forEach((term) => { - if (term.match(escapedWord) && !terms[word]) - arr.push({ files: terms[term], score: Scorer.partialTerm }); - }); - Object.keys(titleTerms).forEach((term) => { - if (term.match(escapedWord) && !titleTerms[word]) - arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); - }); - } - - // no match but word was a required one - if (arr.every((record) => record.files === undefined)) return; - - // found search word in contents - arr.forEach((record) => { - if (record.files === undefined) return; - - let recordFiles = record.files; - if (recordFiles.length === undefined) recordFiles = [recordFiles]; - files.push(...recordFiles); - - // set score for the word in each file - recordFiles.forEach((file) => { - if (!scoreMap.has(file)) scoreMap.set(file, {}); - scoreMap.get(file)[word] = record.score; - }); - }); - - // create the mapping - files.forEach((file) => { - if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) - fileMap.get(file).push(word); - else fileMap.set(file, [word]); - }); - }); - - // now check if the files don't contain excluded terms - const results = []; - for (const [file, wordList] of fileMap) { - // check if all requirements are matched - - // as search terms with length < 3 are discarded - const filteredTermCount = [...searchTerms].filter( - (term) => term.length > 2 - ).length; - if ( - wordList.length !== searchTerms.size && - wordList.length !== filteredTermCount - ) - continue; - - // ensure that none of the excluded terms is in the search result - if ( - [...excludedTerms].some( - (term) => - terms[term] === file || - titleTerms[term] === file || - (terms[term] || []).includes(file) || - (titleTerms[term] || []).includes(file) - ) - ) - break; - - // select one (max) score for the file. - const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); - // add result to the result list - results.push([ - docNames[file], - titles[file], - "", - null, - score, - filenames[file], - ]); - } - return results; - }, - - /** - * helper function to return a node containing the - * search summary for a given text. keywords is a list - * of stemmed words. - */ - makeSearchSummary: (htmlText, keywords) => { - const text = Search.htmlToText(htmlText); - if (text === "") return null; - - const textLower = text.toLowerCase(); - const actualStartPosition = [...keywords] - .map((k) => textLower.indexOf(k.toLowerCase())) - .filter((i) => i > -1) - .slice(-1)[0]; - const startWithContext = Math.max(actualStartPosition - 120, 0); - - const top = startWithContext === 0 ? "" : "..."; - const tail = startWithContext + 240 < text.length ? "..." : ""; - - let summary = document.createElement("p"); - summary.classList.add("context"); - summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; - - return summary; - }, -}; - -_ready(Search.init); diff --git a/docs/_static/sphinx_highlight.js b/docs/_static/sphinx_highlight.js deleted file mode 100644 index 8a96c69..0000000 --- a/docs/_static/sphinx_highlight.js +++ /dev/null @@ -1,154 +0,0 @@ -/* Highlighting utilities for Sphinx HTML documentation. */ -"use strict"; - -const SPHINX_HIGHLIGHT_ENABLED = true - -/** - * highlight a given string on a node by wrapping it in - * span elements with the given class name. - */ -const _highlight = (node, addItems, text, className) => { - if (node.nodeType === Node.TEXT_NODE) { - const val = node.nodeValue; - const parent = node.parentNode; - const pos = val.toLowerCase().indexOf(text); - if ( - pos >= 0 && - !parent.classList.contains(className) && - !parent.classList.contains("nohighlight") - ) { - let span; - - const closestNode = parent.closest("body, svg, foreignObject"); - const isInSVG = closestNode && closestNode.matches("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.classList.add(className); - } - - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - const rest = document.createTextNode(val.substr(pos + text.length)); - parent.insertBefore( - span, - parent.insertBefore( - rest, - node.nextSibling - ) - ); - node.nodeValue = val.substr(0, pos); - /* There may be more occurrences of search term in this node. So call this - * function recursively on the remaining fragment. - */ - _highlight(rest, addItems, text, className); - - if (isInSVG) { - const rect = document.createElementNS( - "http://www.w3.org/2000/svg", - "rect" - ); - const bbox = parent.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute("class", className); - addItems.push({ parent: parent, target: rect }); - } - } - } else if (node.matches && !node.matches("button, select, textarea")) { - node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); - } -}; -const _highlightText = (thisNode, text, className) => { - let addItems = []; - _highlight(thisNode, addItems, text, className); - addItems.forEach((obj) => - obj.parent.insertAdjacentElement("beforebegin", obj.target) - ); -}; - -/** - * Small JavaScript module for the documentation. - */ -const SphinxHighlight = { - - /** - * highlight the search words provided in localstorage in the text - */ - highlightSearchWords: () => { - if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight - - // get and clear terms from localstorage - const url = new URL(window.location); - const highlight = - localStorage.getItem("sphinx_highlight_terms") - || url.searchParams.get("highlight") - || ""; - localStorage.removeItem("sphinx_highlight_terms") - url.searchParams.delete("highlight"); - window.history.replaceState({}, "", url); - - // get individual terms from highlight string - const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); - if (terms.length === 0) return; // nothing to do - - // There should never be more than one element matching "div.body" - const divBody = document.querySelectorAll("div.body"); - const body = divBody.length ? divBody[0] : document.querySelector("body"); - window.setTimeout(() => { - terms.forEach((term) => _highlightText(body, term, "highlighted")); - }, 10); - - const searchBox = document.getElementById("searchbox"); - if (searchBox === null) return; - searchBox.appendChild( - document - .createRange() - .createContextualFragment( - '<p class="highlight-link">' + - '<a href="javascript:SphinxHighlight.hideSearchWords()">' + - _("Hide Search Matches") + - "</a></p>" - ) - ); - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords: () => { - document - .querySelectorAll("#searchbox .highlight-link") - .forEach((el) => el.remove()); - document - .querySelectorAll("span.highlighted") - .forEach((el) => el.classList.remove("highlighted")); - localStorage.removeItem("sphinx_highlight_terms") - }, - - initEscapeListener: () => { - // only install a listener if it is really needed - if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; - - document.addEventListener("keydown", (event) => { - // bail for input elements - if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; - // bail with special keys - if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; - if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { - SphinxHighlight.hideSearchWords(); - event.preventDefault(); - } - }); - }, -}; - -_ready(() => { - /* Do not call highlightSearchWords() when we are on the search page. - * It will highlight words from the *previous* search query. - */ - if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); - SphinxHighlight.initEscapeListener(); -}); diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle deleted file mode 100644 index 07777a97441cd29fd6e92c5482d9066e5dfab3a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 551506 zcmeFa3A|)SRX?7|tZ()$lL<*kXCpns%$sb4Fk~eYLYQO{5)uL-bo#w_-*n&U*ZtDV z%)CGVkzfX|B$x(N1jGegK|vG+WihDePyF!{1Q-6|1}OUDqag13`<_#EZ&lr;y6fKV zH*fIIM<@Mm)ve{!`JOs;&Z%=>yYek7PFr>w{V&+snXlEG$0xn!(R#bpob#I9ez5s@ zy?SHjX6@0F{axSHf23aymRINJ`-g(HGp*@v+w*4X?S8Obw$ba>8<Um!YPZ&?PxXT} zmAkv`JMmZlNxZmhUq4uRPseL_(0;8t)2@5XxoW#!ot~~&`@zJ4)^v}0NAa3F+b!Rl zrk|T;Ja2x+>&$!8M;i6!;eN0JJ)>ad6b%t|<v=?9ZvU=+u&UFZrZLqf%C)t%b+z@i z4YiH6O|{J^Y4zIEo~$<AYR=Zt+6FoF@b6VOiGpap6Ro3OyIsc+F#TX<$LscZ{@(Gf z*X-0=%})OT%q}A1@$O``*KJ``{a{;2TRc2k_l`}sW<2w0vpU~uc&%pN3)VEM&BMLw zVboZCbMtVc-l^f&yr4wCwkepHZp|;W>xXMtpxu{Wdij-mN-q#(EZrW`aZl;yxoWfL zHN4URuhFS?IxWxy1FE&KP8SVVe{~!0S34NU@=GVL=m#6S-rRhn+VwiTwwQ0Qwh}$- zSA)&o@##iy#-rk{*A^tHZ3$LR9tB%r7L!LiV(u$u>KzP!XKYm`y~Bt1)|;~!?DF~? zmStrf3(^5q*3MNsXtKieTv>0<c*py}nUcbl8E>}QYji8E`7W;nG3e?!Z*GdX?6F`& zuZj2est21pwbn6oRP);PZnX(+c&ry}uFlL<=2|nohF57;=djR^1#4^Fxkja1^X5Q> ziE5)d#ls-ZrGiek+O1DV)L1PafD{|O`QB7zy3?u5)*EOFwA#q87>_paBVVhuq1l@Q zLsn*6?YU}~k+!-62w+;E_TA!F>0&VcDpc#WiA$beKRn5gR(7jX4Ln)%V)`#XT1)ia zJJo1SAHn;#f$9JcmGpwAh18RDAli1iZIsi@R~@Z3dKfrJS=$A!TTUx@=zIFLJ+-~H z`|%^#B6+f+@#AU0CC!Oz?yfzv_8`?<4d@U=`n3wbTAQrx6K$*nLaGbl^I(Gitjx}J z`-eo$OKN3Na~-Bo#mWHGOwHBe?@qre%6AHKR6_JH-Dw&7!H!q9TdnRRldlZR9(g5D z`$%8BSUT*1S&w%s)kdRrtTNks_~C_0w_R;^!0OCRCxX?o4oxdKM=Pv=28Y`omU+4X zkbzz&#JHbZyGAs>hWci<4WDcf0;tmI&Cb@3lQdZ|*(Nk>Mnm0pZ@P<RouMK1JEDzE z@(r(v)nwr}(d*9cy?Sq_ept++c17(<QFn8_nZRIh`tIE!oz{m~X+z*hDhE4>^=Erc z<}<K!8}hg2(R3aY(|MlwZ?Lu7ny$2_NGMlO2eLb?5}cPTsu0X%bHuSTt+{F)T)^ye zF5aF4pSQZrR@bYvy;%?4PJ5Nkd=-EcbPU#W6GCu>#0@siFC6AA0(e{CSumSztwAU@ zNH9iR0N#`HmA!6Jb(F9WbG)>6nPAsVp-ihxLEu9W9}>?u9Kjw`IaX~q86$FpTROe@ zd1isA<N?{)4oDLgRe;FcT&oFg@o33W&I4YHWv_Vi^+xM(xDxybOr<^A%7g+qA$Yr$ z*+!M{DQLKH9yF}B7r<Xk+2HhffQiYwzKKn_17gyy-amARICrynrfpe|pacc$v02Px z%jr~lZD3clu%=n>&ex}pEc8!srH%6MO8s!N1;O)xcz3(`7z=qAvRM|c65=de&23V; zL89Ro#P&Rtf`iKh{SVdd5FMX8S3O>zLpj*HStT@7u;t?)uXz~t<?uE^KGrH|211^& z8}_k<pL-91)S(oWZ>$U7fT##5xVGEqR3M(}vkT#)b@XT&JlKZfAzxkFgThh)g`gFM zt#v^8?n6B=Z?qm;wP%&8l-kQ5I^fAg*{+w%&5}iIFcHco7H+5eRqP>aShb-oj5Leo zSR;rEmJ41_QcCb}1^aTX+NpQ2^ENQ>TB|WbuSpKwz<UvPE|29Qw4e$vIzJ9Y^DQ^5 zVMXw?U<EyANw=13h~2OD)!J9-t*z>rw%v*{S-;)|CeaJmU&r;O=7Ft)ABqu$Q|?2? z^JB4TqIXhyJScCny4*}7wFmnO*Wbi#Lnmu?>$7#d5UlPsk2G7yAY-)7JJY;>*Zx&J zT*Ghm>N9;jVXTO8Pm_k%-=#k~j9Om!NRAHN7;fpJsu;z5i@+)OdM>EFpmwY1QP3<@ zj*LoyAO&Qn1jBOCs303XhMFnS9#w@BH4h5^fZjjkN(Hh27!H?xJI@nX63;8g>NAA4 z)5Ke1HY{C%d6LfcCZSAHP85UdD?-<LOw436w+SV9x?N{oi)hHC7A4TuAg!jL_+s^B z$rgU+7&I-2O;WJ1C9j1ZT7MXos}0d%?WWoRDScTdVx|ifD^ajjE6`-OkffrFIWIUr zrd5`py_O(9`B=ewx|F|CiNjdBm9FEvLNhe>p9vlWBzFrkf`_%9pUhT|k{T-?)?QdU z$fdR0YPX9YH`kso>Tlxukk9R^IrlR}(@;Juz4;la;MlHNN#bsV8rcD_PE`SWXg2&< zyo9YCly5bw4KzvY5f*RbHpR|Ct6ZOELB_9&fy{eQLctVANWk&)?fi~<Ug3!ar+@O7 zWS>IG)%k|sla!us)Vq?QPKX9Y0cnsGc`h@0V*V5bG>&i>J9rrCd8kW4lj=fk5>1Qw z(NKVvX2+|xr)#8XY6BuDhVRNH69b~oVg;f(9*|Oa<zRP;@sPG7`oX(%v@wSRjyMe! z#EvZA6dXdZA$>1g8bRh(uRGr(JuB4uR<hP7rzhY5#RBRQ6dq{y(JG0B7n>~Yj#ASM zPM<8vmqiD1tdSg+B#<*@g6T4z2`9P@XE_Z;07$Qh9Yrn+>FG04=;*5^=1ThzX&K>4 zoWr!EV+x;Ac&l%=pt-PW=kJ7lLM)l+nfGugirC=Lv)qfh<tr;BWAIS27L=N9&4>6S zLqtD#Zmrv$@9f{VZ+fOV>33$lM*V1evgvjAHRtE{$+|aOvCr!~YabS4@7!Et?=+1K zl_k|!<)9Yh;%8&nm6V~hU!VT+av%Tf>U(1N(aSjcVwYavP5tzj-%phu2rESmfg@(2 zrN|Wt-@P1)WZLs9;?Kh~jbsn7VTU&F&Ea!8Jn@-Q7OW2odbBT|5Vg0459y#-5q1{2 z6+JB~QqrYcZR05^D`JN^GpvJ?5#*~pQIY-Otmofz+ij&oH{O18>6)8wzwy@FZn*Kl zfxB+L`|j)dqUSTztHKrnGedO_2BzC?Jao%FH{OExZoBP<Mt!o?J{-QYo-7l`ftJIx ziv?@uXP_$M2^fv0zDX2^+W_lSwQGWHvAtrF-bk@F4QVo2MOGK=X<Zz*xZAa&Te&Il zqs`(G>}TL&7P_Dqmz*t1NMwm$b1-T^!ZvzyO)QE&52|w<LL17tcz%|6quZKqct<^$ zCWNVgPK$>`jqRdFLg4GoYWl$G&6XV2Ht`~t(G~*Dnv@KFZ=)!Kp-9;5Ai?<g4)I*u zd?K}n%eRPfHdsig6KK{<wOU8;5c<dj=G|(yTgPDj5pAxM@31!K{~QShZcC0&s0<o3 zxlmHu)F-$^4jml9XLl05@(l=osEpG`)JaE_oK4b9l!VHh&QFO-Y*BzH#Bsjf#(MDH zEBlUGBGs5M!_UuBJ+!@tV1MaWYF?F<`EYn!^eW;6juRBWtrd0aa~}4OaP75{W3BcP zIvgBanRp47Fz7<Gjc{{2RZp@+5hOVM73YUMUdpOR=Py1{?h*~2qbjxmO^EtA=mX(U zZ@HoUaXx~G$`gQ+)L6h7fa<0gRAE7lJt0MpNV&Iqa9M=F4b+a}Yst4yqo;G#BiQ~0 zP{^=^UoGs}vdXp&z|-)=)*k9s{`Jv*v<0GqY?Wl(krwNWf#NK**I#uytnBCA(e#L1 zUP;rTORd>bXx|Ms++OcYdkyT#Sig=EBwNGYQsl<wuq+9~up}Mz(G(PYf;FK@MzZ7? zVG~Wv)azF34IsT25@}~xI^Ax;3Km&$A||3Px*?ILYownBt9M_!_th6X^Fg^$Y~U(Q z?-&sV#VdME7)it?vW?5gJQb-k)HEO4Xk^^9Gy)iEjyTvIhmjUWmu@#Y-EW$%)MqNN zPxCPa-GN`Y?pCtnLa|6I+dN$nO8F6Q0r;8W-6L2H-53T6nh^hL&0_2jU=2K=jkiHt z$pjtB>P^xGgEeF~fjtA~_zlu@Oh&^tY=7&!wKjlWVXGzt9uMifX|U)JrjRqI=jVl5 zoisFYLtD5)>a@30QRc+Yr_!Ouu$gK?hwB~299l<kY7Jqe3Yg2tTNIX+{p!)GI7<%K z%UNWgp4SXRQ`PAsFx0|FB8?sA&o98q(X7x0*=s(8&6rFBGnMYbd}!8}H7}Aihnn66 zva(d(NTA@*h~tdc#=(jjkIvm^0HF{YUSl3QQ*%ao6WDVTm9TkbTl8mG5xUnQ|HTj# zq_J#Q#WUVfva7KZV5QgG3&9Xo+o`I_?n0AJu<SBbZKJ9t4x>>6T0cjo$e=v~6LeCz z?j_+Gy|h_1hnLuD7?o)aw!Jwr?waLis&|ETG~9PiL`|Hfs?61!(Ei$Uk@+vGq|vVf zy+;7ER*uTGF$!k^3{6qtCe?#H`frc#CNIDesu`cHUZBGY*(M=L$n*r^qE<~?j;NZj z**>7!+M(KF3gC<;4k?@V^*Zf+Q}yP)TAjS8>J^P>QM=-uEzvt+fqJW?Is)gCSBL}| zTyw;<kW^sWh$5T8WrAy!rI5_${E!)T3+;twm0)X(YS;|r#=&PyuAOqsR)wS!geTPS zxbqOyHG+>Ch&;8+0(Q@_n?Sy?UKX&L2e)Ap_Ku_BSywMh9No6i;f57JIzz#i3)WvL z6ha|{w^Ieosv_Kn6^MVFF@yEh25hcV9`tjvVX>Hv{E?!)$b5|!=jz8j7#yiu?b_OP zqW;-o(`a6J-jrkuH#yZkTzEKC&qMC0O^ZiQgChw9OFxQ&3DvLY=Ay8hs1gKqWWlS5 za~nLaWJDKlM4htKgb2k#u=2{&+?i}ox+~!qC%GtF*%8*0juF_Wq0hJF%xd?^ZTzgT z8hKH?_EGrwggZBqsGCBkxtxEf)ozcT!?Ml1O_po9@06m#*%o{D1nsaDM1EkQXr2*O zB>h8r6r#S*3SIM+!>tz7LFFY4S7>Kc19}MTSkYpJ6`med2z_&P_)K7r?bfJrv~wk@ z!Mk&m^yI-cDK4T8Ovh_p6tzkFVRZ&hC^iPNX6_xYl9Ccl^?X}pa?(XLpJA)1>40*l z-C|V7oXAGQthCiAff|BSzGMrts7;(07Hv1)k~&#fs1^+Tgxw5Q%}#8Cj$Sv|TiTM; za!&WKt-uQ<4hWGiNOeG3WTn~!X{4uE487Nz3N{Es4F?2Zw?4Qm*k(Kt`XnS}unNa@ z!tJ5ju3)1K6p2m)tM8O?A7LCy?Tp&a+QYS1JqrB*?gnxo3NvUZLTj($P#6)w@Hodo za7Y6LgAAK^BG}Bk4K@H`KlTYdf{GKo6|pPY{~8@u)`?(<j(GG{JVKB}_zJzv`ww2_ z>i*YJ!KYgO-%-`xRBf7?-7M!MP9UAh>Hfjx!Or-@8iHPc{w`7K%y=PUG}u^$vM|0T zY7J3H2PdM)qwq0Lh1xnR)|OH@X&7N(PWT#`@%jf(56+0aC6vGZ!4--Au>kZ!d{~|C z3?A1m#t2r4w)zLJ=>^-RYDSI_u!Atn_fG^{jpwlF!o7;9134^MCW1Af4f#(<3YUY8 zBr@q7BOS`Y>Cha54ebAc`dt-40xM{1h0%}VU~qmSdn(*&pz(>|jA_(50>2@Sa}WzN z<i7^I9}Cvc!^KVeF6(Ro4BNtJipQNvK?X9qA%<%s)zq+lC|KW~oz~ucM))rL6;+u3 zreSuNtb5&AZUCIOkJJfjiQY3>+E{NImhakYgN=BB6}8H7+H8nu1k6rv%6z&dJkNK$ z#w;0=kD%(>S{2bjY#4*xBiO+TNgY0cHt`i~hO~RkVEWs12W=Q(LMO!9^4gnE1RFwA zIaUvDtXdiI3FHN?gl^zoum-y*ZvnJW42(Cf{&ML<y|d0(#o&13>T`B}jsEHd2*n^1 zAnf}TMiH!o!K)F<nqZyW1YsfUB5qDNgTVo)xSVkEWdBjbxp9+(^7AJr_u>Cy%GkaN zj)mB2Dp)#%eWlkSJ+rfq|K(~KO<|lZ+QDs2L9GY_^tjp!_uW>XYUAv?@A;7I9+{px z`|jie+T?8bWZ%6aI;gYnipl5fL&V@d!DsXrNf<og#x6@Aey7^L9RI&h{uj!FHcp~R z3R&j7HaKIS_>cL<(=*<{dN+6&w-lYz;YLeL=nByl2gk+c-NC_fFBIG(<gwe=eQ0KG zA4CfGzbk!!VigJd;7!ni>ORp4)<~6OrthD#9HRL={6mZrY=HZO3=Y-CvFbvn|2V>= zDirNOt{Z|HPU#c`QS(Up>=dpQDo7LxCJ#1AkqKeaq~j4d7PZ+f240mxqZ94wF|l3I z&bMZ|hR{uzTwsHNOrz?=ij(qvvZ0VsIeOi{27?bi7vpi$vs)5zf+a%up3*d?2w!Pw zYGJJy-rk3Lm?La2?QW^nEWNnaqnOFk<yV(3yKMiZ&)I+ZWhIKJoLu|TR<AT&ZI-Gt z)%k9zTdQ}t$&#?^biKwxsoN?oAe0p5ydx0IdrI(nm+IXTG~ixirc~{gD0s4q06ciP z>rJ%bl_(ah^dQa~MBWEW!sJ*#>P`0jYcV&R5U-~xu6QvHX$1Q3%(*_=rx4;`6<eLU zegAowb7!g=tktY?w9758v!M;fG#Oj>0G;eOG84bnATmPzL3SW)A#^edCSdj3FQUlc z29k#g1U#<pR$;C~M4*2Idh~CjfA$l-Cy1#9tMY@|j^NIH_dwQl_QeB~_Z<k0z5AqU z)=3CmG}hTC*nFSTsRG)LJ#0U{DPHB;ogplkuWJ>_0%gGiD}`0Us1rQ%C0+v@=n?P5 zU~oyt1j6|dOWi_Kbb3=PkRXtUx3M_>?f5V4Xm{Yh;L{h0|J*J9bC3AXOZY!M|9<?} zpQeA9#t+i3m(xE)?b;6i0s8$4{Bv-%BnD&w45lrZ%S^OKRPmpU>R3Smovcd34^oVb z)!fyPF&xN<m^DNVOKtfL2*6q|g=grx@*l+@5SImuVHm9g=7fM?!`#G8!hX=%4>K?c zc_<#MYV{dxNcgouwiP{CBdpd?I}V-}tmW12w3-dLAA+?IlWI`>XV{DXy%>U|@NxV! zs5v2K)uSp|OBQUBG~9cv4dW0@8CBo1iXF5yXcZ6jro0$`1iOz3PTkvW?TvBj-p<|- zZbGfEn%opTQ@%SCmskB1=BwQ)#!UQX;k*ip#m*Fm;EY)kY`s;uYD?ATOo^SAu)s=@ z&G<^Ipu^}rXs{rRek^-3TSFMFo9aP_6yYElAd&KAf+9vLP&4MtdcmgskfZw_M5rUn zt_P!e^42s#XY|A1oSONX|7$clNfE{>P7<IQ4m!uto~1H1%TXSNs59DQ3a<%A1jU#3 z53$0(W20+1Sizk`W5#(bSdD-8(qKFr$5X(GX!|$Ob|#Ken+R5+c`$ch9H1xoFOJOh zKaa)&+^CpkLq@Qi#u2Q;zus{~MNQY~R7S;QE5kvAUJVU%YUUF7PoXUX_}j&RKjA!J z+2F@A8vID!27d)FiZT5X{Yn-75F7rlqEtg*$b4bkv|_%Gn-%?UQ?ruYK4mHUw53e2 zRoIuoR{w?9GT~bGKZoL+O!e=0b!1GnW`zq=`Cp-7uZbp{#Z703mHQXxk!Ep|Z17uo z8_dg18-yqm!D`vOR0b8Zcu6md^O9c1ytGR6WN^}@XnZ`Jv==RpjFa}~;G}T6S$woZ z@X>DPac1$6Z15R*8yu34;>wJvo|yVZuuAN>{b1Sdz8v>2g3r^$v$=t%C{0_j<5ED_ zUT7J6rIry_j>0;+CX!bNg4*CVS9x}41wPmwhV+pM4Hj#@2Srw|0Jpj*u$%Q-8TQ9& zZch^EYLY`6r+aOj{X_dTbno@y6Fw*%^8XuV<X{Wwifk5`#kExU=dh8lx>wvy3pIvd z6+)e0FoYYHP92AW3Fr!N%u^IP{-Ahi9Qo(yzUDe<Ek_qe@aJ0jCp)Nv4N#3?z~mdI zh<Og+YVT6q#?~+-Mk|D6cLSLkp~Xv!B%W*(;R(`k0h@ksws;Z-<_HH(c%D5(VIUOG zpdPG;&w?WhD2NXxWPb}L1e4_!#2SHAFr@Z6%8<E|11`|bM(JWh4VXOU@MMB4u80T6 zy}!r&4aAYJ4bCymsugy}RbYBYkOEwqt7tIf`rjnTnT$LR&W)ACn(zY>BO67#iMZw9 z9J3(ya<DlH<^U1s9!uXpg9cs>wjneNepguPG=u4(+F6*UGJ@l*xD3_()A3KRVFtc9 zxNfA;92DXQ@Q||eo0eu1KVc>&i?Vt&j{xPFRs~iB)WV%sT<xH15b8}{W&~Xyt;0^o zJhlnpW5T^IygYajmqEovV}X|S7(89R6h|JcJUIXm;v3x=@wZ~!k3l7@9*YdpU@3~+ z3$H$jfVuwdn=kPvQ2CI*n&!KP=6eQN<JqhYR*o*^!b*bYdoRB9O4$F_^DArVm38#W z1SAajkuQa;A?x<$&H_wT$1BklIh<n~Ed-GIJ5c{Ie;d8JonAec0=W=&j<^L8Z7SlP z5yR8w$RB?rYT?Wa>~e&hFxekm=5M0s{&H$)1^u&<|6YZEAM-cUZ@2~FJzFDC0H(wO zkWi%1Jn5)r6Av!kO@W$SNCpTWn99j70*`?HR2YZw7_H4le~^Ywb|pMtO%KKIvi~DA zoOjSa9(dTFqCF;<pc<sGv)hI1oZ#{kJvM}pL4@C769>KHlaTKP8zPB;?zpoJQ1N-~ z$<ra8kP|1YCuXHT5%pls!m`XwwHnb?Nv^s*_AshFVYE0A_R249HQHw@DEY|Fh_@w6 zV3q*7reT%ALihcrVP?VVo8+HQf`V*F-iQ++@PYf%9ll<I5#z=puFn#vjK}Mu$GouX zq(uY{tHWfrTRTG_m-tXe2AmSusrVdpuN@U4%TU?xW|a5~Sp}|kA|AkZqcvE*zDNA$ z1paeyx&KD|C(tZEet-uj{O{v`-^Bkuj(-oH=0CxIycz$ZktgvV|LeqK!dNCuIl)~c zvN}S=$1Qg0xMf4zGNFroiMq@(4f$`wsD`u#{W0-6AM5BBw4J}F2h<fE>xMV1Y>F9& zB5MOH)QM94=>N~?F;lZnJ)TQqla3(B@vY2R99)HIkR79TO{is<Hlmop%c>)47DkvP z=Btz|<4mze&yCx0;fE0=akCjkRdxGSF^AeU=@U4VV+q!T9y62n>akArohu6y{R}jb z&N>G-faohxoQCtf1oyX~!Jw2u?#XEK!FlO)S2fZWAU+wj0HdA<)H7JqD80j;1JcD= zDzoBPf_EtfqiE2(`ibk1QQ2hJPAY3<&y3A`D=37_H0x<1nX7E1Dq2LF0i<AU*n4?b z$arO8<p=8Vo{Fn6dkHST|C$Ra@_T>j5}y7g*X=1?6LuxC2kb9JRZ5p!cO3+-Fcp=3 z7ArEoPv`49nXg6v(YR$Q0(0EUN?~iFG5oDJ^fGQJ!(S3CJ7zbx--ovavS~nW$20$> zB-dVsf25o{6gBoj`lU(h;L#!*jhTsOUx*-hocBZFqeBEzjNnc~7Eda^6HcIIQq)pF z1T8!~$mFFn$$nO5YvyuT>gmhW21PPAk1~#l^}~DNI^=;skHxr{*ZA*r^KpXw^O@xL zTT~?W<#6s3Jol7|uL*Ht&Qm?sr}cXKwARqH#GD}BJ0kXL$mzUp$m!HB4ph9Ri0n3( zG7=Lm5?!~4pD(lYq<CJXV8qd#)%?Ey28>!+<vE5;Xk7iw=|mztVH>#-?}YXkxTir( zXstw2kr5@suMn&f8%s*MqYyfMzYkjng+$E4f5QtTMvnYSFiAkeMu4FIvovIy&>P_6 z<^okyLjDCPg)*k`myjkm)2opH2zgH6jRF*4=*U>4vL7?O2WLHxqJj69_5<$>iv16Y z`9~I3DP~v8iiUjrC5)sq<;QIH!Pe~7gg<<>ylY_&)BiY4O!@&>wy%<Fp`+p{?lVIs zOKU!5PQht;VJ}Z9V<{z-KS`akYx~#nD_fsV^Q)T7$bKFX=GXT>gT^!$k=&&+okS;s z39NwREoKfHzgQB%_`={HQbZ13IFFXt4j`yWyy3Rz$vH{?)nCxM=*OK8(gU6C<Gg(3 zO%z%}j^++58eWOKn>g_!@}o56Eg(V@n;3<Y(T*18M~ZoV^EIKf=igwInR}7#AS0%| zB$qNl`BAIG{`H_*uwP10k!_&7t5nWZ6T)q@g!QepW}p~Db1`xXCKcoGiD*7mO*SW5 z+Y#*^{s9ay?I2V3Z#7GTo#EKb{&dCoyJN3FCE+kfIWj{8#>#Y7+px;QYGwa%^x{8( zf1GuK2{f#bh5)K3mxP9C60{%Fxo~$0`euZAiij|`m*8}@1`gUvLKQrRsKXmZoKF7P zR1~R#Z!wp7F;%5tM>-e6F92PNgBnuRr}&H_03_6>6_{$IKKbt<UVCpgul)>)k_jRu z+ru158WU?n{?AcMR}vlHN58JYuRy8Cq`m7<`JTT2^W1d$bg|&3E~PDySi)7*lfJ2Z z0L`TV-GO6dm%l*cXFf4Ifl8+hBXf&H(h<^PRtX80p~KW3_irZ(t%jn+u_*o_CKzEs z|GU{jf=o)YiMSNdPyXB(KHe*QV<&?3vM~I63u;J}vJ+L>)NF;%!g|yao7RPorVo=k z#|_>@G>FJ6s6j$j7p>#jOl~w7rGo1UO|Rj&r(ET@r^sH$wzZs>&gIeM!b4@*kMA(J z4y(Z?9H+6-q*u}Rn|ZKSrfO4UziAjC#D4QbOK`u5h!)BBb1`g9RE&OqiPOb@H4!T6 z|77kj=UQ2D&^8mFSoSt^7&9K*HuDxDCvP+Fz%PB9Ne4r?+YH2^x#?)DCL~~;`i-O_ z4)EjHbj(h$>1e|!yy?7;W^fn%^M3m0?&#Nx@#}<t5C3~F|N9dD_dfpjrTp*9=--pR zK|I$Gi5<tS;Znz~0a?dVJU*j1Z=98mL`*1qJJ@K>J*+5f;PFCz3;1m;-B`AOr_iv1 z1h#<w65Ik{EQo~f*oA+bBK{u|iK6~brtm*AgXIQ^{rHr!#s0@I*RhHHzb8Vn*#9T| z(#3w9^+SPg!I&xPwKWo={u9*KxJA9$2}Hd%jKZRR)oRRuMg3~}#iE{nojRia*~mbM zxFRHO^&G|gp21>XwLLZwe@=uq)fpzT_qr1NbD{7~D*bC!?XZ%N@OptR-Ah>Du}JrG zh;t$oK)OG%G^D#uph&WgU9!ii;ZG8IqW;<4F1$G+!B{6|$HE1eXw~Ds7iDB(2MSl! zm-u?y5~rG{b+1P4{mP}mHXGw=3wOpI4$fdQTSqpOfo=^cKgp3HB<6E5LN_l=!b0~P zq9<Ek29Ww>Zlc>#Ks{&!jZY_g13eQY7~2Nw5q)_Box?AE1Jxx<xOtwDGSP%#PJ@70 zxwEK`NMu;fNJ*dOvv2Wm%e#dP(Qx>X&?lD=Qs&?<d5w*(iyxlv;hHT{*46PLm^vJi z3#O3F-HHyk9%hj#QB&b2@gTiHOIA*bMQX<v>3YC8Sc@Ee4P-w|Sl}b!6kdzwil%gn z*O85-#8Rxji_<U0Jb2MleHos}y9{rl39=;lUi^Y)rT7#=N;tFS2&Y=e-)n@qL{mw4 z-JhoTa>^stq^t&lWlbiuRTL8}i{bs4u@ahjHN#Opi1$RRKY~`>WU*x5cN%od)In{d zI1x4R1|Eg~M*K%Jw?)*2<<Tq&)(Ori2@AL$P+*kk9P)8AkqfAbLw*fSBsk<<=Fp-+ zCs+a-K8va{Hh1mh9t*8d?~C{d@sbgf@p<Q&=sUb{I;31>6|^Kjjj`vik|Qv;{m1-2 zBf~%K4*r+v7X`W`cKXkv7$D-AoL(v$v!JqMWJzrL3GL?Z3(ejCOT3;Ip^-6np@)49 zFS*Zm*{+o7CY)@86Eo00A+Y)xjH4h{iGxRi)f^LfJ^B_CF*g-Wl;vnu`QS`_!oVp) z7BiYI3zit@gCoWfXXK0U;T>^C=3l4I8TomXTMAhR>klKf;PE=LKT{Gn$K&#|2OpPH zyBXWb`4y4wnc8nzBw6G6&eZ4jBlx<z2XRB)=^8?vANJ$}ih{+55Thr2^k(%Y3Pp}P z+|Eet&)nQI>ge0jwP2^rZK;UM?K#A!k$R02`P-Mqi9CaB(cw6LIKL|23Wf_IgVbU7 z(_=?WH7?ke(nqWT4l1VTc>dUA?EQ`A`{Aq7+8!&^SN}fS>Ici3_VDw2X^B~Py$ipv z(XwFyo-It3MmkTQ2<(X~T87>lEZc965r6B$s@sP(Zy(m-_^@6I-9Xdpf&nr4$8Ej) z9vZXWdQw68k}5AjdwTcFAp@f6+tn|ws#E5T*0H5VkWwtPj2RtZU7>NAYE};G${R4k zY%O6LrB>?2c`9SyOx5cXW|}+En_$q}cvSw2@E?6CHpL`yxGZHqzG!Pz&9IU*b!r9r zO1%$VWeQf`fet?{hF*&eeE@_$YVE#@QtL7(49V^tG4wmu?j0~ByN@qN5e)sQb!<xk zLtn%QM}i?iz42mbb6j}|@sR}4I<0D0OQ6Uo(P4Dj#E4+@A52r<5k?!W-8;ZYcJBzI zbFAGvz({sKN*GOA$F>w;v>PKF35*2wMhc^RjRj}%H@+xQF?}{&-aZh9&@kXdMGwbS zaQ`4Mpxi+Fai-KaLu8ypL~|IjXID%_T^*<|9V0u4-U_QG_gMKMjbjrUg>w81AnwU@ z{5;)$CLQDhiq9<D2XrO)X>2~A*I>1T59oXFOZNd~9BV^&P{}_1gl9-Yg-{l+BA7%+ zS0~TVrME^#4o=~VFy^E9ARpx&DY3nyggh6e<0bsFP$H{9gf}))y1%YN@Ns7dn!cb@ z;e;+$C?MX@SLjhwmPKaVvV&27?VX`Ojjf7apws)u^U_<H^xuspU@BBBNXO_*lm3Tb zi`68yHp^IM#Hb|U1vuZd29(M;^ugM+mzl9d2B?rDL(4_@)hg(2l-<WX$mg~^d?GLH zK1NH=Mu(5!SC)03%52tswp45mrxtz?JvKSxkRhTS=!mSdz!&pQ;}4^0`~gqH#fw(J zo#Ov7^{aUlNVZx$C_0T}9tBBarppTAAcHV^=>!Qn!CQiM(xpgs6pD-4;gy@>!_M@S zQc&gl`w%w~PdAzks;4U(fC3ahiy`XcXjlVq;A~acyw-LcN>gD%5l^&c*sMnrS+Jop z8*IK18~+dpxj65L6+$lH5$8pS|MwX5@J=`X67=SP5S^Scgh*;;AVe<}e2@YWsx*3t zOgIy?FhnSjFm!P!jEIK=Kw{Vi!s7`O)hN-$^2;&7Y~$NdFu9Lul<qsGvJu1Np}Zqj zFlq9L7YimG^yUB)ot!b4NNQ%lL@$-=oq`jpHF})f<4n;EoVc9!WfPPZRtW45Kz?PL zF)YliVq{3o%=AI0+S27HRE*3!xd{h#I*OArAR9f^;rdIUb1t|lMf!tiVt7S5p4j31 zd3<oOQJUhfHFhW)k%y1j;PWlf=`GZXg+LghzM<*-Ru+4@pj9r3(sZ86%btoch-{0^ z7)FSc!5l`3&LDq<VHRYNKSvY!8Dxu!SSXdrPBwG|)mrtYp&<XO^OSV8-%+W-$8w^G z3w&(=hh-U1G(i3TCuWcIO_0iLo1l>AY*W;ia??83r7SXUY17O%<JdkWCY(c*E5!aI z(=!L?6=I2xM}pWK6Hy^lrU9nd(M^R=nT9t5t+o&<R`3UgP*E)rLiK#Gpa`MjU#Ct8 z)$_G)l+K9z_A|M1+2CsGpj<YYU5zc2>Y~VQo7uPR%IR5|Z<%|yrJgRQDmFP)BrxiJ z;=agsiNL6LEsek^3;8mGqeh<aCQclGj;Iy&e=@x)7Yt_4L7tWP?6N&8_hQ;(^Q^p{ zXv(*10{qfFD;8{o-j(4{Ds@$vU{G5`aiqDAMi61Z;$bP06vylYyNNc8%pG*tq&V-O z8StgmchWDuw93Cuo!#W7PL;o&E<VDF4|%d{z%@_7)q}T^^nS*+kDMO?HN9ioCbA>_ z6>|s4s-$lpzYMO(Jh2qnK0atb2iwOFFOBUZi*S+bjtAC`eD8=;#{U$ND(e4a?j0(h zO9q(+WKD}tEqmj5ALcx^jpI*=puBPX6@KX(M;0W)U1JDLnp=jpc4Eu;dFp%ITZY*Q zwhV0;g}01<q8ad(@ooCWTL%9c!<LcbaHo!8H`9fxh}58hmLPZ#6=WLP^o)>5CbxWj zNQ4#ii;2L$MnQx#FmTIRwCrDw3iuSTI6AeF^3J&bq?K5|k!AS~1bvdAlIf+NF-z#H z?a>#|%`L_#(f5^Ypjzg>VzcC`&sc0G!t2W$eT?Ja4h(-KXr%clmDh9l&!7bQCoIGl z6)w#FqJknpa6#rr6;!3PG)M6%Me=d<v*ARtSA+}4_m}WN1u<^i|BfH4qj4jH?8TPi z$*9Fty(oKv*Mp~mRr2GXMsP;1m0MZwU@rKiXqXaxFStdD=4<g23die4s&GUE8sdWh zQQa_2lGqwd;(&#R&!zjGi0tJ~wJkMZL{@fd`^jUu2P+zVh6^9<q7O^8+6#IGP|IuZ zr5t{vbZzO9&U~xes2{F%FG*bWLh<F#x@wQ^4dp9f{QOEhUqCj_cD;j(VN<PE1CL+a z?s=NA`5_aX!8tabGG&UrsxD;ivI&{8{|Lt5zZ(CfOZi05r24eMp_u3if|Jin8uFB~ z7{6^d5%GyhQ|-A<z^a{q`4cC{3Ftpa6peJ;xQ_kyCCt<zA<KzdIos1lt*Xa^*f+(h zhc$)UB2lWZ(=ppRxm?oepdknz$J+&uTDy0+T_C%6yj}35wR?x#1+x42!iekZGCP7j zo;-2U{wJ(sOLKbbZlVDf-5}X*7u|xhEkcz)`yfA?a7b>9D!0(PnGdoYJPx<M1W8@g z_=MP1x8GVksszr?8?d>BKuTWZLDrD0Z83aFpwCuO2jcHom)n7EzbU5b2*fX1yLSMh z?A{TGU$J)Y07TjSD1rDd*0GHji2jGsx%QcoB;LM-3fZwS&U`aoyq#;+6+_@8(Y98- z7giGJ(hGDnowLDqNOYjePBi4ct?jmU?|>%Ry(5~gws!A;CfWTc(ey&=*iJT@p3loY zg54|M!p&HT<Gyel<i7=5l}Ja>nwKB>HcrXGvTIFH;cp#FUE837Wi5Lyf;Qe3htzx| z`EFb9F1ZL~_n(eiptQrPNrrWLiB6C=+lEA+&zP<D8u;2ZeRMs8IKj3~Z=OF~-oZDZ zyASnR_~d%@Nr#=wOqz{XD4(HX_ti=Ks*n~b!dTT0D@kFj73lQ(85_M^&KU1SL+--( zSFGJT2xHm3qcHw0YxfSAmfa_Wae-tSe`Fn7L18>7nZ`iX=JUMVBM`><7Veu?;<ztd z2kmKQ<w0V1*+!cR^BOc}&0nG9Zob)XvUcx2`?%a)4lAH3KKO|)H_o*V;fFIRFsyJD zgc+}J-J#w3P}23vaOO$rYTW2BV}rG(j1BrKE1eva-OJICyL>%h?cPDY%I+QI>s{9F z9T-)1KT7#JV;$Scmah-;a*sg1=3BT|TZ!YoaE|gduy*etU-QlWhpgSZ&pt)IMp8zo zXOOQ~8gk<&twSg-Uj<>tEnidpMcMLoB62W=bp&;^=lUM>2`h~pWb3b?A$QsO`_}Fq zWUK7nQMP``+Pwpl%I@Q`bp^TjqIIwv$VFX!ZN6b0T`}n@db1^58K}N~omYGW;x*se zO>DC1kM3*dC|=LBcJClw^UeNZYxnN6kBiq8<du#%SKRdBM>>OEVI4$q0V_x|QURN< zG5^K5T9Qn^G{9Fo>UhM9EZ@0TffG?&$26JNS6RQ+8lONERg)mobJ3V%)S=bKCO>d5 zzST-26;X#(aFkDfzCnJKH42kL98T;*teRt77~l?4Gf~(RHlwU>;w8WLaPI*br{&>F z=-oHoRT7cX$g59Z`tG)?NXIo(y8Y(6ZoBnRsT_rWP?jG$wam{|=S#;tiU{fKqK9bW za{RvupmBAgL-Mc{l4*N}^l;J@HiZ5x$#4y^yfefb`toL_1ai2-tSA044x@U3PTyDM zrLVfkynrSUa;eyt^rmrU1bSvHd;$!N4+Ky`7Yc)-yU?g0IX>iAKm;OBH|He6EDU-j zN_C>WEichjDxfFP1jxi2Q9RK<mD%p8CUTl!`r$m~(Se@mBmUXEBUZ^8eu_t&r5>dr zQIBtM{D^}8KJ=zv`(;5&-%Ut*RCQ9uF2G7kW+ZCROSh)5jv$~+{X>-%S}ifVW`wSP z59H7Teg7r=A5At18SsQNQDqY<_0RWl6T_$exhp#oA_=6~R%6BkmYStwwL0<(w7m{o zC7sf-dIQM^JZu)Nwl@<pUlL@tXbJ;wwu(9<{}pDNE1FnA@5_Q<snDac5kv1^^Nv_S z@7p}$ywLMMf!7_<3H>{&4+%Y;lriW@N@hS$FP#jbHzczeu%w1Y56dq(6TC1i-={(* z6b$)Ui9YnSr{vYUH9+x#NLjmp6tfFLb?pNBqF2XjAl^6B>%`m0<A@j6wn>?TG8k=* zl-F^t+7*pd+n1x@0?zd)bv=p@_ZpMPP08+2YF_I*8}fRHhXHZDK!^0Dn+rpF51Po@ zO{r|ekiI$Zh!v!t$0J@WNZ*3qhJ>_E${3_2B{Lwcm;TTaW?Vyj(4a>zK6W`TZej6p zgYxC8WM%w}b5BJu?huZVC8*P_HoK)eZ+!7hFR0vo>&tGQv;bN)9aa)rrk)E>2lT5j z{epY+ai(CpdQ4?bfYu%E%)E(@RJ=Lwh!vpU#3NoTKtGAzh6J=u${3&}B{Kl6m+o<5 zB?DsA%;+K3b0&9Th}}e6t^DSZ!kBny1KHg#zU$TlHxEKt4nOj5g9Zh0_7syb9cNTF zVw`;`?}!!7{+LI+SUCGL^fn~UbW+A}CMlVLGre@uk(~^rQA49g+9#X|UKnXlMn1n% znLJKx+o{h=>t&<>8`etJIQEoKi_H3a#0gck0~HvD*J`6wZO*JEV`#luZ7;xJ)W&HR z79%Qew(6Y)VK*}OOWk*nJmYGfNJHP%p6k2g_AP}`yBSSnsk>C>f?Ct1Cs>rdeEOJo z<sGxa?K61Hi-p@~qPHP&s}nPZTS?0d-0G#TIoaH42m%_}=mo(B=M~Hl1PN!1ai=}i zVy1G7zA^97TqUF<gLP(B0Nagpm0R>^-chK8bf)>gm_boxLO5vnj104UT0%OyE3MpM zY$#eYOCQ0*=O2)4AkC_aln7K$<b`;cIE_;x@UKy%M4-FT5jBFdyyNpQX;k3$^V(i> z8cBbq7Q`0?AL$2Yrk2)c`j7N|nwoz-{^>wet~4(p=elTaqzK?k^#@=|#psSSyvl65 zHCLH#Ass6=7Q}|rS3-xqWq+0B@}9cuo9M#v+WqiX%zxi9t(faY-Z|GMjyvbm-Tfu{ z_kZYJ^tS;MnQD2FyXa5G#Cq_KrF0iP$)D<$cl>fXS^G19W11Lj6?FyWJ$9PszrG%) zx&ITi2$|Q{KX?k_Bc%Aryw?6v+xod&Ir%Ueg1mRUP5V36?j6GRWcQ9?dtbD6?-2YX zyN`$M6}i^_x7M+xDG0jTx7fAz!MAC@!pog?s&EMR6qIw(Of9$9f00L(xV^q3eVbJH zi?7?}_zPiGVX#RS>mqUER?9Zz0;#oV$Q@GWSi5(Cl<eLSQoF6)J3vZyA77dkq~Ju$ zF(49_>*{NBjdgUzKqW?2C=&K+Uhxs2N)T_ns9HifAs)0YtAjLpIWK_gF4nYm?*KX3 zy(8paW$oSpa<cn4<cjQKZ?cZ97~ptZh4A)9UhWa#O;B#Ucw4lb5FfCvnFE^M$K-WI z)5opdJD^E+?}(<)Si5&Xlk9$!X!^2sY$qE{f6B`}0yO1YxPP+}$9>@(?{TczW>fnd z?s4Rs{SIsQ?z4~I<1msu815FML|3*hvJR>Etqwt`@e19s=X|)<N+bti`y4dnep)za z?cPDy%I+P7?MtoQJ8-S+J|S%N5ET1iArYH$#5%Tu!nSbEhr_(wBM`Rv7Vc3iaoiWq zQP@6d?cPDy=9~Syt=+rNJ}zvB$ocSo>kx_yS3#K32-mkPI}M3?@IODxK%+(Yj4S!W zZ(9lGAZVXLL+*n153Suh2wK^_qoDmOYxfQuE4v@1p#8RWY$sdL{v$8<2n21uh1<N{ zrdGNyoTH$9y0v=;L7Q*(d#v5N&pt)a4od#8-#Ucif>sb_G=er;zK%Ef!`)UIImp&K z(2%=qty;Txkgc+NN7>r4cJIKXvirDfH6z9BT5K};!*^LnS4_H&Ao;^1yy7Deuld&Q z?N;izubrcK{V8kr4&pW6?0?zXz5DFr;&rIx51+CQqPTz+q#3Dz&DU5)@`nMD4ktPJ z!%xDcIw1K&d;;0YAKrw<RMgvh=;ILY&HgyV&!EVjVBJXmKqD2&AHE5W^6Aeo`2)UZ zkrnom$OfUsnaHcc)UKW`VEAkh%>!Y-CF;LETSxMTD#D==C5;R7nwObw`W8+Y5xGS< zaCWgf*G+%_YQ=QgrXxdEW%h_uBfv`V$G3^wbpALQ=_EFuVLK*R2(HpetV0usTUGo| zn%H-AI*DC*iKgzfUyLR|CI(zQodlJ++z2rItlT0$(Q$QM-Vv+&0MF$SXDM81oTA4S zxu%o20ln$>0a!Grr<2f08M_Z4DVcE}KrbDbPJ${cv_|pHxx&&(SP2<$fiqDPA^PWW z6T_#Ic%`;`aO`iXOyMqkWruzsken{s;L2$iNrx!=(0u*4hvX5hUUR0}u6xn-8{Uv` zJ2l!QOXcGg+*55Mkob7TYtHN`ErfqB(BIlersBz6lA%$CuP9lpbN5k@ATxkBH6}jX zHRyxwx6x{}1r<~ANM$Z~G((L9^CcpRzBlif6(S$wG3Q03e>Yxt$TIPLs6Hejbz;U4 zDQTI3NWJvIu`{D!A(<|Qx*k2gTh2>V7~iLMx|mObU<IN4>rC_Xt(D4LpghFZ`h~nB zRzUt7k9e_w{72|*NFeK^i~(6vG6TqZX`ys6)X?Z*`4MM=7l!5k+;lM;cNB*7S~QWR zEmPTuA$?)q5i3ZSc*KhZ>5I|ZkdW3%8H2Q>WCo=5(o-f~3=Mkp;$yY*;uaPkODSE< z%P{?dd-T0b!Sp?v%A5eL$LcWiCPH#rc}J`O-QW=~7N8$OZ$koFCuI!Kl9CyK)=LYd zi=k#l53#$Q$z2#?H)+8nOCnv&dq9JNIQvm1V>-^LY{WSGNZt`EoPC%_yjVE<HS{(l z&U8}7a3(34fiu0dP`VguX!J;Xmovc&BkemnUCcj%o&{0+e|bsLQA=ems5OHC1dArp z#jHLv=a?04SD=aP&!i4A54#$pCeYiExYdan!>y!c25$AzrIjv*MmBmu@O9=o7s;C; z2wc3}vI&(g=A67obCoWJ98$UL@+w`-n!KY>>0(UxUNMJ(N*D8l;Z!!<ZfWUaM53Ou zfY%U-V#p>e62;s{2;)RC{A=WiVsM;aIhGtR*GBFLnc$+`ns-U=vd<;C3)&uAR+p#J zCX$}60yVpo#s<C{xOCdcztd_jRFDF)CiA^;vNg`a!w*W=mb7oL?x8gN)3r*c{;;Q_ zsIS_?UzU*h6V>x8_mpPg5SrN!k5H?DmPGotD07?fT=V!mWUh9A*a~kxoFd#zQQ{o> zZAK*6tLmPhhin^JkyI{o1c%63kMC5xbqS_&A#PNuPU1OSwuQtFlOJ*QYel+y-UCx> z=;VE^oxJ(8w#3QnzlP|YnYHEprx*-Ec0QRITi$A0JD2nl-;ahMy&W^Q{J6Dyhge(L zy<@EH2dv#YL@dhg<FU4eqsSg=n+VQ$$~v||s`I!rwtSqIJ4-Eeh|w05b5Ra08C%}O zqe^6KSwgubzGhuj2fF>0n5rY*zHRN^0dKN<N4%}rX**Fm;7xWvO1$l`j_qXQZ7W8X zeUNtMoAKgp(Q-@dx2~B3Rjy+4y6#>tuy*f&CfU6sn(noB?|>%R{V35?vySa#qiKeh zdjz{zzJ+_8l{oGT=Xg!z32XNb*F^Ho{+-tD-De-aCSqieFyaM`68!}8v(_OMzceBU zHC~}R_S_PmvJ%Nb*nR>HxgQn&z}mfou$A3A3fn)ocJIKovipRv)&122jtW#&XWwsH z$5v3-7S1j44PNdM2-|!Mx8bZ2>725AM`3%mwR;C)n{W2Jtlhh_ZCuz6kz3-~)*%!Z zu7WV*6|Ot9C;-jqsVq2gIOq5d%$-&`Imp-B(2%=)eTB7q2l*<yca*OUYxfR}D!Y#_ z2uJ^f+JK{ceYJILCtJQg%*#Cj`I>Lxe!xl`_l0wmukW#T?;v0E&Hfjy-Mh~|MZOM7 zDe+0`5Q@uJL74H%*R4tCQMPPd$(6%$5fCAt=~~gBSn1**PrrbM+~w)tSi5(Sr?PuT zdHT=R?j0CYb|06gW(0{{peEBuOgzn|logYxBS<5$62lvbwJqP;U1+6_``S5*)XS{h zJBZYLv%lWjz5DFrB6X-V61Q6iQCz4B(u`NA?nw8(hk~>0$1$ya>MYch*aNIR*9GjX zl|~K%b_xx-3)rr;dj|n4yLS|@ud{aVz^1bM_+k_juzl<3PP%}7f>(S5I%~eQd!Lm$ z?rY~LU_WZ@-a)|ToBi)tyLX>`E&=;R>mZ5?SV5YR3fO#&W#s7@5ZiK+^Ypw9e&PXn zdg2qv&eKyvV`IzHLn9S=dRCo{U-V~~r{|26(56I!9xbFu-1+yZ!6>E++tTm}dft4% znxLoJL|&e*cesr&%gvOg5ok3}i4?jNFjt<d&Uhk^&mHq#^QL=ujUk865*(kdPproR z=8KU>wA#`Sz7y;<L0qb{*U8B5bADb*tNcDsM-vD%R`4MW?mIfa&oz08rt<q-jV3@Q zR;uIqeW=Xk3WpI}#w{j7$X=9p#OeaaAs%s-qBcm6bj|N`H+s`AaIi>E&+ns?GIoJO zQj%%1qO^B!$#9nGr33T(P-TVIV&VEKzt6LriJG`maXB|Je14x(JO9TC%r@W75T){Y zR1ho`dQ>)I=)E)Vh!ynS&LhqXJ%1LjJ0$Y?5mX-%dO9g%(36zRfSz7jDE|jFG<sOR z&Y9qaVY!qp@P8iDF9@>FG6mE3H!5=inH~@!_P2Q4!{6o|u>#pwdBlqavcE%bLxM~v zWejAJk{KY=OAB1!r)EYEvClY@yD-FV(p>jT;sXEq=M=`-xo9FwkEF5@<Ls)uBUU)O zf=9eqIJ+9X4T&?Ilrfx1N@n0pFD-O|pBfrH(w^o_@WM#@pPS5T4#Y0Fb=G;k(zi}3 zbAmKPUg+f!EhdhJugg1P1?kuDh!+deuSah~LRu$f4APR48IaaXPnl#^H0aTbk6Gu% zEi67>$YC9&GF>3%ytB8?%3H)_DlO4H<Wjv;YSicIWIsiU*~_1G)o%R%Wa)r6TkSQv z9ePL?k3;4!`|*sjL&lE$3Z`EW&>vz7rURPFTmWtQ0tNRb(sg_$@0b;&f0xI+SdjkT z=xs<y>%@#fTGBED(t7Fs0t_YW)G{k9H9C68eZZOcg(3GHopNX8xrH&j3{7O|*;F=i z3_mUJm=%W4<S{Q6hR;E7Lt<DbW(>oUmKhk<OP5y49U9r_1;KxfN)Wg>tfeebDR=he zJ*umeJLDrOm~!XryrWPlcTA64F&n;0xnsJC4NsUY<qlhAhe)|Y^+d{@BgA8za)*DN zIw^OqI_z~TGhVY*?|5yOTsvi34j8@Bu_f8LU+<+HOOt~PIH}*igU)(g>D9@x3j$0Y zkd#om>7wMmc|F)CQ<E){`{uPV*%v&%1ajZ#>t;!Mv)-(yXS*?r^zeiy?Uc-)<|a-_ z|NDuwnQ3k=8Im6rqrGU&X{YV_uKpwavVRRiC4x<{7F5l65aL=@Gpr;|G<tzfq@S`8 z$t9o6PoN>FUXJ-Ke%ac+Lrkdb-Z3WhQ`YVsBI{)L@#Qdl{`Q#rgvI9z*0Bxp<c~X_ z%pdS_XKAetvBZLME}D-epUk^?REc~t;|{F;ck5C)5aXZ4_#Hts@pQ|U;X8mxcJBzH zGp*e_fJk;92a#z^v7<=T)dk!x>*$KXNc6@|d-;LC>HdjeVt!#i#Bi?xv(|^#Lwv8n zgXu=K)9D|QTKiM<u_FFr(Zv|vNN%p=Tf3XA)Nx-s$H3|rS-W=#tj;(4inV+9+2;zZ zp0f_3cwn_4%}51ozQ!^Fs|RRP`&XN~&;`S5?7m%Atcf&yU0wv%<tQdE&L4c(C?rfC z!`QQhN!r*Gd+BpPZXuZltjkFbcz+9a$^ilI@d;!HyuT8SjV<7vMk)f{e+A3q)1P6$ z`$qj(lZbTJP8DKB9-)@>P~_nw-7mYv>z2ATuhgy|u66OPKXJ${wWfTenJvw>TXS5@ z$A?n0Iv2TQ#PK1=`#PvT<_s#iQOXa(F4d!|SeK8|y6Wqa6(U~t-)Ks+T1DR5EBlX| zCBfP|t8FYp*K2oTCpoP^r}5|V(pbfae-=%^GNu@hPITjp5x-g;S4(9$!P$+dc#zzK zQ(mdp@k+C;cJzfxT*3%Rl5`mA2VLV*q+X!Y?HhUNrozO(jwZ6)4pipib}){NY+z5E z3|E|I)A!TFyhM|7IxIsIZaYPh&%mxiZ@SZg1z~!axK7HL(?L=)!|9-xUNjU72_}#( zLV8_cxR}vd1&)7>86)eIY+0#ai4F*VEqLo!@jx>PMS{csxLFW<N4p5G$;<f)t5-AU zr@Q&7%mu6F$y6|A!p;Apykk~qJ;Y;nVIv)_{#kh4A+r2#R38$pIx%Btm9)%2t6sXa zT!b{T(F=lSIj^7;*>OSOa`ci-C>P;h<P}HCMMx?_K^Ng?ghU%&6<U3l*X^~NF+C`H zs&D3R1)Vd!C$?`$D<$YjG%>sq6c@kGN-EiVN_SV=m*fA#^JWRU%<W#gQE!G%LUl%n zrJQXT``LT5*w{siXiB)ybbmZA8!HAP@-8+5trHAX>MqR3&NW7f&PY#Tm<1W>6KEno zBjGC!@{CpvxkUR6#{kPl_^xr0?vI?ORA3hg)<k0%axeKjGe-KxOl7u>nRl6Vd(Jl& zch=!r^>fTRwu6dE=MeZx|NK8p(;SdjcqJ|#30`wdM8$-dN9<zixrzxf4Jrm!Z80IN zPYn?hLiI#U$TLd##W5lLYYZ_Vaq0%^!ek0`S`Lj{atDkT-h(s51AYG`{2w9oYj+BX z|E(3KI^_R7Jz!t=4jg$a=IJ9kmX!S&vm{u_XEJl6lh1Uy`z%l@m)xC3e`3g&6R{(6 z3|3VQ`8*7HrTGP;XvqHUXn|brci_LEhWO}Ks?HFs_L|*x-RtxpK>aOfFrXCr@c29z zMhf$LNMhQ-Iih@TdU36CsN1hf%3qT{jmUgC`WakLGkC`Btr-uAE!a~<$t+Tbx~m_Y zomw!-uct=%#1}-(<Uqz+l>J-HlHi%#JR*&b)~E4#E7*$mlxiLsGdaEM9;D)!q3>kj z%AvMR-Vtl%^82s3u<ISiJD2b@FS%|{=^6lK8eh#iT<OeLsqLsr>5}WN10#rNld{;E zRtiU+&a$)2vc99&v}t8@2j3HQ?<SxVM*l+~lVG~37<PhJjW9?E5bzq4aE8vbrs<L& za;dat)7eaNlM1Sd$6oD7XTor`#A0Pt(pT@hZR=1Z-YQN?|8+#$C`u^)U9Xh_KZeOt zKGTQ$X8UmS2Q>{C?zyWB`%`eyFh~qnBl*EB>`oDoRjs(^f0d{eRuGFCKGdo5UK>?h zqL_XR4PlRP48Zu1wR?vE4B5S-DESR*_YR^&b{}5`!z67#c_eJrpSO-J%>t?)I*LUx z1xP5Bx*6L7GCs>3kfky^#PSGY#`Q9rT9J^;cOni@$mMtOs1kuq>$EK}L`gDD<SJ1s ztRP_|AL=mrH|t_K%>CP9xQ;MdbG}XYbAXZT-VsJStlc}nNOqrqk)9x70F2_96Ux@H z6@(FWW{W%c8dlR9#B>oxm+eh*=9}?iX06f`LqsGYvyv-?<x=$%&vd}tW?dGCiNAm; z=(_K`%-X#JU}X1>fT>x#cL0p+ew2WD*gCe84Va_6+#}dz1m#8wn0$?81a}S4Dn}he z^z;hO7&wM^_QiJoeSG%l2P@m&Y<;HhKS?5O75>0cr0;+AbjUCN{^i(h`<X|f=+v4Z z&;w{Jw6K)@_fQM(#XnxE?ZE#T6lG~9ejg)&MdIhE4H}~e9Qq*Gh5wX+L;PC~_ywp6 z8;5qd5E?^;-j1vw&}oMc7P|a-)sENMU)mqWt?qyD)%X<kbZxTPoRkEX|D|&p=>1?Q zDdj17wQRw#KYy4Z84t<}o|&T?|2Hse%^mK4k|?BK3t1%wW(?pd9zX`_%KqoD{vrV$ z^uxX4oS(jilJuXXRpKb#kE7-64KP*O7|f^Zy#8m<Sg;zr$?l3kS{%|GxW}sPX8(l$ zXEYAx5sIl0eDf8W%+u|w)|d03Xk?`0ToOlpK~G{8H=Bl>iij8Uzl`_gQCl?lA$p*r zVWr7H#jSvBLz_gH5*B5KZqLOe5CI0(53nVSY>4ZswPs*TyU<cAY%JBLW==>mi2K9a z)Wl%IZpz2^mtNiM&CM@NR@?3Bg18>1Jx~~r+b&kiX@@n0z7##xHKzZ-LS))^5d}vK z`~?0<2VUZY^g61~5d0Tog~86RKbe-Rkf_?7wzvglQ;gmb@#43?)}SJ<NLVAOt}Z(s zmI>11Z=LAdF0c^Y#XPbJ4Y`{~&bM~&pr*?19o5u**6tnDRM~x8O<id$PJDk;l7*d= zva-H9H(JM+x_L~n<}z2UH~V%I$vPdswlf}WAKDpD*D%y&m1}wVGd56nK1wK37MDu` z`N}r3&N`|z`l-e;)YiB#@z<gcWxI{vNm#GT%?OG1BYp}a964ne;cx+x%bi+XG#Eha zlXXT2Ht=2@N%8^5h4?J8j|<-f)JAw*5c(dU7~V`=`aaqce-OU{={^Xejre=|{?DT{ z*ksHsaq&Q7cCokqld-otoh1$+)l<FcbxPHea4b?FHxlbtd)=1ToQ5`pKO2Wz?RvL1 z$5GxWl(!Pf^||U{Z&xX{xs9etT>`(`8F+@exwKRbv1IQgR?rpRSfJW{tCyX2+KuKq zAX!(n6kcTHU@7v?&3fL9)bC17uh*_N@SpCnR{Kb&bgbsJJ-Rruw%(lYbt&B!#lLlM zaiLV@-)mdFE=nd#w{}a@t-1NO*TLD6Yspud2=cF%8m(hqd+$tr&TDq+ttL7l-T<c{ zaahf3u5EkMttOm?J=|8IE=058#TE41_NZ<6<*VH;8sH9jLRy>k?gAQ`K^v%{*e;UT zv_t>@gwY72gXHInfy945aU{DxmuIl(Nx3%jRNiT+h|y1=37BA%*d!f!oY!VHA1{@g z^U*O43G<^Mg?RqF0Vjh$%R74&Q2!@r0`q0<HvWwSDznAyeF5p-H8W1ICY)6`A<?XQ ztTW`d@{U~v*8c;KJxifYQyq0njqBGEzK!1Wut3_R{m5ja8Dj)Kbi&3$10`LV=E*N6 zh*B5rTHDS<-(PeljBG;1tAC!G82*a~7x8XiDpyN<W)VkT>;jPJ^(JCP_-<Ip7s-2H zEBW=XT=0#2rZY|XLfcU|ZN)>{L|-Pj2u)-$Je9dH{LZY|niI*crqAu#ymM24*w1sz z3kZJ#ucsL*Mc_3Vw;4a(Y8y9S`~LN)?f?j#@G(G0x@Q1FlokTS`ObvN07Q;as0$qb zCoe3ucwTNI$0$y$#$vIl?bije$8v$=)u3~xeK6IbBI&HQ<5!}I;kV<MUK~7ld~Z|R zUDvM7LMW@DGRS?VB!pLelC|ORuWrX{%$DZr&7RPBIiNp6_J@`mn_pxoD#vAJuzmM# zjB5ApQh9f{LGF&C9OE|t{U5;mBYog{bP}wB;@m<Q@RNOgvt2D)jRwT%S&p6z<Ker| zT&@*)2aSUn=7;brOJY(PBqon@jW;)6t9I(0*htr^X`6#hR}4Owcf`MtI^vk95d+Qv zAnBV>dhiB8owqV|Tx4!Sv^>d8B>3j8-J@pS-4Xp`xbgphXeT{zAHZ*o(~L4^vO7mT zE`wvgi0*T7tXluiGeL8#Nn(*Vibeix-UgLIB^KF*@%&d%uzm&qNRFYM1fns)f{$Z# zy0swZ#KlyDyi--16p8R${=fJp<w7k<BX#M-w4rD|wj8ahODCo=&Df}Hmrhu<S|uEZ z{dDhG?QvGX#Fdks7hy^H$_f7(#g!BCIciiG(>;VsyKSNH+g+$I^R(+zy{-o@DuR(y z;yk5$Gi+{bZq$v!ni};J?Y(g~>6&;IdAf}r>&pCPSiejmR>V=dmlz|m48l?R=t*^y zMw3_WmH4d<<C=ZhHAwD&jgT(c@oqpv&|)0Dk9S$Sckn*S?mq<)uI;Un)+l%>ng8xV zYyW8nUfslD_bv|3e>ap{QOwLms454Z6x!+rOPsy^>p_5sw-TL{Q92f9Opp)@?3j5i z`imShN+3wjjQ?FImQ#{}UE1))_PU$q6X6#OnHAXOaG_0hsWvII6Kqo2FfuphvM`8E zM4~x+pL#P*;x61N@xPyb@jk`B#;{K%*4*M|P7uNjqXQvcM{#xGEuM^~B_U+wR_12? zu80Uf5)pxaje-bt=}z0M<0Hj2M^p%JWqRhdgz$0I&v!GFu31(x<W%xz=%zW&g%G74 zkB%68R7jNSo8<dJx6Dn_W-U;+MSqq^AHfL=tZs{zF^!SOiScbw89kYDTa-yL8K+3F zcaGyMlh;Sn>!;l(jZZXkP>+6&91C}Ync~8Bu{3oO(CeO+(CbobPMSTXDtg(ozYZx{ zQ#VwH`@k#f9V}4)G5=OH=6@P2B?ZZ~_!}zL4~$a9VjAp=vB=<Sm8ql)<I}{}ViF15 zKYT3VK64GU9Q<1P{XM1KyXPsbT_>_$K@K4zL8E^#mOHv%XF=hryM5CtUL15c>OOPZ zOqEj>4d<(9OqW=}dzUJA#eo^^n|}N{?<GSb-P{|7eoNmo)?94aGm2dJjjxNp8a=5g z$4`SBO~jZpix=t>*kPYQ{t(&$6Nm?}o(GZVH7b-WG!^6FjFPv1^;C?Z%`hHSnO27t z0=+;d%N`q9T!ItJXvi&?KLJ)1oOls8mbkb%5q***q>>*eKuQ&!zxG_8{((_V|As}F z{+e(f2xnjR<C()x->q!TJa2lSPx$552|MHtzfUYtoc^oCP8E(&oUg-&`apc^KpZXs zih;y6byGDrHS&Rsm#?vmsMrDWVbp<|`?4={rK&*ccGpg<$bfLo_*^1wI6<*5V7qm+ z5IkeJ-K=k1_o6|I;LW$uFZwgQ?nS>%tAMt(2-WSc45h$g6+q;Kc`^&0m2%xHK7lZq z*JPOAYN#7uKa6oFqalJx{l?euJtZ!Ey@%+eU;0YV0QQqSiVT-Vp=)11PU|w2(Q>L< zXL6-(Y4bmT#@w%cF|Tk85%UjU`x+w6yyPZ%^XpVoAO*`4ceyFma@NvE_Y~fj>X~Tp z2kAj%3IK-UNV)PR`ici-rS8<K2z=!of>U%OP4z+xv8n<ml-Xvs*W@tMSk}sXP3YUr z?_!j>Y#w6Tr`%~FV{KNhG>(nR4(@PlH_~{q(c+L4bQO;0NWI3FdXA2rbkqgEo8t0K zoZI6Tp4j`7#xPP18YZ)9mOh6=`;>VEF?%gjw90}Ygn2V?4;a5YT|>^ShmkG|*(0F- z!x=Z@sV97SaHc+uAg?feR{Z?4!JMNZ$YW(X`+vj6{zd#^UpLSXqs@m-kz=*FY@tO5 z;wye&yQavBs)dZ-PuyxWYg~p)-c($tRSugJs<ly~ulTBG*aV(~etkL`0$Cih(rmYO z?{IrjcK=dSa0Sbv=xsp<{H@Ra0&Djk8mp#i8gj3@4;6$2mEFgWIYn<TUTGa)G5_Mw zw--qZ(r+(n3bVSscquP`mbT{1M~Q=i#jRvHr~Ma(4yKHQYEw+ahFD1=YOSgnRuYV) z7w8;ypLN9?=<s4Ds4Jdkt=&7|Np|mur>?bo2RzB{<9J$LAj{JmtYa&NB_5aU2JlcA zdL1wM2rwk5H(m^Fj%y_$K9V3>r&SGW$!$q5(P8w{*2Qvw(R-Mtt}yzrwR;B`$?hFt z^qbc19bhE8A0>>wXdT;9fYIl8$wvSqLA{Z}C|_e4Cd0T=?f)mXJLMCJU!-559~lN@ zQV?}@M4o<$O;Iei?xMHC^7Fr}3!gT`gzBI!&JQ5&lCj4I=h)7febXi;^;VUKD?ZC? zOYK*{TjR9UvQ1Xx<|>2Lgt7Kg{6ef3TLlh;pNtP;2iWl9{nO2Q=E*H_4`0KIP~pEu z;L#0KS)pG^Bky&0(go?(G_GIsrD}QjF5y~!>+T!xk~da*9Wq@Vt{?T9CHC%>j&Y9d zm=UXJV>)QBb_T6s#XH4M>0(`<MckyX>q)r@eS6-OP*<;Bh$aw1r5KlvHsibreWzwl zz^yIHUL`J$@@-M=Z|x!}U)<vNB-g{98-6Sy`aDeXf~jGjFsxNZiO$=#ycAWpt7p&z zXed0OrLtifpt7WUMOi}Qx2wf*+RP;-m0XQdMi-Cdoq@Vi`Y_KROV>%;@^rU|>mBRY zpf~+WDT!xs$2!#}pp!Rt&r4F5DWAM!t(RV*QEzBI6MQ1SK1i)80iYRkU6e6RE()<y zb*8**Lftuf1ve4DSf*Gk?jgBa86!$%oP-&MWGALfB9ym-%fml#x%+6V(W7h};h`&u zJKc<7z)mmFQTHK?IiG_hy5ju{V%n*wqcRuN83qAvk)P-z{++xdRw(-|9&uij`QMM% z9WHMFFI0CxnNH3a$|N;2P^On&G!z>du%g#T53Bb%le#dhZq<ws3Re(2Q%Ii#WX;!) zdyNj9klkY*RJT^sBRLdeiyW4Oy(YeVl8v(*CXi+2!btm1CT9BnMr9*L+K#*<R!G~1 zCLEpqTDm@0r0qm+4oK6<8AF<+W(Lyq(kpW@mVrEKE{VLitT+u>r|`c+x&8KHXZyEN zK`_Vus<JWMpLZ1MqAMxPxoDv-y57P~IDA<=`f#SPn?_Idjp_cpa8XBs`_RPjM}oLM zahA~2DGiuBvC32nu@kAKp23$5f>U(T(iAP1oim|m)zPY(NRUk^Mj$dRHX|4xzciS^ zDA5_>1csSQw^9u81~ieMA<m3WYBM4<0k?z^W}w|CuwRhe9Dm<9?!41^diq(#QML!k zu{cQjA7X|{-#DqvwsDF*fNib%;{M{I&R*Jjzqb0c(;gEk%m<v+^clzYHZkEG!kl8F z#Fp|lre_W@pfF6FJrWG(n25?+U>cJ&5tpM?bs^L=JsSA6Wi8-y#lWluR7>0j{W?e} zZiDi#QCx(iKq-w1W4i5jj}gsOIpVdOUSkCDV=o**{Fofg*uu!ZVY6z7q|gj?h$a&s zCaBz7ZP%+)4e$A3up|dqPIi$5w1p2mhFgAm5E{~=bL`oI{I4=S$Omk}MrR2U(!CXt z9b!+Z*=o;K8}&|=tPpar`%6=;R-<%n>G{=02MK8RUT0*+S7)erOxyM}E(og&S)E=* z7sD%dS@zf>5pJiUVO{wNK6*+<xP|Pj+=%f&w_iPVnJr|N<fW-?#-s#9RPDI`+^|WT zx}DaJq5Pa}<2#oNRA-_g_c*&<*6tkw8f5p50S(W#cJC0-AiIw*$SQNi1~|9F+PYl0 z)jGmKhID%-kBf#8$kva<4HZ6gGjm3klI0LHBZ%yx(Ioun>W<zv9#tX)4_}WYsCe?A zG4LZC8_oJ5Hig)a7wQW;XI)qas?^0q90OcmY3<$tc(Qv(;GM8`?*Kg6eH?g216<#3 z9bYlnjW)pbZM^&=K$oE8c+s^=sBa-kk|B8mGFN}hx-1T$`3O_ZHT>@Ptlc|+Mt1KA znm@62?*JOveH=7~)5>m9NqDpV-a58ofZ@&xM`8U9FZl?7BB(cJposI01t<$)nb>NU zEf{Lumfe=)go|3Y0S&pUb>~^TcL0j)-VrE!t=&5SMRq?*pj>Yq+fo3^b9u=}02D#J z@d9OxS0<*dE9J1+RG6Tyo6SSk?j0~ByLZIUYpmTnU`Td9N({Z(I<}>Nq3`1*9|490 z^~Q^#_0nc`JDJGBZ6&Fjt>kK9x!88(GyP!mA?xBez~&d2hOV&r4Quxfu#w$6!sfHq z?j2wwyN|<0e%>oI?%1_7Sy^A5zqF387<A6I*j$U75&n$XVFZv8lpQamE*NZK4uO;e z+V-@U!|KwYoLWU+=+)00kp{RN4Y_N8XIQ&;fT8T(5r!99yLW)0>^=@dBRlZ`vtBYi z@3X9<D+a>B>3N4T+Fi!0J_5AmTfaN36mnm`c%rFg*P3|3-#U06uy*f|W-8z8k662R zpZ%v}$$wU|i_4^de5O-j!8(i|-jH<*J=oUi&Cj>m-AZS!+U`EoYjwR&|AY*G*@<W{ z;e8jx8L1%7*I33qwz%ue-wG3gazMrJv5n}1us>j>dNJWJTGL}6BXx^_O4#Goy|w|w zUOM;ME*!$~J?MH{e6rcs+x{J~5sP%a?borK;(FU};#cx|Te=fFyybTB5M)VQcGCbQ zM8bbkC`c5l2eo7P%Wky;!gGV$ZJpi}vNUxmNV+O7wneEIXW;xtiW_+g2nU|}T)pef zl%^I+$M=+QkqA+TDyX0&F2{wfq?~{juUlO-f5urzXz`0kbMqY$1Rz-EcZqFvmU$Gx zWm<0G=-x`%AzXItos_YdvwWG`q+Xye$Y17N5EUc&Wi){pD}@PCyT^Ht?s_dKpj2jO za7j3<#SNYX5TH%IPy;f2agKeYA!U-+cX9+G{8wHAs%vxqh9*EV4s?uvl$6SB(UI|M zbL(|-gcB7_n?*VkY};cybER$F5|w{A0UqYBrfo(OZhNX8jOu!E?hN#%ho6$*w_Kdl z2^<T?l=RKGXrPy#pCO7hz7jN**W~D3g>NmW&qdeMq@SSkKQpgnoo_5lrLM_+i<=n! znjEsi>7fP5o2wdOX#1*H8;yl198PRlAtxpw7mqavEkwK`@j{(x59VcB1-x6BY14s6 zWiG(WabNYpyfaX+dw^%)!VWs@{4!p5xJfsK>JG5e$s2>6q;3Z6^wJB5;VuJs^!Dh1 zcfgs_61(|<cO|}@9bQX4jyrO#_DsE5?eg{1>0Y~y@5h%!>@HoJlPJwZn*Znc5~_hN z1TE-*dK+e#>$-#j)RRo4bU;y=3!n_IJ~K+fdH*wcN2~z!lRV<Z0?^N)HwOUe<ctAG zQZoZUdg-p=S;v48wJ~}aJ>g96;xJlJFj^=KqW}>LCW_1mhQGiB3!>=%V;ZHSh{{Hc zqJPdiVuhk_@rV}-MgNN498jc_Gln8b%?uRjrMrgb90Ntv#^_P>C(iUPjH0J&#)W8C z5(yIMu6u}yq=KhsJ}`iz7wG%Y<le#v+Knc%PE=GjVg%ikcf<-oH}HrT3qd!dHwOgi z<cuLmQZoZVdZ}3M5;Kbd5vnwLh+N`K(83V8oXu>dGRGsZDT2Qj3Oj@-I9Bi0N{v=^ z22WzCs*<o7GHT&rOtav2bCfBSzTHrn3s_=qerAglZ~o(XN38%8@TeCHFmFb04uH`~ z8Uu`^Xa->P((?y%kAWk4cl0>wIMcZ>j&4m05-64Fn%kaIYo6}DRU3@217zu(t0RL* zeRi^Rz?-f18eRV80ecE3vv;MD#47wIXj2e;pJei;gOAEwz-K!51&0yQj8op9<Q=nu z-WPeyiv_(ep*IKUNrJ}hqNnePWiF=&y4LZ{;&hQ+XT~<g$FwHo<&aGU8>q+n_*P8j z<TbT!%g{uA8?CFcXcc;MUpMC3n8+l$0tXo)Q!j-G7$6V~iAk@HUSfU>t-6spLt^GI z6svqM|B%;EtWpG!W2az>fG-JK^BXf=TaTM1L6q6WI4VR>bwu2n7ZJ*J^?Wojyz45S z@8xFx?n-EQL#~%5XRZ<%NtL-y<S?b2R!DV)KN@YXIs->8I2Fdc858^?YSUozmk|;p zPow6Ea1r5>M^z4rm!Q>LY_1rL$iLVOW@L*on9L~A8SNN`nQNO@jMhaH`5EmTn+GQ3 zpYnikKASHkaGqfSH$o5}iNh}O7;{Xzx<q9*b&2;6!%d?v@{cYm35;RnoPTVW6w}YK zXDCQN%GAvv6%?e2(MJO591~G#Wz5(LP2%NfRi%|NgM17)+tSLglWkyH8LB1H%KQ;X zDALOCuTv+j%pFopi3}*65hRp3kciA5=7VOF<~YWdN@mU$I@T$(cF?JGTa|D;FqhW$ zmyo}OK0;PK>Q!dy?fvvQvSB__rsRA)kxM8~CEde{LQ2L9b(!~%Hknr>dCUJL7S=S5 z;FnIx<SoeC_X>m{9|XD+-zPgX+T{%wEtyK?99u`~wRoiej`Y{U7X));RnnPcVxLX> zakv+?5)FZnjtL*mw07@sAwzcWcp>9rYxfQz?Xvs$GOZwK5G_ik=|G%)xvsu8&$f;( zEgDGI+w56Z#K;O?U%!G^Jxix>W*?UgJQ206vZyTMQ6;jdY%rv9xGc$=PHVz?VHE)< z^;ln|`>l)QK!KNtK|2DdZtdOyK(c#B03EY-?*Jg#eH=i`v3*9XV8;(v)mP?(b!^4p z!<`jI&!fELBS4R!-gwb7#yjmlXI&`=4E+=n)O8d3h_!nM49V^tG4yF`_YN46-6t?q z;4^@KVjWvS4AHm>W9SRK<Rie4px$^fG~Uku{<n3p9ANbCOjB1FZMf8?N;<$ucJBzI zv#s4bz({sKN*L|6j%_KxXctD9ZSQsFosq&QUt<~9C*y}#|1>bWItVVE8-3?m?GJ<Q z^2Mi_eV6ZVaGGDFyL=TenYhb$7{8Kt`Qp}$@D|^BR#GJH?`bP4u2p>9Fj(M}I{f{; zdu|nuoKov3zHd@3!KUL);}*^WUE|ZfS0~&+9h7+NCJJr(;(|nnyhqy0kxI)azcKZp z>%uK(0i=0^a5L`|x9|uyXb}5Fb}O(!)}6d@UdelX-jz`9rtd-%uum&CC&SA)ujJjD zZfz=+$z;KyI#srN^7nsW1?|v}Ccb|s-W%rrLXc&wGMso>m2_5rS6%|Eiw<u`6Cf#r zGk#@{%4~k9co>Lj0?M%T{9@iQtMHFs;4x?E!Glx`*DHFzgx++=7RhtV6+NAxF~^pq zryxve?_M)*M=vc8&18Zd<V`(lLZQBxw@5kDe!!XBi7=42a1+Dd)Vn=2OO?v7iZJZ( zA=Or=&f5|02vIryX-nAcDIpZ05n_;TkZX6$qmR}kV^fu#%fOy`tfTGkFo|5=bA`6A z2|A>rjmlimX4s3k#e`XC*=0FLtg!Z9JmS1q^FNK(9q#2V$ABHMrjs*<HA&43tm&oC zEy7s_{HWE@!|$)1SD-NbmcsWWug=T63T;=SiLAYi%AC-qTb2ac=!q^LZqGYng|-*+ zh!+cOcc3>1wCUuGp-oaV18sU~j_*m*>!XL&WzM87467yjJ;~RD5(W3Q*D^8FwMZ%( zG17i8?}!!B-pV6hETp|1y*VIFCua<4lA0Mv(@RJ2JxOYA^vHX}ne-XRb1|05CRAAQ z_vhVKRfrfJP78*Jy*lqGREU^))Gwy=s}M2Mj$|CcZ6RW;?+pwQqgo<F>~D#~?p}p| z_}8fuB6eTBS?^Z(I$T9wfvZqd)Cgk5ZqFAhmNB5Q1&!^CSt>L72SM;5FU_}I_Tyn+ zXJ))=nhrB-={nf*%Po6ZkwCEjj)}tHW2Z_WSSE2ZBf?IHnK?WU-;S`cNBU*|4*d6l zzW*ZepEMgwB1q*Nf;Hz<iWAS@f@M;Uh<F}H<7Dd?2~n~!fS)$*;RA_A6A5t+Mwsn> zN*iH<vMOog0Lm^M7tb?>lNN(~J@NTw`+EKjfL$bC&-00!-?tL~9Kx@puP0M-g-)OH zaKuS?e>4~gp#6s-rEvBg-uv^6TfA;~z1yoFuHp76?PsOgc56;PZz3UIBp6r&9rh(% zMBnR-P^r6-MH2p*?-ao+R_t!#onag`F3A(4TV|mY=f#Si>Z@@i?`kL?O$|*zK~&60 zMwd(<P5kcJB;6-tPJ<(beoJkN{3`TkXWpBx&(_1-11A5uzAR=gt>v#WNUtf*E~i3` zH^qW3pj9{VE}Ky23L<F1bA`uEI5_u=J7Wgh7$rLE{2=<sWj9c)^HwyGpLKR7)o<Z1 z2$^KiO|q@Y1`Lbd`<!Q}D-({6rXX!Jy3v3(7mMTRr%{|`?W8iB4Tj}I!hP_mLeuv@ zir0s?{Rcwp(>_e@FyEMwL`*k_c|bY6-pka?Aqf<WiMdAt;~W!F<^gkq(WG3CR+V|c zR5T0-+sp&Z5(CWxR7;o#{)2w8d4PYNI_80clpRNy2S#8KxFMfKK#gH+Mt~Q_G*{JS z8GHJ4twLFn_`~3A2C#h;TnX*CePFF>HLN5|&3b{pGo5jTWoIg41=xaym9_?D^aH1g z6+kCp=D|NJ?mcn6B&%Zbf{C6R%}^`!0)6fF*w)VF!--`yg#FO*lF5E+_YRT0vU|tK z-WOQAcZlqj-H$S|_hr_xr5P@CZODE{YcyXNy_c6fYtwd!>=o2=*&!1)8g)hMBI~Hq z=%yOWi0qBaA^$@3k!?^rXBfFVAnQU(^0U{Eks-$WDYMrWSQ2?$Q#QB(i?MWUaA#$1 z)`QG$@hN7T-PVJ$i)42DY2tY{yL|w^l4dtuI|wapXJ?WiVO-N7B~JDmsXyIRGrV!_ z+}ofIhSoJoo+wi5#BwJJrDi}~eXsmgj40O$T$<8OVeLgM$uGy3BrD9>#d@ZHVZ>Bf zv~QB=%kcYomq8gq{ui3SDN6AisV<o|v=6}&n*M>6U(G1-<7T&ub*H6@vSdRX;wxjE znT(uVufK0<<z|sisK3oiC>7K76*Q4$<)AW~l_MUnZ1|bdO(6fBcf=~v<Ue@CSxQOT z_OGi=jz%PZ*_9Adnh}LWqs3^XlQU*Sk<?_mtVl#F>!oxWs8Qs5$TeckrJ0p#DzRD2 z0HN$Nf9XtBxo@kl7<`$V7(OU@@e)Tr8;h7vu1BA-xdKgO;e^VZa56ad@wU7pRyetp zN1PWY{&u`RytUCkgz64B(a9OZiKJ!*PV~~u#L-k~^bon!nV=aEaXAOcCRCi&m+}Ht z8B%F;ENDpmw7~jU(l@>tbk2oVwf(;dO$@*N$M<rnSdxi{5^|G%$+z<o$+?AsIk>tZ zzkf7~IbEPC*+R+hcjaYH#TG=g#byh`8D=PlMv1QUd<?@Z$Q~a>6ZzR=gGkygv$==5 z+92Op%7^7Y=R6Z#lW~;LL6|pwcxC2)Gee|DAyb)c&tvhOV&nMR#hvr*EqoBO@31lH zbB=9HV#+y$w?gUfF-3C#U7?hCcO)pyF%jhjGY^Wzlu+dbGc5uJLTz3!R#gUi!Kjw- zf}Q^?{9-Q{|2lQNU@x1;-KutL+Us<})PXZ1x8DeyVo1{H&ChrgA9AEoZyuhU8!Dw@ z=8(qbBm3Q$%_(yP<?trGpizbHG$N?D-Q8b$b+b1&zc5*Cx2p?#qD0NI9$h`g_te@8 zsg<W&y=GU`G}~d1T(>vh@a{L8&;AP$px1H)XflZRtjuYJ?+C$csi*In`@!>>yJis= z-c<yq$chIS-X~5K7oLT{nI667;<8k@)XC(J=VcFsnOeOWcUkSsdNX`Q@Kts-ovmJE zV=EW$;_Yb2-Md(^cJJU_l-)ae7w4?qJ9rmm_wl7#X)NU+hmxqQug+_%;~QiuvwIjt zqG};Qi>KmxB`<%LV&vdy6qIz)ZIp9R9;%e5@m3yH!drh)3_<bz!dSJW3;$f}>m~{Z z)YTXJ$E=I(K*D#4SvxxVf5F<l0~BTVj!^uVwR;CB%I-%E#m`#Dx0Imxd%XN3fTEz} zc%it}(8dM;Z=F`zgqcyIgX*8G%jN*8e_*P*M$at2%A&RT4xp0VJA!J9wR;Cp$?iuD zstc{-TS}lh4<pTvVt3}Fk%B5;V;PY&@#BF10x*7dB+b6u=Oz0+ww2tj5qy687@0+O zS2!c-t;{A#DRI9ku9n?z%&cminS+#&-47sbQqOEz2e6cIm_^_{F#_)~2>jjF`MDF= zQ4GJ?+P#Aq&bz+vvJT+XU*8W}=QsBC{e-pqMOfe8w+`S`Sl`HyCX5%$9x(9xm)7|? zuW!B$Q=TqWoa2D4a_Pi5#;?<68_t4NZEtp_HQo2WdO8#y|9%)Z{XX5~<$LS#8E1z* zUIwjUk-{FAKO4j2u*Y@yl?;2d7+Aw7$lXI*q<8ftQC<L|z`>zuM}kCGkh&C^Q(+Ms zJ}9z!XXG7_@sOdRL1gozG=7n(0#`)axRQ)Zq1C3y^S1}TW=d1NdSiw!iq7^LjmR=C zs+gPPBJ`&p#kOH}GA-DtnFu7QWpL(qj$K-C%4XtQol{OqtY$gys;FR%i_wGu1u_JW zGgkAK5EpU3P^rvrp%QDjGD{}XU=maqDH(7`MssEx&y5&|>}opW-;|fcD$4VEG?5j( zMrAfnemu(4{6e8{Ux{7UDA8wdU)~w0XtsNJ23c0AK`M%C)aT34n;tYkJA)<aQzvgM zXh2doBbrSwJ(p9iX7ZY#r;Gum_Z0Svx!+ZE!Zpq`mJ(LQfIf$t7(NE{MKLHw`xCof zlX#5EbAWPyE!{xofVw(!KY=Od+n1u?(m+s+nIxVxn##ru&!5OU0|n0?<r(CKr$2|+ z9fD2Yi|P*W)X5uzr=)HMJoVBGhG0DdqxACVF?zz8(1kI2t7bM&BC^?P&sCAkz1pp} zq$XMFbr3f>+iLTEsTGI%V{*eZ4DbdLjS?Mqe+o(z#N8K}m}2va<BrP4jJtoxI|GHg z|I0I2EZlt)y*c1cCvOaQlDZkV(@Xa_F_?isYG(8Z{Jb;CGZ5%vMvzUYFz~DLjzUEe zlHOe~lJEj<!XYhAlrzb|c=S}q_f=Qt#J4(GT!AKrKUu`Xz<n8N2U!+sDJ4D>(@x;w z%e*2IPcP;YaoQ$D&QizRO+vvaMA2e)YyjpK&?^-%E&@ifs!}Ttpw(>OSDNZBn^3Gu z3%S^=Y6PGg>}r(gEIWf?=Gu}J%U01uewIbFGkvJRlTo3G$i^rFGEoxoV^Z<nQ_@bw z#vf5y%R#~K;n$huxD4a$f-}*KD0ny3F^G@EVLR(F6H0AikNL3?Dzj+|ywMGJ+<$yg z>5)CA#iWeGaqA}*l{^CmmX}7QvH^jixF^%P@{vWQh%t=3^Us4Gqhnp_e)fO({J(n2 z%|CV+5bU2r9acI<8#E}WW6;h!5*;JQMAXF^)2d(0vZpTAm|i7Azp!1b;k|X>#Tu$5 zF4jE#IrzmFYxvixbFt<nnoE<vbR|3kBe+#_Tj5(Z+IYrxrKXeZz|^`gYrn^N^<_u; zYM6(ltV;UM@NDp7raoTe(#sXZ=#lRYmtKDT6uk7Jt!7_E=$(r!^I9&H;4H10x#-b) zyl9R2%2wl*K|#4%<)}qgm)Gef`m!FfEvw6=lNX{P_e&=)w|4IkO(MH@j0W?q-8)1J z$?iuTl=~{{_|lI1`gv|KFP$9c<<GKhI0WSiO1kX(mP;qkw~i`}eyXvIpxn5)@^3~T z3i9#qMJ!@a?t8|_ETam_{ZU>J*Pz^Awa&~zO33b=gK~e{I)F4jI$1c(BCtIu_fM_! zb0@H)82(#p_YPt>@B03WbpWUS`mWz^QQlnczDNQ)uJ6;V-7muWmaPLg71q}tlzWYJ ze$MzUwEL={+yPtV(h17Fc&H=WphTqc>1IddPD0!)Qbg{{!5JbVcLu+b5xH4Mzc3v4 zlA%bGNKmRNMIyrTQcPK$@|<FEZ&gRwQdLId@^MB4(sHQnVXx`6t6i^Csv{DYqrXx@ zbj>r-2;0?9R1GT@(`1e2<@?S#{)%O<6Z=Jndo24&39S9Dyi1~diLXWzu=Odvro(P# zU~Sy}ty_E2!hY(V1v4r<C8|e1!J95ry+r54x8|L;3U>W|G=Yh-4Iv)YLuEEU-3WqR ze<tq?R8-GT@(i*LrfG20Rd?55*Plagx+8~#t|i!2CvVJ<FR7am)uWdR+m7TPvHmi& zm1-&U6*GV<|G?wU6ivh+5Sj}52VTidj3->?uhDj<t<!crLdlE2Koj}p#f#LIhmaU; zv)iKrVknB<D2c)jqIh1d*xdTY(7wTV-^T1y8P5fW+O{Y*lW+2p=V(F&ztFNQHscu~ zE~ezZ%j@>q%~E$^-ZPxo+n!sP0XL(G{0um&?I{RTK^)9N{DO!1IAXrB#JpshuglJa z(xtoqaj?VivC@Gt3<oiP5k?v9qA`CxmDzSt-T=->T>*n-u3J<}WDICAY4S9kCMNqC zgn99z62>;Fywr(BxD3THnGqiTqLRZHM&9}7L5$I{t`xuafB5|0ddkf|rWgzMcQH{V z6p8aegMtw*w7rf*k;pL-72#qYuZt=8D#FFI)fh^IEy9I2(}58#R7*s-{2oXsB3$^_ zDHP$-sUG!^G*+Z{4FiNbCojS!eLQ1}aCt?{CYatmGRDRTw7)b{pGF`*ZPs3ezSzAV z$>7_2N}_>!oBz}Tq2nK0+>zdsdA7-_q;CRWu?fK<!7P74JRRA)P9<wz7HKonw>~@P z`i85O%)@$SMvLl=cznf{#2aB<VX{go*V*7dZEWBY{PM482nxPqn#Xn5*iLy4UK`oH zqgU=MYxfRbIoW-DaaIu8qxG=++(lh|ZJucz-5|T2J@iHNRyf1hB^YA18sQN0A_(ZB z38*j?sobbUtN$c;F&;>^DJFHpg-PaAU8`z_l?0mf0)46Our8GY9S$-<U19WqwR;B` z$?hFtbi~@d1B_(%aTpn20<)uttLiKBh;?kmK*XID#?S&Uxv=TIW%+5#PNV-l(l7gW za4vWMMdClsOf+6FZ7?*J5G6?{tqJReRRoaKV|}sSZCxw}3cQ19>I$RxTf29Fk?h_P zM!#n5-T_9k`%%K^_pM`F3NZRzUh*u{xHIpJ6g~MG%Lu=WE7<<GNaK!_)TJ9!lA&J@ z$nqASZgxz`mq3R_iYZxkElAE;-X`!XC8i`}u30f9>D3c4CE7|0f6$-N(np6a=-<QV zcWd5_BRt<gmmalbw21PrQCWBySjL>lZ<y7ah)5wd7x_Byjgu1oo^Kwe&rODbDzmM| zjMp~B|6+HpZ!%l3V!2$K<p2H7InN3P+DMG7Gf-A^ii4Zk`3t?z$h#uS*?b|IfSFDK zgbt&b!6_s7LN9naX4@&12?m_!O~b=<tJ$sAoA?5f9c!FCk^MOw&1Hfu1Wz(1Cgpf< z_*YZPbu8SNm+~q;=2|ondG=y{8Y;7S_Tup|=6P8Je((`mAM?F=$E+e^?&dLP=?a6i z8P|xI`_P;2_@OPs5)q>lG-mjh^vsBe(M#_fISYy<kYP2{l@c4ptnMnTX20{Y$fLi? z824;$V)%@47ps%L`ph=jWohs0*1SP6X}Uqc0G?i;bMKolz<j$;l;7=*VvfuO@rX1k zb3vSOwB{BQC+Hu`J7R^mAK?+_#hZTwuMZ!i;Qs`wJK#+xXAEzWni+W0OSdF>#sCb} z9X(*a$C<8$0du2JRqJg9m+<@I1Q(&~m5$ZCwns`J)n*)#Qpi~AWN&85C}2QIJ=THr z$C!ITApIeeFFmxA%0>*NZ{!`Z0@B~{h!+b;|A5{cfTWW%1|&(%3?S*H`&_xnfEl$k zdYJuzGu1O-=3)nsO{g4gSLPjsiv1%kxuDCwly?-$WpAE2{vUg90w+mP<pDD=H-p@# zpv5IMIMcu=3d77GFx)U4!yy7THQhDSmGnhbHB5sb-i($C(s;72C&;R+uCkuXdf>TU zyWZF8x~>Q6s^7BfwXWZLFCsIJ%!tevnbp(n_s#D&*;N&halH5b5ij0*5m8QgP%e9O zDQv6-d@g&MTXJ3Ym`k|qpSA%$(V-OdsShsu03lIS_|Z`&0HP&F!w<1>C{^@lA$wvn z5qj;Sq0vUCGt<lr@*R13bRiPpQrOlXZAwT%pQ<3mJD@#@Kt#9gjfU{(cJT+>8hr~M zowNw|_8g<@Wmn5}Q+p=vmFz~GA-?DqGh8kV>sQhr0k@Hh#j^O(g-}<rECylvCH_EU ztixhw5MI$vH5eI`^Hn_>HdA_gbsFt8@L$zyOl|38eTo|d0tZcTL(mG*k!z4g*&R6^ zI<g4v4an+9bRm?G_CaK>jFvRVyX{u9GjlEYEcS*1d&k3-=2N51Q@~_o-T^F$F_0ok z?>O-a@UP$-BZHf|GY!eLb=jRwOoi3=^Hl8T8JmH*@PDH?CJ$61!VcQNiuPmWOz)(k zc?YcOGNW5;hASFuSW%wWi&`CE)XW{xxlmX%4Z<a-srB$3Y-9IUcyNgnlH=sx1VICn z(`(^U5D1$=qY5n3iqbDWmLyA901F!(Sg1$mnkl`5Ek@LjJr>UAY>aiZz@3Y%ch+3J z?#OO)dv|T^7!s0WHms_x0~^xNV5hZhurt{hf>59&OYN8q8<PF5b)likfmt6QUPl8& z#Pl=0**mN-{7hJVdMu6|mRW;E%4xp|$RzmjDkw}Jse132%d(WhVlu}@H&~osSyVm; z;+2u$H{(5BCO+WfZaumc34R+qvM2ZygC?B}ir$YLi&cxrj#S&z0*TqVRI1*EPx-s> za%|F_#k=s_qFt~LD_R=kI%&HdQj*G1k2-r8!)$NYV~<T<7bY9{LGSH%eZ7sI4aGGw zbul^ewjqN+&^MtV7{_e4?_x1FnT?2l)En}Mw;>D<s%S_`*_43{g~kOH%=1<16=%t- zWZ2<BwTBu@lB@Qho-inso6d38NDxnL@!w>Mo9Qiro3C2KGtp<D_c;zyyEn;<pJKp^ zps-jku1EJFEbe#1=<SfygAmq&3RyG*cXWX!{7x(un=SmK2c9awzHlabcbp_eSKeBs zjUz&kXYlPrX$6rk?$tc;^hT%ISzB8RN&?NZYp=V_?n1mq7>M<@>tbxknRbaR#DM9c z(2=x3s5cN+Q}hX-g{FB&Pe3~9*WWCSTW7SQPOWgDp&oq|)ON9qTRJ(t+P9LEEciIG zgl<zi3QBf|@@0Y6luKh**%~OUw*+LE_Vx9o>XK!{y{XY2pV<+8AKO8)@`G4Nq90>t z4$tLYd<WXYkR4Red8sxC7NCgn^eM?j;hBy$!uxVU76l%RKj=WRcjZ6%3|#D!p?0JJ z7F(Jsn%!o*Q`^#<o=Cj@!hJbTUjD>@E7X**BJ_FZd}w9RGFLj}=P}1q461xVP7Bpb z<dEk+hg2@IQY&*?&#jF$yCW0Buxvfc24>MB28_mJE@DlxBnBbYB5lahKh0|O<0#B? zDB+fcMt5igmSs1?imWvbyESmBIowpgfRBFz#k{C_!`6QHFgt0C>{gl%g$W-N%IwOx z-WUmBnEcRuT3wmEi`VfW4z|X=PTLX7W~<_+t>*Xp2+|k&*v{F7@mwef$im!(G2^YC z5%(&qXWAp)<gK1zkC4^d3!p{DnX!>SfLvzQLHRy!`!Y47Wpr`v7zF;z`1fImO}Yc3 zg}zX7)Qx(e)CsLtEDYrAkBX0&@81oX+&Ua%1t%z(T0n%Y;BKQ<MK-ARw8mKlKbwKe zRn9n*&^`17onznha*RQTuZpHK@$_SF^$a}8>X~?Y)LT6RPqKQO9lOD#nDD`mCd#UF zX7SUwx}LtS@MDQ8D~+LDp@o%TNKmi87~0ELO=7;JH)8CrWsP$Q6d5TxvySyLivgo2 z5KXz$(n;Rx88DL7GhuX=w|WMQWc5|T=;_|Jm79{Pfzf5ea)+UUqtXcKRSKi9!W_m# zTeFUCh2dA3#qHCu%@9}r=$YOU`rJP9J%3ARAsys4FXOXBQ`u{!LZi-4%^~g_vefnt z^R74ZPENHu>NetT1@Y>y5m#7m$&ULrV5YF+z8gOEQeK;$wU&+dw>;iUjMTms4KhNJ z9YGA~hO6Qh;0+hIoANG2J(9lGs0~eQKJ8Mudu6JFCarC)8=K=bu+BF}Yd1Ap+eW&U zajR@$`fU0EHg*l`-e1CsT`>1S6e^v$u01F9er`JXLMS`brjyS>5fB@sq!-uT{oHhN zv1Z=LI7D@7Y;w9rOG%LRWZMab<%*3Z6n~4x-em7etO%wzmY4^<>5d5_MHld&hEh~* zCixK*0W=hTQfo5_rllP)N$gc*ZzeI$zcLJPMvC5pKZW){Md<#4df?J~vZg<Mfy3Qe z@@J?`kI=<YT5K&r4_wMVpp(~%(3RA6MCj_NPtxx1EG%b&%5wJzmZk;(&AiJ|%(TH# z3@iV}ro1dd?H>78Dx&!Ak&~2RqE?4hF>U@r!*RTOgwo?LfXN#tMyGJ6q#Jj-Ny89Y zJwcb*6Hnu=sAI|{8%j=qB3!7$G!E(v;{Zuh$_8*=Xp0rf&ZZWJqAc16Ue9tylDCo^ z*#ydNqrI&Orj83BI|F4pIW3e)YC2G+ryf;Ej0{-e>(#?*fKBSsusT;WRVZA+u(PGv zMlembwl_!7L)pEl3HsZ_coWB=7+W~O(VPd-c5a**Mh^pMMv9KK=Kv+b{FDjOZY5%7 z&u^GkG16Wc+G2&YyQ#&qg|t^gZ49L8<g}0`sp&wPp8Dh<!7`AC#Z`~Io7tpyATMBA zRohO!6FRM`Z6~NF2gNn)SORpV=#)>3nfb-=gBCTDD1YD@HB)*^#KF?mdM^1@$MtuB z&Ox|VD}ir95ye*mb`(Z(i@3SlR16b#q9J&{a0wm<u(3XnxRHJqDtL<JNRZiPdB7>- z%T6!N`o&O0IO`9YnCebWbwyx?xujEbm)}abLNCGy7JD4Kclug{sU`Kyb}&ZqL!g;1 z^%K*4lOm1p&h^}rXO#d(GXnc>&0?ba0pqvYRDU2*H()$aU`7$I1k3>)QQHPhvr)NK zquMZMS{e-?`?d|z3L<ygAm$Q#<*o-3ifx1RsfxXF7$l`pp-+39o^Av(4PM`Dk2goN z&iO4G{-q+wF03YkOtz_Sfn@*ZwPnW?(JXWFCx}1lPPB(c1_rNav|EiWqs_CXWCSHe zT@G}c<DCgO`&UwUSY9t7NNh(hZI`iV)AFyfJjfr&iVbhsM5W&cE<_tQ-dE8cYmBx! z4KzX|?c6dkF<M(+JF79;X;N(4ZDit+Q7Lk9R8Q^j*e^>o;#o^5FWFgi<?H#rA-YV& z+wF+B#L5g2Zy%e#5pS`GE4QK@`1YB<6#0wgCw(@uaj!%S5`iK0lI>*IBli+2>elS6 z47z;2&L^K7KlZDjAkcD{p+paOt7pVO$m*Ff5byU^&xnDL)!Xb@Z1OKBHZRVt^XIeP z7UtR8{Q*Ts6&b&0N=F=hk|e{Wp)ta21d%yPR?79R_Fdggtx84h9qO2^j2O#w^wIvA zuf@0(lZ7LX&h1}%xy>Ne&qVK-X#AtMdIlP0^-MG_JHxkHWuQ@3Z=<nnpzLG4?JI{x zvAC)#Q1(D*X(d5^f|C7(++v~o#b8N;Yr*z7O#lhL>!3N+%N7P`P9dssr?3mX)iXdN zt7n4dYH#%n(8%g-&=?LczojPS2^;gatsG#eveI)?i&$R4+$5;iXP}71Q4EF*piIYU z5-8IKQ10@wg8`J664kgs`D<_W44}yBnLv4`w|WLpWc5`7<sZFmn+rhsFtNM>pa|;q z7btz)dhzdGPBAd_eIh6qL%;D>&%ltZo{6D9d#h()NLF7ZhW6g*(;nvnhW3CKR-%;& z>h%{xE2P1VENk(!lAdxFQMNc;Ogr*7T}M07%Nz!5P9Pd`VRMGJdIoG{^-S1Y;;o(m z8(F;#n?(kba;yw8v(B9%Z~MwY=dm7xZF$?mAc;c-(~_WUe<5{5zIi$ZQW|LcWxX6{ z7r4vLqBHtMUPd!u_&lOJ7l!wEt7pJaR?mdto4wUDU?{7%VYm<-4GBy9YbB9a=gouO z)|CUHsIByB={>~t3eXnDzb|<y#OI%Vl+}Xu3G>MB4&QYKea~Ax;~=ZB-v8WNJ-_## z-OY$K>MbJwm`MTon@)w_dz*2u^Ej{GzMZMb$%%G%urt<ZcW;=Q=)#$rJ7jRqK?~wY zC_$V`2jZ~89Q)yHzgzSQFq$gImAxNsMV7BIZ-y4eW}WH>o!LL-wp!EUe$Z04lAAS* zrHu4ye_Rf+=hFVTql&oE^R~&^{dI4Xy9K0f*0#xQ0G^6%a%aJ(jBRq+e(-p=+!KnB zCbel!!<C4UycL0#c)Y>aSbWpm$VPF5ZLLv*)0N>As4m7?$2T~2rs33|cB|7IHZ~GL zL_uq;)rDWTOxL!rs=?kPI50{DCe*|xySS8$h0yF(tB)0%*kgqjA^8^-NFe0qe3V{Y zZg$FkyrEF8s3_d)pa_WIQoulmdq4N%ot=)lsMX17ToaCM+7J}ODRUzpme7oqiu5+T ztndV5w?bA1UD$66C9B$$cQX{>iqFI}Uwo#$DQ|^Now(a#b!H~%eYiWc4{963ozw@H zW}Y?c>Y=dQZF%=VZF&GG&I+Dwc{+iu08mL^$2JB%^@svuCWtC`;o-{)_F5z%M;+8g zMlqPr;X;)9@Wiz2#IMDbmC=V!(in8DPw)vNJvLz>nQhxobG7#*EXqVLSu`!o_A z(Fq0^9eH$F{wL^M&}IXL$4?9TkWAS3KVcdNk7msBdf)*ZJMIsv{y}ID6dJ!rJqSf( z^fq{%v3>7{kez`>oxBzrC3PKW)KiZtBy0vA@%8HQ_%NH)rSbUW?P}BBcG#IW(H?G% zH@dVbc4(^IhWjFFB7RToMfXpE(Z3x5bkQZ#3U4^@tkQ_u7m9GraG1tHlo1a=l9F=! zKQXk$3PE*h@oXVzHPpsHkWNkuL6Vvd1nH?Oi;Io{BP^qO812QTcX=31D;Q0ehtZE# z*)TGLAGSabOHNGBBqE9F!=9KhtzsD67}{b5qYkxrwqUd!YGc4iC#MA?Nlgcg^wgEb zMaO^<mQg*7u4dD_G>jgn86=W38pOE_xWztRgQOKc{lEod{?QY3)$X0pxsnKafasHr zAWW+mK_3rou|m*4Qj2E`K@UT13<T-qv=Ahz=|GU4D%f2kVKE?rnW~4#eQbi3hR7N+ z&DHAUB`1?bw+%<vf?-c2+|=rh)J7*7!|;oBOja5;1p^*_58W&Ymj5P7WrGFNIAF0N z1V}700s$U#c3`U&V0MQhc=mtY62V>j>;<(k0Hc%C0*s`n12B5(;rY^I;0WKX9!LKV zNe5?ODvhIavqBJRb@Y0#s!dGdp1Z~<;cFw_u`mV@tF^Wc)HXJ^Hl{|qbPoeL8Izl! z((uZTVKC;W>@50Bb!Mm-D<i~dB*xj`!!!=~%(ws{VH7H$xA_^NZC22`lG@A>i89c; z25MtKPZHENnC`l&7ON<d*zki+mv(u&$f}(I8FrhN#<Fa-O#Q64?|J3hcl)gJ?FB)6 zBdN89Oo;=>kg2D_5Rfw<2$D+EExua)h`E7HX2*ybU_e&q&D;=buu|t0pdYB@c?H)} z5sdRElapnPp*Z<fN5p4<&Oxe=@^pO?iYV^svd^12Qyc^to6YgQQnZPS(@>SYu0#G@ zOo0=&;LB*c*%+R#fycKE);zeJOgG9^RHh;3-*SmLX9$-vst&~XdZ?Hy0Ymc7wtxkk zZu39T%#wokUr<E2pdA^Dm~pg$>6wYesGbw_Q^2>f`#IeHmYCmrjs`KN{3Xy{m)RN9 zd^!|ODu(w)A7T!lRZ1Am2<*Q#b&Bo>Oe6~D3yHb`LxsXQN`ECd59o+G_{NOSDCekE z2j7^{LI%ct2j7tIE%)FX%q0%Kc{*@G9DGBc=Fh=5m&&nA3|*aSj=VYB4)!m4YL0mW zR;O==-Hdxf(K>a~96E#DiTJM4K`^C`tgXSBGI&v1<HqLTaI3u*uS_d)k(wI(?F-c6 zWA7yS<BVbrWGCuF-wnQ@ugrlmV<^c<m=wf;eR%#JC<DhLCKor`N6Boemd7#Y(g(U6 z>Z?e-X73_6Ap5oW1tB4>OuD4p;gb~3(Js%2f?ytJ9wzZhZ}p7L9<qAoW{<act8XsK zxpw;LkU@m&$m(r2EyN)qVT#kXAQs1zSLe;&ds~+mujN11MYOE+W{<xkuDkRL#$F*o zK#q!#iU?Q7w%kswN*&v>hcPtAY)S8;S{mnzvj{k;pLHgE+sh;d1->pC%>>X-z11@S zB&%lv=zqM`GXNy3w*j;p%%KSv{P>})I%k%iTV^HXhYwX&8a)f4g>E+pTXy=3o<8oE zU*+W#gAR2fD0dQC>#d%FAz3{WL+5y_XJANHpTbays|ugtZCkl1sG7rBt{|3IFartd z^%q0^y{hmwFS8ghx|wLog;CF2Jp)FvdM1os>#d#vBUycwFnWi#ZF2!eZzGmh03$)Y zN?{aMm}6_Ey@HLN4JwRU2+pP5f{*jtA@cSK+C6pe6C42&%-TM|e+5Ys`viXspEC9d z+J=pIhhWW5j?~^jjj>{p79pn-;{_~Mi|-A*{9NJisZHDn*RM3-;`?@U2)6M|;}${f zPCel+>Oe}9+)1(RUu>-CpqEK|Inius0obQHbd~r&+2fGrIr<B+_6S+{IZB}}3$Fcs z4EN{qiyQ3*>=JFZts6J=1f3nboyT3FNOmYE=q^wM*sYbUqY<W`+x^bXwmjA9XuhDh zo(360>5d{Wi+1qCINZr6-Yc@(q31GO8O~N$CY`{K3nj3M@i_#FaQUY&&F7!8V@6DK zki+Wpq|i327@y;*&92EjPu<{d^g9u1(;Z$ota~>4=>)YLUXq@IFt}UI2=dWW>xG3( zh=Yt7!6Fpu%XyKMlkGq@xl=JC`%w|axBFcfo2Y7au#gb!;KtX9PK)Lwxcm##;n9|` zTUCR&h0z#;xJ8|I?aCkGc_<xer)*vZ_SDZh+OCIA1i9K3+O`QgkObJfCoqkJHp6yA zC8kV7w}-Y^VeM9GaVXZJbKrHxHooUVb_UjTa#~oE)O27?Pd%lKWEt?oQmcpGFq;FV z;WroVynH`&yCmA)OO%r#mDWwOn8rezZe<c^!(a6A;q##_R%rVywRpDB_C=_Tfi|6- z7TP2=9ca^21Ma-U*Q<xsyV;~J4XZhN=jCqamqyy3iI~|)!?cQ#c2H=G71H*HBHX@- zJROoduN?xlF_5N{(?Xi0rUPkuY6W**VsX_Y?|-X89>;Jd!K-4B_YQ4^3LV46Y01#B zKfz*xCx)^kDs;?T>X%dcRp^*$Ofr_>zR)q!_i{tWFqa4&YauW;FNOzwnm?gqSE1>P zF50@eIS3085yMnX1lgui5oD=G^(~O>yex}ls(KMmX5MuME4mG}tWyEgH;_>XZmQ6D zNhhWpM;=`{d#-QFC=)Vv8%l6uX#*qT$LC$hSO#^Skz@Okoy+8A!i-Cnn#XCbkePEX z4q8Onl2T}HlfUUKe2tHVoLH`VpdfxM*Ztn=8U8<6J=6d9ptpL4|4&wL`~S*b4D@Ml z`|=bje>h6Dr*nRS*za0oG5pAak{m6>6V!E=w^dp6Q-wKvf%ec8-3fIlUtph(Y5mQ- z5rkisAh}e-)G@6&#GXrz*P{!~+j;(1yTfk(>om}L*8HyrUH~%ww-~wlc=(jze|0De zu^aZ7Lc~dVV>M_A58N$?wL~vqd1H^;sB}y4r-F7V4A~HI502Mi;bo=kTWiM5DwHAi z+xi@P4A3mh>ITQk{beaXf{jO^IO%M3Ia2HW^rWr}WsCBpo(x66GET`Usz6Rps=b}` z2vX6^U47`m(xfxi-_l-|g8JPhp`BFzl?$N=mp2pBICdy=$D6(n)=1IOvo*8_$}TlT zJ#Z-}S!#g3zme<P9D&+&yA%$Y9^a-;Udt{esq3&y>8ZQxG9#!b-Ith4VXd4cL%A={ zV^dVl?aI)D*ePk~c?uQ57$X*6+JIAotw@XbM_uUN03`<v*=lU~D<~p-Y&iY0>B;7q z?e;_)M+7)ksMCa9<+UdL(%MRaLSp#X+8Tw^P&(k8?ZU{BF@t$F2!C{$xwc%E)EW;w zV*1m5*QxY@P%5dx<w0U$C^Vy6;B}`fw6|Mx`_K$Qx!Y)OYr?LY4?%tgHs3?76Es+u z3NFA@82kvHCx)@efGU<(Jyide`oN)Z3aTi|vklec1PCLDAo*1n!~Y~c1oTjW_2*DT zI9LzBvmOK*H4CP7(1R<JAp(Dfc4Ue`K=0IO{lCP&fFjgrjRcx)5ePWB;m`|9kJ|@B z5#ge+M_n6%SH`1gT?`Tn>V|K7H8nQp_y(t5bRxT}x>DmGIis0fVO(9-Zf=zWXU}K` zV+6%M#>%6m-H7gUEIo2yQi6Rfm0n7)k=>ODc0fmzzsXz?mDAFczsX!K8$#{#H_@b; z>u<tb!rwFsBozK8`ZRz1O`Gs+#z8u(u^K1S8Np5_)snt>md>}0FsjbFI_q^USVAx+ z7hFkpXNXV(bl9aD*zEHMma9_ZOk(iU6ZF~p1t2|6RlAH6={YEtiIoBDDDR(FP9&X< zPS25RgJo(TvnykIC$oM^uc3SC2|5Gs^)Zm+LV7h61ak#*H}l_kt7o{7Wc5rJ(g(cN zGh9frdfSC$9E+c`o7oPY`<%CJd3F!K`>2|on4cn+yC!gk+elE4GY2bAk5ntvSpYNM zR%Ovm73Odo*@IDZH`L*F8y#9?@XgU2GmhbXw2uPO-}`ufU4kW&zsjwY!;HD)RyxEz zY3KQp>|VNkNzVe}&YCajkWC=?<V!jNK4tilbVVU{ARX!^L&|HUAxpR$ZbPUgiU7<o z#rN<Xb^&OJ`f1+ctVioGZ=vAi<khFlW1;6xohQl~V6>&rUw|ef_;L(Ng3gzn;s!c3 zlo!f+v<`}Z)s+%FRAZcOpa;RLxAHkNx6ag~b?D$5lv-B3_*R~yr2x_)Vrn}N9w~;K z<t*_`JC9cA@0)76nWPKtGeQZati4x25wSJE-l~IX99L3-tvVB-Emp3hQEIVELCHd@ zZe`)Rj&6Y3bmIz+kRI2OPEO0XBB|+c9qFmKGBBh@@Lal&FsH(3Im3jq+iYf2RgQn^ zvb&3^h~ki$z3WWwhn9s6?%<6PBjcMz=ZJeYPB4vyll)CK9|>)-!pR4z#i2Nfo)51( z{WvLWWb_bZXW&F9r-c(qO$Sc&ROfXjn5lY*yn#(n2Shk)B3XnA=)W+u70PpflVeE( z>&a9E!_S+zi3|fq@~b|pEx0HUt!n!JKWJX@>EDh5k=iAid+?eVyfQ|HBw5qA&@%J0 z8{_vr(7jCI<UmzZKE?R7CzKkr!$OG#5^c7{BEX?^TzT<W1x195#~$J;A$iA8tgCr^ z`ZScu%Y<}6-^lKXuE{V*=w5uA(NCA`vdbOO_c3%ZN11sV$&?Usd(Oi&-<&7<EG*M{ zpPw<ieU_&2us&N8ljw55;H|W*^+eGCpevN3>{f!(fQ~5dn7L3ar-Ul+m}wR;5bE=e zk*bpG9m8D0J9Zb4P<Y4a)BN#{Jwu!q(d<k%hpr!O4p(}h_eHjI2?BE0!2bdHH$Eo2 zJz!gYvRl<Rui0R+`s>3soz}vEPeX9FH^qevj>928@^tU`7!LZXg$UT5v;!PHHFO$R zCVdqA8{a5c#=~|Wigsea0lU;E=9P!dMPH}4?WuuGR<pLfnd?ADiRum8AGCMsjX1BE zIy2IBS@@Vw7C6qje}IDc&blvot7katWc5sE-S@oJGn{p@dYd^55%LK?{N6f|SLe;I zysgW#HTm6jqPEhf5C5FF?oufj{yITGj#i*tY;rlG{B<9sR;7L3*3cU>Cd22ga>khi znwDz`I;-}**tcqA&|yy~h!3N~z11^dB&%n_=s0in3>eAkZ5SD*T|bIa$1|PgZCg1I zQDvnuw4PXA0fq$i`ir5yoPXc+@`!<+29c5*G1Bo?&p?l?o{664c&lfiM^;}YdhYhN zZ7!ha<;3y|&?Bf<DSE;Rb3}~T%60SsnB`Q&$Xp6ictWu?QeMD<-D7va!W)4U&VYq` zcG+dYF8J@-ndowGu)?1!#h<r>8L9^>wdQ23M7PGb#VgMEZ?f{7A-_ZPnGHbpccKC7 zlOTE`a^VZ`DI;>hwHS+|80y97l!|E3I4}J}C<@8K3-pKL5e;xr6`b<8b!rr@R;KeE z@nA>Pa$4gJIGT8}(eBdes}rrxG~Huq9!DJ8rsbi;Lv%MYya(SW$G4&Lxgqbv+&VEj z+*B8Fkcn=#E7w)Fud#<V&FuXbwzd^g^e-sSx)izMFBqN|{n%o|P@yO2Y<VP<Ez1A$ z6DR`AcM2t_QTH?a;=FkHNQ`2&I<EZaOjZ1V7nTDkh9<_ljn+5}GV<tD#F~kxc)5{| z(a2cH8wAZr*Xg?G65k3XYbKAyJ@G;>fFgjBgk0Mqk7+)OeCiluV`WT5rWe46gtl4v zp%0`syVQfMZtGqSZoI~!P@C?D#(BXLub~svGWSb*3c{pz8tSP7OaT)@A;USaAO-ny zmUQK4_&?}&kULO?bNrEtC?3vnv|5;}_$M^7;^dWV$8)1gU)US4(i3z%T^cHzD*9;? z$!0d5FpYyJV~I>slUfOH3vIDN(=fF-6iv}_@H!)^qXpR+Xwu1Pp-EEHfhIk5@3hPq zfWf@g1Lk}-UFF~$4w%zow}XO99QcKB5!zbqrjaJzLLtur#{|^s2y4l%`Set!j`lX7 zq<+?c^m^!f$?&Mx68W-$glQE6>Aj&XRzP|;wRpCG^dQv60Fq8l3rLch4j}2N$8n{} zfEkulJ<MLkrn&=WoQ1tCLd8)1E_8NOZg|viOS<8I6xs^qhBwy><&+2IhJUlMmNoQv zpBtX$mRvVH<`QoBg_pu7Iuw;Y^}!7vAS8+kGiYT<)?z?~_u~(-Co)y^G^8d55TUg$ z8X9eMIy248?E@n(kM>3aT#Bc{?vs#$K2<@AYoI-eKt#9gy~{4Q&P2D1KiJl22Ru4y z5$^5P5q|&Ga#_@#iMu8Hk>pTznTBcB5r7-HSS)HET?n=5g#0D`K!iLV7Bhoj3Ca$> zA2w5Zi>A7*(PYvSla2gMpU#d1Vg^lTLr|Y+at-;B-Q<&?$&0}Dl-1<uLMQ=u5nKd+ z!N_%q_>;NDS<)Quwp(!W&9#t!Z#07)32|jpqs>!bJ!+c6sM`ag^SvWPF5r$k)5zea z?o2~+VO@5Y5>sCFy*U+o^OT{9vB{}!b8xaV-p0M$V2=___w{e(OxhZ#b$>uFG&8`& z=A7#0MhDaC(Ya<yZ>?TSee+18YaRr<s<zqufi`Dvg?Q1#(_D{kunIlY!?1yPRU~BE zpH&z2%Y33<k8XuFM7O~sdk9MTZznPT1&D%+EdcahUSS*wG4wdW*2(F$!xKYr`wg08 zV4>)vlFk<G)^|HfXN8$hKhn%h(kVIQr{v3#GItiI<a3>rjJ6<Y<7p(audF|^fVjod zlD>z2ck#AyTw>a{z7TW8g$R)oKj{RS_7Q{=mNEqe!I;V1L;fOf^$d@ote)u+yvJKT z!y_oGw>^Sok0HL_+rG>R2hWZfo)`n`=ZrrvMI0<MAcV-{Tkoaz7i%N+Om8VbTPQ%A zqyqjhjx031yqRRewfJJVn+17O%9v;3O$~Y~XypcKRVrv@DU9|xh+44OgcE$%vGjQ_ zw;0|1jA$VfOW*cZ&%lzbo{6QOdaGw(NmgGqmj2*v-|S#1`Vch23z`3c3~q}qTZSry zOjuzKFT1UJSQDmwocAI_@5(!XL1fmkdDLd^YC(5T_(xLNHqRKE&-WU%&&~HN=}e7q z>X?Nb+EyLGa1@^81WTIEah6&qlt1yD=`DhpsRd{AH4y`gX_^|EiGBhHp2>-0#;Hvu z>U~NC&xgX|g=;;!4@<b;t-nzmf_FZn&;!^RPH_j=QW1A>39yG6{=%8)-B5n-F}n7d ziW|_BKQR+th$ST}P0*8y#|<2DhFD?ME^aoiuWfE^8;83g!BD&j0tK42OB>+xG-stE zFX+&?k_`>XFZ4r!e}1m683g4oL(b`xclp};dgS$JD2<h~y#+;pc}j^Es@wf^wm%Wq z4_Sv~Z$9nPT4QW-wAGy&md9_#5}0;T6k3J6D3m<P$M-xa0ti9|bK7T*X&l#tdFG<N zvNTe35ZxQv1LdlC4fVjKEoV&u`V__WpuZk!(_Ixb!u<e-wzL|rlh$%mNXk0g6ng6Z zjaru62pUQ!Ip$YbP0X5U>!r`+rVUPF1h}0|S6PJe`Q1uI6nB!>H)r7nraW-+jSn@6 z66D)+<0faV@l|M1ko8j`=F6f}nTWx(J|pI5p*>KD`7!k%6fx0z;B|(V{O6FpAYydV zT8NR9bs$Dh1;k`YjDZ-;Up->Jz^1DMF)4M;vtpM;DEHmXp{-EvJDf9vMvon^ds>Vh zTd4>}AYO9Vf#H%*e$^+9fy)9xth9nBLJ`Ha0{aMr<!H69-PjnNYQ`gxm_hXfL*Pz@ z`Z5KMgTmAhy$(v{t$t(?iq%Mn*=BXXu?E*bGlRx$#qz75h;Wwg-fnhkby^^6TVQkc z`oKGerRxTEFLYIfIq>#&!|Dr;ykjH=*=iuB`6e|QljUMwhv|!EwYRaQLp#jCqnqjd zwPqU8-GCuj#TQ0I%>ZaCT%xpAg3Ex8s0a#k6<AKQRIvl*s@}k)FM@*fj-^|t#wlLe z9XNpbMBu<fKtvHkL7%D!96%4MMu$GRhtC^=tq$NFZjMcMrw2u>+hA*aaJbcO4#E9j z(;S!aI?KEyeC6_)S5e>G$P;-r;|T>_*yMr1>8j&&f}lK@K++{Ss-U*McFbgZVyM~a zB!TY7koOrpsPRNSOTOoC_y)f+zUQx?OecmJup_;BF8H2v#MR@EuI0%=%s4SQ<!9HY zpdb6W5bn3Oxe)yavc>7QKC2p8j!BVrZ9hJz0`;ctA3DVSX8e+%yf33p^Z)hHoZ}k* z9TdcOjW564rztYrd9r$@JMSQG^$d5Otlnmq5l5e+e&VR7bLLoY+wv@BerFD~tCTC} z3D7$CVus<u6O`lVJt?1%@_IiigwQ?*<>*3lPYj@Rkjd`a`*AJ-Gb2Uk-X<^i81y-h z2+a*SxyD;P16Q(oCaxlH^$c9e>Z`=nv%GEF*|^$H>~<|i_;SN!+$+7r;WMtYhY?-c zTd>~54}8~A^A>OQ&xXPpnE}YsP|}7B!k`r<wtwfXp5Ob=g6~j^t?liTR(MTvWM$Cl z^HFaD?{(6rw{K@^a&n^G9qf$37VI0QCc0p4*dfVw5Nv4I$yVuL99Ebko+3w)v*Rhs zOuygvl6q$k6W@W>xu@T()}>}m6-kjp)twwk@l%-7b0R714!9#Jz6gc&Es_FTDk3RX zTmhf(YaB^&MBch76<wh%Q3N)>jHM?_Nmg{l6VIR(A6@Z^Hi~#Z9v!nF?wm+$73P4% zdQ%^%_5lh6nSf=y#e7;P3;yhhJlFZNQ(`cV38lL-y&nZdfSFGTAg=5B8G~_?dr@m` zC!G|#uM=U#gF$W@X$_5}MY|(y4{-d*)>^Au8=e3I6<uT8+}?su(|BR8h<ZrJbNE)z zhR4g7QHR6np=?o}><v(aEA|7^d`5r!yaZ!nB#!|7qPO_U&=xDt^<~szmoA$%N$Cz0 zZmh>uP@C>Qp)oi+)<Y+y<xh~5ba<}y)XlUdwPJ}B9FUPBSeqJAG&?p&r%JgYPhoRK z7NH_VPNE`;M~Ymdt)B_et7;RIbd1R;9crTQk{4Mq_D@Wi1GSCKt&OSCZU=um!nPP6 zk?c20qu5xS8?ZG}bg6$i^ek-JO3pQTi69P1kR79iX%*x2Euk$|IDI3vI25PRD7?;y zFu4!17sRO~r9FD>x~dir-O>jNKj>WiNO_vbs+~4FyG=`Dfi_#Fe%9Ofh4StD92CJ@ z0O(^YmuFvM^Nhsb8e66GJH}Q$b$z)J!5Brc-0DZsJJ|GhjG_T!xr!b-F|-xRb&c9y zN!Rt^R78KGhxWNLa6nf2?4D3WaedZ~9)dILx+C$iKVnK6u92r#uA)r9=Vv#B^GIl0 zrf_mb<J1&igHm~egDgUc1rlwx#Udcm=xNZ*p!r&f$9gCtTs-!-6%ulJCo<ujKWGqi zysS?Zm$N%qVw~?e8dPw)zJz3^l;my-Eka2y^0N}j4H%hKERJanD5txtSRB&^WJs+q z7Kb#n0<k!lPsHNf0YntBIP_`$#Ns@8s68<$?h@fd-8{h`brToaxA>ZAt=SYaZyw4J z-}8ZUkqoE77bfALfx)4PiS{r?-ZVRFYolP=SS2p;(k}(c9Hi_ULT2TZhc|*?IS1@A zkv4yY5}TOcAkyZgb0X3vksK9nVxRG_T=71cH)wj$6ZARZ-F_N|$H~|<jNXMrb;ikz z&8novv`L54tdQ-<+1S3w*o-1pj`BC1x}Wk<mlF~5aVUr%5%X1V^$gFwte)ur{-L*e zh6_|yZ+q^`9v1Paw|#jwMSoOG(ZeG0H#+~CSntw=7+!oqMUEzt^7E<an1`rUsWTz= zBwVOaO$9WYdGhp9oQ2{{0!Dg*j-`X1?iuYlSlSN?;$!Iv-s%}xlGQV@^ki@K3@pj& zZFU$|eE&)#W!^u_+qQBzqRL7|mz_@Rt^hxRa{a~6A#PPHMoBuPY`?6R;_L!c*;#aW zMP4Q{hMBEIZ*Gv;c5n3zc**LS@Oq)QdIr2?^)|c~qB5PZ#E&nLSLe;Ey{#(;Fi~46 zgv}7gD?peaUVjm`Cmg-e990XNm?>#kEmt|?Omc?O5_C3w#LFfIgg!t7<wEFl-s%|; zlGQUI^i6N|3<$~UZ3vZ_p&s$JtsH>L&rm-mc2|HOLAn0o=MeY$KSoI!N-kTVeo}-Z zj}EZMTvd?@xEu=NtAK}kt7iaAR?h_3vEJ$#0F%{M39xnEw(V?yokZ-e0APZ0l>#iR zFh@*lj?rZ&M_>LOtQm8nFYOMvqc2|#h4n4^5?d;wFQ-6sBK#UhU#?IVwp5&@X5tcY ze6PiF5<?=4IK@w~y8H|<%3>%Qt*C2L9XtqD#8<}ZKHS=qm}}_*tPX4tg*y@8E(F*B z4q+}B(&oG5s!w(3L-sA~fkE>?&RNT=;O=&m4V}BLC{2btTfcnD2s6?XbOPTQN?_%+ zd?^$G{vRd1I5+k)Nb^`B)AjMGu}QePt=(=+Q|y-b8A7wRG$CROd=gDK{mvCvS<nRg z_E7q$XvzDb2%rer(d{TKOyfjh8Ruac3^r194u3SX2P!J-AE*be2{3PZ=0;C`9BR|u zyflVpM^EacwIX~ZWgQVddg{Jeaw8}xqaQK1LTWh=sygi9Eo`c$;&$FhMHG*Il$S|S z97!E^c@k{&s1hQD8#KCc)sQ|tK^MN?K?9vWHsAg!1)oPnA2Z>DX&m?%i$E%oe$iXJ z$1?(3tl+X7ir~e(7=aRBgHADm825zQ3c^Jvr3DvBNe5i?)V<U4Vt@tnRu7inkQ8u+ zpweKuI#!f)zjm#TrZ~b4e!yrfU5&!8(i^@Cg0k9UaH8YY_3bCDs!gA;a#gLqeGPnC zvl1?`aLr5Erd9)N*;#ZU-WV#x3U*H;A<mw)FpUE{(|jppj4YaZo39FOvjW}~)Mk#5 zlmXt=P+LLZ>BO{vCu!*bo}Rj{l)xDn#bT?+=z2E!OJnpbWlL52bM%N^N~fgO<XB^J zRjo5Q(H(7V8v*FHYw}JW?O?8tLh!u4PnK=Py%UH~a>nZs9kZc_X&mSknDO2k+F}K~ zH&Kgc3wZZKZ3Tg+lhOj7q@)9Qdg_`0fimERg;fu?9c-ePhTC<S)?0-<T{V!qXVgWD ziFHA)&7^4pj11$jj1!ZkdtP+dca4eBkw>3pz6(Sv3D0j5-Lv6|X%)lsH=!+7@cd6| z@od5Kzo52)@YG3Z!BbMw0Z%>kwDMACpcTum9<5(v^T2^tj>T6Np>}D!K2(iXLCt9H zDH+uK;?P#8pk~u}R&GhIf|^Z(t6|jg1vS%(tw2yS<`Y59r(X@9=#obIG=GAcPsQsC zVOcZUy16+B>JvY{`2=5lb7tv%3w2(bSzVosAZFAvEciCmZX<)Eyum41z|Bgm^3@<O z&S|Smtn!s8h=~yzEatDC1F_1PZ1EfgxWD5C!#|vzN7oG^Kas<OnQbCREu^|Lm{}Mk zO#zG*qg2RbwGqd+`$)ivl6)2v#CMUu%v(LfMJ}sny2$VKR?l#e%j#_xdD)2LzxB2+ z&kjFZ5yyW+taoXfj5sDiMUKAXi8$WwZB-WSRACNxc@C`YBcN7f%^!I;Yl)2n`Y83y zc_9Q}EkSOnwW?F0atOVX;}S-pt2uEAb_d*X370})eTz%LmWsH9Mc2S5{2Iq49GE#h zra~07iAy-KFT)}e{ecytaNI_vN<y3gD3j76AmR|fE&#u3KHg*sq%|S?Z5>0qL-(EP zl-Df<$LP%mB}p)6DRNn7jw`~TuXl0PLW!+H3=V@LU^S+s4|NM?h=ILt{s`gVO~ngn zG8fBM`s9{^aRMiXc2ap<PJkj@aRQjeu`3zT0EUgsNYOEIUT6=Lo#|}qfotZ^nqzhU z3pY;S0;o;5Gtroq9VeiZ*0M86$~x>!dg|`Fya>w4_yEkMa8}M3q2dDu*wmC0r?S-` zZc5r}4xu6#AxMiaZNNo|aDj-v`ig(l1@8G!a?l{G#)aoV5#i&)>6cAUHqUIg!4b52 zb*+ufro-Fl7dWa7BjLo*v9&b{A3JnrTjrcpck6MsM`>A7t4Sj5cb!W2hEholEUzIJ zhQcx$gxB5i2w%DYQt=Y(Zlk>o53+kbWG@KId#GW;lD-gmU>u!<sW9ddGEWTSj)77v zuX>ceg8INAZVII+#j}ml<bEszrpd3m1pYJeA)to}r(c93!f|?l0-~m+Cb4}&LR^^) z5%?jrBU1zddZz~J?-Tz5ickYJ5@@zXAmEIfKSMK14%z<;MTCpO9)=PZ51@4+0t@QK z__5cuG=BJZ%Q@AdgXnDzQ*~V?XV9F1OPKXRvu8A;;OL3{i}giIsS#c0SWe`iq=b48 zDxK5+)VPMMu0*H<I-)#9<|3$^a;7{*=DODqXrHHu=F$S5BFrZ|MHc}dgr|r;%^y$E z+1gmGJVp3v4gBYvh;uUAV-(lYH_y@O{?5%o57LNlJS*ct8b$$4j0|8LdBa@wASF_v zTrc(kIEQ)p8qYUky2;6_t57%ji68D+vWXwvh}@Wqo~4)iNWk$d?SO({+8bGF2I?(X zYjOv^>l}EUw|a(WNmkGFEIr_@p5a-N)mQCV`mncsd6t{m@+`fdSntwF7@j3TMUGmb zoIz5}QD@n_z}u=U+Nr`Eo~0aE_sO&LAM-*8{;dSLCGV7HDTmNI*|RhaUCr?<*&T3u zmIk4)zIm3grNXnc&oki@evLg#aKm6m#85mJr#wvB1SXsq4J<m*FJR;^z6o|<qpCW~ z!{l`^abMPFn}dJ|LF;5(f6XTqO0Z~u<hjnGo#JO&9ZGa%r#cpjfVG^GLDV$nl%MJJ z&`v6I@CGO%wj0>{Q8BI0ex@r!d!YPGmr)N~dO+5UtJ`L{ex|FSHr*scBV4whNhhsk zl97~k_?h%nx1R}fDV&uvWhhI}DQs${EIo*ul9rxhsEB^}neKv;g9c+YF1!qi2p<>b zg`eqxP%5c`<vwCzC@iB<c%9*AdOKt<2+KE7!^EmR?PtQ&D*a4YUiB#bYw81sxG9vP z6wfwF6OU59pXpzT4*@+?IQ<S35sp)r3(07@E0f`8`W3VzQv?Efrv~a@5dQ*-P<|#P z&}@r9fS+l_VCf-y859vN3LHPvVboZ6002$-hJ#06Djd!3s;<lA44TFLOdh2M`xonr zmQo|S&atD&K}iYqAyj%Pp+;6$BGdsLQGO<K5mZh&Q+_6M^=k;U&(B12X#qbI<`aIV zYk-Kt&qSZ*kDuvuh&maJ4_(lYYT&q-p6qimxhm+Jcd6s5F>7nms+#-GN_jzp+9WT3 z*xK6O99~=7GBGh)TVK1ZJ=N5<z|YEtrYR6Nr&3<V9d!fBabk-ATgvO^fIG^?PtTsF zgWT`vfpzX|`XuvwKefaCPd2rq=OOu>{->)l9HZ69Z|wZ(_mvE<^-+@J#(E_b1hXpB zjrBHf^$a(bte)w{`g?En3^$gnzG^qtXT0spGYrj^8|z_Wy-Vd`xUmEkIa-VIJV`}N zxv^eBtxD}L1oM5Ti+B38CdLPo+m4G|(crs~*jQ5eGU}t)FTC7k(Cw$9t4!?u!CO58 zd$M{a_Lg4fnK2^<_GI-o_KcHa{6TZ6L(>lNwyhlQsIpQA%pU-)bDzh?mYe?Kt&a!H zZ}4)7L5H<OQ10Ayfwy`Feq{Ab{5->3Jp(_o`YQ1=>TTQ3#?J_`yMp;jP_DoD*(bfW zQM#ecvqh9SP8SAZ`I|oR-05Wx12{dRBo{cZ_g2pUj;x*uoOgJuX8=c5Z!=*bE<+O@ z_-7uGSLe+`-qw|aj;O8F-18ygcm>!A<J~vC)Zz24vxgORw?1JUnK>7%H=^!-?5+OU zP*}sa+qMlEM1(<D?;rJ6&+q+bAv!}p9B?68PD}!bpL7A;wc*p-?sd|jw{K@^a&n^G z9qf!X+T9zbCg57lnH^GZKWKqTno0-Nu)-X%Y&j-^og8BILQv{+Lagi#xI?T)p|HM% zSYb;=h}H2RQ4xNPL#z&Q*@{xpRhoH50BameP0VFrkSHEqb@c^}sqvu^+9rwi*IF0N ziE#XSbG)$y_DkZft*K74jX!moqs^f%{nVM-G70h=-(xN|Sc*g2VW~OU9J+o~o!c&^ z<i6IVWA!OstY%Fnnm=Qn*ct`jpM)}`^W7D)#fZqz?-(!^_<Dj)?(;**tvtTxKoQ^- zQF4t&HD|=ugXRD}GANr_FMfpjfDqVZADX;-VC&TAsN5`E?F9r|LusVqGPXbwu>;Qz z_`)<!z}NElK#s<=Iq~TUI*)G&ZNCcl+D`3v=}=jy)Lo?9aIagTHa)I{M%(OgFP*TK zXH?SF5$>g@9^@1qK}LDT0KTFCTh6_xysv|7(#iqvgMcJ4l3YVY6bI0`Zi8a_AlU|- z3p+Y2=aA$8S#dp0a>PLT&<>wP(HNP08FeXsFLcuBuJWm{3We_ybRvncQHW_A6dJZV zDluh}`%Gwy74AMsEe^$9bSJ#-j_0yN6Qa*S_JX+6NonCuQqqAtJ@x4L*jT@e86d>> zs|Vpb*mN!p!i$wlSb<KQl}?9Ui#ZImH$0aa9n7Sc!5vZqwT;cK4ZIu*vK)~drhY^` z8KkkuK0*D@K#r1F`y)|QD33PQFs)*&?YAYc#R_YCLlJHpb>1Au#o7T-TS2Vpq_nUm zDe1tPp1Q7-Xc-X1VylPX??_-cLtSYIZXw%at&Y~ORkevpbg(r>>1Gi)GaVLBuyBGE zRHNN&;95znpde3eq|vFtn1vx6wGJG^i>c!i-2|B(geF=h2Hc=5X!txoRIt^wcQy%j zHWV?914YwPDCCZehx$}~U1*yX7_X%^bEH96IJscl0<{$cqa@}xtV=3(T~&)&EeQ=j z=rq}0o+h$tr+L<H)6!U?&6cU3_4e&3-@X^lD$icR<{3$=HGoR_cMPC<>N%AS3C3WG zRa8HiZe+8<F_?1fkg^DM)csYVL%NEVM&m-sz|u2ATcH9=O;b&|m7fYMH4T4;3B?y! zN=ki!z*5X70!zP*GDb(;)2I0pSbBlWsyeu}Jux<jXTotpOgDstn5wG!7HoQcfo{5& z>=aN+r{mLwUWq+zR)R?X3q;GgQYaHd`YUT(?7ejk2a#$rq9QNtgH4Xe=dw9b7kNRS z!gn3=@*+IM)aFIB0BTYlJ#4Y*lPempHkSk44)W2G6J)v{6vPiQeS)`oM!bQno*8fO zWN-BhudS@!jyEujXHI>Vl(Ljn?JRHG@|NlT08^^0RItJ6#BSHRg%PJBD92I1Jb|Tq zd0Ul5GgX+wr<^k;*yp2|_fPs+F7oOl+hiYkE@~^q^wARJl}fWZ4<(1NJK0&k5W1S< zthYPhcGf=vb9~>N_1IG3tp6+ggkNK4{ZaWdamsD4O?krU@(V*jVY%&}a(1(uTvBUX zUW;mN4J}LHycgH@wYtZ2YIGdGb=qoZAv&(!3`B8iZ(g6uZs_x!XF8eS+Z&+IYQYVB zbGhC7dLsV^LMgBO?hir{uxM0*iF$_9?{1&S-*7J|lsh8!&!81l9KbyeV%gFnPA0)2 zVMs6-OD%Ct`y+fVzaZb>7ecA2jHI81B7lCRbJ+e0Oyd|y4fTdfOldJc3~jM8k$#_A z>{2zdCUxCJ%Js?r2x`+!q%^2z`{Z>}TIM!MNuo*m7zjOeeL2}PY;0Jrf_ypijdI+7 zicNnx*DLE5Lb#-L>+h%tMu-sOIEX`s1E&WyNF5ACgbz|j(S6%P6XV@RYn(<Jd9%Ad z<d}=*Vy_tDu^QT#DIOebN!}{)I2KCfxf4_3fyA3_@d!97;yh?(kQSlD<ZLJ+TudID zwfDSMN8!;nRr?nm`(>43cyI>U-PFh1=(hmW;;|UL?DiBKfv+aP$)3zG%{Q5ev6)PX zx~e!etGySCvVh)N^Nr{%XBC~o@zaTx0YiZr=25yU!Er!GloP{Le9O&(%86kvgA5G& zoEU_L0!|FfC!84X03r$}27Q`8PK>AFYICfyy)`y9hMRVWMg}ovfaADWljpcd7vDE$ z#c7W2T;FVuH%F;!Yiq6X?y8#T>z0YBaX9D#ejy(P{Ea8<dNeC8ick7Rt}-r)kD){+ z0o<@0e$5<lQDjJivew&fi376v88b;tBCbsO4DnSzox|M^Hl3rdAmN=STpW=viE-!B zM^)@)zpS#_M(o|StZ^<uEh9xI(IY+*al8sYhJs+V%G^HxJ8$(2uY#<e=~Y<V^y!HV zuY#=JX2@>Z*phP=7-iKtbC9=fd5h_hcippOmj%1vzupqOhzo8tn~CiB+8)(f%F?_a zG}FDPV7M0q2|4<N@(4&3Nu68qLm`cqSoZ<!WlsPxO6rl#y4|&`aW07^Jw@l(Ixoi< zq&SIa%Ei)o-s%}xlGQV@^mK3a3@pj&ZHAP=Qsix0K9>3mp{>Mjmp;#yn@S-RR+z&> zmoshJ9=b9dpPADfzthX{EO|_gb;>=LL)D$^p8GnC#5wLcy8~|b+()3WzPabHrNTY; zF<?)GUt{+i9jKPpVN)(SO$`*Torkc@L?H+LsQ6CWC!tGD)(L;dTe#^7!@B9N(Jc@O zK00v|#e+A-;Wt{;m=je{3HpTgX*P&7TgALseF!c+jQrNQv{M{#-wma<GFpBMiU5O$ z5<^tUoesDPHol&$tvG6Rv7%m0TNFe>vKImUbzQixbsY95(7umYRMWmVW36I1-;5Mp zP=6arI^}KqFDSz0ZNoI5fzl3hHzqFOZNr6t-r^NoeJhWw89+iydE1sj5pK;ps|elt z%k{QB25Qr-pEO2hd)stUTGmfVNr$&hPdy4HCRd0AN#$->d|kn~oH<c>O@2*+;nL2s z$SgUfcEkQs$kvB;GolicjpmW<2|rm|VVJ0j=K~t;<I@r}DtS<)l^N&CS<h??l~IMN zr;&_`dTbvyrd5opt3q3>P;~{hn8R)zRng(_dU2mhbTwozh$@|w7OEsA9jMY%301j5 zWS|OPuO3zF*<^O0inBnGMX2o{kAz}dc~Wr7E$K=5x)>f_yd-;gs7Eh1Q+f=C`Rjqs zB|V|9gCdG674}$0S0ls{M`IA_1m+Or%47)QyIg|E0jm@NHN3wgR1lR2Ac1CE1OlAm zpND3a6ot=15#ge6kQ4*W<s@deSQzR#Hqw341sF=zzp;B*V(ji^wWi=${ymbI>}e6x zeA8mKKKa{O?YdBKe+t9W9ntp}!TjLS2KByL^OoppzzDA3`)#6RzzCq=i$Yxqd;>b7 zeBtIAw4Cy)eBq}3!GNyM7fxDC0be-g6Ta|)ZSaXU^wFpJ;|sqc+u11gPtmbXaKQCg zbG!q)>^mF}`8j+Kd3L3J^P4}D)pc#9FTLp_&DOS&uKaRSYq&eIGo9*Zg9JLKw=z!k zGf=b>>kyc=-Zf{P>J9-?o@v|FzKSCP@iZ;wE#9lT?c)kRr^4OxHm9P?k#$bD{K~>2 z9rt{;z4N0!N^!jNBTx|EJAbpcdWJ_)R?qY(-r=pD;Zc;;SLsoFt+#DiRv}&0%-QpY z#==rg`BxIVU0M;tqbMlHQEXC<D&>?PrdFl)*zT^)BMN9Xvlfe7aRxC4#Xst!%R^qy zF#7%>(OhOk%jdn-GcY5oXJY2t-s%~ck=5I5FihM2_+`qfbLJP`w(V@p{FK;T0cHf{ z`iq(6O5KVPkq%*5M494rff)Il&X&DKJc<)%l34)-@h6$bd8=mtMpn-R%qnm748X|h zs|3sjZ`*b@VAc}5D*%k3T%~{sE6fqLlA~5u8MZPqr#U|C<#?7nrnG^Rmw-lo0XV{< z9IEc*u$8C7Y>*SSVt2qDwz2^V>s#0gwp4_z+ym^1@M|2lGQe5grGi<s#gpLJ)3Byw zAq*pZ@nDu~&W2zX^ysEN0X5oTj%hSq)f(f&HPrRGBlOYX1{P;W-b9DVn=@R0tI{XV z*RjE>c^~Gn9YILLt5Mo?Y1k=2Gw%-NfeM;=ClmpeQ6=uE#Qc9CXy%_nNvGWVpN1lU zSmcth-TRp4^J4@A&HNy=#mc?^J!-K_X~~+x^mRKoXy%7do9+^#5js0)Mkl4^CXtkM zxcBwcfS?(CUBS4V-$A)$9%hp{<=+1o6;b>M`D28Ez>JrX6A463;ygm;{CKuV2cE^& z1S94w{!t(J4{G^VOj$w{5BzXOs~A1^gCbnW!L*8zvpTfJ3OUD8i$jqU{Wq|a5g2nE z)K(BVIw>vWNJ=`8qo*E-@{uJig6}fI4Bx08EPJylTN*4!3th{I*c3k%gGxcu!Z7sA z>67uE=CdpY%5_AX>?sD*DhA4QXp0q4Zlo5^7Eo@1+6n?iC#3}xNl6D#^i&Gf$q*F- zC-_43IJuThSO-ox)&W_BiWz$-bZS!(2dHtDj5zokF+27pX6zxLa}a8kPW@phqPR|N z$BeDU!8l{32uIjw+&&Rc=wgguzH5l>mt11Y0dqXnqm6?M9iI;sTO}|^&e;~2fC#f+ zKr>4U&d;ETaKY(&gxP|K+e3Z%z*K^ABg{O@i9eCVWKWxz=9@NY7D#z-4xH7lry|S> z_SKr#L{|gGd$pAL15q+y1W@orp{@kJ0Uc2hW~RZW+)7VHn3+aF1G>HlGg=N5h%m!^ zBEoDF$e)NXqfhfE!tA8ciN^3?r_mmy^(QBW>{wq6nOSV#qQs6f>#2*FIEdtiXs=GU zO-HEQMi&4MG}>)-1K=#3rLxU8ER_lS8bWzX?3-Y&y=xAHeVM$NQL#;SVAo^poa;d! zxpqcO2zH`w+qltB&+y<Zo1W1W64)7>wWlR#iI!)d>EOzk_J=Q5MJA=uT&E}KwCMS0 z!SRgW0R@4zhZ#!pT5t6X&$z6f=^1~Uw|a(WTvng*jKk=W@F6FZ1heX#`H;75Sr#~5 z56cO^!pcg8U;RC?+oduvLXZUIIJ17r;i|%~p6_i{7R^*)4$pWFrftvoimZ7eXV1qX zF{$Xx|4|>Azq>w@l@fv<lpwcULn>!^4xx9lvwS;rHOE<Qcfjo|e<l>xH)lDvR5;7` zz8*f|*VtLUmpNmm+~L}ECD!%VVOfcS0K<E6clfOrfJ#_v)Ha`Xsk|S$g=aX#*C>M) zwTdhqLld1fV~uWYE8MA$R{_>q!jU0PzQ!B>AP1d;y=pl%zuVfnRj8Tite8f5lR=jz zzn$C`9oPo~PlD_RxLTXj8k%(apv>tKvr}B=t3s))%zG=L2w3VVNT7D(beY@cz0;K* zrVe&*Z0SslPIa4jM&k%xR;i<-j$#gX&W=w`lLTvL=zesWv1_)c>vD!8PfyT=?zB*H zC^z_eD8l8;!!)0<<r`M}3!Kz`MQDqak76^m*rlOl=>od`#C3x|9ct5k6g2i`yTNr* zTDBZXNr#U@PaR+ilMn~#<HLd!NXwZ?loe?$o8VFhP*x-aT}dm_6R3#(9L;_wlpQp9 zt6}A(P(=8!a%|$_$AdAFO?$Pg$A@5K85{4c8Xtx8XF99az&co84s%{KMCFap-b_*9 z04wD$cs(&Gpa>-@NXXe1l>mRiL(t5UBJ*J=B3xwlrJ1N!*Ay>pYVog07ty=Ms`M-D z{^+A>bUnOYJVc@=8&Ggy{Sp-JnxinyH%HNsD^^Bu^)%Y}^a=E5v)XH;83BE_CKb_j z&I&t)*UuAWOW_rzxDvbubVNA__JdYr4rc+SDhGkNOfs<Qa}W?13OEQbpKuV=M&T1} zL8nji$3bwix$<P~GJj%m4?(AIE`mes4&eH9(7NnmR!&ww8DzjYqm=OmoQT4eEZtzO z`HDH`4d{5>0ee~;G8Ldysy@7*<0omjL%=3!bT-o1=@3|!2vyQ}+ZB+J#Wp%;WTDwj z`(5w+Gku-scmSRO1@R8+Q^r?0<0wn+6(tIDSaNfiv6Bsq=Rt>a42*UM+y=(up|HLg z7_p_o!1xmUgkNI=<K7kqQx--|{)N404Hl6MIvxvSGzbQ;mCu>Eb*3JzLtEIOT;SBB zVKb$-`^IKxsNI@Gb7BG{q2TE$ItXT<8O}k~7sWXQb&H<dW%OiD51+dNoo$QNX%~RK zRv214wN<rt6R%6bkaD;h6SgZgCMTQlhrYw!eY9PPYr-0%qj28oaHHEWNnJsCI)mOE z${=AkjoyUZp@Da|EOr4wsxVYOX0p+4jFJ70?s78L;C7<kz4wQ9Pgxe;2StGDsXB^l zA*aFeLXca8(natWYz3EyKUr3>l#vE23fAO}7A_L3cn|VM9|MYqeC~mlJ~-%YrRn7U zMtO37wE($$D;t`v7Z10F!>qN7^%84NXL$l18<+K>MI<HANLTzdoi0BMrArEBiv?@{ z0}ABn1SxStLRTYhvP~t#ZBbiXGNPN-<Zn6|7mo$bCJN2FK@kR4GSJ-H>ohS4gDsFO zHJ~2LmRV919RS6}X(S)%SM?4Y6xxB594r-bupbmyQVx(J)yRQtlPw1UCIDqvuxEd5 z9A1=eb#HgL2slwuVogoz8Fu33Vr;&W{s?%CTr9}?GQfr!ISqM%IX=K%qih<cVg^NP zs$054assIfw@Cq;#yKdEmoA3Kx%i1}8uV%Y*fiFUPqfDxqo5{*MLr(qvuk9O-8b9D zNg0)i7|69XJ)C7{$3boZNpULaWh@`hL=j9B5K!G;IR`8s8BFn5KlaVcuFq4MIrKsQ z20wYjtspjeqe-N<(+VOy7N+PW6Ps-hSwR!uT4}RSmV~xVBz7d|1j+DjyvRoajxFSQ zP!Oo!%xK7aywx+JA!YT<XvjBvt7k+*%IZ^0FoLJ~L2(ay+n2R=(S1+;h{)=K;@(57 zcg?+w$Vfp&j#lEar#;)-sw~>6!W{Or99Z`$GV=TLLI}Q7g4}Wiq#`482)&aHmmTP8 zj^WbofZK3+6%-b$!}aJsJa_wkcr-IjaM9Z#srOiq8YQlS1XJNVu_SD%FkG$}mtSMU z<^CDdXUce~O<O|!z8VWm^adF3i-$+9PAaT5YOrxe#z=O$6Ky!eVY~*vY99M!`lGcQ z^Id(8-v>JGRG~77ETvH_?B=>+B-pYia#v?d6{fxA7o%yf*=@GfDx0{WC+MU;CY035 z2yhe>0V^*hcNs>2#15Xa=$?=f`B7UfuC5YEV8-3jtR<2-9E(}{+>nC$)4I?;t3bn( zpa?(`k=8zM2h)5(9Co0g8Aze)enyJUwM#;KpaKs!Q4d@SK-N^Nt0~;T!_82e9wS0S zTXx`~PFgEQL{gThz7U1P2!GL24@r!c7{O|ak07KBGQ^h@3abh-JdsV@ltB?u<+Nb< z#=sp*phvXd{ctLxKS72sfwF^!Xf<x!0Y!w58+)k%!8}e#fHIwIu>D@BJCp4kKxmVW zAoy#D-~mObfI%e6Y_mNeVDN*`%#!T?dnh8D{d+h<1!-(pP&WpK&rxG@R&vg<_Fvdt z)d$LGE4<E#B{Z5*aKyy^#gmaWVv4SFR%a=p{xp?dN~n?5l?Zh}N0jl~RJh6w^~wTm zYS)H9`=aVdEDBhlF`uwNFPnf*WPzqn^Tz^x?qs_;*`63`b~=OLq#vZ!gEB_5qU=ub zETaZ;>gk(hdNQZtdUE7I2XEXG+x1t~Bu$#bVxO3iMyIL{j)N*sd;4qaYsYjZC%U6} z&&x4dWb~}W@*M$^=N#<IShOF9BAqOOz@q)8IbhMwVW!8r{rKEhb>%)cx32J?;AcU& z)!Sx4bUgCJY4yISVo_FWIoo8uUsg>jyKS}I)5;#_6xv`aRj2LQKH753>1RMed~^Ec z-s&0VbXh&qoId2Oo?%Xx)!U3Qw$b@Fa!^*CGgIES<*iZurgW;T)V}f?h}|y5h+#q( zl;h|&%IYoEH5HP2Dzz$gx62{!*(Qcc`kapaGhd4H3urm==xltAmyHZU-6Q(O^jF>Q zt)2leSv?bA4|=O-08Cb2CBQ!IZQITU*e8hH6#z_7uD<{~%&W4+m`P)7xq2_oB!HzS z=xF-6muCz#{e;NN_5S|eTRj6!vU(<(mP~qd(TIU2S$&mgI@sH`osFjbp>^(PE56(? z8TTYFarlhu>|q4j_ZF--;RD}w)STw6{@GAi!)H`&Lk3~v3lrOmyw&r2|5*sL)3zD( zcGs4NCLN3vog&wIn{=;}BE5Y(Q<IYu?e1V_tkLe?Fg4L_c4l@+MdY9bCZQ@Fbi)dB z1P0`+e0H+G`bjX%=J>1a4!Hf*2SZ_f^H*a_<whHjs0hEt{_4YX7Q`vvwYK;aXnQOc zo>&N2zUwp3m>9pY+3rFpdvdx@2faa>#~Kdqf$bvFo!v!`cB9srY!0=ywqUym+G<QN zRaB-9!@ImN%$hVb3+?<enFyA?45dV8smt%pa9ru$Z6knOPtd7;Untd;`|8b51ekl3 z$l}`Hxs&BVbHGmg;q~J8YFuZTIMk6nbW#t5*EeeE-5a*_gD({Jb|5f7!a?9QG{mx= zcC4rDCkByIsXC=U7D{R5Z2t!+BKB|C&UQ@WINJ?#1UZXRR)?>LwpcmWzd|i`tz5D| zt^16)&h>9XZMv)ICHOttxvrDaaurERI-Kiz>e*Gvn~)RfiN_k$xKPeLgK<D&wD}O5 z6LNU{U{b{Usfgk@-JEGPNuw1*6eM168fij6m4?f)#<nI*PVgg5PM(+-hyBF>s3VUK z)5qN4TUTXCY&;FYu~~xD%b^GtOfjuum>wD0Vg=J0wKx=}(a%9Jio15BqoKBfFx5$E z!BkSx0aHEo$uUe>f@WY6i>n@!OW0&DjmeXgl|=!OeygFAO$G^h?zBkHiMoBpK%1VR zL+lyQZKoT}xA;^u;T1$VVIQ(*LQJa|ViTb)RuCJd7S9&MZh+bfLQE&61u;oU2gLN$ zqY8<T0V#aFdPr?%li2|&&JtS|p>E`PU+843;-65fE*UEFhR{~1P!V&DQcf39p(5sD z)>u3ELPcnrDG(}x`9!G5M^VNoRD?dwpHPu!<QNPF@rv5Pp^1t1aBI8)b|=mq4i}V& z9Z6N(w_uXjut{Jo3n^g4A6=pmaB#Ra)LjdQG!AuF)zl<82ck~C1w!ncF3Uune9anx zd+(k5Q738nQ!yI$jT6UnB`99^3%!E>x~}B>)X%l>Koy&7(NB<#&OnuIvxJJ6cJ-9U zef9!a{?A8qP5{dvpdeVmG5zZ++8&@r43D6!p6OUR#9KYXwIZvp(j&Oa+qSG#wQdLM zcK}NrT33ljP*9GeI(h<F{znL*9S^oM16VHhvXS9By?`jr1=usa)iVGlt7igi)LT6R zV6yru0d||WZ95xaHxs*Ei(j_f^cP?UWNU?Lg0uOym;FMVRp=4vWL-~qlb3M}(!8E% z%!Smuz11@yC97vb>LG9S3`oi9ZPqMAeLi7_Kk8EC)p_$}Z|ll|O4L>=?(*}*@d{8S zh}U0K&01L4qh6*l0QGAkFBed|b}CW=W%W!z?d7eW0Vr9$4JgBH=*LsapLm3~ZROxZ zm6bx%<DhkwD1l*&TjwPXpK;8vu=BjtGs42cdjE89_59vf5Ei!8+obYgVS-SV4!U85 zIl{tn><l|OEbI|j9OZ<C*&T3)g?$+c>sweDwp4_L&45Hj_%#j-Tf;R_rQ*ai+mG-) z{|nZp2Ne}R<K*daoR|vy0>66$uDRM;W$0M{s?k-q*Lu;LHP^&$d<b`dXtMci3Kf#@ zDwH-|5_U#-*}Fp7pu)@E0Y!j|NJ%<c=KlZiG7QPo1^#oPlvYmlPeBo`xD`yR*s1>g z&=xDF`gf_tt`$%g%5}3MH@xiMpf=s9PUCrYc$rR0%c(9Y>2Rv+sr?Br!y44MP|l^R z!plCv=0wWx{!uF8FFd^Lz^-q3m?g3Cyp)8O?F&V?V2WuK!*o?>ixo^)Qj0@j8a)bv z!3ZxKfZ7VeR41hcQ%Ok&O!d?X!ppF@>M^+&o9v}Ad5didt<}*22S*XFCf7P#@zH2c zV}NJ3(Hd`!Z>vqVwl_y>TPCK)ha2q{#Cn3ZiE(<UdSWyhoV*SD5Uw9>*6Q2g#0=PI zv#Pdz5H7b^Rhy2#Pvdv(FbMkw*0crIh*L`^>l5n`P|@jrFBYvfNQ}siR>L$7Voi&t z5Kl64>TTX0+Gd5>DQfd<VfJRItsrJ~Vp^D$v~*xrPrVLF)>mN^?2sYdSatRIzJ|@B z()hkuMaJ;LM+a&fn_C-Gqg}-G5y=rQN5r=I3c^a?1>`6R)VC8wvw@0f9H1JOQWD9O zLG<C!7Au&3j9NTfF#QzNRuHB-DJ_^vN;+Vwr>-j!R_YWj1A<s=^$>g;oBR$4a!hx! z2o-Mn524Dp3OB`7cFAzl2SQt+!c9$^MY*+!3O6-vVumfj7j8;wXMu22%qPN4_n(4K z6mCkN=1;ikTFnqiXU%fLNmmsNC#8b>7A|^rstZ(~c`v~#P%YuAv=O-4X>DyQ+<u3e z=?3H03^gIm%8_CNATrKLt4wg`u_%j)`423bch9ZhP9Y5{ZqW|j+{@-?%orI|kxJI} z-}Qc~h6i8TRE^dlnVrFxM;DU8xM%6m$!f35*zBVUCp_{ZD2N{(+3;4+2sM$_Gd<%I z-s%}HMp?b>8DCWLx{T*|+m~e-(ruak5J_>E>VRlrDKGi0#Cn&$$%w8HROF~Vo>0m2 zsa2`S<Gt+BULnoq-m)ZXoJWi^+VA=R^Hwjj7-V>(XgM>|_`Tlh8BmhdGokb`Z}ki) z$?9!pETXA7VT3=-L}u2x^A&IV%0Wq1R|-U5BBoaWB0;}OK@?V)BZeSny6n@PGk@wM z`>PvCfA1B7EFnz|fa=bf976BpV2x9ut2x0Mb_d+S8b?E6eGAsWmWp7FV{e2{_%#mJ z*vHm5Q^6RTE+|~^$6#rR4h|Yq@nDR#7bj;$%e!W_OvCM=W38?-n%~$ModSdTO|9+- zoOt4xz{(V)kEzE4J)8>_uNhnfRLte&hv3#~<haf)SHMKQp9k`s8A@jrF>yK+0agwr zj;O5nGh*UcTISS@n+VY3BYp;huYyiIsi*C|1@El6E|fkh&fyv;!sS54G>(<myrw`u z*4jwXku(+B17-DXQx9AUMAqD)uNAm)4>v(=y49D4#_YHUowSzKS5nqt_0?0wjgsgn z(Bwu?Q2J9aw}NUpJE4kUxQb2Hlri@TDx!D{!?DSzU8~3TsMXRZO2d14SWhEITca3$ zP3?DG{@w{~3>(Rl5QGOrH;I?_@f(=NL6D{FQ<)h${l`OFtx)ri)ap>wL@$Qd8DR(y zL-vBG(aC9{MpDy(8a;J?;Yqip#=s5cuO2t|vFYl-4QK6<a)N9QZH01z;KW(d334hG z!B7yET-xkTwa2Yn>XKh|;4Zl-5V%S;SO`TFR}HLd>3e%86FMB8*J<3?OpfCc#*&P5 zL;Mbc+B3zEgGtGFHEiz>rMfq6WKD*$2*r3L%WN|~;IgR`p_xG=w-SIgP(*0~s1Mz^ zrgknK&87w2<XCA)bc~4A^Vq%7l^Eu5+>6!ApTezhcSPUE3r0P9%vmH5*?|C<=9}PX ztX`Io$msKRv)X5^5d~)=z2DYMB)T0iL@T78K~xO@yFx0;ZzV_#=!o)Dn@h!V`ls?! zo8|%or9MA3=_LjH)R<5Bsb2*|6n<*@G=Kcm=c@&Qx;JZZ>qL8Ss68<`38oQ_<9dBT z$8~aoicwSFJlR*~cajEE+qJDiv*^&Go$c9vw{NH`<Jo=(N^fGP0nheZ=9XvMAuh^G zY`ePk)4^RY>z0KA`E|ANAN`C7cZS=Hh#o@DIGy1~6_HwHAF|Iqsn!?%H6KwpzVLsB zg807hfA?0;aNx=6nGU?)c&leP@MQHV2VO~E_-@;|imt92&XzCy&%}C{I>T@R3o3Fn zl9Ve*-Fx)~A&@qF_Ozx41vHy^`mwEsJxNc{2bg2L++xt-NGOPpr4zl?Gq5D9XJY9L zZ}ki;$?9!(7;(h@MOG@n_;PRCvX;ihaYU7sa)Vz&?5+Smf^wDOC#*1s8$4&C?2{Y( z*?nYwb#Cxmyh4yAqN%Y@xxsS?y_4PGAA^xO#|>_G!0iUV9}4T68ys6I+~Ds3_C)wK zc7q?8zdBhtBMoflfRzQ7v6@;aJgpC4@recxBYtte_{xiIzc{#w@VIi^GZrrb!F4n- z8c%S-h{JeKpW6P8jUmlEIp3Bhf;sO(j_b_XDQ@sjhZ0_yIv<824CzDNqMvT?XVL=4 z<p#$Sn`<|Xw1!4%H#KY9ns6VJv{}G*$mAU78iaXFbuh-mDbQ&LU~Jpe7m4yWU6_9u zN>k-J|5qpisF>;a!!(~=^c&zlG_GpPxN%36>~x*~Hna!I3HT`Wz@>C#%{RJA#C4tj z9%|D~uQZ%yyUumeTBcV?S%(u)Pd!_RV0l>+awFaCSc4i8%9%TrHTXMhPROxU-AMCI zDx$c%{VcTzQrj2l-V3?wSnM~ece?G?<XB^J6<mTQFPpDTw87=oUIYI%r-!}MSYIL) zT00##&0Xon6HMZae<Bp&!X&0~Flj6{NZwLwijAQyRv0{uTHLs2;Vy7VBK(Ukgcz|~ zXX?>K@b}u8=o0ZK4~)?YD2L&ZKMS%K1fxz<3yhMa4lwGeYXT(8z#SG=J?`p)`V68w zaK~9A$s*LA#jk~;U-^P?f-mU{`j{9%UJOn_ZEDgkrF*%V(n}ok2D+19_33s8(7B|y z_JvSHaTUgP*FRoN21;Rvi|)WzlIR_#hMb$*5Y5-RM3XbK#zPsvUFe>#3KdNy6iBk! z7K#8@{`;YsC57XCP(-+J$XE?><&&Ifvzp(^l%ZLEp4}T=sbY@fS+0DKUiBFgh-{S= z(|pq-4f5ngClVR1{2$J0pS4C5oWk^eTT__mcEIqhl($b3RRh4Tkc#qK2~q<(qFnjr za<`mrt6ce}g~LFp&y`OKO#xRv<`b^`gKvgUwB?*W%^z3(85ln{NU$30P7IDuP7lHr z#DkMO7ygMp7rwKGzPawloK@DTr?$(UvJbb~$yG(ot*!0yiy#fEkn)ElR5;$c9?#$P zXjZnWuK`hWPFZCf`U5D#iNy)5X7|nkhrW}OGs?qlJMs_qyrkP^Jo$75@-#oe!yWfF z!K0@k2b_-kORJY%CAzksvRXI)l|B-3-29uNAXsEG_vtph)iYd^vU;X#vg56u;hL1y z+pfv7Ti##bZC~E<f41EG&mq>kR2_zUTTqdst)yIC%FTZfwJNpceGg+wQ82Svw=~Wd zXAugr`dJ@{9`N#sL4mi5Ml(_LesA>*6v^tDDEg$gdIpMQ^)@REo11^>l`_VC!`rrU z2%^eLIrzUq?5+Sgf^z*u&hB6*iM6j76!pkv)?$$>&LB_||EOc;k6z9&F!Ng?B6sFl zc8f<@<J?6jt7l^7KyUR7%*g6(Hk854N^jeCHfD~7*131Hu;r$|nAy`>q{OgD<7T<a z8D|pM(Gzt1T<GNzgAV5sLAm(3+FLzi&XLtK@ze5F&%lqYzDoSu;%(c`#?MW}?h57{ zLAn0or+)_&{k4}#4EVf`=*fl8JH6F2;3KPN!so-@>KX8n)!Xo~_AL9Awv5fpU+}iC z9E4<br4+Z%64NUHk)U6tAPOtY5t*4|3E9a3gJ*#1mlH5(cfcJmxDpEMTfiW;R0Iqz zeinSfuW`WOW1U8^)B!r08A|vApNPdKmO-$;6b}@9(q^zP*BZ5Lts9%;>Le1dGuOb* zTmw6Etu>ycZ-o;<n{87w2`WKXVO9VsoCebZN9N26GpJzHGUU3>C|A%RV`u#GiyLjQ zes`N~YjeDwpws*CP<pGF!N)-n;H^=Dh(^DD#te#0QLdOlh;2pm#Bv!N`L`~VGAi=# zBq+iaWrS%yH);iuf0u;zKt&yGq8_*=wY*7}8~L{xYSTTnG%jXG{^_K(JhhUtj$k7_ zbq`u#;h{MsF#;Ddeh>30be8jRDi`pHY<i~Rh}KXM#pCzZ(Od!!GZnoz2^V2uuQ6O! zjN%Yv+iXKXxS#|j5N+HjQdUnRsz?2-k1{);&0(W@60!FJ(QV?YeS8k4aj;}qLa4-) zk?{4QEmqih9kn<VJJD8noe`+_2FP9zJ31*X>_|#Fu%o9Q%Mc<1SXfB)z<Ms5*rkEB zT9`F8SdlR_zKlnVEn8b~3lBP^-AIZpp$3lPA9WOc4f<FTMgL4>$`0(ow2D#mNN9@{ zihe>Zo-Gvp0%|LWBAt{LiX<f+DAH38lQJYjsco4tfP?Q<51cQu>025&;^@OciuA>> zak}YBkNZ_*aHB@Iff~rs6Lj<(ersv;90o<W^f^qc7(Gu3ZLvbnlc>eBg`Sh3wu0!< zNok=+QqqAQJ@o*G&=|167pjNNA#B2yhRp>@Fq3}nq52WV5CI(RP`eK9^Ai!wxO#^> z<ZgteAzb3+29|aLqJb;zcO6z^K!}o)Qj2JrJt<)t2UeDqk%TD2nE2e#Rx4;dn_4|v z(0V@9RuEb`IW1^OYC52$r#>}Qt_<v9iPd9oE1U8T>~YMZvIw;q<G9d?Q$_Ql<)maZ z?_)z-p`v+BJ5;%qu8QV0&5(wD$QR8^tDXYUyqHf!^L_<ojG}qz)BK6%J%twLG-P8m zFEfgFb@3=(D7kOZyBDN8K|Qjgc9Y>`EtrtuI#SW?ty80;gSe0sr*ElAX;y-Be*u!? zoVv;c=l;|h_IfjOE;tuuLPf9ILAiUUxEixY%+eX@x=!#%KVidzaBadye?Uq*gK$p{ z7R9)`{k~pm@7p{g$ceSx0}6tr2{TIY@!skgE@xRi)8)L{TRp?&EUQnsoJ$_5b*i_0 zdDidQinTq3SnpCq8DR^8iX5fL6KlJST9t~meT+E~D4f~6)0P`WmLWr4RxyY$DB8^g z(hc6~89<WNGlBGMZ}kiy$?9!p>;`jo%&N#Axj|X=$>1(;+sc86Dk~MW@ls-U1>g~s z>o0ir%hH-+zNF&^Wu#%EWW_nf9G*(mnf9QUX$&~Mhv>_lmp<XGo&hIWJrhp<?5&;w zCs}<8PGIy*n2`e~%&K$d-@R=s2`8+q6r8?K?5+S#f^wC@DXcI@5LAvPx|4&T{sd}q zP7svc0e2A8ze8bt3xdLyiXf;%pADbzYa9f%Z)y>e3Vzbme-TsjA6T3oQ&T+nY0c)$ z;HL(KJ&_wPC-y0%03F#!00ErK(E_1Qb9#{}*z<VgvCbY>$Wvdh3wvrPp;gS&lc5N( zX({=`#n=3gdAc-|GAib26BOa{kzpFgm~WhEW~>5?6dgp{LVKVL`@_@&*Bq8N!*XMu zT2PyA*r#DIJLX9zt!3Dklyw;P^;BQX6XsL!EN2N;F;C~S>6tRupF>3yk9pdZtTLUh zGQ&w`xZfcND!!@*!(GWzCU&ByV+on7)W3#)gbndY9MtOsDTvc{92BN;@Kw-R_P)?o zD@?tIS{;h1=vnYOBNpoKA$vhg>EyI9C8_Dal%9IB5;u?}mSl;sOU4{xnbqU()oj|A z#@}()LRG~`;bOE#p<_Dc;>A!JV5wEAF%6_r^{L?J(C?C9`w5XQ+cS-69IzD#I^5;< zz!oc@{fW(N<5Vdo&~}9e7X+G4N(*R`k`AEhsRua3$3PLjP(6x%#3rl*MVw`5%ISP& zXe*S{8CBPkPUjP-2*$RA#g{f(ou;)VA^uUv?3tkmP^$UqP(*Rn+&=$r;Iiq-=9%p_ z9QlWr@orV2(6v^lHa^jX?JpT;@YdZ{QTw>lWl0V3s3*o3?RT9b*M?F=spQXqBHY`f z^Ay^g$@fbaz|_19B44|WHXP7A6AeOb1;>Ods9~b}3z6Q2r3+JGfTdyK@O(}fV*tKe z{TQ&B+RM>mB!CtAP&z9?U%)V;LO#rOcsWI1g?yOC7XyR7kPn)33WR)MJ`wWqdgLyJ ze9)))6Y_CEXBswVwP7qAY&RRDbb1@AO0Drmdl~{E+T9N4GPVug7?9km`W6&2U7(xP zf9$axDT4GMQkV&JHCuOTa<qB%Z8QK6kaKrcP5%bxAjd1US&1NdKM0~z#Viv+@?Mni z#83vuyS;TTM3Cf5l#0c$LrRXwmx-8pV#qJ@f<94x%Fm1Npc9)H(I=5P&Y+Xyxsn}s zI~{AXmsXS!%8>T;!3+%J3F0X(PHGkEcb!<@^%08`ck)drh#z<Ih_`x%e@|A=^zZ%7 zTRp?SC#$#pdu7jfTmBr+u#)Ks&=+yD6?d{2TIp6R89rh`MUFz_i97kK5J>xo#J#j> zB@aqTRtrk%cO6OtUS=`Ka4gZ2>ndO8t)2lTSv?a<=XtAVKuK0#HI%OLwl8n(Gh0x4 zI<elhuwctjrBDhh%;7fAnM>_k-416ceEv9!MO2cpzI<UHMMG9sDwg88BoyiK;A(SN zT5z?|tJiva#TXA{^*Lk}W2rtKzRlZ!xq>(saaUQyU1bpWBi_F8iOU>pKj*EUG1!Lk z_M6@Y%yr%-t3#n0FSyp=?JvB2WAip_*p&7nbvt9ufVq?7j6MU(R!*Fe-2r!;(ceO0 zeTy@~mWnu|eV+@T@M|1rbX5MzG!=OCNi0q*0YzlXyYYu)!44~;;(<pSH^=L0dGHc0 z+33I}R5-~r1RgUm4dL+|&GF6@9Mo~)nU`L0?xxx#+=ka|cU!h;y_zERQT<?`n$yye zxg?RIjBx<-&VC_ydH_m_&eNR|tuzoydF2v$A`}7USS7T$WbbFR(#FK<kUph}q#NZq zJ}6^+qScvJr;R0OjA!DsQ<!P&I5(7n%7t<!6yb_$!ZeN}*oa*++}TEoj=pDx_CPs? zucjWjmKb?cH#e&3I;c%|0@0wG9o3|h)^ZF>$~qjwdg{vJQYGjrBQCHE1@Ur@5Eb!s zI-AyVuvE7+o=Qa&k9ayaF;1irXHFv}V3*VpLsQxq)$h8{z7o0+Hf1EiPOlJDAOWz0 zoiMG>uzP!G4;1X)Mm-3HUDScs8G%plgzN=jr<2x#ousS-c6#anQ?v~1VL{bn@8xWQ zJFv%5;AIi&aDa88tx%p~oU}`NitAJaBTgf^lhK%#l3#Un{~F2;Lbp;&ehEbsS4-?j zjVC9H!f?&0F+-3U#A_%8!yLH6iZFzD!SftK%z?b7Dhti?|A=t`MJVw>;?B1C1l;NP zIG|riF?uW%5iUkg9iJRP@xjZ+)~sArgReNKiLb_73Tabgcoc5C-Iy+X^Wzd(zF}*4 z61&&BgNHdQ^pYkNoEnaU*2T*1g1XUgO!7^-V$MKP8n2x@tNmR_^@ntJrO|5HS)qNb zGJ}%}5dsO1!eo>>G^?~onh-*cN_am#tNjh;{jMuB8BEL%0fBQZclWH)!)Qi;4D1>r z_eQ0<((u5%>bs>D3&;nkg=%5A3i|JMnP)A+rD~w&b)4-gnb!k4q5=p_(^$E6vkD+I zji|<)?h7EKMN)wPLd+)u2!8-X6aj?vsSg2!Hg)UK`b%Lcw`i){8tu$9qf2(%Wf$;A z2$sh`H=@hM&sWkP!TXVmg--bBLQ~U>eu+Pj4f-UQtq0+i?CaQv&6M8q(TT?J;Lt>; zp*Eq@FsCQzsQuOR0(G<@s97}r7f^)0*3%k)8Z>^<qU^>;7eWcQ&eWre;4hHNpqfdn z-je1xL{@?&{94GrHx$^bk4+3ujW$oIWrs;>Wau3uvN{gc(sGUrZtBi7BxlxTcP?>p zRNt>tv0qOC-mMvHbc=+Fs-~};>DBWHF(6CMj10ATsJgjfMS1ouYIT4IGj~MiLSfOe z=ffx$U5)ay9=?MEp;vhTq$170<n-F%i6J=spaq9y!kRIUPVv!MS^Nia-slkLdUURt z(mNq$C2onrQ{V`e;)-W+CR%Ov1|!5ZUcsg>Fg`r5)dTUn!faO{zdi~)5m@3}sg;R! zJq8Na$A&(fmR5q*2_#g+rybh5Bu0&CHHm-KiMZBJ#PA?hn~2fLNL6Q$>On4fOGLyD zpv!$D9h16mMkPu4G~;CE(CKxtk6xTO)eE2?Kqm88r)PSrXT$`^>Y4E#qu%Nn@gA~z zJGjo+lIRcgNnMa|o40LQs;q9p@CVjWWuDlnUj6{xTMA?P&}gI6nb{;Kl813Nxd0zG zlQ6i<Ym9I^L04PX^QkGG$klVat;(XPD$EgXmoqBZ;dU$Zy%Y&j{emH5opsPY&_~e_ zOG~l$!+TWGUC;=x5WKYnxury@Fr6GiR~@Faa!}~2o#U)I|2SG-9H-{HncgD2m11}% zT89K#3|~OgnTdX~YocJyfKDQCVfP}@@KO?fAQZ-o)yc<fGy{zq8I0bE4Z`M%fSs@7 zC;S=*>@16wrj;|25$C`guw2yUJkg<}@Krs6qj*%#X=l(`>A2tXjET*sT?zpT+vtKE zWB(^Ai=EcZ&Dz!DLldJ@W8<Aw<D;$dW@ptJE847r@^p-S7kcK@#tOvaRDW2Ik~y|I zZR=QqdEc^`w^PDzeiKS)<>&fOD8i6V)I^-&H@2Va^b9RZou`0_@l{S}YHq?!POYI4 z+^pPy<NiA}Jh>_!%F~fFnF^Sp#%AWwC2{c!LM1VA^Y02p07*zCwB7ue=JPn%_oNv* z4V9QuT^<|SV&&F9h+6E@AhPCaUHjoi(;No1>9$)M5woLdbW&ROOG!zhNqV=no_cgK zsS;8kBWdt`HPn`~2r7f=p8+~04W@{`k_OYCQxW~~qhB5>jB0$j6p9ERUk<@r;Ka~D z2i$2+&UoAq$n<42L}9B-6gYU1GrJOnAt<$^C?KI`TNDC(;?IL-2F>kCByNWy!bQUH z-^8<le;HuBqE8R6W_Ly(DWl`z_2L0gJ);=~hs+tMB1o{5Y~B@Gg!1bk$10J{l&<bE znoE!=zmBPMl^eyCU&mC#4Y|zn>!9&hEiOm`3V3%gpYZPd6MmxOA?Q;T-W{}kC)9{; z+Z(+S(e2_7Ha9vL9v#qOD)(fN#eV}S*WK3Et->_Sw)`J&trG`moj9QB>{bm-4?uB? z_eoYo^;o@Cy_;i(?;nFWIfvsihVLJuoF=PN@Nrasd9}u1u8%_qhvG`?^8g{Y4d8oP zJT>)(RH{Bb{I{RD;RbP=xY46XZKpx}K!+G6U9s)qc`u~R;rpbkNJ=NAJS&4vtKDDd z5k!tLd<hf;Y-Ae45B65iFow(Ona1#Aywx*|;j;QFjo~MI+m^Q+EN2XlaxI-F61!c> zH^ba5D92GSl!aQV8W%4G6p|5sH*c%5Xr>Btn7eZ@-zRhTP#>9Jow<9k1i2;el({>H z&~w4u{aYCBbIjd#FWlzt??GWoBfW1C$ngE}Xl5E(qqjp+0T-2F?#AW{bN8LVs0hEt z=I*_%*)_EpRh!uaw7!ppC5i=%^u^8ICtd)-L0~$>dEa3bfGb5YOk&$G>{1<VZE3^N zW#&8<ScX2;y^@V7&0a8HG%3NXyOG~Ivv!J^`|Y6wS2l;YK@qUFQ__e!MqxAe@oDWS zZROVGGM2ftQ9DbIime!h6s?bj5<_hm{Rk8R-KXkolQyPRY|{Q(Xp5Ce`(LQVE-fKz zKGqF2T$A=Upf=q;L!(}{Nn0nSWzv?EbeOdD)csJr&{1NDkQj2L1sk&~ASSE*Aft>j z4SkSJRymR>(+~nHs1-YwK#xe-dMg#t9}D)LFY+x*vIIx=Pz@a`pos9H<7mxfjaOWE z8?AAiq0q3c=COFZ5ST3Zjv*j5Xl15=a6qHYQ-U>zL8(FJM<pOgzS$O#0K4{jXr|MU zlBr6i1Z6E05iTfu)HO-bc5u=7VQuo*M2&SH>rC$$=4M@gxq{tQeK3t40k~FS_4bUa z*uQv!vPM<Wb<Q#`CDi9r=>fP<LXE7hM5qHgq734uc2;guPzG^RK{o_C%OEZ+_;n!` z1x(>6KEf3KQXrx*h0~|XP2p(<iR}feA@l&Y7sP9(c%Os5!yt6C1MC;DIa-hQ#U<CC zmXSNP%_5b-+lFs1G>3a_&%)w#8+<{3y~Ul0srC@WVf+%yoPY;zYPbRZp1(`fraw~> zLnrM9IXdvurl?ELKSNMdbQ64(yE|^CUvX>2rsx*>{49FjO3&Nq`D}Pbx8vhE@Hl@# z^jz`hdGKdb^n7~0fSxbJgk7V(p}6xGMK8i{i=sOyX$L)D49`2FJs^GL_UI+>CF<eh zrTBOmK3<;ub|-$i3m>n*$KCkYA789TGw^xS$ibVUd*B0vcrAdRqh0awN=%7fMbB5$ z^ELE*Ej?dH&wJ_lSMU@Bd_8^tYyAEOeCz`S-4VSJK0;UD1b;5v>zHU6{J1Gvf^{s# z$D1+dTkx@hQkLV7yW``n_~O!$yLLqPVe<X>H~<pvi1x+g{qXTN_;E+{82Gp&dI0k; zi1wr}yJ6}=d@Q2xi{W`kv=@FJxq1_fuzv%&H$`uUCq#t36aIkb=w0H^d&Hmj(w};? z8g@EBo>SpZBl_%7^yORdrx8tWpf5Y%PlNVGKsNL^!A6t^<;$-}q`wXyd*B9&<@h+R z29H(vcmRrt?!(7bP)2kGJ`RHoNzozr_}TN|@nd|f8-vHm_;@82bvHbwqW5c6?4aUz zP|-jMC~*fBxr2(^K}GGLVs=mwJEmyw4vIT9j&?C2TBD+yMliEAj#xW?;;kbRL2|=L zr@{>*gM*+^b_WOZBHLmgiO}q*ulmZKn6f{1ehr5Lm^p+3&#I6D!%aLzq1n!(z(AbQ zBn5R^C&g(<fb;ONa4|fV;bR*<M)C2F_;?r}2QGofq4;<*T8>Y~#}&K7<7#~TEk53h z50dh|Q0Ngw(fRl|1s|L6@iOq#Mt9?5<Un|g;p3LW;Bh-X2p4M*CKutOs9<8|5VqV{ zAzL5}xH+236Ut>Wgu1IU<XY_d7JU5I;qdq!KI%ANti}fo81KMOI4(s$!pAr8@e_Rf z_-J_i93OwI!(*3~@c7vPJpL0Oe>edif5yj(C&6QHe4KD1Jf4D&fs^6!Bz%1D6nOj) zA2cXkgJTp9e9;U(UWAWV;bZHm@VFiyx10`-+wn1S4m`&2F?~KfZo|j3E`-N(@bSir z;Bg;5XppPnn1|aj3$q$Chp_s&6|!1Hb_>6KF<&m_HQ7#G*V%qPlHp=}eDN}Pd<7q` zz7igPg^x?GhR2oo7`zr9!}u5-gvSl|cw`Gaeua;Z48!AN_}H)w9%ta=nGrmO@NxVo zJWj+1%`A7}r>k&|c_uy%o`A>W@bTpv;PEwl96be(WASnSP4IXJK33igj{$t(g|rdf zUyDaZM(@Q3&QuZYP+azW_(TyW7^EIiOgq}|BQ*C<MITy7Gw?^mpNHTN%%vX{e?Bh$ zJS_fvO8ohZ`13jV1C#zg;h$Zi&%>YSi}1J=&UUzTCi)lni2F`Yg?YdCn9g*k+Z-Dl zYj!#ikvntuO!mfHE7BL#B5`?z47a<i)g5itrpAYxZ44;~<JCm1GcwWc4jAW2JPJJz zT2(6>)o-8(&{U}LdyKZa%{JU6uw`^&=z6p5z5Rxpoyq3V_0XPe%U8>PreP&Ji@rAA z?GA2(mE%uN@e7~`F~^Fg+Y17(GQMcEd1G^Q=KNiI3%hXH(@by4m8V_0>D*0c&-4}| zp=ZuNz*N{}rN0tX`ZfG1#LwO#9u5Yv`tfYa$)+n-9|}bPt9OMzS|_Su>}q!NJdDML z!ov8M04(NW%jR!%Fcg)~S|LxQLL>vEY=8(GIRNNZnE8QVK8H=h6o=1*A~HC9&=?IP zgRy?*fUi574&lq$&Gc|uG`JLm4HnnuD0(N^L`(5@Y!-NX8@rhv-eQCMfMPd`1&T>i z%|>y37Et^eHVIRleq}bN4+g8+8u*_FV^2OE$M>-t>fyC$a&<U9evab!V{D?Oxckto zaQ92>hI+V*P3{Ad-Aooprd41zl8@&gxq4;n5jJ&GV(^n}F*smjvoq9gO?F!o<H<C= zdbO!%yE5tU{vErC9s$6{f&jb;R&P}*WV<SqQ_<qk7u2<d0MKet7XZv96tZ180uZQ> z?Yo1!SV?htFDN2IA=_8QW+zNGS)7?e=WmVOI1hhCGpifEPg9H~C0;R>!?x;idkULq zDUP1hH;$gmZk&gs*vvi**>1)P#M<XXX?`>E-F;QsN?dEH$Zr=p=NwqHqebNUnz(Yf zc7!+#A$53{W~?|OzP%aFKWMg_<3r71(~8n$6FwysTSzK6KJQ+<R9z68A{L&z>8y)p z6mrg6p_Z--WQ{p?h#c~5E=)eLU>va4jk%P(y*wpvEl<hlW++3^@!yZCnvRzjrlVBZ z2W-_nmy)k7PsvwRPRYB$1Ronys*%VG3schGw3bW3_m!vMdn%{kk<WKguo-<F#>P$2 zH)w>6zC~XW-DhgcRBtI<AKe&kbQ?3#p<rr`4nuqM!r|6X7c8}CiS8}#qS?4JgC5tP z?h09~;~y<O=!sW0M~5cH=wuTseBzi+4UUSL8iR8c8>osNZkV0F5=vT(TmTIK51`3u zTPj>b*L{9auKp>EQyJf86AODKnug_1!LSU+0xDWQ2yNHQrU@<U&Wk$g(NmE{djpLp z8$(^Zp|`QE-IyFPE$c~1!Uzu++{kIlm5svBf|>V!Y~uBnw#LCPFy0uQxr4S<Oto7x zBw)SejqxFHON=+hny_nBPE!Aigrv~Z-y<QnaHd6B#BY-#9;G587xklQ#TMy7SqHxW zP3Zv1?eLj#kf>-iLFak+=JWCKB7EF|j~(zhf4Atx`1vLH=)q%0^iq1hjGixtC-{i& zq%U{DGkOI+?#2hcG9{KT%Ro1~7Jnl$?f2q9GO0@^1erJ*yri_ccIG#N(jS6mWyyK; zJ4nw=_>(Jv1a+Tt$6<_W!kIMV!=SZo!2wDK^BU+p&xch|9((&9*%DQ+hN@S~s#7w0 zTqyCCjIIhT!X|zI|4;<tA=L$vdOuJ?gE*n&XE0X@lstl;bd>xYe<*^IUtmT;3BDpx zvOun21WGO^DtkuTKmqkmHQOqZPNY`eXgM4zMoJPJf<|sZaG|>%3h$+{Q^^4J3;RX3 zUhPQdicdr-#plAQS?GD?>3X}Lu9XVqCl)!zSsG54Zj{kj2E89((_4;%ABV~WyzXOD zDSI4FNqX;yBQ5PR2^1ShI+Gff-^_2$zMbn^lY^b+5NfQ05bnRF*`B#WmaH)H20t&| z`dk1+{JcCU?tV;=_=FFGw_hpG+b{EpnW^)od3$_5Z_Uo7;rRuA;|g;6bL^6(u&8<Y z(^P~L-<6BR<FiF#@Osd{o1?J(S67{Oc?nl_N}>KwY!Vek{ZqM;A^VsXkU#vt?R^c9 zWY<-mWLcK=FIm>FE&MbqX?j+(y*sn3wKUeOE$vG3dUke~owZ~<TAH4jH#6Pa)7{&z zdv`|i5*+-4sWG<k7y=cD6Dq;PlwBlL2$aF3@&h<=0-<mqfb#<ZV?rfWP*5?rD&INh z{=T1{_qumAlG!P#xBI<&&pr3tbI(2Z+;h$?j$=*+`K!W^cbq})O=plO#u|HuXN}ze zQEc;;mo+AevPP6-iqYcO<z$Kn3q#&<rnu8E#Y)(Pf53TcxMB?P-r*VI`ND+B%Mg2V zFof+{k{M1H$1Eo^e0yQYJI)M&VFn6Zs8t)tQCz96*P=?N+FXhA#fOLIiw_j0QC_}y zEC*ktb~4E#?=OyIP8Rv@!jN~IMIJOP((Z(~NFL^yNV^p+r7EF6J3O2GOkq0ZWs@gz zut{b|ldST&;)v#CmCqK2yyL9$fMJ!WdOie`h!c3I*d(rZ{Ey-J<g0~=l$TE)&%r0@ zy-YI6?-s{0CzJekVaORwGN3h4%mK1X9sq>hJN?+8+O;)ni```?EG{w@nLD_F4PQ6v zsepJ0Z&$W!v*@lYFaO>I{xvZeNtO)Ia505lF^;v3+|M8~Pg`C_+lV1=Tw!^pFnLuk zt*Ps9VM65{p@&l>j2ST)LX_}Kj@>(oqm)yeOc#cn5GPX%B6A8|awEu_4WTN_oz@yI zMr(DJYRzglj4wA4Fe`R=lwgK-Vfy4{hBOOE3Ns}7nB<PN;yC8yj(TCpJI)<<#<`=@ zYR5LapB|nqeylKI^0Gym$uyfS(77Z({Ah9Ha`M9u7lyp!{BVm{2ITZ7#t2^?o)NxO zm?C)@VXW_B;r1%Y0l!iltDGG0Zwf=s;D7<NHmmrFA~FC7tA1WC#qU}Psdo+W*L<|- zGL)A`?$0{z6eJYs?OEqlz+^}r@SDs4nL1#m8Zd|^-T!>-+F43*;3?M+7pAl#k=6co z6(&*M!FqFILh~q<r5lN{3W_6=a}M9nkTZwyWmMyD<-V7fTb&El&QeS|pB#QLXN%J? z=gH=S{RUHaC@GlVRUDz5gZgY?$O*xGgh6D^;7hK^-y);m?MPNeZzf*^E<>vBFBYaq z-kJPR-@!NiNlfVr#WBh``rX2iGe&=aHPu;`8H)ix*k$>?K|5lxkQHhuEH0OFaBD1N z!ejX_qU*(2KAT@Z^||Y=zKZ@lud>bCb_oIqh{<w?`of?CV9i87&mc0_mrMb3=~aYV zW;q^68>u~V|IfnYR#V363jeJzt+GeVAE<*#3Bx^!$J~@-9ZZOv-z$z{PLcCF{YUv_ z)FQskCxY)$6jLg0`hlX8EHUcW14J<;I`60-8En-34kwk4*A+)NCl6dx7;<9Sxr#w# z%7ja<bUf6LS<)S;9tVoW1apFC4i+X<UY?n`6g-pZT(!SA-Z@!kUt!2Q&N^@D$2xJ_ z^YZXavsjo!d70+vOTjcLZdcz`9OInqa;7lk9cPzPj9oZUC~x^I7sA@gYBxg6S9dkG zKz(v}zWI1zTIJ=N;{)<dM%R-|)klk?o|A#TzcAz-XP`I57>LtCFayPS=9h=(nO`hS zp1eHs<bXV5dz)mFUnq`kPB!_u!jN~IO?JoFB-58E#x;L7JlA}^Ftze>&B+0|CbRQN zCi>&z$me9DKP(J+$C+p}n~BI$u#xKaci+c`R*dfkh|9B?njM~loSrAy=Z(cN&&fWw z7l!<bW1n<CxtIWYc6jzVQkYbE1<;`Eliu?r`#f13^PKE+s4(OV_8Gv0YOSzh9vT3I zwFQ5ru<c59#9|?)$f2;fT(;ob;#prj>*PlY&yBo{efuuea33S^hX!RKYXtsY2JuQT z0^d4^%$WE;)e8L6h3Tw#%vynesxYzg4pq`4Sq)txV^BHXM}?(5`u``zvCJuNexm<K zzl?_9x5TL68%ATR&sT;Y`QI!~)11f4&nA?Yyd&@TIl1oqdU2d{^1+u2Lr$zaUt$n1 zpE3C1z6_IY4Zh~%Lo2;k0mS7|dXom4!T2WAApFh3gS?rOeZEl`@{Y4l(3gGU7U6xv zGtQpN#yIc1L;@$pD7?Ek(m7dXv@qlyXPMD7mg%fX7$)Xw>OT9-@SOAB!lcTpq?{Oz za}s?|E?LhP$2}(loh}S{#~J9&aR#z>(wKtt{ljz3hYQmuFV`fGy21REzkXZQwro3` zWR(vTM>r>|yuUEy9cPtNoK@0o6EU{=x#8L7XA9FRFWV%|!nxTdz4J*H`kCU$=VYPJ z6^5L_LIc<{tVu++YXg9=hM7+fs;XHm#5^z*7MIH~bFJKt=6dk|zru4OFGKIj^5B<@ zwt|Xc1G}03%RxEG+GqZpL1fxzUdCPfEtCPZ*9|M}sM(1Lqc?wI=*`x>0C9OXTgeC= zXVA)SuaZ*cuHsnblrnb|hMbTxw=sy9ZyP?c*a;E7SqazL-Hpm}tAUH{aIb1*sn$Wd zwpM2&#uZ0_-;fSj&lILo-Wffe(1$&)*rumRPB~m0)0~|0j>3?4oKtREM8sq29_jq> zJP{S9M_!&7-G(Q0pOT~BE{;>q(O)YJdB;cpZgN{sY#3w0;U|V?gijYHO<qQr?8^wL z-AnSsj}=ERCr|unVaPkq6K_c+T19OOV!ZL|!}G?M3zH}>Z%h^E4c*Nok9?^(nmKvo zR|-SkaUQvkqNQo&Xd@d-pL`MD9G*SCQJ6Y;+2hf^?2*;OBxn3paSU^E#$ObMyyKkl zU>4mZ?Z$Gg5l=9)`v-^CJx2lJ^6W_7J`j)Cz9zZl!Q!~)<dz2tL*8+2xrexA4apMM zdTZpny|`M5kUlZC$UHwhhny}<o4itF|F#^G>|c^AzP&hpIl1C^VaPkq73FlUkXcn* z!#(fV$l|V?2zkfjXM!IXo>$&qm|}T(<>&yslHThi2Yq*OtaEbEONAltI0xOvM;cIB zQ+KvMGdz!ct}spV^2j57dBpEmk_$dt9Iu>Q@R`Dpcbp4u_o)>Z6<-~m4Su&UQS!3E zcmXy@aS{0K;)vzsgWoC)dB^$S&h2d+H-2(xCG_<Gae0)`WCk<W0GiUdq+GbRIC44p z;WdRJ?>Ij^;Ka1xs;Wu^i+D&oe_1W!a^kV!dE?Q-M9M2ClDU{&-q@z2Nj{k@j%ZFk z*;^R$j`PXnHsll4EIV6fI6UJl6sB5U#z}@_6kwc0&y$=~DUNwgPI{p*<Q?avH#nTc z8<^M*_XmgPl#dmrN?uM$-WHL;DcrLpCu|nSEGH*?q%h<i=Y(AjCzurnC$t@7PK~j~ z7l&t!FBB$IUe-9&S4-Wtt4Ut@`QoVN<duI>81jzu%A453N(>&|R;AhAsF1qSZmz_5 z<bMy(BY#quJb8H}nR&?-ADLZD^2Q$(M=>XF{6S&JJI)(-_=HRH#JyWX?`ZA<h|9C1 zDfg8diLNDi;f~^{<>ZCi3Pav;UU)Ftz+L5?S`=2`4AWpCK~e)L+&dd|4R$xarFmv} z<~UrKPI(1J|1+2E`<mpIcNE7pC$~%&hMd7I12}G4-%oKp8~}v%K)qbPpSb$Hx`Y#A z=sI3F?)wUJU|#mQaThhYN19aBwvL_~gASN=^gPcXUI~t#*Q1k@Yt?Q{9ry=@X{*R& zLva6oVKU_%o-7|v%O`O3<X$D`@sAY8D(5`@p~8?8^Z1ht;^p)46zg`kw!EBr$nhV5 z&X6vhzgCzid6^)2Bc<qs4ioTK+q)z){JY}V<z$9`T^Mo(GYlY+txy*+GXRLVP#*w< z#X@d49{_~KLN1aY00d#tTj*`x+HEb;{nC}N2`wj#wk~d!>R-bR?=!Ed(-p}xPxLl# zp)$COTCSm{BJyatw&Fax4W+uBFoZAkVxxzPO$?|rTlEj3xhexZv(?+Yja*ft3ie%{ zaG_UgETJeD`Iu__<I(2LD~;9yiZIM*>tkD+w@YKVuFZXV!%}MvDY=)b-6}P>dG#Xy zb7QB~>Q<o8EVLS1_5Vv(*1v8}etmLl?EQ?}F(7q(^QNe_(15GelMAi$;g<dVRM==; z!0&5oaN6tQ3$AfmY*af{x{@0|uUl#@Hmhr>QvXf{bZad-6}n|UvUz=FaTVR`gw3rp zTbnmSdu%li+b6w+&FfkVb-0Zau~rvnuIg=Gzqm?QTSj4*`*EH6Y2LqnvDOt7&|9if z|JB!CbrtCM1^%bEdCg+G&E4DeDcpzt=jeI;L45OjT`%F$@%k8jZeGtlJkdGPMz?P1 z!m+&p2ltcc>RN;+H|Zx&c2@Aa{s>nc=TGi=eGk5Wq+Z4+hI$|W(_5&|fhww3t50ZT zzn32hi=i;F*clA^8|m)${q*q^eO&uGe5}&PFVn|8*Wu&Q*W=^)8}adZ`Y7Lok0<Ek zW4Gg@b~irWcRxN(2Ke|+`uK|n@G<rvKE6aBzfB*1{186=ri72Lm+|q}6Zp7!KRzZO z#mC;q@$uES;p4?a`1n5hSa~}>-uDzfYVX9yi!=DRIE#;ebOIlTPT}Jief+1>`1q0M z@i8}#kMBBzkF^Ru{&WE!zqo{tx3A!%Qpd+c10U~Q!^eFseEh~ad_3I4$7e3!WA}^r z_`{3%`26?a<Ax95;~x6>>Ibj7D(v+(UsIRaH3?c{HeQE3dp*o3!z8bT;<Cz2pi11l zT8%2<xgK+lotYou0r*IdS#S087^J#XC~e*vyXbyv^UkQfT5GPCWx_?}_C|LVGhy?_ z6U@R-Lx5~-eG(vOQ0sTlIDQr%AL(wre{1ue7&x8zp|e$gFFK(rP5PA{$f{I6qEmvq zwV$NguLVm;lY6(Vt&xyL-oxaz#CON>A+Qb>gr!pwxah4A$j=*)`wD`LJp8^$z^=o* z5d6ls2S$!Ra-FgV=x&-@4`OZ!pto)hDE*dNx2Feasy>5RDlp%+Jxs@(NiNdZZmUZ< zJzSroiT~pU?ql1-WpjtQWJ_Q4=>h#50sTu2wEiziq&O_Ohkjc=ekj>y%7s^618*Y; zFG5IVvQi3!<SCGg)DHk!{XGzQ0y2fuvq91=TrR9tlALEDIR#d!Uk8PUczpbc`w~gs zhaq$sNd0RhejOs7px>5=Z;H3Uc|z6QGH$&yRPWP}+k#udvgOn>*O<8V|D0BUdrbWY z`?Om&H(|H{N~l}^K?C671c1~;_a1$JjX>DGKbj9jJXgMp)PEs}$FVjERSpjXv5)Ng zqlW<hPq9V{{C8af_-XR+uhByNcd!aeGe<5#Gro-c6I$WFjul=Sm>sNvtaQNch<pQ$ z)c<BuxAcy|TH<XPv$V%RH<5bs0Mrxd#)-jz=aaA#Xr}&c(1N6`V?(#)W~Fo~RwhmB z%h0rjYAA<z|9#Tt-eD$7LcGCvmYT`I8-fi|1nnG7EIe625}D3i5`36|z5%MEkl>j( zt@8ryGn1D|cRdT;Rhmf5fWewbo6Ikfg8ZI$>Xx3pG@bG1^D4mCYcsly<3qKPh|Kc` z9IezF(DH?F2@#u{a2a#@eYAo21U3)?KQX6s!_P4T{vqvCUaR@6{tL8Oan|N(`fYhT zF+toDMK4U;1u{cGehE7u>CY4Kq49uh7gg*6{*Sb)`abNc1aM*j_5qvFR2RhGL+$!g z*pmr}iGH}H#^-sQaf&u~C$PB_Xpa|$X2RfH94i1=e*wEifqI}HR8qpy;=?>N8?^KM zuh@ACz(a!o6djaoH6G}%18V)Jmo(_f?Leo*Xt-Vf0wC4P*cl6^?<@{Z@RYNB8@%A* zd<gLC$FcL4Mt1jWgr_VfV9KuWJ8AD8G&Gn;@`Ldu**<`%AI0`x&`Id;E?1}dpt|(? z4zeO#4=aMeN^G`VSdJ2q=A7w~>|QcV{PH;sH=zm?fZKmF^Xq7%erHcNl-SB<G$bBT zE+rlUjQS5>(151<jgCVJGt{1|kVlK31kn1uu*wLH6FR($qJP5fIF@)2$H>I<n-?`i zq_+**dY=koWH}om+z~uTe*hr$AO9W=sqakBalq>m^mBk(|L@<cK-WL<0sM4Uj_c|7 zwkrouCq6MWhfgk$y9vm@|DZ-cVHFWVI6(NTb9mtb`+dNvfAqr&Sg(HkQ)C}2)t|?| z_4nXo^Tt^=m8BS~Rx7I&9^U#HDt*%rc~&X=mJI~XTQU&Xx4iRp-qOz3zWqcDGVKlR z+t0_|lGbV8^1AInrghuC<*{+z(%6`{V&B`mrW3JIS=so+-h55eCG&e}^Tu|kwbE*n zb(;)?s?g@^8r6lc!6w7a*RO<4nA*ejt@<d)vs&4_S=j^|t;H&qiOt(9r#sbV1p6_- zob0sL$s!1Id;J@)0r9Ux{jgJQY;9h9l)-#>YvIFNo3F>7N5BG!jXmbqYNfs#&FJd& zas1f4Nd_=*0lY2>tDVKwt@=U6Dy7zqb6g@gi2%1PY1M10{x<2)9VgkS8N?dt(S>)d zrX>aUUlHL$uz90)eS$&Y7h$1L!7qZWz<+3qM`H8ZZrFio{o)o(xvyh67Qu|FNJ$L8 zwRzh!Sa#`n;oZ&Jxg)j3uF&ygTR1XUYVi5VR{dFk-n{up>q3(z1=Wb8*ybBrof`S5 zG-MI0^g1;(w|PC8@+<1BWb?*OxD5A!W;a|XzSw*t4ta=<IKjafSGu*X*pxT#_Fquz zgc|i=^G^TWT9xD0>CKz`Hw+E|spkDX{`+d9;WQbmEEw4{s?EFn$~Z;oZnOoX<ST>h z?UnPj@WNtiDXf6Yl*zo*$2eVj&w=Z%x~jI;ZgsjrqqPE>uH2x0BC=s|RsX=*RC^<+ zMnSWE!wom!oG6L{ZKR&MA;90r$jD)S+-(KXYPAyv@E!sc!3$Ba5N@=ZOM%!v(MGV` zYcBFs)OBy*FH7NaP{H`rx|K>P3LDE~0-PG4pJlP|2GjD(+I&l67J&1VK?Hja1yQ$S zApzBA!*0MG1WxB`iy?jly(q-5cG$#hT?tyvV5Qv~je_d=Y7H}^)~Iziq!GgARM_ox znvn%c4;8EuS{s|vzW{k5B;ZTI!iF@;eWeP(#C)$U%ggdYb@42ah{|j2s9cLG3IU3K z51`g$l%j)1cypv8G#!ipmTf9*n8p@+OVwB-Ss<wB)IJwV6lRuf_iRDMSmj!Cxm8*o zc}d80Q4^>Z`P3OvV@U++Fqu_JJH)9rdS;mMKon&JhDQ|YI~CNL-Er`u4iHxlFhn>O z<dAWGGDcj|s6}1dBMi<_aAJ+~!3N#cFn};Q-)caDfjO`atb_r)uY>gfADA3y(eei! zCR$L`6(6sl1iZi`R4bssb;Ac#)}pJ+@snghryIJYJd&aYXezrhjietX>iSqP6|`&X zVIx>*b&&Qe3R=rSSY2FoJ8nS6csJI)>1n4EJ|UcDr<vrXX1iSNbgCPr`F&@`#!L%X zmtzc;tZE7q+31h^Q`#5jgJ6$?&p62gJ^W6CR39^=WSg1aGjS$(#Hl(KJP{j7zjFk_ zRxe}e!Bj3Ku%u#wX^d_@ntfgZs|lcPAgh^T+qSbM-G~yGuekXe0`PdNdlU!cA!6ja z;nLHcPOD=9sk1A!=$;Kb&9E^57-w^$AgYtA0bqG34O>6T4*(iKY4i3Y>YTQ$7p<+$ zYp{lG&D=0^BQ(D|%zL{gZPgo4Yi4eqc@qkJn<<bg(Nx*{XC_egEv9Vxc&fttXAYq7 z{ig7epy-X6Dtd6{ttdKTie`?BD*yP*6w2Ra%6p(ynI~qZQReRSGO!YG=iff_4itL5 zF0@tOg8Dr3I(pip{mh5xq??b~570R<fBTgA_Gji>2<1iI{+;Xfw-3;HC)fBr{jFF3 zX#ng(Ws7e^oh|8B={?W9B}*4-MK>&WT5AD0?O^(|x<udQX%ea&A?lL4pEslzUrRk? z)0O?Zz|tXPnNu~4Isej?bRe=5#S#~FtIckt>z;h_^x=0_=8nGi>G5Fh^r@pqp5`C@ zU@#<Izhtunjt4Xi(rkO<P(I=7YfKebusb0(Y>Qz8{U;^PHeqrZH-eBvYu~@^5?pTE zIHWFolUZ4YvKG}A54W0d7ArNv^I>CJzd3sRnG;l!bXuAI!WAW`=3%2kO8XS8Ls*Qo z5B?Mu-c|$J?deW0WQ|0#jw~`-afK>^{m*I_dXeHZakC1TNl8=THUerxq_?k*SPTNC ztJ?CU35&kU%8fHa0z+bha8M$INpHZi*^5YTj@qqmgOP()M9XX&dm_OHYw|L8Z9KS8 zYcy=XS-GP41J-X%Gc<~{0&*|{)?fr9kVZoN<8wED8J4jTS+4dPcnQ>ra?<65%43LC z(o}{1MZkPog3bNuLh4;?77}J!|3RM|de)l3{D`5!$apZKX)toeY6=FG=@?{(Ii@XC zhef6h?L|*wRo<2ipm&WZaWInFUaWK2I8kSORZCQX=c<if$QnRt<g~|A!BQ)XnxkE) z=gVP-$X;y*AvD=8ae(lW*5Zu@FPy3-gl4O-Wahlwz^kSN-UAk!S#0K6zM@wZuwCW{ zm@_WbJr;7+Y1Z{o*p+IIE~sBSg3h76KRwNqJQ9jG3hfW(o;)R7NqZV12D@Eg>o@!K zsbfcvW4fhI4|NCe7_k~aOyd8vc^jjZp1jx_tkT55Yt^{ve>NTCl_k?Jc1yv9)f!a( zP8ji=;+YD8z?lw~3}8!t4M>KaM9z2+)-bO+?vPN=>{K9@!QLF6p_(vK8~ZAnkfs%4 zO_`l+VU^yIT!I6jK$PR{5tdboa>9T{EKpkxZy4D9_E@Ge%M`sPI$TpWU>xpA*@0yM za`?-Eq?dtLs8prFAfd-y*Q*@w=?yWK@m@~{;(lx*kT%+%5ieQRxfm$MM>VyTQH#Fz zj}xJQ3A^2*jdR^BiGhQXtXBoJ2I_tMPi4m@o}V6xV~!qC`E3*#yETkW?&;WX(n?q# z@<}tD`gGh`lALu!(Ku`D=DJv7Y1lBRA)LAw!*V$|+-lG~rN?Ag6&2&97;+bR;U*Em zG7t1N@&f_|2A`|}xTwe7SrIdoC8r;bOpdRI8V)Rlyx_>bCo1tyntk&13zC{y)RP@n zturv|Sm82lzXEM*c9?d)Yc&ycYKMzw8(~7d%~&R#1R_`_7rQVz;&U8&VHUv$Sw7=z z@0dgMf_Zt?Q=&#~xrXHv_T(y*MyzvAmuayYdda;s>#Tzn4@6L+fgmF={(-p=(X?bl z>mrncW{9@3^$^%WVJTXz<!)lVGK>(E){$cf({emmM-0o-c(9>=Z_saREXy8py+9Mg zQ$tr)dSPHTk!CE=mY<#V*-qXoD}8*W7x^lygEJYF7JOyRcawx|E8T}%`;9i1klXzp zID^I#Y&!nnicaw@p;I6}B14(TUO|Ra8ms~|h_<kd1F0o%=j~{J-g9;K>1;u;YfaH0 zV5`8{TeyNyM`#w>9EoirOmC&N>QX3*#tEDRAAWA^6{KWj573ZHyd5FEu<?_fTOjQg zQTOcCW?f*mwHx`P+VDy2#&ivE?%SxX)rbe7@l8H@a5w(<)e$ykYN2fme-`R1%IHdX z<}eQ&1_9{m2i`GiJ(qqf4MNOje~T0bUaoOYOeRcNxkkuH?(ly<gEE_KgAwu;6mJW) z%Oy=e0z5jRDzy;Gir?jWtJaK5{_$XWWOw-`w2qDV7><-*Fv>%Yx~K~OPgImW6!}8b z^tn4VNuo1^=Ma42x}n~IGj5KX%C6uTj()6V&j@6L33m#;@sEfE9-D+!`^12|f@k5` zV`RFc!`QQt<r*9XRfFm{fxI7RYovG(^O5H%dE00fwGJ8>pBmZO_gVWoHLV+U?=+z? z$T;${h99a-f86*qe_~u{*_-Cie%twe1`3CZ9NURUESijp66*AZ^4U6zqDw%c23vuH z8pzj7w?~;#BXWrGMMlbHjPX=rxe8{gVJ_9wrTTNZZCctKj(%S;XUSC?eau<x9dVOu z$Wtf(x6O>;<o|jzsnp|#W}d|3`^@9S4oQ_eGE+slJL2WQYO27}%*T}v!6Jnvvmd}` zZr9)b?%n#^r|wtZdiCn9>>F@r{1l&MFuVdjb(ir9*w!U-mX3ByT&&z|Qp7KuFd^)C zRwSGoX=0P}p;E6`LpnBP9hnYDm%6L`-I0}1uN~r6PUCH&y&g$=`0kMcSlTsjr2)t! z`C_IjSLFurj{l8SY|E*%?N@dEBpyvJmBa^#-RPz#HA75KTC)_xZiLmd8-Q&99HR%P z!ej3)?JG|>5{XO0@Vw70jMMe=XbN{wQnC=Z97WR;<3XzjR|5U}z+>Zqi%Mz#c(8xW z;8Q~RiLq3fLd5a@+SMiU|C}C;VAUVhLp1G>H`Y0zJFyMAgx)I&-^o`QzWZNg_#Swb z;rr;T4BvyVaD08qikwN?5%}?gF#$mjc1oZTz6;w>_;Ml)>wG~G42-v%auWv*ys}7q z;8jQB?WFK4j>P+4btK+yVSdGtc=A<8;)&{ZqV26QL2(e0;}Xf@fkfNHb~GjgJ@s-w zRPi0fcpDNEejdWm&o2?adDaepdG56%3hta-a*=*_8|r_X@+KZf%pkleumRy>mF4Op zwlTEDF`GIVzAjWdD1ZnxoYPMsNKWEe*o9aBu+}12Ndt0Ptu=A-UkxOhj;v=mnW*-< zE$k?;kHpW$3LI*>t847thL_6AR}3m+!Mfe1J?YnkZMmw?J{AKC9pr=mFkDi&2F<XC zNLBpPz0m5Mjo|bLj~{ZrGsLMi+dbHM-~k7ZJlYIV_@7$<BZv~^;3y1ktu^>LMG^W# zrB&4?>}XY(?Jk6!JtlDh8l~Q``4?rI*4eKUvZGz62d_YaBJj1{4v3ITI5J1Vi=s<D z72GoS)B%nlJs08<fKjxTA*Cf5CxGPeMAPLx=FdD@hi|hULG!R0sCY;UT5|n5#8he9 zP(H|}qJh81JX+t=EYt*1M!7I)t7)ywBc}{`wJz~tuvTmKWHi_h%Hl*edcEUaH#`r* zu2$P&X?;AHr`<C4&J=GcmIC#IO#^4__IDRT-}I&)hKaQvth}gC!B^OS1H_~gTNRzH zwaF$uzkbHz(!>LYi+2T2A3uEJ$kV3`f>eMJVG{z+urk>PN=*lJMxlxHLS)Rq8`A_M zRz}<|1#02Bd65Bj^74S)e|f+jxIADV%?CDvga^5{A@r``$kQ3aZiF*xnDPWwOi7DK zU|wp1J&C!>Z5(Zn!RiBXFb%7cX7V&7XpfWL1&7giBjlrMU|mMUGKS1Y?7+gyk5~qa z`iSk{0mL$<q>tF-4j?vB&BJ69S(t$VNr+jIq=G5d5zX4XfsO39u*un2gq0cmx|zpd zC%;+VsU=^%nwt3#UR}$tRN&pU^oRrRK1m5F*=YWW5n~|#=g2aN;JHL@s`R)uSj>L| z=>pTk<zkrzxDXu(HfkoU?j(NdtOGpB^$*10sp@Vr0*QD!x3q@UkHhl1_?{7Hr+tHU z(IYB)Dm|8Mjcob4D3dF_Tt?j7ERM7KRq%u42(?7Ywq#UXX7ZhUwr!S(#*ZNL#uqxC z3vpyyK{k!<2GRyKpp7CcgN?)iOD^_0a1lq&-C76YSRXRu7kR^%DizA2QK_Jy$`;{A zP&px3ET^HAT!!os-ie|OHyaOj@8;wbk#n{J44i0xA6rq;?KJeG>4>V#EF9CP9ae}8 z<k+EdKY*rC;PJx=Me$=|%zEW2Xo(XagSjcr>XFm_w1bRa$c#KGRXW(jFQVcx_*h-5 zUKE;4`9u)3=)Ts6Pjsx6RfKTkO%R;jz5NfJ(lbaM0YWahtD@`6bE2Q6cp{k365Yi~ z6Q7i12B^;WRT=GOZN0*{EkgpA@;K#BP}U1Fv;E1y#m)+Ly)dm%ar$#+5QPa=&m*#f z@rm}DD6w+8yQ%_7s0v5>rJ|(*EuEM@D$n4&QFG>MajaA$38dm_8WQn?iM|gJP)Pk! z>tM2b!ZE~>>@C6t)V>`2fZRWnYD11yDdEQ~akU*tj6XZ0a5eD)T&bPM9#!*?Wyqum zNaI81K?ng|-)>E*7Z#(W+nsGGoArYd<Buo<L72J>=M4^%kZ?WSu%W-p;Zg|^s6+&H zXf5Z)vd@z5na8HGHT1$;c!TIXu{t=nRTd8(Y~Mq6F;;ETQ{NkgIozcu1bMYxp)6dq zo1YftU*S5kh+H#c+6gJn9hM=|vnD9!FdhXuhq{iW;T^pftc`g}iyj}^`|HOXULmtl zqcIK!Rl&?u-^MSK0FuyUaV_Glx!%UBA%llW)eRdVPaC+$u`NZoQ5Iy&AxU0LbZ47* zl)gxFbV?T1hO>z9mRMR4^D3x>Fu(Q6%aA~UP*Lc5x{&x*Q7XzVg>X?KF3WY}D`;T3 zT-{wIQwCHPNIDp9*1~GjXRZWo=0~`5BWLDEhz=uX$PsRTu$!tQdmKd;N>rBSjbsIb zi9>;DhaBYyw#05}^o18j$0((Y9Xm4noeek0pDNLg6--3j?Q}Bu_6cW_Ep@|AJ*ul( znM`eF9>ty5bSh7O3{LtJyFt|SRtm~z0(%BaACqUWK{vQ9kL-O34=>7Rg}zT-tRPU{ zl5QO1tOil-eMq1y?cGacqGm6TpS(asKjkeeBkfMqLT&|BOAVd1<*}WXQ$uYij~gqE z<w0sMO^;ciO^NIr$DC&6J(7TRF=ZRy^k=HbW0Y+QR=W@~*!C7E$pHz8Y9LeHsA)@X z$^-ODyAC6z7))-+J_YAI+XEGLqoFXemgkc4!XaQFQaKO;Vr|Jl0rE)E)+3Zp@1W!u zN_|+=Q>4~vY-lh_40_Pk^}@IgD=TtRQAz+dWh>oDof?pEOhaZvS0^KF@#+peRkkjE zBB`|uC*TXy*RIAo=3gH3a;%qTcJYdQH6V?7#K#+_B%H9a+5qj2kgXb4U6|LGeK&Dt zu(BQBRE?qk!0_bLG{i_q9KP_NB^^!`DE}PU=K1KNfn{z9vI~e|Tx@axR~|!;ZnnDV zGsL1y)YKZctn0x8)4?c~_EBF7Qo$~gJTAhx)08O>LC=)dS7i9&o+{9v!{TFQz=a## zQrJauGkjqtRhclPbUY)5emZ>9iAFt!Pr|1)3^#XCUawN@E!)`lIF?Sr(jVvfDH3$+ zUJ5gai>Zy+lc_VHVvedFvYIHv|C>PQGPQ$lJ`!gi)0CeB<q9pg8CIqxxRXRdi99T= zxb(kMnmP?jZQOiL6EQ$*ypt@!nXhT9JR0VdfxNDEd&pQfuODGKRxj;0N56q^vdx%< zmYWkDgoT`>^6lb46X$7J>U`gPk4^{T%b?Sk6@jTz+W|saMlIS<`VVa|_<m;pG0Ab> zZty#=T@;igu5@VW{lMa428agAk_Wp<2UoSN(K?Fv#xx8z5EaIGZJ@ggLuzjzg-Xr~ z5?}Hk5<`~t8KqO8%%_$}8|jfjJ)JmHz$~gcH1Th;HBx9Dsp}Nr!ExxH)tiYO>kW6$ z!B~+hyGyc-iq7@I@Ws$yS~1O{bDgd`U}95d7TCQzn1r--+KN+$N~G-Dof_V#TG;+$ z!+Ol~slvpUH)hXIE$MVB7P`Ah@GHhT;1*nL^<WHVHOf97NI0D|neWsdK;w`pg?Ph& zpjOO%<X$2bjc*-gMU8f}W?`2iR^%i%0=g~fiKU4rNgyxSzM*G2%oTEylBUAzR|=v( zSaGoCt&t*qVLL>RL-LerCD%CzGi`+lCuhTE36d&<{T{@(l$J(`H>Nkk31gM@#}b*x zRE@TYiL$TxjU6E;aZtRBL6FIvDy99-+s-O=F>z+)ONh+cd$A!i6UM3svGN8#A)sie z#hQ$Ph_!3FybJiOEzstQb~o^e3MhjPvW&spXbOo#Qf%w7uly)XMU=uAG7_$0`3OKJ zCR?R%w_OS87u2GeL@+ncB07ns3n5hjOK`5EUHDDLB%l?xs+i33ehQnb8!F3-lL^V1 z<~f~_Aw3iaM=m<XQz&pw3Ls_okbSG#e#@5I&hezsa~7P07_ll7+A;Zih)KAXk}Pb0 zP*%d2E@e&~v@L>8AoM|$*b|g}6!3L+ano;Ft{w7d7|`Sv;2?;KoJoih>~}AOIH-U! zPIziKWEf#w5#ehokRj!KE2ps-OFtcwD=8ltBr~)+VNXfy?U2~&aRvbO5*r9&Vi3pG zC&q()aOg>Wfq*Wk54KmkaQlTACuq()evI_1Vq)JiU>RJvaz#hOrIvPEbvov2CC(Ib z%EaamNW^CyR^zTXg?&-tyl{FgOs<{eD2XmVDcQ}KcOGN9>4;w$rx(LcD{@J1WxeQ# znNr&HbXY(!S<UwQ9B7$7tyd(Oy`lykN=x$oip`4d(^LjqJ2_gK!C-BZJ=u<L4A=m3 zlPmaQ@J$a$Iaz1x8@yPM`iuMH95T^Fp)!14ps-2W$9O<svsW^ih9zz1h|QI0m;e{~ z%V$$cfG2w6dixB_{P7<KJ?_e&II4qxWA{!Hn83$~Eaw+~-wXtqN)Vy3=^y#r=nlYk z;2ja5tHr8d*xjR$^rm8UND-ijWH;Ou&&YvX9l9>VlHJ|!1o-OKlS8|G>#;foT2F9R ztRv{WIbB{+-_rCmjeV^8*dr6+p8aEcCU>um?JZ62F3s*)bF5gpRt*25jmD~HG@9sY zOe15|c`K&mo~Meb%S>~RK1qt?mKa84SdD!N#_NogjhZGg?5K~PL4?=4{3ym~l+aXt z_yzFv7r<e$a-e16K>C5R>r^8%&AHyK8spP1(O)y#i8nqaz>9Is!iVg0g#XSi{oAwx zuQqoZXIM3U7z}J)Qm5=w_{PWVFq7C-Dep=&Lj50M3yU^MIZ!O#nO-ZJP4&MchHTkT zO%dLPCRtv?^8dZqzfU8Y<Y?DWL_d>lRDS?oYa`?b%iRY!ABrVPVR)wFNucJH7~MQ% z`u(_QcqFaVMLQ47M%CYzNP&bufZW`ooCp$Wey8}FA?t;p5^h+1um6d^qYKLZ)M^CS z`W%(h&j5#X2-$+?4&s=w^li}Y%-NdC*{S5up)HvnB-ugYm_girRAozt<aU)vA13-3 zl=uoK+$hDJ<-H+XD#dvRcehEctdnx>pP@Z*V1sN$HSPwskn|QGI=j3&2T%}cXUKC< zHQ^1gC9&SR?%4KM^Be6}4UXxwG`X`R(k@BsM}pD4ocwCkwXNV%ypZnE3!54BqA@zv zMtIcdaX2g>oAv{v78Ngp(ej8%#x0EEWJm+2yp(~rNvBPnrHw*uiMJDS)l@&kVw((x zFaFH9ECGC!)uVZ|fWr*-*3}fIf4$xqa_bVyUY2<24Y%fXfJ(d4ojQ|91D1fDK^lc< zH6mq}>}9E%Y<%G&PDtto{@R&>rmrbE@*}3UZ%3uM>UkP?i<O?n!~=TH63sMW>0icI zUdBDwl89T-vgSm-BbIJsOrlNh_Wk1HVJCOZyall(5622+IESlvln3~7t9xU0*i)1> zOjT_E%u@jUP^?&bFIANzGpA8ySFDPXyV6^wgQ*J7&0I)nBi%Nms%*@BKdO{sZ8%l5 zn3wict<9OAK&>~&YI&HclK*(-&rtIIekJv#TK{ME=BrWm7Qd_t@p%Kk<QSiO9?~&B zrBVIummbmID*N=eXD0Qxf4X0PyXLL>+Y3|r+tt(RTd)4Z0F6i?cue}YJ!9#Z#Q$aW zuipN5D7zLSj&j8csqh|s6BibiTv0>n%$qMR{o55Qq&6EbI+>@H1|-7Wcj_#l8*b-_ z3K{2wHb8)G9~?C2-?;R0MF*K+8mrLd4Y+Z=)159RV=5d{_)#8v^{ntiJleQIqss>< zWw#Bra9oLOfMu3bR4U?_mCrqd&_?muZ;8l;`BCl<-TR;dCq@y3Z#u3vN?b;s5|gB_ zjK=f9-&93^yP_Rrw~{>3G9)D}%F%#Tbi%7DmLYcxgVi0K9>0=e7nqaNmaH7gEXN?& zeLtl;_M#6iS=fP6B>P7nm_pcn@UbZQ=3?WI%U!a95X7_jTQSZ+5hD?9pq+|RkJxGE z#;%9+6>J05@pXi|k_(i+UkN-Q5tn9;zTANa83V-g+p&r5MEn5<YRI8gvsJ<M5KE<) zRfN|Cbv(FjlmZowIqXAG<Yl^lqyklR%^ng?q=Ociv173cR3quVPEYCYk|Lp-_twf} z3p6W}j#}hRk>*HBSdvVHMohQB$G~~9om4b+%Fl0q+?$MXP~0eWy)IEZm-f$^LX!a) z!-OSxeSoCXQO;?t#A7_Xx;xx|Fo1*-xLvT{T|=um8{qXo#rCPbSQR*(2gy37Y+Nx% zUA-#X%^>y^M=T@5vJM6n#Zd1;*lO>rHC8Rpu-nHS%p91u?x`x4xya%{jCdMmOTLU3 z&bRa$e!fB2>5z?Au0$3QN@+JJX&c2{d1=ZV=wY|lX~w|E0`+M1wK7@F<h}u3HC%U# z9SSau6jL#KZPE31n9(sYD)^fYl}1k@m<v6EFYEalrG|4O6-KRss)ilo6t1_C_o-c8 zY}DGW?<1oOzc85C`D=Ntx{j1kW4rkP|B*Fk7p;Vd*yXM`EE-v7XWWjT*cgFyDve{6 zpQ~_bjD7VAAzWbKxHbZ3g~hV0=f3LzcPSkeC&sY4B~Bg;VliaWmQH(C?(F^jdZN2X z;I6+pa?0UEpYU+qc^rUwohU6f;<6b_xyFNHohZ{vyH1p>6k!zj<ieW%2X$f;0i;|$ z^?3&S;5j}#nngqa2n&d_Vc+Uz$gVgWipX$SORc~}OFQBNx$$kU%ONi8j2R0pyqsoJ zaZwM;-If?wMTd9TUjs@oNAe6%!Sd&suAf9C?nsmAC1jU74a{+|(R0LGyb5FD0L(;V z5N9P|7bBb(ZecYLmpoKM>lbeKlDh|QxFN9hR)S==+BrCYRgAaVuXuZi_?ah~wcbe% z2tKFMxb;6EalLtb8hBXiA=Uq0@prl6@8U)n5nnjo0$KwD6BiHn&^&g<-zDiR6^+HV zB%-jeh5w4b3nhN`R+!`>=SoSq<$NppyL@VD;VS;SxK-M`XU;#NPI|uF2j7eP;-#!E ztNc0MJo5<3JsdBWep;vM?3sB2bsmh@@kU7L0IJ5JneRf4htg^!mQ__{VWy2L_or2X zvBC3R>CF5jihf()qS`6tr)GWyWp9m@)lMn&l6_Ks^^o=^`OG`?w?j|sZ(lvCzukRI zf4lFv{`PNAs&Bpe-EU|AlQ+fvPb5Vvf5PSD+BtKfo3h-ncZhN@Sv)_f^UP{rlaoh} zVI#@eWsj2YrKEL@7HjNQ$<L$OO0(LK7uZ23TvO6rT>9mQW!AxcplosCHt=H-5veLG zEM593!_p55XVkAYk-|cCfYZ|6a049?8@;Q7MwA_d<zQdC7?u-LF=-JaH&)+%BU+zt z4dYhgmN08_g2yQmrJ7cj1Vq9J5Zm+H^3JYb@A#GJh>b>Yx-+&T#w1}cqUeu<V+i@! zD}f)Wdv~UxqrDcT;t{L(UQ#+HEQ)b!qA|P;Wl7v_IP7pbG!hG<9u$=tDyQXe5UZgY zcI*(?VmOPu*=u7qT$|&inFYp-eP&eog^tn*IvEVJ$C*Z){My7|u-&ZLX1oWTHdlrl z24-a>jtw`4eE<V7k2g!-m{>%l16|1p{X8X^A9(s0-D6x0=AJwy0!Uo?ox_1~gr`$@ zHj8m23T?{WB+7oTE%y}A9^wAq26B1u=8<u+;$GYPZFzdf6*6Tlqb|PvxNM}l5Vab( ztb-1VRw*LDMY=?-<5U4RJ2OmW9Z5|06d4ZCcGe^M!CcD{%;QFzMsKYdjW=<pP8f|( zit)yg1Sf%uvb+&mW96u~jO&l-qU903X4)QyNYiYzCEB>Pm|&bGxi38Q(aDso;i-`s z03P4KokTD;aw&k_%*i6)o~t%`a?n#6vD8FH(;iZqVp(MNpu-gem~;X&^vVZZ%>eF^ z5?zdhVdbbqd{dEF5vCT#0J#OD#ZHZL4SM#9l>2IETX_sr7Z!~I3I^er4j{Y6$!Fv$ z6=DS><yUtA(f!)EWvPLLQWW=KO+f_iWVM52-w30zDFx_pM&pD(-`7o{E|!B;zSvlj z1}21)ri<VzR?gGWCrvC(9FW7gbkydoVTQg?)X;5bqpA4}a*6rYl(aTKr-+<|^MmbA zBDk2JEI~a|X%eX8^ye`MJ)q%$0c>6-B*lynS|qy+dP&B1dti|#Q05{X<>DkfKYRzI z6@|U95DV(<oRKMeZ<o@B!pvgtFR-E<E@5)L0qy-+xPur-5T}yvh*}(tu*8St7gAvG z4<ir}5|j>M>5>EmMMS=&A2ESoX;L{GD;<HwoZXhAT?2~XUs$azt|l9fRDxh+=RiLG zZm`rs$N3mIMC!<Hun~3*$2(o-=Da+kuA8HpR9GT}&VJs}B$-qaQZ>UY-^A&u=+AxB z*-x0DOCCA3eBysoVPLTOkn)jWd35hfPH!)cGAN~ZYQJ<QP*h57z?r@%zIGNvkx`H# zD+WykrR1>_96}iZ*qzz#9T3Q<H)D~@rKu2A9HY1gdkkzY5ExM%AeKd57>ZBxf)X*b zj)vj}DT0UCyMbJVYs)oAZW^vMW{zR(aWF==swamdo8vfOVZ&QO5AC2?2PdX0Nvc#5 z#2cd}Q*o`N4tKzE++=_pP0D-2K(++b;N(P-r-JN8NpmCN2yWwK;1rg{_4Pu43_Bz_ zNVA|B=zv6b=ABzVC<;K|)^LX1wt^AX9~c}<Z5eqJg{b+Ig9~EB1~d*tL<W59S6(n( zT4}TvO8qM?qvlIM8}VZzT{&Qoh$QMF@OH7WvzebVZM2^-afZ%uzE@J5>z`%(+-HyK z3QRrpXLRo<K5ct=Lb~9nGb@QRxB#f{t2zmFi;B`8RxdKRrO)F&t*WDBy(ipeB3C#h z+ew~0z|3}P^Nk7GPv3HvS+e@gcsqr`{J6z29+`Ya2!Jc%v^EK_C=(g9hblt49SO#X zw}J(vKY))@4S8bKIz|+hC~FmC5g?Bb9HTlg+^tt|#~}Rj^zRM&ZS^NRszt<*S(B+% zN6vWCNuhu_67S~xh<Z07laz7HC<km+Db<D4a_XHaiCP)u1Rf)L3B>0W`Kc4P$okPo zk_{(6A;WpN)N*GR29~aa2w1ahX$bmX5%)^)&MQux^5@YMPa|>&u~Uiar+Y*f7XFt2 zHwxF{-O5Uco3xOOY^}FOYplADsN~#ztl~lBB}*4cIYGA-VKZ&^AAEt9K*HTP%^K-E zB!bv?k`9ac+FfkIu|uhfm`YRKoR;-rGigxrm@hiea?QKcz|h3O)2*-iDD7$p4p2cQ zu}w&lMt~~Al7`BS+FKa326h%wW<nrikAyv}+qvDr+29G~9W7)veV}@0VHBQ}x+zFN z%|T4253Y1}uSs64wEkqxzQZmG0_!eV+}Chn309fNZALMJ<fl_V*pDrnCusDNbkdh7 zhqxSS2{u29eIuyqYsQd^5_};fv*qPr9+i_(-K{}LD4f(%%A_&FB$zve<$+h03lGm$ zw34PM{0v=lo6GqK>!>wL(w%W3u`-)NRJsM90H=kWCT`LrlbIEqNzNgjv?aM^U!J8_ z$&fFGh9njpu+z?WeT2`GL*<O*@2V%;@pz78chHO^XT3ct5y=i&*y-AbebZ*EO#T># zIemqp%9BmtnX`#+IOiB>-@(x*MiY~(hkf7d)2EIdJx)7G+*jR&)|STB2F>^hB{x7I zwM1ht2(|k_BZdTq-h>HvE)L2^aXWZ{pqXH7tYw4~ZFD9jO)9~apI(cw7u!U(h=((n zE=itfk_SFYtj}UGAxBQ>p~wAm;7_!^yxgV#qt)6n=O9+UC#}PXA?7@M@^vbIXeJYN zNL*@?$>Y9Mo6)wkpj>k2Orn46bAw$$^+l|qUGx#>3eM)0Ob3$d#;IVZS$n=lF+f0^ zuLZ-uI0`Av&DU6Y5I7Mv+@7DBqHDTnzAQ=&Cba4@&Rg8>mfCcth<Df?)O#zi3vzxL zp-m}j!}(BPFHH!nUbBP!X9HKNE`{r*MFfMcU^<sDgxHzVHSE|iJ2jRj^bVQ{U8%lU zAwaYyb!h)l+EW7LJ-Cw~*h?ApgNGbAw0}lH3z*Ar&)Sm=2Z(oCjYg@BKv^0{hOdaB ze^09R3}^cdqjB3naV!XW8Wt+e<OR^Fbpd6>%c8te?L|=y_qy3OfqHjodS7`G17V*^ zCvb^JS9dh(t(6ow6h!}>A_|Lm5rxDqEURZ>IU+GaOBL<zx}6@5I3hirUWDz6X3~pc zYtNBZ8+Vd)f<@es8+O#)NLURNGKY|ylhB%Un3LKklnjmaXi(4fKuloxYzMihzb>>D zn906iCX-<1+)<c=V5T$_s#%|^xMKh&<>`HDWjH6J7n`ZL;(}+Yq~tBpxu4LQtW5Rf zL`8W^i*xh!)QJiKQU_e_T14%hb0#X~aL1j*4V$!mQK8mv?w;#AchA|mtH=|ZyXTzA zdoDhCsmju%KY5uR$@x2J=dT$!l0NPqO>EnSn%K?*n*3b(oIkP8>4~k{R`lbsl}Cgq zjkjsqOmD^uxY=gx^tR9X<Ki+_3>R;PS2{o=KF4h%?i{yIr8DVs8~}F*L=2~pLdMQ= zT}YwQcaEN;+62%LN@j>Kxt^wai1#{F;|l&v)xhF2H4PZeSKDV%2j-T6j24@7lkSWa z5a_$*NHu8{DM(|G+O%ZTdN!%oEc(H{D$Olpsxjh9`J=|N^o``{2CeQY7|`l=&fShv z0lV6yJ5!vrx1cbb02dwdorh$27u(x;Iw_Cjx?7ms^p%lmDxH9cIgH6e=xx@JYlhW8 z3rd0{atPGcaUVQ4Y8%Va%v6JLCJc@e8K85S=5W?Q=I59%6qS+@VV@N)&5mgX6=7ll zqYUrh3iBGQKKbaQ+yh<aC;=^#9ojie*3N9==ydP^QW%orLT4|f(PQwWaYvjXsiE}~ zao|o`F|cQhEyRg3+f*psE15f#^NfgjQs61Aq`sq4aK>ohP#;6A525vIInyaVwuH33 zk--wn46A*Fouo6y#-M8u)8j^K7f>|3!Ub$6we6N~X`x<g?OxH6Bzhm0Jd!_9FQnDf zKwbi%ccCa9b3fpU8Ns(jUFbY!va`hX6?NwGv>~O#sdCa1BN3!XyHQ1?@F*STARQ*i z$(c0SNaphyN>u2aG?m}DD2`;+K`2m!%aHmZZJJY22T?6}wqZnau_1Mi*bzg1DLB#a zj7D5D3-bw>pN8H$zNBp>v9RF@1424$0C3kmR+BkI1Tb|hO>{jz#&c~bT+382Lu%!q zeS~TZ(4RIioGkHCDbY;?3mLW;q+weUOwN?S%85>re+D!O)iHJM$7w-j-tP+Lh!oN$ z2txxza)Lo)Z6X-z(9eh*C4-byi$fq34FpC(D1_X2hTj~<NeDE66)%+5S{n{^m3GwZ zl;&2ejxl3An6na+*E(KM4DTJ5s=>*ydN!D2H*zvq9LL5xgq*<1Q<~7DHoP4^78vp3 ztFF;i(>;XIb63nr&LxY3Ww13t#J=@el(rIv2Do@x2B1#LI_Qn*Nm;#c2~x9*K`CJi zv9J92<01<P0Iak7ut;H`;DJ4{uT(l2@C|TS#PH19kyG#X1anZ$<%&2Gc}fQXB*&_{ z2un^IDnZ3L)=Dl**)AeVR@jp_^#EcdTrxK}bBcB|V#liR+=SmGrYbd$(P}ls##CK^ z)tR1S4!}1LQ#Wj2m&lKt%bm?!rXpBXv`+z40;XtRXL-t|z?aP1c>oYh2h2M&+}T~$ zGhZ)F#yx}ZrQCXqF38+#bge_4rI4;K)?t<((v1|0Y2UL+8dRopO3oqpZh%UlA&AK* zs*p88Oo)<T6=&E$o5skTQD7M~t+C0E2CeLIs0a>hvW;$O{cbAQmR2-32?vckP8`C; zELAiV{ui24dqZX8(Y3+od?PcrZO(qpp|3f-l5<g*#ngXV$Q^!eGB|wd#L1IKk3Sp0 zTKW9Z<3~<B&(J7rW32^3GpeQVJgf^kgm<}7T|xF<*e9!N&Q=;CH#kkK3h&E>>f%}J zcMOse%B3-4!zD7Fat0*g-O(su*mnH2<fcI*-x8GW-!)tfpysCGN&UbO$h?6X!|jo` zFLdVe)6YG9{B-5mQ|~@~`UG|UxJ*83oc{W^4DfPW1$~+(sGfrWafc9`UhKj}?!>;( zw`P%p#8K|pmpBEt*%R-cdwTZ7b5F-H!>G~;zYH#8U{KhlUAG(Ia#zL?H#K&<;OGnB zXqYZ24T{aOlGV1N%ezndZSMjESU}_sEVNHMr4nH<<{tVRY^dKcUQ7@S<06vKt3@^O zMvX#nNWieJr2PU82?=}zsUH1x;WD|-E)g_T;tY{!Ko{K51r=yJXbekzXk5swW`OSr z_S?O+Us{I8mQ9DMdm~U4CYez6pc7Onn}o_ks*z12+!L>8!le-;*-0X`b|Y~}?2dr` zo}?KRK#W>~9X!H4@e1X*1lH8eG@3!V$<3NV5KS=m-z4$U=;nqPxV7~NX>Me?y9M-j z-Hh%?qM&cq($$8R5Zed`jW>x9Oy^YE>pn6UCW%9+@@z#@s&}bibkC_&R#Tcv3@_P~ z$G<Q0#MdL@{>u~*DVR+@?u!(Xj;B(`4ul4pTFerW!LnFSE$9teb}^6OG%5*T9?f57 znc>n}f7j$;#?IoSfoR^3N_zd&fD>dQ^gNnpq2^Isn)HC-07j{Nq)08}-iK(_QD>+f zQtl|_N42?vEh4MX<Bo%*;*q|$H^H3}2r3;5N2VoMJw=Dc4`sxsrs&V$qg8SbU+jNR zwqU2kc+6WTO@jmB<+OChXE2C2x=%&J7$enna*9+*>|Kz)6junh2{;VY*kr>Xf`eMG zb%USw+5;MPgE6lG<Me2L;tcl9k4>3J6Z9wnjC-8^f!Y+OCEX>6`;rjlQ4(yn4w%*h z8DPG~m5HxA$K!Mm1N7)Yb$;h!n!bW;13!}h@rEA*^<*ru?kZ^oUg5{W(|fe|*C+KZ za@3{T8Y1v6lo0j<dqcQ{ywP4G%Dm*(;=L5yOqzWnkRBP`%V1&#jB<CqOIFbfh(X4_ zfDBY{<6CMt4nuBBbf8L+W;M)kK37%aoUVLRO$)Jnp@V9r<<XZkgo`gU^%=k_e3{0B z3iwj?y6l?3RHv;5#+Y^({E8p)HxzbQKu>TwTf6`}&to7veP8A8iV>(hnGu$r=X3rN zU&$7#fJS;5g<amB9adXdU4k~~dM~U-Kpg*Qb7y;BGaYa?>qG`{HW|<L5ZD^@(j9f~ zhRzi(rT{9!>q~*!wkFk9t!M17gos8^78R1zfG@tX1?AarLyg*nYOOmHZj>f)v`-M| z4`^}$T;tJMDvh3t$6gSkWNhlRHlA!WWC){Jeqv?1Bkwd#F4tfuj*!HZedfw^wna-@ zVTXdxhCjB?(o7IufYF2eY&FjAHd;I?$p{6LpF|qfx-gr_?G&<9_;$Q({Ix|*Tja>- z#c*-zAklvGBozxMn2AR$VY$_{TzZ?U;;5%&qVHC*R+F_}FW-(emBDK3k1pUr<KR&) zb_rx&CtK!;oWlj@Ad8h?{;b^<oC?=)6CVU(GhD!7^;tzhC?rJ02C{Gli>t7aEy68F zAD2)(mSgiFwx?@bDtt(Vxe?;j7uV}G!+G)wvvY$A?h2k<g7X~7UYOCi4N%ogABLsK z>QYU|$=Y_51XFV*jnewC0pQ#tID5RH&nJkHlp#9}j=m1j+H_Un)CfD77-m8oM(Z&3 zDC=_%S$|iQ|D|rqn<jLC7Pl&2iqkY}^ERYrDb451X%mXynz9;KcS!tcLDtb0L>|Qs zOLUK}Lm|URqtqp(5x3TFP=s}99sU;^lVetWvc%QcxJPYbJg19AYVEZudET{K-9~L? z6~3h%N;6G)MJ%JG4vdEDi46{BRszX0=ri`Pmopt`1o-rfJHk}aQylW%K^^5XV;Akr z6Uvioh&a0{g#oEQ$>r0H{^N5$D(>A0%=J}iD7OA6X${ieW2)D4`($2^jXR!>=A8PP zwP;eT`=@rK8Jzq}g=iJ))YoV*u4HpL)5CPa@Lad_dincmd!O2^{JqXGus%TyOJUQ< z+Gi>2J--Ec2N_G-Kl#?bjfpek@U+e7N@4_kSpMsbPQ?mc%AVPt_Qgw@R2@z4Ddr#! zZJ|3XLOha)w7!GXNY*&T_DwO?h9G6nQnicscZD9tS_E9)$-qrwfs0EOwR=u|?M(7a z%6VNeTwsb50sSI|2U4HA14Yau@!QGUTX}61&eh%$=?jY&c+IsKSUDms=MfLjQPJoj z!r(JOnZDq*fW51SzShrkp1ZpGj9rSXeh%E(oz18uC(U`TTHUbl(P^HiHPb15np(~T zi~B~%Lr&T!3OItGu)9cAkjXPq)SzU0G?MgZyP+5D0h9rzdqTli_+uL;oj0C_mfFf6 zN3$!#8GgB^BrLoFo4J^=+;c%fGgi<sVM!-gr0A^99+wfjo`ZiP|J%c+N4fbJ94Prg z>Pv!5MjZxcU6;5ib~)juW4EQrGpXaCHk@N7W1yiOrD<B&Gm}_JL!f>4;`#33R-@G+ zx;P%55To?=@QGt5PE}4l`_$x9&z|yk7YszM^u5F6O|;GsDktd8Gj}0*=bcXezC@9G zXGSS)XlfBEOlquxwtMC=6urgI(V*VFZDy9zg!=Dv4$+e{t9XgIM;Ui2oNfo+8jYn8 zNh_V4J_^*?nRS$Yi{*ay9*k#MQH5XP>wEWYQ#g^yLDl}~%xBQlU1WAhM&qe6pPl&v z%8aL%Nsj<kHNQCXpHXwfgldVlORkVKdR8CQWcsbyH`4vTw>h2RVHR++cV9jG5WT-W z;pV0al&+qAD;2ocFW~rJs)AEj&%TQa-n8g=y{UJzSI>S2y}O4xtObs{e5!IUTs`~0 zsN6_aIcpPAHNJNB>^G>!4FpxTzv|65ubvHFgEtR2JqO!K8PBgrRoL~K*|(trXPymD z={&MuJFUO{v*-1<#=QQvaYldpP(^=x?V|qnl_mY{JuCX#dR>2eS3`e`*7UdiE&c85 z=k&L?_w=`abwPhS{G$H$&5QcmuYQmE)~kOza@pd>Ww`J7H!e%YTb@tINP{_8de5EL zo3yvscJ>y#k~g*$t%NN|6;3g`vV<hI>br^<<lMO0%aJn|(zP6`wA?dfA#<PA`LIem zR1FTdBsU@)-LXP@xBQSLhO@|}WeQ};=^N8hP|zzYZ-<pBMuep-;jjSN)QTe86N{-6 zCFvzI#5UMNmocIxl)uQ8y`!q5WDt>_0tpvjpDt>Pd$+S;chxvR!-~mA2r1pg`9Nnu z<-H8o7sGZpIC?@Zh+?E@t!RWRNT5g&$no*Qayg2S1WH^-J%bgT+F}1iGObCPECL~Y zBS3b`BhPxH%T*LzqOm0BGMG!4Jrqt<S=qAUE^f7j+5*rLE-d$&ZMdbCMh?|rVMm{# z4<o1JfiaUdsMd)(WWz5|zDQ}DuoQs3Pz;l9vrtdF%|=dSc#IKLM@m&*!ZZ;q+r>~z ztXHi=$n6ads2u@b;*Bn|2k8)K2vrlcstT3XV}A;RM4T=&44f(~FP5<~>H!=j{G5Jh ziGd*LC%%pb4@t}}0u+F|*2|V_oi%E^U6vri1LP(w$m;8g@NQuPyG(UvR9jnFT&ID< zbJhq-^8^rJQ4Je(x#I{gX^m=x>jw`|P3{q~SQLh5OX`qAHEuc2HZGL8%moA~Sp8}U zXa*rUc8lUAR~#?SZE>Kn0#Q&42685gx_hleA+d&-qlZ?pJ0oazItwl5(L9Agqq2rG ze_+a~JT*zT6xs}9)Z&ChaZ9uFkH(67(h=spsc~$a)p3KE<H^3mLHgPfKX>e~VkuJX zl_*j2l_B6L+=F0rq5fc)$Vwc6E8x5Ukwa=TVSvp9aTC;LJRpGjfn$%56_6KHO4cT; zo>>X)qdp7aG06|iDO=67@s<^}kEB%?2N(+-q?{5OrZ0ZB)%e<na5x|-loSYwr7ji> z=Pp!=z%;#SOY4B5G1ogs8X%m^f?o*V@(DWX)+>$0Oiw!S_qye7n9Wu7@+q9igq_21 zkLZHECLEq$ptA!6&`LYyXTz?PeG1P@&T_;%9~7kWWs*xzMo;oRqW+$Ti|ODu3^a#f z9E9}Sq6;3bQ>&M#h%>L7c^foJ*^t=IsF#Omx5C=v6Ccnz*<XFo=wx5P!|qnEw^087 Dv<Ox= diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree deleted file mode 100644 index 6addbae3328c58d148b5594bc9042811279dec9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5034 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 E0Rk78mjD0& diff --git a/docs/build/doctrees/modules.doctree b/docs/build/doctrees/modules.doctree deleted file mode 100644 index 8ed4f0e57d7a6494e2fb74e65e852bd26b2354ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 334144 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 z	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 Iy>0#f1zh=$IsgCw diff --git a/docs/genindex.html b/docs/genindex.html deleted file mode 100644 index a3ab65f..0000000 --- a/docs/genindex.html +++ /dev/null @@ -1,389 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="./"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>Index — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=12dfc556" /> - <script src="_static/documentation_options.js?v=cb255500"></script> - <script src="_static/doctools.js?v=888ff710"></script> - <script src="_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="#" /> - <link rel="search" title="Search" href="search.html" /> - - <link rel="stylesheet" href="_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - -<h1 id="index">Index</h1> - -<div class="genindex-jumpbox"> - <a href="#C"><strong>C</strong></a> - | <a href="#D"><strong>D</strong></a> - | <a href="#F"><strong>F</strong></a> - | <a href="#G"><strong>G</strong></a> - | <a href="#I"><strong>I</strong></a> - | <a href="#L"><strong>L</strong></a> - | <a href="#M"><strong>M</strong></a> - | <a href="#N"><strong>N</strong></a> - | <a href="#P"><strong>P</strong></a> - | <a href="#S"><strong>S</strong></a> - | <a href="#T"><strong>T</strong></a> - -</div> -<h2 id="C">C</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.utils.utils.compute_psnr">compute_psnr() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.load_cosar.cos2mat">cos2mat() (in module deepdespeckling.utils.load_cosar)</a> -</li> - </ul></td> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.utils.utils.create_empty_folder_in_directory">create_empty_folder_in_directory() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.utils.crop_image">crop_image() (in module deepdespeckling.utils.utils)</a> -</li> - </ul></td> -</tr></table> - -<h2 id="D">D</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li> - deepdespeckling - - <ul> - <li><a href="modules.html#module-deepdespeckling">module</a> -</li> - </ul></li> - <li> - deepdespeckling.denoiser - - <ul> - <li><a href="modules.html#module-deepdespeckling.denoiser">module</a> -</li> - </ul></li> - <li> - deepdespeckling.despeckling - - <ul> - <li><a href="modules.html#module-deepdespeckling.despeckling">module</a> -</li> - </ul></li> - <li> - deepdespeckling.merlin.merlin_denoiser - - <ul> - <li><a href="modules.html#module-deepdespeckling.merlin.merlin_denoiser">module</a> -</li> - </ul></li> - <li> - deepdespeckling.model - - <ul> - <li><a href="modules.html#module-deepdespeckling.model">module</a> -</li> - </ul></li> - <li> - deepdespeckling.sar2sar.sar2sar_denoiser - - <ul> - <li><a href="modules.html#module-deepdespeckling.sar2sar.sar2sar_denoiser">module</a> -</li> - </ul></li> - <li> - deepdespeckling.utils.load_cosar - - <ul> - <li><a href="modules.html#module-deepdespeckling.utils.load_cosar">module</a> -</li> - </ul></li> - <li> - deepdespeckling.utils.utils - - <ul> - <li><a href="modules.html#module-deepdespeckling.utils.utils">module</a> -</li> - </ul></li> - </ul></td> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.denoiser.Denoiser.denoise_image">denoise_image() (deepdespeckling.denoiser.Denoiser method)</a> - - <ul> - <li><a href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image">(deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser method)</a> -</li> - <li><a href="modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image">(deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser method)</a> -</li> - </ul></li> - <li><a href="modules.html#deepdespeckling.denoiser.Denoiser.denoise_image_kernel">denoise_image_kernel() (deepdespeckling.denoiser.Denoiser method)</a> - - <ul> - <li><a href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image_kernel">(deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser method)</a> -</li> - <li><a href="modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image_kernel">(deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser method)</a> -</li> - </ul></li> - <li><a href="modules.html#deepdespeckling.denoiser.Denoiser.denoise_images">denoise_images() (deepdespeckling.denoiser.Denoiser method)</a> - - <ul> - <li><a href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_images">(deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser method)</a> -</li> - <li><a href="modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_images">(deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser method)</a> -</li> - </ul></li> - <li><a href="modules.html#deepdespeckling.denoiser.Denoiser">Denoiser (class in deepdespeckling.denoiser)</a> -</li> - <li><a href="modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denormalize_sar_image">denormalize_sar_image() (deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser method)</a> - - <ul> - <li><a href="modules.html#deepdespeckling.utils.utils.denormalize_sar_image">(in module deepdespeckling.utils.utils)</a> -</li> - </ul></li> - <li><a href="modules.html#deepdespeckling.utils.utils.denormalize_sar_image_sar2sar">denormalize_sar_image_sar2sar() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.despeckling.despeckle">despeckle() (in module deepdespeckling.despeckling)</a> -</li> - <li><a href="modules.html#deepdespeckling.despeckling.despeckle_from_coordinates">despeckle_from_coordinates() (in module deepdespeckling.despeckling)</a> -</li> - <li><a href="modules.html#deepdespeckling.despeckling.despeckle_from_crop">despeckle_from_crop() (in module deepdespeckling.despeckling)</a> -</li> - </ul></td> -</tr></table> - -<h2 id="F">F</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.model.Model.forward">forward() (deepdespeckling.model.Model method)</a> -</li> - </ul></td> -</tr></table> - -<h2 id="G">G</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.utils.utils.get_cropping_coordinates">get_cropping_coordinates() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.utils.get_cropping_coordinates_from_file">get_cropping_coordinates_from_file() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.despeckling.get_denoiser">get_denoiser() (in module deepdespeckling.despeckling)</a> -</li> - </ul></td> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.denoiser.Denoiser.get_device">get_device() (deepdespeckling.denoiser.Denoiser method)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.utils.get_maximum_patch_size">get_maximum_patch_size() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.utils.get_maximum_patch_size_from_image_dimensions">get_maximum_patch_size_from_image_dimensions() (in module deepdespeckling.utils.utils)</a> -</li> - </ul></td> -</tr></table> - -<h2 id="I">I</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.init_model_weights_path">init_model_weights_path() (deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser method)</a> -</li> - </ul></td> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.denoiser.Denoiser.initialize_axis_range">initialize_axis_range() (deepdespeckling.denoiser.Denoiser method)</a> -</li> - </ul></td> -</tr></table> - -<h2 id="L">L</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.load_model">load_model() (deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser method)</a> - - <ul> - <li><a href="modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.load_model">(deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser method)</a> -</li> - </ul></li> - </ul></td> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.utils.utils.load_sar_image">load_sar_image() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.utils.load_sar_images">load_sar_images() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.load_cosar.load_tiff_image">load_tiff_image() (in module deepdespeckling.utils.load_cosar)</a> -</li> - </ul></td> -</tr></table> - -<h2 id="M">M</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser">MerlinDenoiser (class in deepdespeckling.merlin.merlin_denoiser)</a> -</li> - <li><a href="modules.html#deepdespeckling.model.Model">Model (class in deepdespeckling.model)</a> -</li> - <li> - module - - <ul> - <li><a href="modules.html#module-deepdespeckling">deepdespeckling</a> -</li> - <li><a href="modules.html#module-deepdespeckling.denoiser">deepdespeckling.denoiser</a> -</li> - <li><a href="modules.html#module-deepdespeckling.despeckling">deepdespeckling.despeckling</a> -</li> - <li><a href="modules.html#module-deepdespeckling.merlin.merlin_denoiser">deepdespeckling.merlin.merlin_denoiser</a> -</li> - <li><a href="modules.html#module-deepdespeckling.model">deepdespeckling.model</a> -</li> - <li><a href="modules.html#module-deepdespeckling.sar2sar.sar2sar_denoiser">deepdespeckling.sar2sar.sar2sar_denoiser</a> -</li> - <li><a href="modules.html#module-deepdespeckling.utils.load_cosar">deepdespeckling.utils.load_cosar</a> -</li> - <li><a href="modules.html#module-deepdespeckling.utils.utils">deepdespeckling.utils.utils</a> -</li> - </ul></li> - </ul></td> -</tr></table> - -<h2 id="N">N</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.utils.utils.normalize_sar_image">normalize_sar_image() (in module deepdespeckling.utils.utils)</a> -</li> - </ul></td> -</tr></table> - -<h2 id="P">P</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.utils.utils.preprocess_and_store_sar_images">preprocess_and_store_sar_images() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.utils.preprocess_and_store_sar_images_from_coordinates">preprocess_and_store_sar_images_from_coordinates() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.denoiser.Denoiser.preprocess_denoised_image">preprocess_denoised_image() (deepdespeckling.denoiser.Denoiser method)</a> - - <ul> - <li><a href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_denoised_image">(deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser method)</a> -</li> - </ul></li> - </ul></td> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.utils.utils.preprocess_image">preprocess_image() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_noisy_image">preprocess_noisy_image() (deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser method)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.utils.preprocess_sar_image_for_cropping">preprocess_sar_image_for_cropping() (in module deepdespeckling.utils.utils)</a> -</li> - </ul></td> -</tr></table> - -<h2 id="S">S</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser">Sar2SarDenoiser (class in deepdespeckling.sar2sar.sar2sar_denoiser)</a> -</li> - <li><a href="modules.html#deepdespeckling.denoiser.Denoiser.save_despeckled_images">save_despeckled_images() (deepdespeckling.denoiser.Denoiser method)</a> - - <ul> - <li><a href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.save_despeckled_images">(deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser method)</a> -</li> - <li><a href="modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.save_despeckled_images">(deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser method)</a> -</li> - </ul></li> - </ul></td> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.utils.utils.save_image_to_npy_and_png">save_image_to_npy_and_png() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.utils.save_image_to_png">save_image_to_png() (in module deepdespeckling.utils.utils)</a> -</li> - <li><a href="modules.html#deepdespeckling.utils.utils.symetrise_real_and_imaginary_parts">symetrise_real_and_imaginary_parts() (in module deepdespeckling.utils.utils)</a> -</li> - </ul></td> -</tr></table> - -<h2 id="T">T</h2> -<table style="width: 100%" class="indextable genindextable"><tr> - <td style="width: 33%; vertical-align: top;"><ul> - <li><a href="modules.html#deepdespeckling.model.Model.training">training (deepdespeckling.model.Model attribute)</a> -</li> - </ul></td> -</tr></table> - - - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="index.html">Documentation overview</a><ul> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 2b55371..0000000 --- a/docs/index.html +++ /dev/null @@ -1,172 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="./"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" /> - - <title>Welcome to deepdespeckling's documentation! — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=12dfc556" /> - <script src="_static/documentation_options.js?v=cb255500"></script> - <script src="_static/doctools.js?v=888ff710"></script> - <script src="_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="genindex.html" /> - <link rel="search" title="Search" href="search.html" /> - <link rel="next" title="deepdespeckling" href="modules.html" /> - - <link rel="stylesheet" href="_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <section id="welcome-to-deepdespeckling-s-documentation"> -<h1>Welcome to deepdespeckling's documentation!<a class="headerlink" href="#welcome-to-deepdespeckling-s-documentation" title="Link to this heading">¶</a></h1> -<div class="toctree-wrapper compound"> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="modules.html">deepdespeckling</a><ul> -<li class="toctree-l2"><a class="reference internal" href="modules.html#module-deepdespeckling.denoiser">denoiser</a><ul> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.denoiser.Denoiser"><code class="docutils literal notranslate"><span class="pre">Denoiser</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="modules.html#despeckling">despeckling</a><ul> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.despeckling.despeckle"><code class="docutils literal notranslate"><span class="pre">despeckle()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.despeckling.despeckle_from_coordinates"><code class="docutils literal notranslate"><span class="pre">despeckle_from_coordinates()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.despeckling.despeckle_from_crop"><code class="docutils literal notranslate"><span class="pre">despeckle_from_crop()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.despeckling.get_denoiser"><code class="docutils literal notranslate"><span class="pre">get_denoiser()</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="modules.html#module-deepdespeckling.model">model</a><ul> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.model.Model"><code class="docutils literal notranslate"><span class="pre">Model</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="modules.html#merlin-denoiser">merlin_denoiser</a><ul> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser"><code class="docutils literal notranslate"><span class="pre">MerlinDenoiser</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="modules.html#sar2sar-denoiser">sar2sar_denoiser</a><ul> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser"><code class="docutils literal notranslate"><span class="pre">Sar2SarDenoiser</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="modules.html#module-deepdespeckling.utils.utils">utils</a><ul> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.compute_psnr"><code class="docutils literal notranslate"><span class="pre">compute_psnr()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.create_empty_folder_in_directory"><code class="docutils literal notranslate"><span class="pre">create_empty_folder_in_directory()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.crop_image"><code class="docutils literal notranslate"><span class="pre">crop_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.denormalize_sar_image"><code class="docutils literal notranslate"><span class="pre">denormalize_sar_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.denormalize_sar_image_sar2sar"><code class="docutils literal notranslate"><span class="pre">denormalize_sar_image_sar2sar()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.get_cropping_coordinates"><code class="docutils literal notranslate"><span class="pre">get_cropping_coordinates()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.get_cropping_coordinates_from_file"><code class="docutils literal notranslate"><span class="pre">get_cropping_coordinates_from_file()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.get_maximum_patch_size"><code class="docutils literal notranslate"><span class="pre">get_maximum_patch_size()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.get_maximum_patch_size_from_image_dimensions"><code class="docutils literal notranslate"><span class="pre">get_maximum_patch_size_from_image_dimensions()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.load_sar_image"><code class="docutils literal notranslate"><span class="pre">load_sar_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.load_sar_images"><code class="docutils literal notranslate"><span class="pre">load_sar_images()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.normalize_sar_image"><code class="docutils literal notranslate"><span class="pre">normalize_sar_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.preprocess_and_store_sar_images"><code class="docutils literal notranslate"><span class="pre">preprocess_and_store_sar_images()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.preprocess_and_store_sar_images_from_coordinates"><code class="docutils literal notranslate"><span class="pre">preprocess_and_store_sar_images_from_coordinates()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.preprocess_image"><code class="docutils literal notranslate"><span class="pre">preprocess_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.preprocess_sar_image_for_cropping"><code class="docutils literal notranslate"><span class="pre">preprocess_sar_image_for_cropping()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.save_image_to_npy_and_png"><code class="docutils literal notranslate"><span class="pre">save_image_to_npy_and_png()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.save_image_to_png"><code class="docutils literal notranslate"><span class="pre">save_image_to_png()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.utils.symetrise_real_and_imaginary_parts"><code class="docutils literal notranslate"><span class="pre">symetrise_real_and_imaginary_parts()</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="modules.html#load-cosar">load_cosar</a><ul> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.load_cosar.cos2mat"><code class="docutils literal notranslate"><span class="pre">cos2mat()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="modules.html#deepdespeckling.utils.load_cosar.load_tiff_image"><code class="docutils literal notranslate"><span class="pre">load_tiff_image()</span></code></a></li> -</ul> -</li> -</ul> -</li> -</ul> -</div> -</section> -<section id="indices-and-tables"> -<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Link to this heading">¶</a></h1> -<ul class="simple"> -<li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li> -<li><p><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></p></li> -<li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li> -</ul> -</section> - - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="#">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="#">Documentation overview</a><ul> - <li>Next: <a href="modules.html" title="next chapter">deepdespeckling</a></li> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - | - <a href="_sources/index.rst.txt" - rel="nofollow">Page source</a> - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 747ffb7..0000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "" goto help - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/modules.html b/docs/modules.html deleted file mode 100644 index 5dc21f2..0000000 --- a/docs/modules.html +++ /dev/null @@ -1,1033 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="./"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" /> - - <title>deepdespeckling — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=12dfc556" /> - <script src="_static/documentation_options.js?v=cb255500"></script> - <script src="_static/doctools.js?v=888ff710"></script> - <script src="_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="genindex.html" /> - <link rel="search" title="Search" href="search.html" /> - <link rel="prev" title="Welcome to deepdespeckling's documentation!" href="index.html" /> - - <link rel="stylesheet" href="_static/custom.css" type="text/css" /> - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <div class="toctree-wrapper compound"> -</div> -<section id="module-deepdespeckling"> -<span id="deepdespeckling"></span><h1>deepdespeckling<a class="headerlink" href="#module-deepdespeckling" title="Link to this heading">¶</a></h1> -<section id="module-deepdespeckling.denoiser"> -<span id="denoiser"></span><h2>denoiser<a class="headerlink" href="#module-deepdespeckling.denoiser" title="Link to this heading">¶</a></h2> -<dl class="py class"> -<dt class="sig sig-object py" id="deepdespeckling.denoiser.Denoiser"> -<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">deepdespeckling.denoiser.</span></span><span class="sig-name descname"><span class="pre">Denoiser</span></span><a class="reference internal" href="_modules/deepdespeckling/denoiser.html#Denoiser"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.denoiser.Denoiser" title="Link to this definition">¶</a></dt> -<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p> -<p>Class to share parameters beyond denoising functions</p> -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.denoiser.Denoiser.denoise_image"> -<span class="sig-name descname"><span class="pre">denoise_image</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/denoiser.html#Denoiser.denoise_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.denoiser.Denoiser.denoise_image" title="Link to this definition">¶</a></dt> -<dd></dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.denoiser.Denoiser.denoise_image_kernel"> -<span class="sig-name descname"><span class="pre">denoise_image_kernel</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/denoiser.html#Denoiser.denoise_image_kernel"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.denoiser.Denoiser.denoise_image_kernel" title="Link to this definition">¶</a></dt> -<dd></dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.denoiser.Denoiser.denoise_images"> -<span class="sig-name descname"><span class="pre">denoise_images</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/denoiser.html#Denoiser.denoise_images"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.denoiser.Denoiser.denoise_images" title="Link to this definition">¶</a></dt> -<dd></dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.denoiser.Denoiser.get_device"> -<span class="sig-name descname"><span class="pre">get_device</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="reference internal" href="_modules/deepdespeckling/denoiser.html#Denoiser.get_device"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.denoiser.Denoiser.get_device" title="Link to this definition">¶</a></dt> -<dd><p>Get torch device to use depending on gpu's availability</p> -<dl class="field-list simple"> -<dt class="field-odd">Returns<span class="colon">:</span></dt> -<dd class="field-odd"><p>device to be used by torch</p> -</dd> -<dt class="field-even">Return type<span class="colon">:</span></dt> -<dd class="field-even"><p>device (str)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.denoiser.Denoiser.initialize_axis_range"> -<span class="sig-name descname"><span class="pre">initialize_axis_range</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image_axis_dim</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stride_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">list</span></span></span><a class="reference internal" href="_modules/deepdespeckling/denoiser.html#Denoiser.initialize_axis_range"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.denoiser.Denoiser.initialize_axis_range" title="Link to this definition">¶</a></dt> -<dd><p>Initialize the convolution range for x or y axis</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>image_axis_dim</strong> (<em>int</em>) -- axis size</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- patch size</p></li> -<li><p><strong>stride_size</strong> (<em>int</em>) -- stride size</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>pixel borders of each convolution</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>axis_range (list)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.denoiser.Denoiser.preprocess_denoised_image"> -<span class="sig-name descname"><span class="pre">preprocess_denoised_image</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/denoiser.html#Denoiser.preprocess_denoised_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.denoiser.Denoiser.preprocess_denoised_image" title="Link to this definition">¶</a></dt> -<dd></dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.denoiser.Denoiser.save_despeckled_images"> -<span class="sig-name descname"><span class="pre">save_despeckled_images</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/denoiser.html#Denoiser.save_despeckled_images"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.denoiser.Denoiser.save_despeckled_images" title="Link to this definition">¶</a></dt> -<dd></dd></dl> - -</dd></dl> - -</section> -<section id="despeckling"> -<h2>despeckling<a class="headerlink" href="#despeckling" title="Link to this heading">¶</a></h2> -<dl class="py function" id="module-deepdespeckling.despeckling"> -<dt class="sig sig-object py" id="deepdespeckling.despeckling.despeckle"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.despeckling.</span></span><span class="sig-name descname"><span class="pre">despeckle</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sar_images_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">destination_directory_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">'spotlight'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">256</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stride_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">254</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">symetrise</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/despeckling.html#despeckle"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.despeckling.despeckle" title="Link to this definition">¶</a></dt> -<dd><p>Despeckle coSAR images using trained MERLIN (spotlight or stripmap weights) or SAR2SAR</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>sar_images_path</strong> (<em>str</em>) -- path of sar images</p></li> -<li><p><strong>destination_directory_path</strong> (<em>str</em>) -- path of folder in which results will be stored</p></li> -<li><p><strong>model_name</strong> (<em>str</em>) -- model name, either "spotlight" or "stripmap" to select MERLIN model on the -right cosar image format or "sar2sar" for SAR2SAR model. Default to "spotlight"</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- patch size. Defaults to constant PATCH_SIZE.</p></li> -<li><p><strong>stride_size</strong> (<em>int</em>) -- stride size. Defaults to constant STRIDE_SIZE.</p></li> -<li><p><strong>symetrise</strong> (<em>bool</em>) -- if using spotlight or stripmap model, if True, will symetrise the real and -imaginary parts of the noisy image. Defaults to True</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.despeckling.despeckle_from_coordinates"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.despeckling.</span></span><span class="sig-name descname"><span class="pre">despeckle_from_coordinates</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sar_images_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">coordinates_dict</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">dict</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">destination_directory_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">'spotlight'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">256</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stride_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">254</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">symetrise</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/despeckling.html#despeckle_from_coordinates"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.despeckling.despeckle_from_coordinates" title="Link to this definition">¶</a></dt> -<dd><p>Despeckle specified area with coordinates in coSAR images using trained MERLIN (spotlight or stripmap weights)</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>sar_images_path</strong> (<em>str</em>) -- path of sar images</p></li> -<li><p><strong>coordinates_dict</strong> (<em>dict</em>) -- dictionary containing pixel boundaries of the area to despeckle (x_start, x_end, y_start, y_end)</p></li> -<li><p><strong>destination_directory_path</strong> (<em>str</em>) -- path of folder in which results will be stored</p></li> -<li><p><strong>model_name</strong> (<em>str</em>) -- model name, either "spotlight" or "stripmap" to select MERLIN model on the -right cosar image format or "sar2sar" for SAR2SAR model. Default to "spotlight"</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- patch size. Defaults to constant PATCH_SIZE.</p></li> -<li><p><strong>stride_size</strong> (<em>int</em>) -- stride size. Defaults to constant STRIDE_SIZE.</p></li> -<li><p><strong>symetrise</strong> (<em>bool</em>) -- if using spotlight or stripmap model, if True, will symetrise the real and -imaginary parts of the noisy image. Defaults to True</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.despeckling.despeckle_from_crop"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.despeckling.</span></span><span class="sig-name descname"><span class="pre">despeckle_from_crop</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sar_images_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">destination_directory_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">'spotlight'</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">256</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stride_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">254</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">fixed</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">symetrise</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/despeckling.html#despeckle_from_crop"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.despeckling.despeckle_from_crop" title="Link to this definition">¶</a></dt> -<dd><p>Despeckle specified area with an integrated cropping tool (made with OpenCV) in coSAR images using trained MERLIN (spotlight or stripmap weights)</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>sar_images_path</strong> (<em>str</em>) -- path of sar images</p></li> -<li><p><strong>destination_directory_path</strong> (<em>str</em>) -- path of folder in which results will be stored</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- patch size. Defaults to constant PATCH_SIZE.</p></li> -<li><p><strong>stride_size</strong> (<em>int</em>) -- stride size. Defaults to constant STRIDE_SIZE.</p></li> -<li><p><strong>model_name</strong> (<em>str</em>) -- model name, either "spotlight" or "stripmap" to select MERLIN model on the -right cosar image format or "sar2sar" for SAR2SAR model. Default to "spotlight"</p></li> -<li><p><strong>fixed</strong> (<em>bool</em>) -- If True, crop size is limited to 256*256. Defaults to True</p></li> -<li><p><strong>symetrise</strong> (<em>bool</em>) -- if using spotlight or stripmap model, if True, will symetrise the real and -imaginary parts of the noisy image. Defaults to True</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.despeckling.get_denoiser"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.despeckling.</span></span><span class="sig-name descname"><span class="pre">get_denoiser</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">model_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">symetrise</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#deepdespeckling.denoiser.Denoiser" title="deepdespeckling.denoiser.Denoiser"><span class="pre">Denoiser</span></a></span></span><a class="reference internal" href="_modules/deepdespeckling/despeckling.html#get_denoiser"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.despeckling.get_denoiser" title="Link to this definition">¶</a></dt> -<dd><p>Get the right denoiser object from the model name</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>model_name</strong> (<em>str</em>) -- model name to be use for despeckling</p></li> -<li><p><strong>symetrise</strong> (<em>bool</em>) -- if using spotlight or stripmap model, if True, will symetrise the real and -imaginary parts of the noisy image. Defaults to True</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>the right denoiser, Sar2SarDenoiser or MerlinDenoiser</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>denoiser (<a class="reference internal" href="#deepdespeckling.denoiser.Denoiser" title="deepdespeckling.denoiser.Denoiser">Denoiser</a>)</p> -</dd> -</dl> -</dd></dl> - -</section> -<section id="module-deepdespeckling.model"> -<span id="model"></span><h2>model<a class="headerlink" href="#module-deepdespeckling.model" title="Link to this heading">¶</a></h2> -<dl class="py class"> -<dt class="sig sig-object py" id="deepdespeckling.model.Model"> -<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">deepdespeckling.model.</span></span><span class="sig-name descname"><span class="pre">Model</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">device</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">height</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">width</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/model.html#Model"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.model.Model" title="Link to this definition">¶</a></dt> -<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Module</span></code></p> -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.model.Model.forward"> -<span class="sig-name descname"><span class="pre">forward</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">x</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/model.html#Model.forward"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.model.Model.forward" title="Link to this definition">¶</a></dt> -<dd><p>Defines a class for an autoencoder algorithm for an object (image) x</p> -<p>An autoencoder is a specific type of feedforward neural networks where the -input is the same as the -output. It compresses the input into a lower-dimensional code and then -reconstruct the output from this representattion. It is a dimensionality -reduction algorithm</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>x</strong> (<em>np.array</em>) -- </p></li> -<li><p><strong>image</strong> (<em>a numpy array containing</em>) -- </p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p><ul class="simple"> -<li><p><strong>x-n</strong> (<em>np.array</em>)</p></li> -<li><p><em>a numpy array containing the denoised image i.e the image itself minus the noise</em></p></li> -</ul> -</p> -</dd> -</dl> -</dd></dl> - -<dl class="py attribute"> -<dt class="sig sig-object py" id="deepdespeckling.model.Model.training"> -<span class="sig-name descname"><span class="pre">training</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">bool</span></em><a class="headerlink" href="#deepdespeckling.model.Model.training" title="Link to this definition">¶</a></dt> -<dd></dd></dl> - -</dd></dl> - -</section> -<section id="merlin-denoiser"> -<h2>merlin_denoiser<a class="headerlink" href="#merlin-denoiser" title="Link to this heading">¶</a></h2> -<dl class="py class" id="module-deepdespeckling.merlin.merlin_denoiser"> -<dt class="sig sig-object py" id="deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser"> -<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">deepdespeckling.merlin.merlin_denoiser.</span></span><span class="sig-name descname"><span class="pre">MerlinDenoiser</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">model_name</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">symetrise</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">params</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/merlin/merlin_denoiser.html#MerlinDenoiser"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser" title="Link to this definition">¶</a></dt> -<dd><p>Bases: <a class="reference internal" href="#deepdespeckling.denoiser.Denoiser" title="deepdespeckling.denoiser.Denoiser"><code class="xref py py-class docutils literal notranslate"><span class="pre">Denoiser</span></code></a></p> -<p>Class to share parameters beyond denoising functions</p> -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image"> -<span class="sig-name descname"><span class="pre">denoise_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">noisy_image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stride_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">dict</span></span></span><a class="reference internal" href="_modules/deepdespeckling/merlin/merlin_denoiser.html#MerlinDenoiser.denoise_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image" title="Link to this definition">¶</a></dt> -<dd><p>Preprocess and denoise a coSAR image using given model weights</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>noisy_image</strong> (<em>numpy array</em>) -- numpy array containing the noisy image to despeckle</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- size of the patch of the convolution</p></li> -<li><p><strong>stride_size</strong> (<em>int</em>) -- number of pixels between one convolution to the next</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>noisy and denoised images</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>despeckled_image (dict)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image_kernel"> -<span class="sig-name descname"><span class="pre">denoise_image_kernel</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">noisy_image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">tensor</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">denoised_image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">x</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">y</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#deepdespeckling.model.Model" title="deepdespeckling.model.Model"><span class="pre">Model</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">normalisation_kernel</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/merlin/merlin_denoiser.html#MerlinDenoiser.denoise_image_kernel"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image_kernel" title="Link to this definition">¶</a></dt> -<dd><p>Denoise a subpart of a given symetrised noisy image delimited by x, y and patch_size using a given model</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>noisy_image</strong> (<em>torch tensor</em>) -- symetrised noisy image to denoise</p></li> -<li><p><strong>denoised_image</strong> (<em>numpy array</em>) -- symetrised partially denoised image</p></li> -<li><p><strong>x</strong> (<em>int</em>) -- x coordinate of current kernel to denoise</p></li> -<li><p><strong>y</strong> (<em>int</em>) -- y coordinate of current kernel to denoise</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- patch size</p></li> -<li><p><strong>model</strong> (<a class="reference internal" href="#deepdespeckling.model.Model" title="deepdespeckling.model.Model"><em>Model</em></a>) -- trained model with loaded weights</p></li> -<li><p><strong>normalisation_kernel</strong> (<em>bool</em><em>, </em><em>optional</em>) -- Determine if. Defaults to False.</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>image denoised in the given coordinates and the ones already iterated</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>denoised_image (numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_images"> -<span class="sig-name descname"><span class="pre">denoise_images</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">images_to_denoise_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">list</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">save_dir</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stride_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/merlin/merlin_denoiser.html#MerlinDenoiser.denoise_images"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_images" title="Link to this definition">¶</a></dt> -<dd><p>Iterate over a directory of coSAR images and store the denoised images in a directory</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>images_to_denoise_path</strong> (<em>list</em>) -- a list of paths of npy images to denoise</p></li> -<li><p><strong>save_dir</strong> (<em>str</em>) -- repository to save sar images, real images and noisy images</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- size of the patch of the convolution</p></li> -<li><p><strong>stride_size</strong> (<em>int</em>) -- number of pixels between one convolution to the next</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.init_model_weights_path"> -<span class="sig-name descname"><span class="pre">init_model_weights_path</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="reference internal" href="_modules/deepdespeckling/merlin/merlin_denoiser.html#MerlinDenoiser.init_model_weights_path"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.init_model_weights_path" title="Link to this definition">¶</a></dt> -<dd><p>Get model weights path from model name</p> -<dl class="field-list simple"> -<dt class="field-odd">Returns<span class="colon">:</span></dt> -<dd class="field-odd"><p>the path of the weights of the specified model</p> -</dd> -<dt class="field-even">Return type<span class="colon">:</span></dt> -<dd class="field-even"><p>model_weights_path (str)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.load_model"> -<span class="sig-name descname"><span class="pre">load_model</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#deepdespeckling.model.Model" title="deepdespeckling.model.Model"><span class="pre">Model</span></a></span></span><a class="reference internal" href="_modules/deepdespeckling/merlin/merlin_denoiser.html#MerlinDenoiser.load_model"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.load_model" title="Link to this definition">¶</a></dt> -<dd><p>Load model with given weights</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>weights_path</strong> (<em>str</em>) -- path to weights</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- patch size</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>model loaded with stored weights</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>model (<a class="reference internal" href="#deepdespeckling.model.Model" title="deepdespeckling.model.Model">Model</a>)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_denoised_image"> -<span class="sig-name descname"><span class="pre">preprocess_denoised_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">denoised_image_real_part</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">denoised_image_imaginary_part</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">count_image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">tuple</span><span class="p"><span class="pre">[</span></span><span class="pre">array</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">array</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">array</span><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="_modules/deepdespeckling/merlin/merlin_denoiser.html#MerlinDenoiser.preprocess_denoised_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_denoised_image" title="Link to this definition">¶</a></dt> -<dd><p>Preprocess given denoised real and imaginary parts of an image, and build the full denoised image</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>denoised_image_real_part</strong> (<em>numpy array</em>) -- real part of a denoised image</p></li> -<li><p><strong>denoised_image_imaginary_part</strong> (<em>numpy array</em>) -- imaginary part of a denoised image</p></li> -<li><p><strong>count_image</strong> (<em>numpy array</em>) -- normalisation image used for denormalisation</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>processed denoised full image, processed denoised image real part, processed denoised image imaginary part</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>denoised_image, denoised_image_real_part, denoised_image_imaginary_part (numpy array, numpy array, numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_noisy_image"> -<span class="sig-name descname"><span class="pre">preprocess_noisy_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">noisy_image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">tuple</span><span class="p"><span class="pre">[</span></span><span class="pre">array</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">array</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">array</span><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="_modules/deepdespeckling/merlin/merlin_denoiser.html#MerlinDenoiser.preprocess_noisy_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_noisy_image" title="Link to this definition">¶</a></dt> -<dd><p>preprocess a given noisy image and generates its real and imaginary parts</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><p><strong>noisy_image</strong> (<em>numpy array</em>) -- noisy image</p> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>preprocessed noisy image, real part of noisy image, imaginary part of noisy image</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>noisy_image, noisy_image_real_part, noisy_image_imaginary_part (numpy array, numpy array, numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.save_despeckled_images"> -<span class="sig-name descname"><span class="pre">save_despeckled_images</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">despeckled_images</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">dict</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">save_dir</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/merlin/merlin_denoiser.html#MerlinDenoiser.save_despeckled_images"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.save_despeckled_images" title="Link to this definition">¶</a></dt> -<dd><p>Save full, real and imaginary part of noisy and denoised image stored in a dictionary in png to a given folder</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>despeckled_images</strong> (<em>dict</em>) -- dictionary containing full, real and imaginary parts of noisy and denoised image</p></li> -<li><p><strong>image_name</strong> (<em>str</em>) -- name of the image</p></li> -<li><p><strong>save_dir</strong> (<em>str</em>) -- path to the folder where to save the png images</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -</dd></dl> - -</section> -<section id="sar2sar-denoiser"> -<h2>sar2sar_denoiser<a class="headerlink" href="#sar2sar-denoiser" title="Link to this heading">¶</a></h2> -<dl class="py class" id="module-deepdespeckling.sar2sar.sar2sar_denoiser"> -<dt class="sig sig-object py" id="deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser"> -<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">deepdespeckling.sar2sar.sar2sar_denoiser.</span></span><span class="sig-name descname"><span class="pre">Sar2SarDenoiser</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">params</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html#Sar2SarDenoiser"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser" title="Link to this definition">¶</a></dt> -<dd><p>Bases: <a class="reference internal" href="#deepdespeckling.denoiser.Denoiser" title="deepdespeckling.denoiser.Denoiser"><code class="xref py py-class docutils literal notranslate"><span class="pre">Denoiser</span></code></a></p> -<p>Class to share parameters beyond denoising functions</p> -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image"> -<span class="sig-name descname"><span class="pre">denoise_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">noisy_image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stride_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">dict</span></span></span><a class="reference internal" href="_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html#Sar2SarDenoiser.denoise_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image" title="Link to this definition">¶</a></dt> -<dd><p>Preprocess and denoise a coSAR image using given model weights</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>noisy_image</strong> (<em>numpy array</em>) -- numpy array containing the noisy image to despeckle</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- size of the patch of the convolution</p></li> -<li><p><strong>stride_size</strong> (<em>int</em>) -- number of pixels between one convolution to the next</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>denoised image</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>output_image (numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image_kernel"> -<span class="sig-name descname"><span class="pre">denoise_image_kernel</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">noisy_image_kernel</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">tensor</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">denoised_image_kernel</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">x</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">y</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#deepdespeckling.model.Model" title="deepdespeckling.model.Model"><span class="pre">Model</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">normalisation_kernel</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html#Sar2SarDenoiser.denoise_image_kernel"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image_kernel" title="Link to this definition">¶</a></dt> -<dd><p>Denoise a subpart of a given symetrised noisy image delimited by x, y and patch_size using a given model</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>noisy_image_kernel</strong> (<em>torch tensor</em>) -- part of the noisy image to denoise</p></li> -<li><p><strong>denoised_image_kernel</strong> (<em>numpy array</em>) -- part of the partially denoised image</p></li> -<li><p><strong>x</strong> (<em>int</em>) -- x coordinate of current kernel to denoise</p></li> -<li><p><strong>y</strong> (<em>int</em>) -- y coordinate of current kernel to denoise</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- patch size</p></li> -<li><p><strong>model</strong> (<a class="reference internal" href="#deepdespeckling.model.Model" title="deepdespeckling.model.Model"><em>Model</em></a>) -- trained model with loaded weights</p></li> -<li><p><strong>normalisation_kernel</strong> (<em>bool</em><em>, </em><em>optional</em>) -- Determine if. Defaults to False.</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>image denoised in the given coordinates and the ones already iterated</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>denoised_image_kernel (numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_images"> -<span class="sig-name descname"><span class="pre">denoise_images</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">images_to_denoise_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">list</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">save_dir</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stride_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html#Sar2SarDenoiser.denoise_images"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_images" title="Link to this definition">¶</a></dt> -<dd><p>Iterate over a directory of coSAR images and store the denoised images in a directory</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>images_to_denoise_path</strong> (<em>list</em>) -- a list of paths of npy images to denoise</p></li> -<li><p><strong>save_dir</strong> (<em>str</em>) -- repository to save sar images, real images and noisy images</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- size of the patch of the convolution</p></li> -<li><p><strong>stride_size</strong> (<em>int</em>) -- number of pixels between one convolution to the next</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denormalize_sar_image"> -<span class="sig-name descname"><span class="pre">denormalize_sar_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html#Sar2SarDenoiser.denormalize_sar_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denormalize_sar_image" title="Link to this definition">¶</a></dt> -<dd><p>Denormalize a sar image stored in a numpy array</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><p><strong>image</strong> (<em>numpy array</em>) -- a sar image</p> -</dd> -<dt class="field-even">Raises<span class="colon">:</span></dt> -<dd class="field-even"><p><strong>TypeError</strong> -- raise an error if the image file is not a numpy array</p> -</dd> -<dt class="field-odd">Returns<span class="colon">:</span></dt> -<dd class="field-odd"><p>the image denormalized</p> -</dd> -<dt class="field-even">Return type<span class="colon">:</span></dt> -<dd class="field-even"><p>(numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.load_model"> -<span class="sig-name descname"><span class="pre">load_model</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">patch_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#deepdespeckling.model.Model" title="deepdespeckling.model.Model"><span class="pre">Model</span></a></span></span><a class="reference internal" href="_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html#Sar2SarDenoiser.load_model"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.load_model" title="Link to this definition">¶</a></dt> -<dd><p>Load model with given weights</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>weights_path</strong> (<em>str</em>) -- path to weights</p></li> -<li><p><strong>patch_size</strong> (<em>int</em>) -- patch size</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>model loaded with stored weights</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>model (<a class="reference internal" href="#deepdespeckling.model.Model" title="deepdespeckling.model.Model">Model</a>)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py method"> -<dt class="sig sig-object py" id="deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.save_despeckled_images"> -<span class="sig-name descname"><span class="pre">save_despeckled_images</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">despeckled_images</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">dict</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">save_dir</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/sar2sar/sar2sar_denoiser.html#Sar2SarDenoiser.save_despeckled_images"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.save_despeckled_images" title="Link to this definition">¶</a></dt> -<dd><p>Save full, real and imaginary part of noisy and denoised image stored in a dictionary in png to a given folder</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>despeckled_images</strong> (<em>dict</em>) -- dictionary containing noisy and denoised image</p></li> -<li><p><strong>image_name</strong> (<em>str</em>) -- name of the image</p></li> -<li><p><strong>save_dir</strong> (<em>str</em>) -- path to the folder where to save the png images</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -</dd></dl> - -</section> -<section id="module-deepdespeckling.utils.utils"> -<span id="utils"></span><h2>utils<a class="headerlink" href="#module-deepdespeckling.utils.utils" title="Link to this heading">¶</a></h2> -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.compute_psnr"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">compute_psnr</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">Shat</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">S</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">float</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#compute_psnr"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.compute_psnr" title="Link to this definition">¶</a></dt> -<dd><p>Compute Peak Signal to Noise Ratio</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>Shat</strong> (<em>numpy array</em>) -- a SAR amplitude image</p></li> -<li><p><strong>S</strong> (<em>numpy array</em>) -- a reference SAR image</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>psnr value</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>res (float)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.create_empty_folder_in_directory"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">create_empty_folder_in_directory</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">destination_directory_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">folder_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">'processed_images'</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#create_empty_folder_in_directory"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.create_empty_folder_in_directory" title="Link to this definition">¶</a></dt> -<dd><p>Create an empty folder in a given directory</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>destination_directory_path</strong> (<em>str</em>) -- path pf the directory in which an empty folder is created if it doest not exist yet</p></li> -<li><p><strong>folder_name</strong> (<em>str</em><em>, </em><em>optional</em>) -- name of the folder to create. Defaults to "processed_images".</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>path of the created empty folder</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>processed_images_path</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.crop_image"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">crop_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">cropping_coordinates</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">list</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">processed_images_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#crop_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.crop_image" title="Link to this definition">¶</a></dt> -<dd><p>Crop an image using given cropping coordinates and store the result in a given folder</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>image</strong> (<em>numpy array</em>) -- image to be cropped</p></li> -<li><p><strong>image_path</strong> (<em>str</em>) -- path of the image</p></li> -<li><p><strong>cropping_coordinates</strong> (<em>list</em>) -- list of coordinates of cropping, format [(x1, y1), (x2, y2)]</p></li> -<li><p><strong>model_name</strong> (<em>str</em>) -- name of the model (stripmap, spotlight or sar2sar)</p></li> -<li><p><strong>processed_images_path</strong> (<em>str</em>) -- path of the folder where to store the cropped image in npy format</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.denormalize_sar_image"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">denormalize_sar_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#denormalize_sar_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.denormalize_sar_image" title="Link to this definition">¶</a></dt> -<dd><p>Denormalize a sar image store in a numpy array</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><p><strong>image</strong> (<em>numpy array</em>) -- a sar image</p> -</dd> -<dt class="field-even">Raises<span class="colon">:</span></dt> -<dd class="field-even"><p><strong>TypeError</strong> -- raise an error if the image file is not a numpy array</p> -</dd> -<dt class="field-odd">Returns<span class="colon">:</span></dt> -<dd class="field-odd"><p>the image denormalized</p> -</dd> -<dt class="field-even">Return type<span class="colon">:</span></dt> -<dd class="field-even"><p>(numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.denormalize_sar_image_sar2sar"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">denormalize_sar_image_sar2sar</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#denormalize_sar_image_sar2sar"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.denormalize_sar_image_sar2sar" title="Link to this definition">¶</a></dt> -<dd><p>Denormalize a sar image store i a numpy array</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><p><strong>image</strong> (<em>numpy array</em>) -- a sar image</p> -</dd> -<dt class="field-even">Raises<span class="colon">:</span></dt> -<dd class="field-even"><p><strong>TypeError</strong> -- raise an error if the image file is not a numpy array</p> -</dd> -<dt class="field-odd">Returns<span class="colon">:</span></dt> -<dd class="field-odd"><p>the image denormalized</p> -</dd> -<dt class="field-even">Return type<span class="colon">:</span></dt> -<dd class="field-even"><p>(numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.get_cropping_coordinates"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">get_cropping_coordinates</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">destination_directory_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">fixed</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">True</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#get_cropping_coordinates"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.get_cropping_coordinates" title="Link to this definition">¶</a></dt> -<dd><p>Launch the crop tool to enable the user to select the subpart of the image to be despeckled</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>image</strong> (<em>numpy aray</em>) -- full image to be cropped</p></li> -<li><p><strong>destination_directory_path</strong> (<em>str</em>) -- path of a folder to store the results</p></li> -<li><p><strong>model_name</strong> (<em>str</em>) -- model name to be use for despeckling. Default to "spotlight"</p></li> -<li><p><strong>fixed</strong> (<em>bool</em><em>, </em><em>optional</em>) -- whether the area of selection has a fixed size of not. Defaults to True.</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.get_cropping_coordinates_from_file"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">get_cropping_coordinates_from_file</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">destination_directory_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">list</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#get_cropping_coordinates_from_file"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.get_cropping_coordinates_from_file" title="Link to this definition">¶</a></dt> -<dd><p>Get cropping coordinates from a file where it's stored</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><p><strong>destination_directory_path</strong> (<em>str</em>) -- path of the file in which the cropping coordinates are stored</p> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>list containing cropping coordinates</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>cropping_coordinates (list)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.get_maximum_patch_size"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">get_maximum_patch_size</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">kernel_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">patch_bound</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">int</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#get_maximum_patch_size"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.get_maximum_patch_size" title="Link to this definition">¶</a></dt> -<dd><p>Get maximum manifold of a number lower than a bound</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>kernel_size</strong> (<em>int</em>) -- the kernel size of the trained model</p></li> -<li><p><strong>patch_bound</strong> (<em>int</em>) -- the maximum bound of the kernel size</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>the maximum patch size</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>maximum_patch_size (int)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.get_maximum_patch_size_from_image_dimensions"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">get_maximum_patch_size_from_image_dimensions</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">kernel_size</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">height</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">width</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">int</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#get_maximum_patch_size_from_image_dimensions"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.get_maximum_patch_size_from_image_dimensions" title="Link to this definition">¶</a></dt> -<dd><p>Get the maximum patch size from the width and heigth and the kernel size of the model we use</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>kernel_size</strong> (<em>int</em>) -- the kernel size of the trained model</p></li> -<li><p><strong>height</strong> (<em>int</em>) -- the heigth of the image</p></li> -<li><p><strong>width</strong> (<em>int</em>) -- the width of the image</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>the maximum patch size to use for despeckling</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>maximum_patch_size (int)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.load_sar_image"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">load_sar_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#load_sar_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.load_sar_image" title="Link to this definition">¶</a></dt> -<dd><p>Load a SAR image in a numpy array, use cos2mat function if the file is a cos file, -load_tiff_image if the file is a tiff file</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><p><strong>image_path</strong> (<em>str</em>) -- absolute path to a SAR image (cos or npy file)</p> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>the image of dimension [ncolumns,nlines,2]</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>image (numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.load_sar_images"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">load_sar_images</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">file_list</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#load_sar_images"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.load_sar_images" title="Link to this definition">¶</a></dt> -<dd><section id="description"> -<h3>Description<a class="headerlink" href="#description" title="Link to this heading">¶</a></h3> -<p>Loads files , resize them and append them into a list called data</p> -<dl class="field-list simple"> -<dt class="field-odd">param filelist<span class="colon">:</span></dt> -<dd class="field-odd"><p></p></dd> -<dt class="field-even">type filelist<span class="colon">:</span></dt> -<dd class="field-even"><p>a path to a folder containing the images</p> -</dd> -<dt class="field-odd">rtype<span class="colon">:</span></dt> -<dd class="field-odd"><p>A list of images</p> -</dd> -</dl> -</section> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.normalize_sar_image"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">normalize_sar_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#normalize_sar_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.normalize_sar_image" title="Link to this definition">¶</a></dt> -<dd><p>normalize a sar image store in a numpy array</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><p><strong>image</strong> (<em>numpy array</em>) -- the image to be normalized</p> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>normalized image</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>(numpy array)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.preprocess_and_store_sar_images"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">preprocess_and_store_sar_images</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sar_images_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">processed_images_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">'spotlight'</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#preprocess_and_store_sar_images"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.preprocess_and_store_sar_images" title="Link to this definition">¶</a></dt> -<dd><p>Convert coSAR images to numpy arrays and store it in a specified path</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>sar_images_path</strong> (<em>str</em>) -- path of a folder containing coSAR images to be converted in numpy array</p></li> -<li><p><strong>processed_images_path</strong> (<em>str</em>) -- path of the folder where converted images are stored</p></li> -<li><p><strong>model_name</strong> (<em>str</em>) -- model name to be use for despeckling</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.preprocess_and_store_sar_images_from_coordinates"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">preprocess_and_store_sar_images_from_coordinates</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sar_images_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">processed_images_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">coordinates_dict</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">dict</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">'spotlight'</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#preprocess_and_store_sar_images_from_coordinates"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.preprocess_and_store_sar_images_from_coordinates" title="Link to this definition">¶</a></dt> -<dd><p>Convert specified areas of coSAR images to numpy arrays and store it in a specified path</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>sar_images_path</strong> (<em>str</em>) -- path of a folder containing coSAR images to be converted in numpy array</p></li> -<li><p><strong>processed_images_path</strong> (<em>str</em>) -- path of the folder where converted images are stored</p></li> -<li><p><strong>coordinates_dict</strong> (<em>dict</em>) -- dictionary containing pixel boundaries of the area to despeckle (x_start, x_end, y_start, y_end)</p></li> -<li><p><strong>model_name</strong> (<em>str</em>) -- model name to be use for despeckling. Default to "spotlight"</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.preprocess_image"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">preprocess_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">threshold</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">float</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#preprocess_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.preprocess_image" title="Link to this definition">¶</a></dt> -<dd><p>Preprocess image by limiting pixel values with a threshold</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>image</strong> (<em>numpy array</em>) -- image to preprocess</p></li> -<li><p><strong>threshold</strong> (<em>float</em>) -- pixel value threshold</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>image to be saved</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>image (cv2 Image)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.preprocess_sar_image_for_cropping"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">preprocess_sar_image_for_cropping</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">model_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#preprocess_sar_image_for_cropping"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.preprocess_sar_image_for_cropping" title="Link to this definition">¶</a></dt> -<dd><p>Preprocess image to use the cropping tool</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>image</strong> (<em>numpy array</em>) -- image from which we get cropping coordinates by using the cropping tool</p></li> -<li><p><strong>model_name</strong> (<em>str</em>) -- name of the model (stripmap, spotlight or sar2sar)</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>image preprocessed for cropping</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>image (cv2 image)</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.save_image_to_npy_and_png"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">save_image_to_npy_and_png</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">save_dir</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">prefix</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">threshold</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">float</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#save_image_to_npy_and_png"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.save_image_to_npy_and_png" title="Link to this definition">¶</a></dt> -<dd><p>Save a given image to npy and png in a given folder</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>image</strong> (<em>numpy array</em>) -- image to save</p></li> -<li><p><strong>save_dir</strong> (<em>str</em>) -- path to the folder where to save the image</p></li> -<li><p><strong>prefix</strong> (<em>str</em>) -- prefix of the image file name</p></li> -<li><p><strong>image_name</strong> (<em>str</em>) -- name of the image file</p></li> -<li><p><strong>threshold</strong> (<em>float</em>) -- threshold of image pixel values used for png conversion</p></li> -</ul> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.save_image_to_png"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">save_image_to_png</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">threshold</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">image_full_path</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#save_image_to_png"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.save_image_to_png" title="Link to this definition">¶</a></dt> -<dd><p>Save a given image to a png file in a given folder</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>image</strong> (<em>numpy array</em>) -- image to save</p></li> -<li><p><strong>threshold</strong> (<em>float</em>) -- threshold of pixel values of the image to be saved in png</p></li> -<li><p><strong>image_full_path</strong> (<em>str</em>) -- full path of the image</p></li> -</ul> -</dd> -<dt class="field-even">Raises<span class="colon">:</span></dt> -<dd class="field-even"><p><strong>TypeError</strong> -- if the image is not a numpy array</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.utils.symetrise_real_and_imaginary_parts"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.utils.</span></span><span class="sig-name descname"><span class="pre">symetrise_real_and_imaginary_parts</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">real_part</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">imag_part</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">array</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">tuple</span><span class="p"><span class="pre">[</span></span><span class="pre">array</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">array</span><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/utils.html#symetrise_real_and_imaginary_parts"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.utils.symetrise_real_and_imaginary_parts" title="Link to this definition">¶</a></dt> -<dd><p>Symetrise given real and imaginary parts to ensure MERLIN properties</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><ul class="simple"> -<li><p><strong>real_part</strong> (<em>numpy array</em>) -- real part of the noisy image to symetrise</p></li> -<li><p><strong>imag_part</strong> (<em>numpy array</em>) -- imaginary part of the noisy image to symetrise</p></li> -</ul> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>symetrised real and imaginary parts of a noisy image</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>np.real(ima2), np.imag(ima2) (numpy array, numpy array)</p> -</dd> -</dl> -</dd></dl> - -</section> -<section id="load-cosar"> -<h2>load_cosar<a class="headerlink" href="#load-cosar" title="Link to this heading">¶</a></h2> -<dl class="py function" id="module-deepdespeckling.utils.load_cosar"> -<dt class="sig sig-object py" id="deepdespeckling.utils.load_cosar.cos2mat"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.load_cosar.</span></span><span class="sig-name descname"><span class="pre">cos2mat</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">path_to_cosar_image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/load_cosar.html#cos2mat"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.load_cosar.cos2mat" title="Link to this definition">¶</a></dt> -<dd><p>Convert a CoSAR imge to a numpy array of size [ncolumns,nlines,2]</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><p><strong>path_to_cosar_image</strong> (<em>str</em>) -- path to the image which is a cos file</p> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>the image in a numpy array</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>numpy array</p> -</dd> -</dl> -</dd></dl> - -<dl class="py function"> -<dt class="sig sig-object py" id="deepdespeckling.utils.load_cosar.load_tiff_image"> -<span class="sig-prename descclassname"><span class="pre">deepdespeckling.utils.load_cosar.</span></span><span class="sig-name descname"><span class="pre">load_tiff_image</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">path_to_tiff_image</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">array</span></span></span><a class="reference internal" href="_modules/deepdespeckling/utils/load_cosar.html#load_tiff_image"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#deepdespeckling.utils.load_cosar.load_tiff_image" title="Link to this definition">¶</a></dt> -<dd><p>Load a tiff image in a numpy array using gdal library</p> -<dl class="field-list simple"> -<dt class="field-odd">Parameters<span class="colon">:</span></dt> -<dd class="field-odd"><p><strong>path_to_tiff_image</strong> (<em>str</em>) -- path to a tiff image</p> -</dd> -<dt class="field-even">Returns<span class="colon">:</span></dt> -<dd class="field-even"><p>numpy array containing the tiff image</p> -</dd> -<dt class="field-odd">Return type<span class="colon">:</span></dt> -<dd class="field-odd"><p>(numpy array)</p> -</dd> -</dl> -</dd></dl> - -</section> -</section> - - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul class="current"> -<li class="toctree-l1 current"><a class="current reference internal" href="#">deepdespeckling</a><ul> -<li class="toctree-l2"><a class="reference internal" href="#module-deepdespeckling.denoiser">denoiser</a><ul> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.denoiser.Denoiser"><code class="docutils literal notranslate"><span class="pre">Denoiser</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="#despeckling">despeckling</a><ul> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.despeckling.despeckle"><code class="docutils literal notranslate"><span class="pre">despeckle()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.despeckling.despeckle_from_coordinates"><code class="docutils literal notranslate"><span class="pre">despeckle_from_coordinates()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.despeckling.despeckle_from_crop"><code class="docutils literal notranslate"><span class="pre">despeckle_from_crop()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.despeckling.get_denoiser"><code class="docutils literal notranslate"><span class="pre">get_denoiser()</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="#module-deepdespeckling.model">model</a><ul> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.model.Model"><code class="docutils literal notranslate"><span class="pre">Model</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="#merlin-denoiser">merlin_denoiser</a><ul> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser"><code class="docutils literal notranslate"><span class="pre">MerlinDenoiser</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="#sar2sar-denoiser">sar2sar_denoiser</a><ul> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser"><code class="docutils literal notranslate"><span class="pre">Sar2SarDenoiser</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="#module-deepdespeckling.utils.utils">utils</a><ul> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.compute_psnr"><code class="docutils literal notranslate"><span class="pre">compute_psnr()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.create_empty_folder_in_directory"><code class="docutils literal notranslate"><span class="pre">create_empty_folder_in_directory()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.crop_image"><code class="docutils literal notranslate"><span class="pre">crop_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.denormalize_sar_image"><code class="docutils literal notranslate"><span class="pre">denormalize_sar_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.denormalize_sar_image_sar2sar"><code class="docutils literal notranslate"><span class="pre">denormalize_sar_image_sar2sar()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.get_cropping_coordinates"><code class="docutils literal notranslate"><span class="pre">get_cropping_coordinates()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.get_cropping_coordinates_from_file"><code class="docutils literal notranslate"><span class="pre">get_cropping_coordinates_from_file()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.get_maximum_patch_size"><code class="docutils literal notranslate"><span class="pre">get_maximum_patch_size()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.get_maximum_patch_size_from_image_dimensions"><code class="docutils literal notranslate"><span class="pre">get_maximum_patch_size_from_image_dimensions()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.load_sar_image"><code class="docutils literal notranslate"><span class="pre">load_sar_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.load_sar_images"><code class="docutils literal notranslate"><span class="pre">load_sar_images()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.normalize_sar_image"><code class="docutils literal notranslate"><span class="pre">normalize_sar_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.preprocess_and_store_sar_images"><code class="docutils literal notranslate"><span class="pre">preprocess_and_store_sar_images()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.preprocess_and_store_sar_images_from_coordinates"><code class="docutils literal notranslate"><span class="pre">preprocess_and_store_sar_images_from_coordinates()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.preprocess_image"><code class="docutils literal notranslate"><span class="pre">preprocess_image()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.preprocess_sar_image_for_cropping"><code class="docutils literal notranslate"><span class="pre">preprocess_sar_image_for_cropping()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.save_image_to_npy_and_png"><code class="docutils literal notranslate"><span class="pre">save_image_to_npy_and_png()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.save_image_to_png"><code class="docutils literal notranslate"><span class="pre">save_image_to_png()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.utils.symetrise_real_and_imaginary_parts"><code class="docutils literal notranslate"><span class="pre">symetrise_real_and_imaginary_parts()</span></code></a></li> -</ul> -</li> -<li class="toctree-l2"><a class="reference internal" href="#load-cosar">load_cosar</a><ul> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.load_cosar.cos2mat"><code class="docutils literal notranslate"><span class="pre">cos2mat()</span></code></a></li> -<li class="toctree-l3"><a class="reference internal" href="#deepdespeckling.utils.load_cosar.load_tiff_image"><code class="docutils literal notranslate"><span class="pre">load_tiff_image()</span></code></a></li> -</ul> -</li> -</ul> -</li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="index.html">Documentation overview</a><ul> - <li>Previous: <a href="index.html" title="previous chapter">Welcome to deepdespeckling's documentation!</a></li> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - | - <a href="_sources/modules.rst.txt" - rel="nofollow">Page source</a> - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/objects.inv b/docs/objects.inv deleted file mode 100644 index 7c8ee37033ec67d9ccf20884554d9b3edd16edc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 809 zcmV+^1J?W_AX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkpWo2+= zWpi+4V{2?_Zf6Q3AXa5^b7^mGIv@%oAXI2&AaZ4GVQFq;WpW^IW*~HEX>%ZEX>4U6 zX>%ZBZ*6dLWpi_7WFU2OX>MmAdTeQ8E(&<swU<qAoG=iE@B1sLTB)Z+O^!MD(!)xT za>&tg>|wFuFWDvu{q-I2QrJya3)md^GWPS1$DU!}0G5Ndz+R=$$HKM`%J4=)@vDe8 zzN~|i-{ZsnN3q}W^D!j{ZG;DxG`Rddp)g6kFYeAEvqldsL@0WM-XaLK;Td4$6`Tf{ zmFZJyM+k(&n_$Uv6<P#ArT7bkeh5z-)#(nj4y-c_yeFrZJkQE_`UYg^GC&u5Gj-p8 zzV9biHJSxs^g<&>2&tS=gc;+w&@{w}<)S)cQ*d#|jj_6fqrl<ybRkK3<7-rT=$}{R zl3B!*{IWt|RnA$V<F`=gG73Q!Nb(NiSO-rm4fPgM(oi0ywxDOqVvEJPmUcU(965CK z`QiZXMwW+R{QNK-$CZ_F@6_=XCZ7PoQQW05|I-khcxeL6fq3ff@ffaYx$GLOe8L7i zR;9DK(3Fg}PGeP4TPNi=6mcq6OI^n;eYZBZ%@)X!2bv(HkESw%YOCVl5>n#%UeU0$ z%=pCVZ-c0+aiNy;`g6j(;+Yv`F~<<=wM($0WDc+}B%o|)No6Dl+=ZCyg##9hYtz`q zCVT37jAR9p)AmjQcO`8%XNxaVs_r?=ScF$XLMmP1Z<=aUS5vW?c=SqsVzf3onhOQm zBRa`1eJEzx4(FsKqcU&QNeM?a+KBN8nJm45PX2McqLtGnW9VY}_CH2a;Qa?IB7-5? zw!Lp`PG~Bu#ZRg0$`VZ5vNx|o;~KdZ!_9@83v~pnQ#pJTKJW)gU$7e3-xWh^->>-7 z-R{P2+_0|Gq{lNz`~X1_OmSiEPhVj7217j1&W3M0G~o+H+wO-K5qXGT!>D~Sd#XO2 n$))ISLc1aJ*kUQ7&(%Co$LjNeu`P~yititB4R`+l@?XK9!`6mh diff --git a/docs/py-modindex.html b/docs/py-modindex.html deleted file mode 100644 index a1e4a36..0000000 --- a/docs/py-modindex.html +++ /dev/null @@ -1,153 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="./"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>Python Module Index — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=12dfc556" /> - <script src="_static/documentation_options.js?v=cb255500"></script> - <script src="_static/doctools.js?v=888ff710"></script> - <script src="_static/sphinx_highlight.js?v=dc90522c"></script> - <link rel="index" title="Index" href="genindex.html" /> - <link rel="search" title="Search" href="search.html" /> - - - <link rel="stylesheet" href="_static/custom.css" type="text/css" /> - - - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - - <h1>Python Module Index</h1> - - <div class="modindex-jumpbox"> - <a href="#cap-d"><strong>d</strong></a> - </div> - - <table class="indextable modindextable"> - <tr class="pcap"><td></td><td> </td><td></td></tr> - <tr class="cap" id="cap-d"><td></td><td> - <strong>d</strong></td><td></td></tr> - <tr> - <td><img src="_static/minus.png" class="toggler" - id="toggle-1" style="display: none" alt="-" /></td> - <td> - <a href="modules.html#module-deepdespeckling"><code class="xref">deepdespeckling</code></a></td><td> - <em></em></td></tr> - <tr class="cg-1"> - <td></td> - <td>    - <a href="modules.html#module-deepdespeckling.denoiser"><code class="xref">deepdespeckling.denoiser</code></a></td><td> - <em></em></td></tr> - <tr class="cg-1"> - <td></td> - <td>    - <a href="modules.html#module-deepdespeckling.despeckling"><code class="xref">deepdespeckling.despeckling</code></a></td><td> - <em></em></td></tr> - <tr class="cg-1"> - <td></td> - <td>    - <a href="modules.html#module-deepdespeckling.merlin.merlin_denoiser"><code class="xref">deepdespeckling.merlin.merlin_denoiser</code></a></td><td> - <em></em></td></tr> - <tr class="cg-1"> - <td></td> - <td>    - <a href="modules.html#module-deepdespeckling.model"><code class="xref">deepdespeckling.model</code></a></td><td> - <em></em></td></tr> - <tr class="cg-1"> - <td></td> - <td>    - <a href="modules.html#module-deepdespeckling.sar2sar.sar2sar_denoiser"><code class="xref">deepdespeckling.sar2sar.sar2sar_denoiser</code></a></td><td> - <em></em></td></tr> - <tr class="cg-1"> - <td></td> - <td>    - <a href="modules.html#module-deepdespeckling.utils.load_cosar"><code class="xref">deepdespeckling.utils.load_cosar</code></a></td><td> - <em></em></td></tr> - <tr class="cg-1"> - <td></td> - <td>    - <a href="modules.html#module-deepdespeckling.utils.utils"><code class="xref">deepdespeckling.utils.utils</code></a></td><td> - <em></em></td></tr> - </table> - - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="index.html">Documentation overview</a><ul> - </ul></li> -</ul> -</div> -<div id="searchbox" style="display: none" role="search"> - <h3 id="searchlabel">Quick search</h3> - <div class="searchformwrapper"> - <form class="search" action="search.html" method="get"> - <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="Go" /> - </form> - </div> -</div> -<script>document.getElementById('searchbox').style.display = "block"</script> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/search.html b/docs/search.html deleted file mode 100644 index b92c946..0000000 --- a/docs/search.html +++ /dev/null @@ -1,122 +0,0 @@ -<!DOCTYPE html> - -<html lang="English" data-content_root="./"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>Search — deepdespeckling 0.3 documentation</title> - <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" /> - <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=12dfc556" /> - - <script src="_static/documentation_options.js?v=cb255500"></script> - <script src="_static/doctools.js?v=888ff710"></script> - <script src="_static/sphinx_highlight.js?v=dc90522c"></script> - <script src="_static/searchtools.js"></script> - <script src="_static/language_data.js"></script> - <link rel="index" title="Index" href="genindex.html" /> - <link rel="search" title="Search" href="#" /> - <script src="searchindex.js" defer></script> - - - <link rel="stylesheet" href="_static/custom.css" type="text/css" /> - - - - - - - </head><body> - - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - - - <div class="body" role="main"> - - <h1 id="search-documentation">Search</h1> - - <noscript> - <div class="admonition warning"> - <p> - Please activate JavaScript to enable the search - functionality. - </p> - </div> - </noscript> - - - <p> - Searching for multiple words only shows matches that contain - all words. - </p> - - - <form action="" method="get"> - <input type="text" name="q" aria-labelledby="search-documentation" value="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/> - <input type="submit" value="search" /> - <span id="search-progress" style="padding-left: 10px"></span> - </form> - - - - <div id="search-results"> - - </div> - - - </div> - - </div> - </div> - <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> - <div class="sphinxsidebarwrapper"> -<h1 class="logo"><a href="index.html">deepdespeckling</a></h1> - - - - - - - - -<h3>Navigation</h3> -<p class="caption" role="heading"><span class="caption-text">Contents:</span></p> -<ul> -<li class="toctree-l1"><a class="reference internal" href="modules.html">deepdespeckling</a></li> -</ul> - -<div class="relations"> -<h3>Related Topics</h3> -<ul> - <li><a href="index.html">Documentation overview</a><ul> - </ul></li> -</ul> -</div> - - - - - - - - - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - ©2024, Hadrien Mariaccia, Emanuele Delsasso. - - | - Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.2.6</a> - & <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a> - - </div> - - - - - </body> -</html> \ No newline at end of file diff --git a/docs/searchindex.js b/docs/searchindex.js deleted file mode 100644 index 94b26d3..0000000 --- a/docs/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -Search.setIndex({"docnames": ["index", "modules"], "filenames": ["index.rst", "modules.rst"], "titles": ["Welcome to deepdespeckling's documentation!", "deepdespeckling"], "terms": {"denois": 0, "despeckl": 0, "despeckle_from_coordin": [0, 1], "despeckle_from_crop": [0, 1], "get_denois": [0, 1], "model": 0, "merlin_denois": 0, "merlindenois": [0, 1], "sar2sar_denois": 0, "sar2sardenois": [0, 1], "util": 0, "compute_psnr": [0, 1], "create_empty_folder_in_directori": [0, 1], "crop_imag": [0, 1], "denormalize_sar_imag": [0, 1], "denormalize_sar_image_sar2sar": [0, 1], "get_cropping_coordin": [0, 1], "get_cropping_coordinates_from_fil": [0, 1], "get_maximum_patch_s": [0, 1], "get_maximum_patch_size_from_image_dimens": [0, 1], "load_sar_imag": [0, 1], "normalize_sar_imag": [0, 1], "preprocess_and_store_sar_imag": [0, 1], "preprocess_and_store_sar_images_from_coordin": [0, 1], "preprocess_imag": [0, 1], "preprocess_sar_image_for_crop": [0, 1], "save_image_to_npy_and_png": [0, 1], "save_image_to_png": [0, 1], "symetrise_real_and_imaginary_part": [0, 1], "load_cosar": 0, "cos2mat": [0, 1], "load_tiff_imag": [0, 1], "index": 0, "modul": [0, 1], "search": 0, "page": 0, "class": 1, "sourc": 1, "base": 1, "object": 1, "share": 1, "paramet": 1, "beyond": 1, "function": 1, "denoise_imag": 1, "denoise_image_kernel": 1, "get_devic": 1, "str": 1, "get": 1, "torch": 1, "devic": 1, "us": 1, "depend": 1, "gpu": 1, "": 1, "avail": 1, "return": 1, "type": 1, "initialize_axis_rang": 1, "image_axis_dim": 1, "int": 1, "patch_siz": 1, "stride_s": 1, "list": 1, "initi": 1, "convolut": 1, "rang": 1, "x": 1, "y": 1, "axi": 1, "size": 1, "patch": 1, "stride": 1, "pixel": 1, "border": 1, "each": 1, "axis_rang": 1, "preprocess_denoised_imag": 1, "save_despeckled_imag": 1, "sar_images_path": 1, "destination_directory_path": 1, "model_nam": 1, "spotlight": 1, "256": 1, "254": 1, "symetris": 1, "bool": 1, "true": 1, "cosar": 1, "imag": 1, "train": 1, "merlin": 1, "stripmap": 1, "weight": 1, "sar2sar": 1, "path": 1, "sar": 1, "folder": 1, "which": 1, "result": 1, "store": 1, "name": 1, "either": 1, "select": 1, "right": 1, "format": 1, "default": 1, "constant": 1, "real": 1, "imaginari": 1, "part": 1, "noisi": 1, "coordinates_dict": 1, "dict": 1, "specifi": 1, "area": 1, "coordin": 1, "dictionari": 1, "contain": 1, "boundari": 1, "x_start": 1, "x_end": 1, "y_start": 1, "y_end": 1, "fix": 1, "an": 1, "integr": 1, "crop": 1, "tool": 1, "made": 1, "opencv": 1, "If": 1, "i": 1, "limit": 1, "from": 1, "height": 1, "width": 1, "forward": 1, "arrai": 1, "defin": 1, "autoencod": 1, "algorithm": 1, "specif": 1, "feedforward": 1, "neural": 1, "network": 1, "where": 1, "input": 1, "same": 1, "output": 1, "It": 1, "compress": 1, "lower": 1, "dimension": 1, "code": 1, "reconstruct": 1, "thi": 1, "representatt": 1, "reduct": 1, "np": 1, "numpi": 1, "n": 1, "e": 1, "itself": 1, "minu": 1, "nois": 1, "param": 1, "noisy_imag": 1, "preprocess": 1, "given": 1, "number": 1, "between": 1, "one": 1, "next": 1, "despeckled_imag": 1, "tensor": 1, "denoised_imag": 1, "normalisation_kernel": 1, "fals": 1, "subpart": 1, "delimit": 1, "partial": 1, "current": 1, "kernel": 1, "load": 1, "option": 1, "determin": 1, "ones": 1, "alreadi": 1, "iter": 1, "images_to_denoise_path": 1, "save_dir": 1, "over": 1, "directori": 1, "npy": 1, "repositori": 1, "save": 1, "init_model_weights_path": 1, "model_weights_path": 1, "load_model": 1, "weights_path": 1, "denoised_image_real_part": 1, "denoised_image_imaginary_part": 1, "count_imag": 1, "tupl": 1, "build": 1, "full": 1, "normalis": 1, "denormalis": 1, "process": 1, "preprocess_noisy_imag": 1, "gener": 1, "its": 1, "noisy_image_real_part": 1, "noisy_image_imaginary_part": 1, "image_nam": 1, "png": 1, "output_imag": 1, "noisy_image_kernel": 1, "denoised_image_kernel": 1, "denorm": 1, "rais": 1, "typeerror": 1, "error": 1, "file": 1, "shat": 1, "float": 1, "comput": 1, "peak": 1, "signal": 1, "ratio": 1, "amplitud": 1, "refer": 1, "psnr": 1, "valu": 1, "re": 1, "folder_nam": 1, "processed_imag": 1, "creat": 1, "empti": 1, "pf": 1, "doest": 1, "exist": 1, "yet": 1, "processed_images_path": 1, "image_path": 1, "cropping_coordin": 1, "x1": 1, "y1": 1, "x2": 1, "y2": 1, "launch": 1, "enabl": 1, "user": 1, "arai": 1, "whether": 1, "ha": 1, "ar": 1, "kernel_s": 1, "patch_bound": 1, "maximum": 1, "manifold": 1, "than": 1, "bound": 1, "maximum_patch_s": 1, "heigth": 1, "we": 1, "co": 1, "tiff": 1, "absolut": 1, "dimens": 1, "ncolumn": 1, "nline": 1, "2": 1, "file_list": 1, "resiz": 1, "them": 1, "append": 1, "call": 1, "data": 1, "filelist": 1, "rtype": 1, "A": 1, "normal": 1, "convert": 1, "threshold": 1, "cv2": 1, "prefix": 1, "convers": 1, "image_full_path": 1, "real_part": 1, "imag_part": 1, "ensur": 1, "properti": 1, "ima2": 1, "path_to_cosar_imag": 1, "img": 1, "path_to_tiff_imag": 1, "gdal": 1, "librari": 1}, "objects": {"": [[1, 0, 0, "-", "deepdespeckling"]], "deepdespeckling": [[1, 0, 0, "-", "denoiser"], [1, 0, 0, "-", "despeckling"], [1, 0, 0, "-", "model"]], "deepdespeckling.denoiser": [[1, 1, 1, "", "Denoiser"]], "deepdespeckling.denoiser.Denoiser": [[1, 2, 1, "", "denoise_image"], [1, 2, 1, "", "denoise_image_kernel"], [1, 2, 1, "", "denoise_images"], [1, 2, 1, "", "get_device"], [1, 2, 1, "", "initialize_axis_range"], [1, 2, 1, "", "preprocess_denoised_image"], [1, 2, 1, "", "save_despeckled_images"]], "deepdespeckling.despeckling": [[1, 3, 1, "", "despeckle"], [1, 3, 1, "", "despeckle_from_coordinates"], [1, 3, 1, "", "despeckle_from_crop"], [1, 3, 1, "", "get_denoiser"]], "deepdespeckling.merlin": [[1, 0, 0, "-", "merlin_denoiser"]], "deepdespeckling.merlin.merlin_denoiser": [[1, 1, 1, "", "MerlinDenoiser"]], "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser": [[1, 2, 1, "", "denoise_image"], [1, 2, 1, "", "denoise_image_kernel"], [1, 2, 1, "", "denoise_images"], [1, 2, 1, "", "init_model_weights_path"], [1, 2, 1, "", "load_model"], [1, 2, 1, "", "preprocess_denoised_image"], [1, 2, 1, "", "preprocess_noisy_image"], [1, 2, 1, "", "save_despeckled_images"]], "deepdespeckling.model": [[1, 1, 1, "", "Model"]], "deepdespeckling.model.Model": [[1, 2, 1, "", "forward"], [1, 4, 1, "", "training"]], "deepdespeckling.sar2sar": [[1, 0, 0, "-", "sar2sar_denoiser"]], "deepdespeckling.sar2sar.sar2sar_denoiser": [[1, 1, 1, "", "Sar2SarDenoiser"]], "deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser": [[1, 2, 1, "", "denoise_image"], [1, 2, 1, "", "denoise_image_kernel"], [1, 2, 1, "", "denoise_images"], [1, 2, 1, "", "denormalize_sar_image"], [1, 2, 1, "", "load_model"], [1, 2, 1, "", "save_despeckled_images"]], "deepdespeckling.utils": [[1, 0, 0, "-", "load_cosar"], [1, 0, 0, "-", "utils"]], "deepdespeckling.utils.load_cosar": [[1, 3, 1, "", "cos2mat"], [1, 3, 1, "", "load_tiff_image"]], "deepdespeckling.utils.utils": [[1, 3, 1, "", "compute_psnr"], [1, 3, 1, "", "create_empty_folder_in_directory"], [1, 3, 1, "", "crop_image"], [1, 3, 1, "", "denormalize_sar_image"], [1, 3, 1, "", "denormalize_sar_image_sar2sar"], [1, 3, 1, "", "get_cropping_coordinates"], [1, 3, 1, "", "get_cropping_coordinates_from_file"], [1, 3, 1, "", "get_maximum_patch_size"], [1, 3, 1, "", "get_maximum_patch_size_from_image_dimensions"], [1, 3, 1, "", "load_sar_image"], [1, 3, 1, "", "load_sar_images"], [1, 3, 1, "", "normalize_sar_image"], [1, 3, 1, "", "preprocess_and_store_sar_images"], [1, 3, 1, "", "preprocess_and_store_sar_images_from_coordinates"], [1, 3, 1, "", "preprocess_image"], [1, 3, 1, "", "preprocess_sar_image_for_cropping"], [1, 3, 1, "", "save_image_to_npy_and_png"], [1, 3, 1, "", "save_image_to_png"], [1, 3, 1, "", "symetrise_real_and_imaginary_parts"]]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:method", "3": "py:function", "4": "py:attribute"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "method", "Python method"], "3": ["py", "function", "Python function"], "4": ["py", "attribute", "Python attribute"]}, "titleterms": {"welcom": 0, "deepdespeckl": [0, 1], "": 0, "document": 0, "content": 0, "indic": 0, "tabl": 0, "denois": 1, "despeckl": 1, "model": 1, "merlin_denois": 1, "sar2sar_denois": 1, "util": 1, "descript": 1, "load_cosar": 1}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx": 60}, "alltitles": {"Welcome to deepdespeckling's documentation!": [[0, "welcome-to-deepdespeckling-s-documentation"]], "Contents:": [[0, null]], "Indices and tables": [[0, "indices-and-tables"]], "deepdespeckling": [[1, "module-deepdespeckling"]], "denoiser": [[1, "module-deepdespeckling.denoiser"]], "despeckling": [[1, "despeckling"]], "model": [[1, "module-deepdespeckling.model"]], "merlin_denoiser": [[1, "merlin-denoiser"]], "sar2sar_denoiser": [[1, "sar2sar-denoiser"]], "utils": [[1, "module-deepdespeckling.utils.utils"]], "Description": [[1, "description"]], "load_cosar": [[1, "load-cosar"]]}, "indexentries": {"denoiser (class in deepdespeckling.denoiser)": [[1, "deepdespeckling.denoiser.Denoiser"]], "merlindenoiser (class in deepdespeckling.merlin.merlin_denoiser)": [[1, "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser"]], "model (class in deepdespeckling.model)": [[1, "deepdespeckling.model.Model"]], "sar2sardenoiser (class in deepdespeckling.sar2sar.sar2sar_denoiser)": [[1, "deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser"]], "compute_psnr() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.compute_psnr"]], "cos2mat() (in module deepdespeckling.utils.load_cosar)": [[1, "deepdespeckling.utils.load_cosar.cos2mat"]], "create_empty_folder_in_directory() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.create_empty_folder_in_directory"]], "crop_image() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.crop_image"]], "deepdespeckling": [[1, "module-deepdespeckling"]], "deepdespeckling.denoiser": [[1, "module-deepdespeckling.denoiser"]], "deepdespeckling.despeckling": [[1, "module-deepdespeckling.despeckling"]], "deepdespeckling.merlin.merlin_denoiser": [[1, "module-deepdespeckling.merlin.merlin_denoiser"]], "deepdespeckling.model": [[1, "module-deepdespeckling.model"]], "deepdespeckling.sar2sar.sar2sar_denoiser": [[1, "module-deepdespeckling.sar2sar.sar2sar_denoiser"]], "deepdespeckling.utils.load_cosar": [[1, "module-deepdespeckling.utils.load_cosar"]], "deepdespeckling.utils.utils": [[1, "module-deepdespeckling.utils.utils"]], "denoise_image() (deepdespeckling.denoiser.denoiser method)": [[1, "deepdespeckling.denoiser.Denoiser.denoise_image"]], "denoise_image() (deepdespeckling.merlin.merlin_denoiser.merlindenoiser method)": [[1, "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image"]], "denoise_image() (deepdespeckling.sar2sar.sar2sar_denoiser.sar2sardenoiser method)": [[1, "deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image"]], "denoise_image_kernel() (deepdespeckling.denoiser.denoiser method)": [[1, "deepdespeckling.denoiser.Denoiser.denoise_image_kernel"]], "denoise_image_kernel() (deepdespeckling.merlin.merlin_denoiser.merlindenoiser method)": [[1, "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_image_kernel"]], "denoise_image_kernel() (deepdespeckling.sar2sar.sar2sar_denoiser.sar2sardenoiser method)": [[1, "deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_image_kernel"]], "denoise_images() (deepdespeckling.denoiser.denoiser method)": [[1, "deepdespeckling.denoiser.Denoiser.denoise_images"]], "denoise_images() (deepdespeckling.merlin.merlin_denoiser.merlindenoiser method)": [[1, "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.denoise_images"]], "denoise_images() (deepdespeckling.sar2sar.sar2sar_denoiser.sar2sardenoiser method)": [[1, "deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denoise_images"]], "denormalize_sar_image() (deepdespeckling.sar2sar.sar2sar_denoiser.sar2sardenoiser method)": [[1, "deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.denormalize_sar_image"]], "denormalize_sar_image() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.denormalize_sar_image"]], "denormalize_sar_image_sar2sar() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.denormalize_sar_image_sar2sar"]], "despeckle() (in module deepdespeckling.despeckling)": [[1, "deepdespeckling.despeckling.despeckle"]], "despeckle_from_coordinates() (in module deepdespeckling.despeckling)": [[1, "deepdespeckling.despeckling.despeckle_from_coordinates"]], "despeckle_from_crop() (in module deepdespeckling.despeckling)": [[1, "deepdespeckling.despeckling.despeckle_from_crop"]], "forward() (deepdespeckling.model.model method)": [[1, "deepdespeckling.model.Model.forward"]], "get_cropping_coordinates() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.get_cropping_coordinates"]], "get_cropping_coordinates_from_file() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.get_cropping_coordinates_from_file"]], "get_denoiser() (in module deepdespeckling.despeckling)": [[1, "deepdespeckling.despeckling.get_denoiser"]], "get_device() (deepdespeckling.denoiser.denoiser method)": [[1, "deepdespeckling.denoiser.Denoiser.get_device"]], "get_maximum_patch_size() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.get_maximum_patch_size"]], "get_maximum_patch_size_from_image_dimensions() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.get_maximum_patch_size_from_image_dimensions"]], "init_model_weights_path() (deepdespeckling.merlin.merlin_denoiser.merlindenoiser method)": [[1, "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.init_model_weights_path"]], "initialize_axis_range() (deepdespeckling.denoiser.denoiser method)": [[1, "deepdespeckling.denoiser.Denoiser.initialize_axis_range"]], "load_model() (deepdespeckling.merlin.merlin_denoiser.merlindenoiser method)": [[1, "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.load_model"]], "load_model() (deepdespeckling.sar2sar.sar2sar_denoiser.sar2sardenoiser method)": [[1, "deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.load_model"]], "load_sar_image() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.load_sar_image"]], "load_sar_images() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.load_sar_images"]], "load_tiff_image() (in module deepdespeckling.utils.load_cosar)": [[1, "deepdespeckling.utils.load_cosar.load_tiff_image"]], "module": [[1, "module-deepdespeckling"], [1, "module-deepdespeckling.denoiser"], [1, "module-deepdespeckling.despeckling"], [1, "module-deepdespeckling.merlin.merlin_denoiser"], [1, "module-deepdespeckling.model"], [1, "module-deepdespeckling.sar2sar.sar2sar_denoiser"], [1, "module-deepdespeckling.utils.load_cosar"], [1, "module-deepdespeckling.utils.utils"]], "normalize_sar_image() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.normalize_sar_image"]], "preprocess_and_store_sar_images() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.preprocess_and_store_sar_images"]], "preprocess_and_store_sar_images_from_coordinates() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.preprocess_and_store_sar_images_from_coordinates"]], "preprocess_denoised_image() (deepdespeckling.denoiser.denoiser method)": [[1, "deepdespeckling.denoiser.Denoiser.preprocess_denoised_image"]], "preprocess_denoised_image() (deepdespeckling.merlin.merlin_denoiser.merlindenoiser method)": [[1, "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_denoised_image"]], "preprocess_image() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.preprocess_image"]], "preprocess_noisy_image() (deepdespeckling.merlin.merlin_denoiser.merlindenoiser method)": [[1, "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.preprocess_noisy_image"]], "preprocess_sar_image_for_cropping() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.preprocess_sar_image_for_cropping"]], "save_despeckled_images() (deepdespeckling.denoiser.denoiser method)": [[1, "deepdespeckling.denoiser.Denoiser.save_despeckled_images"]], "save_despeckled_images() (deepdespeckling.merlin.merlin_denoiser.merlindenoiser method)": [[1, "deepdespeckling.merlin.merlin_denoiser.MerlinDenoiser.save_despeckled_images"]], "save_despeckled_images() (deepdespeckling.sar2sar.sar2sar_denoiser.sar2sardenoiser method)": [[1, "deepdespeckling.sar2sar.sar2sar_denoiser.Sar2SarDenoiser.save_despeckled_images"]], "save_image_to_npy_and_png() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.save_image_to_npy_and_png"]], "save_image_to_png() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.save_image_to_png"]], "symetrise_real_and_imaginary_parts() (in module deepdespeckling.utils.utils)": [[1, "deepdespeckling.utils.utils.symetrise_real_and_imaginary_parts"]], "training (deepdespeckling.model.model attribute)": [[1, "deepdespeckling.model.Model.training"]]}}) \ No newline at end of file