diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index d650bc66..c764bf41 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -1,19 +1,38 @@ -name: Deploy Sphinx documentation to Pages +name: deploy on: push: branches: # branch to trigger deployment - main +# This job installs dependencies, build the book, and pushes it to `gh-pages` jobs: - pages: - runs-on: ubuntu-20.04 + build-and-deploy-book: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + python-version: [3.8] steps: - - id: deployment - uses: sphinx-notes/pages@v3 + - uses: actions/checkout@v2 + + # Install dependencies + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v1 with: - publish: false - - uses: peaceiris/actions-gh-pages@v3 + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + pip install jupyter-book + + # Build the book + - name: Build the book + run: | + jupyter-book build docs/ + + # Deploy the book's HTML to gh-pages branch + - name: GitHub Pages action + uses: peaceiris/actions-gh-pages@v3.6.1 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ${{ steps.deployment.outputs.artifact }} + publish_dir: docs/_build/html diff --git a/.gitignore b/.gitignore index b767cced..9e08da2e 100644 --- a/.gitignore +++ b/.gitignore @@ -102,7 +102,8 @@ venv/ #dataset, weights, old logos, requirements /napari_cellseg3d/code_models/models/dataset/ /napari_cellseg3d/code_models/models/saved_weights/ -/docs/res/logo/old_logo/ +/docs/source/logo/old_logo/ +/docs/source/code/_autosummary/ /reqs/ /loss_plots/ notebooks/csv_cell_plot.html @@ -120,3 +121,8 @@ notebooks/instance_test.ipynb !napari_cellseg3d/_tests/res/wnet_test/lab/*.tif !napari_cellseg3d/_tests/res/wnet_test/vol/*.tif cov.syspath.txt + +#include docs images +!docs/source/logo/* +!docs/source/images/* +napari_cellseg3d/dev_scripts/wandb diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f9fe2853..88f44ebe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,7 @@ repos: - id: trailing-whitespace - id: check-yaml - id: check-added-large-files + args: [--maxkb=5000] - id: check-toml # - repo: https://github.com/pycqa/isort # rev: 5.12.0 diff --git a/conda/napari_cellseg3d_m1.yml b/conda/napari_cellseg3d_m1.yml index 8209be9e..d901c429 100644 --- a/conda/napari_cellseg3d_m1.yml +++ b/conda/napari_cellseg3d_m1.yml @@ -16,7 +16,7 @@ dependencies: - tifffile>=2022.2.9 - imageio-ffmpeg>=0.4.5 - torch>=1.11 - - monai[nibabel,einops]>=0.9.0 + - monai>=0.9.0 - tqdm - nibabel - scikit-image diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 5769afc3..00000000 --- a/docs/Makefile +++ /dev/null @@ -1,196 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -github: - @make html - @cp -a build/html/. ./docs - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/napari-cookiecutterplugin_name.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/napari-cookiecutterplugin_name.qhc" - -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/napari-cookiecutterplugin_name" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/napari-cookiecutterplugin_name" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/TODO.md b/docs/TODO.md new file mode 100644 index 00000000..31473b5b --- /dev/null +++ b/docs/TODO.md @@ -0,0 +1,8 @@ +[//]: # ( +TODO: +- [ ] Add a way to get the current version of the library +- [x] Update all modules +- [x] Better WNet tutorial +- [x] Setup GH Actions +- [ ] Add a bibliography +) diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 00000000..1dc49385 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,51 @@ +# Book settings +# Learn more at https://jupyterbook.org/customize/config.html + +title: napari-cellseg3d Documentation +author: Cyril Achard, Maxime Vidal, Timokleia Kousi, Mackenzie Mathis | Mathis Laboratory +logo: source/logo/logo_alpha.png + +# Force re-execution of notebooks on each build. +# See https://jupyterbook.org/content/execute.html +execute: + execute_notebooks: force + +# Define the name of the latex output file for PDF builds +latex: + latex_documents: + targetname: book.tex + +# Add a bibtex file so that we can create citations +bibtex_bibfiles: + - references.bib + +# Information about where the book exists on the web +repository: + url: https://github.com/AdaptiveMotorControlLab/CellSeg3d # Online location of your book + path_to_book: docs # Optional path to your book, relative to the repository root + branch: main # Which branch of the repository should be used when creating links (optional) + +# Add GitHub buttons to your book +# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository +html: + use_issues_button: true + use_repository_button: true + +# Add auto-generated API docs +sphinx: + extra_extensions: + - 'sphinx.ext.napoleon' + - 'sphinx.ext.autodoc' + - 'sphinx.ext.autosummary' + - 'sphinx.ext.viewcode' + - 'sphinx.ext.autosectionlabel' + config: + add_module_names: False + autosectionlabel_prefix_document: True + autosummary_generate: True + autoclass_content: "both" + # templates_path: ['_templates'] + exclude_patterns: + - '_build' + - '_templates' + # - 'napari_cellseg3d/__pycache__' diff --git a/docs/_templates/custom-class-template.rst b/docs/_templates/custom-class-template.rst new file mode 100644 index 00000000..cbe78b90 --- /dev/null +++ b/docs/_templates/custom-class-template.rst @@ -0,0 +1,32 @@ +{{ fullname | escape | underline}} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ objname }} + :members: + :show-inheritance: + + {% block methods %} + {% if methods %} + .. rubric:: {{ _('Methods') }} + + .. autosummary:: + :nosignatures: + {% for item in methods %} + {%- if not item.startswith('_') %} + ~{{ name }}.{{ item }} + {%- endif -%} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block attributes %} + {% if attributes %} + .. rubric:: {{ _('Attributes') }} + + .. autosummary:: + {% for item in attributes %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} diff --git a/docs/_templates/custom-module-template.rst b/docs/_templates/custom-module-template.rst new file mode 100644 index 00000000..d066d0e4 --- /dev/null +++ b/docs/_templates/custom-module-template.rst @@ -0,0 +1,66 @@ +{{ fullname | escape | underline}} + +.. automodule:: {{ fullname }} + + {% block attributes %} + {% if attributes %} + .. rubric:: Module attributes + + .. autosummary:: + :toctree: + {% for item in attributes %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block functions %} + {% if functions %} + .. rubric:: {{ _('Functions') }} + + .. autosummary:: + :toctree: + :nosignatures: + {% for item in functions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block classes %} + {% if classes %} + .. rubric:: {{ _('Classes') }} + + .. autosummary:: + :toctree: + :template: custom-class-template.rst + :nosignatures: + {% for item in classes %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block exceptions %} + {% if exceptions %} + .. rubric:: {{ _('Exceptions') }} + + .. autosummary:: + :toctree: + {% for item in exceptions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + +{% block modules %} +{% if modules %} +.. autosummary:: + :toctree: + :template: custom-module-template.rst + :recursive: +{% for item in modules %} + {{ item }} +{%- endfor %} +{% endif %} +{% endblock %} diff --git a/docs/_toc.yml b/docs/_toc.yml new file mode 100644 index 00000000..7b4e39fb --- /dev/null +++ b/docs/_toc.yml @@ -0,0 +1,23 @@ +# Table of contents + +format: jb-book +root: welcome.rst +parts: + - caption : User guides + chapters: + - file: source/guides/installation_guide.rst + - file: source/guides/review_module_guide.rst + - file: source/guides/training_module_guide.rst + - file: source/guides/inference_module_guide.rst + - file: source/guides/cropping_module_guide.rst + - file: source/guides/utils_module_guide.rst + - caption : Walkthroughs + chapters: + - file: source/guides/detailed_walkthrough.rst + - caption : Advanced guides + chapters: + - file: source/guides/training_wnet.rst + - file: source/guides/custom_model_template.rst + - caption : Code + chapters: + - file: source/code/api.rst diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index bc766d97..00000000 --- a/docs/conf.py +++ /dev/null @@ -1,306 +0,0 @@ -# -*- coding: utf-8 -*- -# -# napari-cellseg3d documentation build configuration file, created by -# sphinx-quickstart on Thu Oct 1 00:43:18 2015. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import os -import sys - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath("../src")) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "sphinx.ext.ifconfig", - "sphinx.ext.autodoc", - "sphinx.ext.napoleon", - "sphinx_autodoc_typehints", - "sphinx.ext.duration", -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = ".rst" - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The main toctree document. -main_doc = "index" - -# General information about the project. -project = "napari-cellseg3d" -copyright = "2022-2023, Cyril Achard, Maxime Vidal" -author = "Cyril Achard, Maxime Vidal" - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -# import __version__ from your package... -# version = '' -# # The full version, including alpha/beta/rc tags. -# release = '' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = "en" - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ["_build"] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = "sphinx_rtd_theme" - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -html_theme_options = { - "logo_only": True, - "display_version": False, -} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -html_logo = "res/logo/logo_alpha.png" - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = [] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = "napari-cookiecutterplugin_namedoc" - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - #'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - #'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - #'preamble': '', - # Latex figure (float) alignment - #'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ( - main_doc, - "napari-cookiecutterplugin_name.tex", - "napari-\\{\\{cookiecutter.plugin\\_name\\}\\} Documentation", - "\\{\\{cookiecutter.full\\_name\\}\\}", - "manual", - ), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ( - main_doc, - "napari-cookiecutterplugin_name", - "napari-cellseg3d Documentation", - [author], - 1, - ) -] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - main_doc, - "napari-cookiecutterplugin_name", - "napari-cellseg3d Documentation", - author, - "napari-cookiecutterplugin_name", - "One line description of project.", - "Miscellaneous", - ), -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 58f68606..00000000 --- a/docs/index.rst +++ /dev/null @@ -1,57 +0,0 @@ -Welcome to napari-cellseg3d's documentation! -=============================================================== - -.. toctree:: - :maxdepth: 1 - :caption: Main modules guides: - - res/welcome - res/guides/review_module_guide - res/guides/inference_module_guide - res/guides/training_module_guide - - -.. toctree:: - :maxdepth: 1 - :caption: Utilities : - - res/guides/metrics_module_guide - res/guides/utils_module_guide - res/guides/cropping_module_guide - - -.. toctree:: - :maxdepth: 2 - :caption: Advanced guides and walk-through: - - res/guides/training_wnet - res/guides/detailed_walkthrough - res/guides/custom_model_template - -.. toctree:: - :maxdepth: 1 - :caption: Source files: - - res/code/interface - res/code/plugin_base - res/code/plugin_review - res/code/plugin_review_dock - res/code/plugin_crop - res/code/plugin_convert - res/code/plugin_metrics - res/code/model_framework - res/code/workers - res/code/instance_segmentation - res/code/plugin_model_inference - res/code/plugin_model_training - res/code/utils - - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 3ab8ac64..00000000 --- a/docs/make.bat +++ /dev/null @@ -1,263 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - echo. coverage to run coverage check of the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -REM Check if sphinx-build is available and fallback to Python version if any -%SPHINXBUILD% 2> nul -if errorlevel 9009 goto sphinx_python -goto sphinx_ok - -:sphinx_python - -set SPHINXBUILD=python -m sphinx.__init__ -%SPHINXBUILD% 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.http://sphinx-doc.org/ - exit /b 1 -) - -:sphinx_ok - - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\napari-cookiecutterplugin_name.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\napari-cookiecutterplugin_name.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "coverage" ( - %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage - if errorlevel 1 exit /b 1 - echo. - echo.Testing of coverage in the sources finished, look at the ^ -results in %BUILDDIR%/coverage/python.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/docs/references.bib b/docs/references.bib new file mode 100644 index 00000000..783ec6aa --- /dev/null +++ b/docs/references.bib @@ -0,0 +1,56 @@ +--- +--- + +@inproceedings{holdgraf_evidence_2014, + address = {Brisbane, Australia, Australia}, + title = {Evidence for {Predictive} {Coding} in {Human} {Auditory} {Cortex}}, + booktitle = {International {Conference} on {Cognitive} {Neuroscience}}, + publisher = {Frontiers in Neuroscience}, + author = {Holdgraf, Christopher Ramsay and de Heer, Wendy and Pasley, Brian N. and Knight, Robert T.}, + year = {2014} +} + +@article{holdgraf_rapid_2016, + title = {Rapid tuning shifts in human auditory cortex enhance speech intelligibility}, + volume = {7}, + issn = {2041-1723}, + url = {http://www.nature.com/doifinder/10.1038/ncomms13654}, + doi = {10.1038/ncomms13654}, + number = {May}, + journal = {Nature Communications}, + author = {Holdgraf, Christopher Ramsay and de Heer, Wendy and Pasley, Brian N. and Rieger, Jochem W. and Crone, Nathan and Lin, Jack J. and Knight, Robert T. and Theunissen, Frédéric E.}, + year = {2016}, + pages = {13654}, + file = {Holdgraf et al. - 2016 - Rapid tuning shifts in human auditory cortex enhance speech intelligibility.pdf:C\:\\Users\\chold\\Zotero\\storage\\MDQP3JWE\\Holdgraf et al. - 2016 - Rapid tuning shifts in human auditory cortex enhance speech intelligibility.pdf:application/pdf} +} + +@inproceedings{holdgraf_portable_2017, + title = {Portable learning environments for hands-on computational instruction using container-and cloud-based technology to teach data science}, + volume = {Part F1287}, + isbn = {978-1-4503-5272-7}, + doi = {10.1145/3093338.3093370}, + abstract = {© 2017 ACM. There is an increasing interest in learning outside of the traditional classroom setting. This is especially true for topics covering computational tools and data science, as both are challenging to incorporate in the standard curriculum. These atypical learning environments offer new opportunities for teaching, particularly when it comes to combining conceptual knowledge with hands-on experience/expertise with methods and skills. Advances in cloud computing and containerized environments provide an attractive opportunity to improve the effciency and ease with which students can learn. This manuscript details recent advances towards using commonly-Available cloud computing services and advanced cyberinfrastructure support for improving the learning experience in bootcamp-style events. We cover the benets (and challenges) of using a server hosted remotely instead of relying on student laptops, discuss the technology that was used in order to make this possible, and give suggestions for how others could implement and improve upon this model for pedagogy and reproducibility.}, + booktitle = {{ACM} {International} {Conference} {Proceeding} {Series}}, + author = {Holdgraf, Christopher Ramsay and Culich, A. and Rokem, A. and Deniz, F. and Alegro, M. and Ushizima, D.}, + year = {2017}, + keywords = {Teaching, Bootcamps, Cloud computing, Data science, Docker, Pedagogy} +} + +@article{holdgraf_encoding_2017, + title = {Encoding and decoding models in cognitive electrophysiology}, + volume = {11}, + issn = {16625137}, + doi = {10.3389/fnsys.2017.00061}, + abstract = {© 2017 Holdgraf, Rieger, Micheli, Martin, Knight and Theunissen. Cognitive neuroscience has seen rapid growth in the size and complexity of data recorded from the human brain as well as in the computational tools available to analyze this data. This data explosion has resulted in an increased use of multivariate, model-based methods for asking neuroscience questions, allowing scientists to investigate multiple hypotheses with a single dataset, to use complex, time-varying stimuli, and to study the human brain under more naturalistic conditions. These tools come in the form of “Encoding” models, in which stimulus features are used to model brain activity, and “Decoding” models, in which neural features are used to generated a stimulus output. Here we review the current state of encoding and decoding models in cognitive electrophysiology and provide a practical guide toward conducting experiments and analyses in this emerging field. Our examples focus on using linear models in the study of human language and audition. We show how to calculate auditory receptive fields from natural sounds as well as how to decode neural recordings to predict speech. The paper aims to be a useful tutorial to these approaches, and a practical introduction to using machine learning and applied statistics to build models of neural activity. The data analytic approaches we discuss may also be applied to other sensory modalities, motor systems, and cognitive systems, and we cover some examples in these areas. In addition, a collection of Jupyter notebooks is publicly available as a complement to the material covered in this paper, providing code examples and tutorials for predictive modeling in python. The aimis to provide a practical understanding of predictivemodeling of human brain data and to propose best-practices in conducting these analyses.}, + journal = {Frontiers in Systems Neuroscience}, + author = {Holdgraf, Christopher Ramsay and Rieger, J.W. and Micheli, C. and Martin, S. and Knight, R.T. and Theunissen, F.E.}, + year = {2017}, + keywords = {Decoding models, Encoding models, Electrocorticography (ECoG), Electrophysiology/evoked potentials, Machine learning applied to neuroscience, Natural stimuli, Predictive modeling, Tutorials} +} + +@book{ruby, + title = {The Ruby Programming Language}, + author = {Flanagan, David and Matsumoto, Yukihiro}, + year = {2008}, + publisher = {O'Reilly Media} +} diff --git a/docs/res/code/instance_segmentation.rst b/docs/res/code/instance_segmentation.rst deleted file mode 100644 index 348648f8..00000000 --- a/docs/res/code/instance_segmentation.rst +++ /dev/null @@ -1,49 +0,0 @@ -instance_segmentation.py -=========================================== - -Classes -------------- - -InstanceMethod -************************************** -.. autoclass:: napari_cellseg3d.code_models.instance_segmentation::InstanceMethod - :members: __init__ - -ConnectedComponents -************************************** -.. autoclass:: napari_cellseg3d.code_models.instance_segmentation::ConnectedComponents - :members: __init__ - -Watershed -************************************** -.. autoclass:: napari_cellseg3d.code_models.instance_segmentation::Watershed - :members: __init__ - -VoronoiOtsu -************************************** -.. autoclass:: napari_cellseg3d.code_models.instance_segmentation::VoronoiOtsu - :members: __init__ - - -Functions -------------- - -binary_connected -************************************** -.. autofunction:: napari_cellseg3d.code_models.instance_segmentation::binary_connected - -binary_watershed -************************************** -.. autofunction:: napari_cellseg3d.code_models.instance_segmentation::binary_watershed - -volume_stats -************************************** -.. autofunction:: napari_cellseg3d.code_models.instance_segmentation::volume_stats - -clear_small_objects -************************************** -.. autofunction:: napari_cellseg3d.code_models.instance_segmentation::clear_small_objects - -to_semantic -************************************** -.. autofunction:: napari_cellseg3d.code_models.instance_segmentation::to_semantic diff --git a/docs/res/code/interface.rst b/docs/res/code/interface.rst deleted file mode 100644 index 8bf43e04..00000000 --- a/docs/res/code/interface.rst +++ /dev/null @@ -1,107 +0,0 @@ -interface.py -============= - -Classes -------------- - -QWidgetSingleton -************************************** -.. autoclass:: napari_cellseg3d.interface::QWidgetSingleton - :members: __call__ - -UtilsDropdown -************************************** -.. autoclass:: napari_cellseg3d.interface::UtilsDropdown - :members: __init__, dropdown_menu_call, show_utils_menu - -Log -************************************** -.. autoclass:: napari_cellseg3d.interface::Log - :members: __init__, write, replace_last_line, print_and_log, warn - - -ContainerWidget -************************************** -.. autoclass:: napari_cellseg3d.interface::ContainerWidget - :members: __init__ - -Button -************************************** -.. autoclass:: napari_cellseg3d.interface::Button - :members: __init__, visibility_condition - -DropdownMenu -************************************** -.. autoclass:: napari_cellseg3d.interface::DropdownMenu - :members: __init__ - -CheckBox -************************************** -.. autoclass:: napari_cellseg3d.interface::CheckBox - :members: __init__ - -AnisotropyWidgets -************************************** -.. autoclass:: napari_cellseg3d.interface::AnisotropyWidgets - :members: __init__, build, scaling_zyx, resolution_zyx, scaling_xyz, resolution_xyz,enabled - - -FilePathWidget -************************************** -.. autoclass:: napari_cellseg3d.interface::FilePathWidget - :members: __init__, build, text_field, button, check_ready, required, update_field_color, tooltips - -ScrollArea -************************************** -.. autoclass:: napari_cellseg3d.interface::ScrollArea - :members: __init__, make_scrollable - -DoubleIncrementCounter -************************************** -.. autoclass:: napari_cellseg3d.interface::DoubleIncrementCounter - :members: __init__, precision, make_n - -IntIncrementCounter -************************************** -.. autoclass:: napari_cellseg3d.interface::IntIncrementCounter - :members: __init__, make_n - - -Functions -------------- - -handle_adjust_errors -************************************** -.. autofunction:: napari_cellseg3d.interface::handle_adjust_errors - -handle_adjust_errors_wrapper -************************************** -.. autofunction:: napari_cellseg3d.interface::handle_adjust_errors_wrapper - -open_url -************************************** -.. autofunction:: napari_cellseg3d.interface::open_url - -make_group -************************************** -.. autofunction:: napari_cellseg3d.interface::make_group - -combine_blocks -************************************** -.. autofunction:: napari_cellseg3d.interface::combine_blocks - -add_blank -************************************** -.. autofunction:: napari_cellseg3d.interface::add_blank - -add_label -************************************** -.. autofunction:: napari_cellseg3d.interface::add_label - -toggle_visibility -************************************** -.. autofunction:: napari_cellseg3d.interface::toggle_visibility - -open_file_dialog -************************************** -.. autofunction:: napari_cellseg3d.interface::open_file_dialog diff --git a/docs/res/code/model_framework.rst b/docs/res/code/model_framework.rst deleted file mode 100644 index 63eef232..00000000 --- a/docs/res/code/model_framework.rst +++ /dev/null @@ -1,23 +0,0 @@ -.. _model_framework.py: - - -model_framework.py -==================================================== - - -Class : ModelFramework ----------------------------------------------------- - - -Methods -********************** -.. autoclass:: napari_cellseg3d.code_models.model_framework::ModelFramework - :members: __init__, send_log, save_log, save_log_to_path, display_status_report, create_train_dataset_dict, get_available_models, get_device, empty_cuda_cache - :noindex: - - -Attributes -********************* - -.. autoclass:: napari_cellseg3d.code_models.model_framework::ModelFramework - :members: _viewer, worker, docked_widgets, images_filepaths, labels_filepaths, results_path diff --git a/docs/res/code/plugin_base.rst b/docs/res/code/plugin_base.rst deleted file mode 100644 index f1015c7e..00000000 --- a/docs/res/code/plugin_base.rst +++ /dev/null @@ -1,38 +0,0 @@ -plugin_base.py -==================================================== - - -Class : BasePluginSingleImage ----------------------------------------------------- - - -Methods -********************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_base::BasePluginSingleImage - :members: __init__, enable_utils_menu, remove_from_viewer, remove_docked_widgets - :noindex: - -Attributes -********************* - -.. autoclass:: napari_cellseg3d.code_plugins.plugin_base::BasePluginSingleImage - :members: _viewer, image_path, label_path, image_layer_loader, label_layer_loader - - - - -Class : BasePluginFolder -------------------------------------------------------- - - -Methods -*********************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_base::BasePluginFolder - :members: __init__, load_dataset_paths,load_image_dataset,load_label_dataset - :noindex: - -Attributes -********************* - -.. autoclass:: napari_cellseg3d.code_plugins.plugin_base::BasePluginFolder - :members: _viewer, images_filepaths, labels_filepaths, results_path diff --git a/docs/res/code/plugin_convert.rst b/docs/res/code/plugin_convert.rst deleted file mode 100644 index 25006d0f..00000000 --- a/docs/res/code/plugin_convert.rst +++ /dev/null @@ -1,30 +0,0 @@ -plugin_convert.py -================================== - -Classes ----------------------------------- - -AnisoUtils -********************************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_convert::AnisoUtils - :members: __init__ - -RemoveSmallUtils -********************************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_convert::RemoveSmallUtils - :members: __init__ - -ToSemanticUtils -********************************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_convert::ToSemanticUtils - :members: __init__ - -ToInstanceUtils -********************************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_convert::ToInstanceUtils - :members: __init__ - -ThresholdUtils -********************************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_convert::ThresholdUtils - :members: __init__ diff --git a/docs/res/code/plugin_crop.rst b/docs/res/code/plugin_crop.rst deleted file mode 100644 index f52fd025..00000000 --- a/docs/res/code/plugin_crop.rst +++ /dev/null @@ -1,25 +0,0 @@ -plugin_crop.py -==================================================== - - -Class : Cropping ----------------------------------------------------- - -.. important:: - Inherits from : :doc:`plugin_base` - - -Methods -********************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_crop::Cropping - :members: __init__, _start, quicksave, remove_from_viewer - :noindex: - - - - -Attributes -********************* - -.. autoclass:: napari_cellseg3d.code_plugins.plugin_crop::Cropping - :members: _viewer, image_path, label_path diff --git a/docs/res/code/plugin_metrics.rst b/docs/res/code/plugin_metrics.rst deleted file mode 100644 index 29c2fe25..00000000 --- a/docs/res/code/plugin_metrics.rst +++ /dev/null @@ -1,22 +0,0 @@ -plugin_metrics.py -================================== - - -Class : MetricsUtils ------------------------------------------- - -.. important:: - Inherits from : :doc:`plugin_base` - -Methods -********************** - -.. autoclass:: napari_cellseg3d.code_plugins.plugin_metrics::MetricsUtils - :members: __init__, plot_dice, remove_plots, compute_dice - :noindex: - -Attributes -********************* - -.. autoclass:: napari_cellseg3d.code_plugins.plugin_metrics::MetricsUtils - :members: _viewer, layout, canvas, plots diff --git a/docs/res/code/plugin_model_inference.rst b/docs/res/code/plugin_model_inference.rst deleted file mode 100644 index cdd4d6eb..00000000 --- a/docs/res/code/plugin_model_inference.rst +++ /dev/null @@ -1,24 +0,0 @@ -plugin_model_inference.py -==================================================== - - -Class : Inferer ----------------------------------------------------- - -.. important:: - Inherits from : :doc:`model_framework` - -Methods -********************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_model_inference::Inferer - :members: __init__, start,on_start,on_error,on_finish,on_yield, check_ready, remove_from_viewer - :noindex: - - - - -Attributes -********************* - -.. autoclass:: napari_cellseg3d.code_plugins.plugin_model_inference::Inferer - :members: _viewer, worker, config, instance_config, post_process_config, worker_config, model_info diff --git a/docs/res/code/plugin_model_training.rst b/docs/res/code/plugin_model_training.rst deleted file mode 100644 index 6a2a39b8..00000000 --- a/docs/res/code/plugin_model_training.rst +++ /dev/null @@ -1,22 +0,0 @@ -plugin_model_training.py -==================================================== - - -Class : Trainer ----------------------------------------------------- - -.. important:: - Inherits from : :doc:`model_framework` - -Methods -********************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_model_training::Trainer - :members: __init__, check_ready, send_log, start, on_start, on_finish, on_error, on_yield, update_loss_plot - :noindex: - - - -Attributes -********************* -.. autoclass:: napari_cellseg3d.code_plugins.plugin_model_training::Trainer - :members: _viewer, worker, canvas diff --git a/docs/res/code/plugin_review.rst b/docs/res/code/plugin_review.rst deleted file mode 100644 index 69397400..00000000 --- a/docs/res/code/plugin_review.rst +++ /dev/null @@ -1,26 +0,0 @@ -plugin_review.py -==================================================== - - -Class : Loader ----------------------------------------------------- - -.. important:: - Inherits from : :doc:`plugin_base` - -Methods -********************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_review::Reviewer - :members: __init__, run_review, launch_review, check_image_data, remove_from_viewer - :noindex: - - - - - - -Attributes -********************* - -.. autoclass:: napari_cellseg3d.code_plugins.plugin_review::Reviewer - :members: _viewer, image_path, label_path diff --git a/docs/res/code/plugin_review_dock.rst b/docs/res/code/plugin_review_dock.rst deleted file mode 100644 index 3aa0f6ae..00000000 --- a/docs/res/code/plugin_review_dock.rst +++ /dev/null @@ -1,21 +0,0 @@ -plugin_dock.py -==================================================== - -Datamanager ----------------------------------------------------- - -Methods -********************** -.. autoclass:: napari_cellseg3d.code_plugins.plugin_review_dock::Datamanager - :members: __init__, prepare, update, load_csv, create - :noindex: - - - - - -Attributes -********************* - -.. autoclass:: napari_cellseg3d.code_plugins.plugin_review_dock::Datamanager - :members: viewer diff --git a/docs/res/code/utils.rst b/docs/res/code/utils.rst deleted file mode 100644 index 88046b6f..00000000 --- a/docs/res/code/utils.rst +++ /dev/null @@ -1,60 +0,0 @@ -utils.py -============= - -Classes -------------- - -Singleton -************************************** -.. autoclass:: napari_cellseg3d.utils::Singleton - -Functions -------------- - -get_date_time -************************************** -.. autofunction:: napari_cellseg3d.utils::get_date_time - -get_time -************************************** -.. autofunction:: napari_cellseg3d.utils::get_time - -time_difference -************************************** -.. autofunction:: napari_cellseg3d.utils::time_difference - -get_time_filepath -************************************** -.. autofunction:: napari_cellseg3d.utils::get_time_filepath - -get_padding_dim -************************************** -.. autofunction:: napari_cellseg3d.utils::get_padding_dim - -dice_coeff -************************************** -.. autofunction:: napari_cellseg3d.utils::dice_coeff - -sphericity_volume_area -************************************** -.. autofunction:: napari_cellseg3d.utils::sphericity_volume_area - -sphericity_axis -************************************** -.. autofunction:: napari_cellseg3d.utils::sphericity_axis - -normalize_x -************************************** -.. autofunction:: napari_cellseg3d.utils::normalize_x - -normalize_y -************************************** -.. autofunction:: napari_cellseg3d.utils::normalize_y - -denormalize_y -************************************** -.. autofunction:: napari_cellseg3d.utils::denormalize_y - -load_images -************************************** -.. autofunction:: napari_cellseg3d.utils::load_images diff --git a/docs/res/code/workers.rst b/docs/res/code/workers.rst deleted file mode 100644 index 5964e004..00000000 --- a/docs/res/code/workers.rst +++ /dev/null @@ -1,70 +0,0 @@ -workers.py -=========================================== - - -Class : LogSignal -------------------------------------------- - -.. important:: - Inherits from :py:class:`napari.qt.threading.WorkerBaseSignals` - -Attributes -************************ -.. autoclass:: napari_cellseg3d.code_models.workers_utils::LogSignal - :members: log_signal - :noindex: - - - -Class : InferenceWorker -------------------------------------------- - -.. important:: - Inherits from :py:class:`napari.qt.threading.GeneratorWorker` - -Methods -************************ -.. autoclass:: napari_cellseg3d.code_models.worker_inference::InferenceWorker - :members: __init__, log, create_inference_dict, inference - :noindex: - -.. _here: https://napari-staging-site.github.io/guides/stable/threading.html - - -Class : TrainingWorkerBase -------------------------------------------- - -.. important:: - Inherits from :py:class:`napari.qt.threading.GeneratorWorker` - -Methods -************************ -.. autoclass:: napari_cellseg3d.code_models.worker_training::TrainingWorkerBase - :members: __init__, log, train - :noindex: - - -Class : WNetTrainingWorker -------------------------------------------- - -.. important:: - Inherits from :py:class:`TrainingWorkerBase` - -Methods -************************ -.. autoclass:: napari_cellseg3d.code_models.worker_training::WNetTrainingWorker - :members: __init__, train, eval, get_patch_dataset, get_dataset_eval, get_dataset - :noindex: - - -Class : SupervisedTrainingWorker -------------------------------------------- - -.. important:: - Inherits from :py:class:`TrainingWorkerBase` - -Methods -************************ -.. autoclass:: napari_cellseg3d.code_models.worker_training::SupervisedTrainingWorker - :members: __init__, train - :noindex: diff --git a/docs/res/guides/cropping_module_guide.rst b/docs/res/guides/cropping_module_guide.rst deleted file mode 100644 index 89cbb39a..00000000 --- a/docs/res/guides/cropping_module_guide.rst +++ /dev/null @@ -1,66 +0,0 @@ -.. _cropping_module_guide: - -Cropping utility guide -================================= - -This module allows you to crop your volumes and labels dynamically, -by selecting a fixed size volume and moving it around the image. - -You can then save the cropped volume and labels directly using napari, -by using the **Quicksave** button, -or by selecting the layer and then using **File -> Save selected layer**, -or simply **CTRL+S** once you have selected the correct layer. - - -Launching the cropping process ---------------------------------- - -First, simply pick your images using the layer selection dropdown menu. -If you'd like to crop a second image, e.g. labels, at the same time, -simply check the *"Crop another image simultaneously"* checkbox and -pick the corresponding layer. - -You can then choose the size of the cropped volume, which will be constant throughout the process; make sure it is correct beforehand. - -You can also opt to correct the anisotropy if your image is anisotropic : -simply set the resolution to the one of your microscope. - -.. important:: - This will simply scale the image in the viewer, but saved images will **still be anisotropic.** To resize your image, see :doc:`utils_module_guide` - -Once you are ready, you can press **Start** to start the review process. -If you'd like to change the size of the volume, change the parameters as previously to your desired size and hit start again. - -Creating new layers ---------------------------------- -To "zoom in" your volume, you can use the "Create new layers" checkbox to make a new cropping layer controlled by the sliders -next time you hit Start. This way, you can first select your region of interest by using the tool as described above, -then enable the option, select the cropped region produced before as the input layer, and define a smaller crop size in order to crop within your region of interest. - -Interface & functionalities ---------------------------------------------------------------- - -.. image:: ../images/cropping_process_example.png - -Once you have launched the review process, you will have access to three sliders that will let -you **change the position** of the cropped volumes and labels in the x,y and z positions. - -.. hint:: - If you **cannot see your cropped volume well**, feel free to change the **colormap** of the image and the cropped - volume to better see them. - You may want to change the **opacity** and **contrast thresholds** depending on your image, too. - - -.. note:: - When you are done you can save the cropped volume and labels directly with the - **Quicksave** button on the lower left, which will save in the folder you picked the image from, or as - a separate folder if you loaded a folder as a stack. - If you want more options (name, format) you can save by selecting the layer and then - using **File -> Save selected layer**, or simply **CTRL+S** once you have selected the correct layer. - -.. - Source code - ------------------------------------------------- - - * :doc:`../code/plugin_crop` - * :doc:`../code/plugin_base` diff --git a/docs/res/guides/detailed_walkthrough.rst b/docs/res/guides/detailed_walkthrough.rst deleted file mode 100644 index 4fd04510..00000000 --- a/docs/res/guides/detailed_walkthrough.rst +++ /dev/null @@ -1,293 +0,0 @@ -.. _detailed_walkthrough: - -Detailed walkthrough - Supervised learning -=================================================== - -The following guide will show you how to use the plugin's workflow, starting from human-labeled annotation volume, to running inference on novel volumes. - -Preparing images and labels -------------------------------- - -CellSeg3D was designed for cleared-brain tissue data (collected on mesoSPIM ligthsheet systems). Specifically, we provide a series -of deep learning models that we have found to work well on cortical whole-neuron data. We also provide support for MONAI models, and -we have ported TRAILMAP to PyTorch and trained the model on mesoSPIM collected data. We provide all the tooling for you to use these -weights and also perform transfer learning by fine-tuning the model(s) on your data for even better performance! - -To get started with the entire workflow (i.e., fine-tuning on your data), you'll need at least one pair of image and corresponding labels; -let's assume you have part of a cleared brain from mesoSPIM imaging as a large .tif file. - -If you want to test the models "as is", please see "Inference" sections in our docs. - - -.. figure:: ../images/init_image_labels.png - :scale: 40 % - :align: center - - Example of an anisotropic volume (i.e., often times the z resolution is not the same as x and y) and its associated labels. - - -.. note:: - The approach here will be human-in-the-loop review of labels. - If you need to label your volumes from scratch, - or initially correct labels, please read the Review section right after Cropping. - - -Cropping -***************** - -To reduce memory requirements and build a dataset from a single, large volume, -you can use the **cropping** tool to extract multiple smaller images from a large volume for training. - -Simply load your image and labels (by checking the "Crop labels simultaneously" option), -and select the volume size you desire to use. - -.. note:: - The best way to choose the size when cropping images you intend to use for training models is to use - cubic images sized with a power of two : the default :math:`64^3` should be a good start if you're unsure. - Stick to the same size for a given dataset. - If you simply want to isolate specific regions with variable sizes, you can still compensate for it in training though. - You may also use different image sizes for inference, simply ensure that images in a folder are of a similar size if you - wish to run inference on all of them. - -You can now use the sliders to choose the regions you want to extract, -then either quicksave the results or select the layer you'd like to save and use **CTRL+S** to save it -(useful if you want to name the results or change the file extension). - -.. figure:: ../images/cropping_process_example.png - :align: center - - Cropping module layout - -Label conversion : convert utility -************************************* - -Assuming you have instance labels, you'll need to convert them to semantic labels before using them for training. -To this end, you can use the folder conversion functions in the *Convert* tab of Utilities : -choose your output directory for the results, select the folder containing your cropped volumes in the *Convert folder* -section, and click on **"Convert to semantic labels"**. - -.. figure:: ../images/converted_labels.png - :scale: 40 % - :align: center - - Example of instance labels from above converted to semantic labels - -If you wish to remove small objects, or convert a single image, you can open a single image with **CTRL+O** -and, after selecting the corresponding layer on the left, use the layer-related buttons to perform -your operations. - -Models for object detection ------------------------------------------------------------ - -Training -***************** - -If you have a dataset of reasonably sized images (see cropping above) with semantic labels, you're all set to proceed! -First, load your data by inputting the paths to images and labels, as well as where you want the results to be saved. - -There are a few more options on this tab: - -* Transfer weights : you can start the model with our pre-trained weights if your dataset comes from cleared brain tissue - imaged by a mesoSPIM (or other lightsheet). If you have your own weights for the provided models, you can also choose to load them by - checking the related option; simply make sure they are compatible with the model you selected. - - To import your own model, see : :ref:`custom_model_guide`, please note this is still a WIP. - -* Validation proportion : the percentage is listed is how many images will be used for training versus validation. - Validation can work with as little as one image, however performance will greatly improve the more images there are. - Use 90% only if you have a very small dataset (less than 5 images). - -* Save as zip : simply copies the results in a zip archive for easier transfer. - -Now, we can switch to the next tab : data augmentation. - -If you have cropped cubic images with a power of two as the edge length, you do not need to extract patches, -your images are usable as is. -However, if you are using larger images or with dissimilar sizes, -you can use this option to auto-extract smaller patches that will be automatically padded back to a power -of two no matter the size you choose. For optimal performance, make sure to use a value close or equal to -a power of two still, such as 64 or 120. - -.. important:: - Using a too large value for the size will cause memory issues. If this happens, restart the worker with smaller volumes. - -You also have the option to use data augmentation, which can improve performance and generalization. -In most cases this should left enabled. - -Finally, the last tab lets you choose : - -* The models - - * SegResNet is a lightweight model (low memory requirements) from MONAI originally designed for 3D fMRI data. - * VNet is a larger (than SegResNet) CNN from MONAI designed for medical image segmentation. - * TRAILMAP_MS is our implementation in PyTorch additionally trained on mouse cortical neural nuclei from mesoSPIM data. - * SwinUNetR is a MONAI implementation of the SwinUNetR model. It is costly in compute and memory, but can achieve high performance. - * WNet is our reimplementation of an unsupervised model, which can be used to produce segmentation without labels. - - -* The loss : for object detection in 3D volumes you'll likely want to use the Dice or Dice-focal Loss. - -* Batch size : chose a value that fits your available memory. If you want to avoid memory issues due to the batch size, - leave it on one. - -* Learning rate : if you are not using pre-trained weights or loading your own custom ones, try with 1e-3. Use smaller values - if you are using custom/pre-trained weights. - -* Number of epochs : The larger the value, the longer the training will take, but performance might improve with longer - training. You could start with 40, and see if the loss decreases while the validation metric rises. - -.. note:: - During training, you can monitor the process using the plots : the one on the right (validation) should increase - whereas the loss should decrease. If the validation starts lowering after reaching a maximum, but the loss still decreases, - it could indicate over-fitting, which will negatively impact generalization for the given weights. - You might want use weights generated from the epoch with the maximum validation score if that is the case. - -.. figure:: ../images/plots_train.png - :align: center - - Plots displayed by the training module after 40 epochs - -* Validation interval : if the value is e.g. 2, the training will stop every 2 epochs to perform validation (check performance) - and save the results if the score is better than previously. A larger value will accelerate training, but might cause the saving to miss - better scores. Reasonably, start with 1 for short training sessions (less than 10 epochs) and increase it to two or three if you are training - for 20-60 epochs. - -* Deterministic training : if you wish for the training to have reproducibility, enable this and remember the seed you use. - Using the same seed with the same model, images, and parameters should consistently yield similar results. See `MONAI deterministic training`_. - -.. _MONAI deterministic training: https://docs.monai.io/en/stable/utils.html#module-monai.utils.misc - -Once all these parameters are set, you can start the training. You can monitor the progress with the plots; should you want to stop -the training you can do so anytime by pressing the Start button again, whose text should change to **Click to stop**. - -In the results folder, you will have access to the weights from training (**.pth** files), -which you can then use in inference. - -Inference -************* - -To start, simply choose which folder of images you'd like to run inference on, then the folder in which you'd like the results to be. - -Then, select the model you trained (see note below for SegResNet), and load your weights from training. - -.. note:: - If you already trained a SegResNet, set the counter below the model choice to the size of the images you trained the model on. - (Either use the size of the image itself if you did not extract patches, or the size of the nearest superior power of two of the patches you extracted) - - Example : - - * If you used :math:`64^3` whole volumes to train the model, enter :math:`64` in the counter. - * If you extracted :math:`120^3` patches from larger images, enter :math:`128` - - -Next, you can choose to use window inference, use this if you have very large images. -Please note that using too small of a window might degrade performance, set the size appropriately. - -You can also keep the dataset on the CPU to reduce memory usage, but this might slow down the inference process. - -If you have anisotropic volumes, you can compensate for it by entering the resolution of your microscope. - -By default, inference will calculate and display probability maps (values between 0 and 1). - -If you'd like to have semantic labels (only 0 and 1) rather than a probability map, set the thresholding to the desired probability. - -If instead you'd prefer to have instance labels, you can enable instance segmentation and select : - -* The method - - * Connected components : all separated items with a value above the threshold will be labeled as an instance - * Watershed : objects will be assigned an ID by using the gradient probability at the center of each (set the threshold to a decently high probability for best results). - -* The threshold : Objects above this threshold will be retained as single instances. - -* Small object removal : Use this to remove small artifacts; all objects below this volume in pixels will be removed. - -Using instance segmentation, you can also analyze the results by checking the *Save stats to CSV* option. - -This will compute : - -* The volume of each cell in pixels -* The centroid coordinates in :math:`X,Y,Z` -* The sphericity of each cell -* The original size of the image -* The total volume in pixels -* The total volume occupied by objects -* The ratio of :math:`\frac {Volume_{label}} {Volume_{total}}` -* The total number of unique object instance - -If you wish to see some of the results, you can leave the *View results in napari* option checked. - -.. note:: - If you'd like some of these results to be plotted for you, check out the `provided notebooks`_ - -.. _provided notebooks: https://github.com/AdaptiveMotorControlLab/CellSeg3d/tree/main/notebooks - - -You can then launch inference and the results will be saved to your specified folder. - -.. figure:::: ../image/inference_results_example.png - - Example of results from inference with original volumes, as well as semantic and instance predictions. - -.. figure:: ../images/plot_example_metrics.png - :scale: 30 % - :align: right - - Dice metric score plot - -Scoring, review, analysis ----------------------------- - - -.. Using the metrics utility module, you can compare the model's predictions to any ground truth labels you might have. - Simply provide your prediction and ground truth labels, and compute the results. - A Dice metric of 1 indicates perfect matching, whereas a score of 0 indicates complete mismatch. - Select which score **you consider as sub-optimal**, and all results below this will be **shown in napari**. - If at any time the **orientation of your prediction labels changed compared to the ground truth**, check the - "Find best orientation" option to compensate for it. - - -Labels review -************************ - -Using the review module, you can correct the predictions from the model. -Simply load your images and labels, enter the name of the CSV (to keep track of the review process, it will -record which slices have been checked or not and the time taken). - -See the `napari tutorial on annotation`_ for instruction on correcting and adding labels. - -.. _napari tutorial on annotation: https://napari.org/howtos/layers/labels.html#selecting-a-label - -If you wish to see the surroundings of an object to ensure it should be labeled, -you can use **Shift+Click** on the location you wish to see; this will plot -the surroundings of the selected location for easier viewing. - -.. figure:: ../images/review_process_example.png - :align: center - - Layout of the review module - -Once you are done with the review of a slice, press the "Not checked" button to switch the status to -"Checked" and save the time taken in the csv file. - -Finally, when you are done, press the *Save* button to record your work. - -Analysis : Jupyter notebooks -********************************* - -In the `notebooks folder of the repository`_, you can find notebooks you can use directly to plot -labels (full_plot.ipynb) or notebooks for plotting the results from your inference csv with object stats (csv_cell_plot.ipynb). - -Simply enter your folder or csv file path and the notebooks will plot your results. -Make sure you have all required libraries installed and jupyter extensions set up as explained -for the plots to work. - -.. figure:: ../images/stat_plots.png - :align: center - - Example of the plot present in the notebooks. - Coordinates are based on centroids, the size represents the volume, the color the sphericity. - -.. _notebooks folder of the repository: https://github.com/AdaptiveMotorControlLab/CellSeg3d/tree/main/notebooks - -With this complete, you can repeat the workflow as needed. diff --git a/docs/res/guides/inference_module_guide.rst b/docs/res/guides/inference_module_guide.rst deleted file mode 100644 index 77f3a859..00000000 --- a/docs/res/guides/inference_module_guide.rst +++ /dev/null @@ -1,146 +0,0 @@ -.. _inference_module_guide: - -Inference module guide -================================= - -This module allows you to use pre-trained segmentation algorithms (written in Pytorch) on 3D volumes -to automatically label cells. - -.. important:: - Currently, only inference on **3D volumes is supported**. If using folders, your images and labels folders - should both contain a set of **3D image files**, either **.tif** or **.tiff**. - Otherwise you may run inference on layers in napari. - -Currently, the following pre-trained models are available : - -============== ================================================================================================ -Model Link to original paper -============== ================================================================================================ -VNet `Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation`_ -SegResNet `3D MRI brain tumor segmentation using autoencoder regularization`_ -TRAILMAP_MS A PyTorch implementation of the `TRAILMAP project on GitHub`_ pretrained with mesoSPIM data -TRAILMAP An implementation of the `TRAILMAP project on GitHub`_ using a `3DUNet for PyTorch`_ -SwinUNetR `Swin Transformers for Semantic Segmentation of Brain Tumors in MRI Images`_ -WNet `WNet, A Deep Model for Fully Unsupervised Image Segmentation`_ -============== ================================================================================================ - -.. _Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation: https://arxiv.org/pdf/1606.04797.pdf -.. _3D MRI brain tumor segmentation using autoencoder regularization: https://arxiv.org/pdf/1810.11654.pdf -.. _TRAILMAP project on GitHub: https://github.com/AlbertPun/TRAILMAP -.. _3DUnet for Pytorch: https://github.com/wolny/pytorch-3dunet -.. _Swin Transformers for Semantic Segmentation of Brain Tumors in MRI Images: https://arxiv.org/abs/2201.01266 -.. _WNet, A Deep Model for Fully Unsupervised Image Segmentation: https://arxiv.org/abs/1711.08506 - -.. note:: - For WNet-specific instruction please refer to the appropriate section below. - -Interface and functionalities --------------------------------- - -.. image:: ../images/inference_plugin_layout.png - :align: right - :scale: 40% - -* **Loading data** : - - | When launching the module, you will be asked to provide an **image layer** or an **image folder** with the 3D volumes you'd like to be labeled. - | If loading from folder : All images with the chosen extension (**.tif** or **.tiff** currently supported) in this folder will be labeled. - | You can then choose an **output folder**, where all the results will be saved. - -* **Model choice** : - - | You can then choose one of the provided **models** above, which will be used for inference. - | You may also choose to **load custom weights** rather than the pre-trained ones, simply ensure they are **compatible** (e.g. produced from the training module for the same model) - | If you choose to use SegResNet or SwinUNetR with custom weights, you will have to provide the size of images it was trained on to ensure compatibility. (See note below) - -.. note:: - Currently the SegResNet and SwinUNetR models requires you to provide the size of the images the model was trained with. - Provided weights use a size of 128, please leave it on the default value if you're not using custom weights. - -* **Inference parameters** : - - | You can choose to use inference on the whole image at once, which generally yields better performance at the cost of more memory, or you can use a specific window size to run inference on smaller chunks one by one, for lower memory usage. - | You can also choose to keep the dataset in the RAM rather than the VRAM (cpu vs cuda device) to avoid running out of VRAM if you have several images. - -* **Anisotropy** : - - | If you want to see your results without **anisotropy** when you have anisotropic images, you can specify that you have anisotropic data and set the **resolution of your imaging method in micron**, this wil save and show the results without anisotropy. - -* **Thresholding** : - - | You can perform thresholding to **binarize your labels**, - | all values beneath the **confidence threshold** will be set to 0 using this. - -* **Instance segmentation** : - - | You can convert the semantic segmentation into instance labels by using either the Voronoi-Otsu, `Watershed`_ or `Connected Components`_ method, as detailed in :ref:`utils_module_guide`. - | Instance labels will be saved (and shown if applicable) separately from other results. - - -.. _watershed: https://scikit-image.org/docs/dev/auto_examples/segmentation/plot_watershed.html -.. _connected components: https://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.label - - -* **Computing objects statistics** : - - You can choose to compute various stats from the labels and save them to a .csv for later use. - - This includes, for each object : - - * Object volume (pixels) - * :math:`X,Y,Z` coordinates of the centroid - * Sphericity - - - And more general statistics : - - * Image size - * Total image volume (pixels) - * Total object (labeled) volume (pixels) - * Filling ratio (fraction of the volume that is labeled) - * The number of labeled objects - - - In the ``notebooks`` folder you can find an example of plotting cell statistics using the result csv. - -When you are done choosing your parameters, you can press the **Start** button to begin the inference process. -Once it has finished, results will be saved then displayed in napari; each output will be paired with its original. -On the left side, a progress bar and a log will keep you informed on the process. - - -.. note:: - | The files will be saved using the following format : - | ``{original_name}_{model}_{date & time}_pred{id}.file_ext`` - | For example, using a VNet on the third image of a folder, called "somatomotor.tif" will yield the following name : - | *somatomotor_VNet_2022_04_06_15_49_42_pred3.tif* - | Instance labels will have the "Instance_seg" prefix appended to the name. - - -.. hint:: - | **Results** will be displayed using the **twilight shifted** colormap if raw or **turbo** if thresholding has been applied, whereas the **original** image will be shown in the **inferno** colormap. - | Feel free to change the **colormap** or **contrast** when viewing results to ensure you can properly see the labels. - | You'll most likely want to use **3D view** and **grid mode** in napari when checking results more broadly. - -.. image:: ../images/inference_results_example.png - -.. note:: - You can save the log after the worker is finished to easily remember which parameters you ran inference with. - -WNet --------------------------------- - -The WNet model, from the paper `WNet, A Deep Model for Fully Unsupervised Image Segmentation`_, is a fully unsupervised model that can be used to segment images without any labels. -It clusters pixels based on brightness, and can be used to segment cells in a variety of modalities. -Its use and available options are similar to the above models, with a few differences : - -.. note:: - | Our provided, pre-trained model should use an input size of 64x64x64. As such, window inference is always enabled - | and set to 64. If you want to use a different size, you will have to train your own model using the provided notebook. - -All it requires are 3D .tif images (you can also load a 2D stack as 3D via napari). - -Source code --------------------------------- -* :doc:`../code/plugin_model_inference` -* :doc:`../code/model_framework` -* :doc:`../code/workers` diff --git a/docs/res/guides/metrics_module_guide.rst b/docs/res/guides/metrics_module_guide.rst deleted file mode 100644 index 98899ad9..00000000 --- a/docs/res/guides/metrics_module_guide.rst +++ /dev/null @@ -1,49 +0,0 @@ -.. _metrics_module_guide: - -Metrics utility guide -========================== - -.. figure:: ../images/plot_example_metrics.png - :scale: 35 % - :align: right - - Dice metric plot result - -This utility allows to compute the Dice coefficient between two folders of labels. - -The Dice coefficient is defined as : - -.. math:: \frac {2|X \cap Y|} {|X|+|Y|} - -It is a measure of similarity between two sets- :math:`0` indicating no similarity and :math:`1` complete similarity. - -You will need to provide the following parameters: - -* Two folders : one for ground truth labels and one for prediction labels. - -* The threshold below which the score is considered insufficient. - Any pair below that score will be shown on the viewer; and be displayed in red in the plot. - -* Whether to automatically determine the best orientation for the computation by rotating and flipping; - use this if your images do not have the same orientation. - -.. note:: - Due to changes in orientation of images after running inference, the utility can rotate and flip images randomly to find the best Dice coefficient - to compensate. If you have small images with a very large number of labels, this can lead to an inexact metric being computed. - Images with a low score might be in the wrong orientation as well when displayed for comparison. - -.. important:: - This utility assumes that **predictions are padded to a power of two already.** Ground truth labels can be smaller, - they will be padded to match the prediction size. - Your files should have names that allow them to be sorted numerically as well; please ensure that each ground truth label has a matching prediction label. - -Once you are ready, press the "Compute Dice" button. This will plot the Dice score for each ground truth-prediction labels pair on the side. -Pairs with a low score will be displayed on the viewer for checking, ground truth in **blue**, low score prediction in **red**. - - - -Source code -------------------------------------------------- - -* :doc:`../code/plugin_base` -* :doc:`../code/plugin_metrics` diff --git a/docs/res/guides/review_module_guide.rst b/docs/res/guides/review_module_guide.rst deleted file mode 100644 index ffecf9a0..00000000 --- a/docs/res/guides/review_module_guide.rst +++ /dev/null @@ -1,63 +0,0 @@ -.. _loader_module_guide: - -Review module guide -================================= - -This module allows you to review your labels, from predictions or manual labeling, -and correct them if needed. It then saves the status of each file in a csv, as well as the time taken per slice review, for easier monitoring. - - - -Launching the review process ---------------------------------- - -* Data paths : - First, you will be asked to load your images and labels; you can use the checkbox above the Open buttons to - choose whether you want to load a single 3D **.tif** image or a folder of 2D images as a 3D stack. - Folders can be stacks of either **.png** or **.tif** files, ideally numbered with the index of the slice at the end. - -.. note:: - Only single 3D **.tif** files or 2D stacks of several **.png** or **.tif** in a folder are currently supported. - -* Anisotropic data : - This will scale the images to visually remove the anisotropy, so as to make review easier. - -.. important:: - Results will still be saved as anisotropic images. If you wish to resize your images, see the :doc:`utils_module_guide` - -* CSV file name : - You can then provide a model name, which will be used to name the csv file recording the status of each slice. - - If a corresponding csv file exists already, it will be used. If not, a new one will be created. - If you choose to create a new dataset, a new csv will always be created, - with a trailing number if several copies of it already exists. - -* Start : - Once you are ready, you can press **Start reviewing** to start the review process. - -.. note:: - You can find the csv file containing the annotation status **in the same folder as the labels** - - -Interface & functionalities ---------------------------------------------------------------- - -.. image:: ../images/review_process_example.png - -Once you have launched the review process, you will have access to the following functionalities: - -* A dialog to choose the folder in which you want to save the verified and/or corrected annotations, and a button to save the labels. They will be saved based on the file format you provided. - -* A button to update the status of the slice in the csv file (in this case : checked/not checked) - -* A plot with three projections in the x-y, y-z and x-z planes, to allow the reviewer to better see the surroundings of the label and properly establish whether the image should be labeled or not. You can **shift-click** anywhere on the image or label layer to update the plot to the location being reviewed. - -Using these, you can check your labels, correct them, save them and keep track of which slices have been checked or not. - - -Source code -------------------------------------------------- - -* :doc:`../code/plugin_review` -* :doc:`../code/plugin_review_dock` -* :doc:`../code/plugin_base` diff --git a/docs/res/guides/training_module_guide.rst b/docs/res/guides/training_module_guide.rst deleted file mode 100644 index 1a424e98..00000000 --- a/docs/res/guides/training_module_guide.rst +++ /dev/null @@ -1,136 +0,0 @@ -.. _training_module_guide: - -Training module guide - Unsupervised models -============================================== - -.. important:: - The WNet training is for now available as part of the plugin in the Training module. - Please see the :ref:`training_wnet` section for more information. - -Training module guide - Supervised models -============================================== - -This module allows you to train pre-defined Pytorch models for cell segmentation. -Pre-defined models are stored in napari-cellseg-3d/models. - -.. important:: - Currently, only inference on **3D volumes is supported**. Your image and label folders should both contain a set of - **3D image files**, currently either **.tif** or **.tiff**. Loading a folder of 2D images as a stack is not supported as of yet. - - -Currently, the following pre-defined models are available : - -============== ================================================================================================ -Model Link to original paper -============== ================================================================================================ -VNet `Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation`_ -SegResNet `3D MRI brain tumor segmentation using autoencoder regularization`_ -TRAILMAP_MS An implementation of the `TRAILMAP project on GitHub`_ using `3DUNet for PyTorch`_ -SwinUNetR `Swin UNETR, Swin Transformers for Semantic Segmentation of Brain Tumors in MRI Images`_ -============== ================================================================================================ - -.. _Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation: https://arxiv.org/pdf/1606.04797.pdf -.. _3D MRI brain tumor segmentation using autoencoder regularization: https://arxiv.org/pdf/1810.11654.pdf -.. _TRAILMAP project on GitHub: https://github.com/AlbertPun/TRAILMAP -.. _3DUnet for Pytorch: https://github.com/wolny/pytorch-3dunet -.. _Swin UNETR, Swin Transformers for Semantic Segmentation of Brain Tumors in MRI Images: https://arxiv.org/abs/2201.01266 - -.. important:: - | The machine learning models used by this program require all images of a dataset to be of the same size. - | Please ensure that all the images you are loading are of the **same size**, or to use the **"extract patches" (in augmentation tab)** with an appropriately small size to ensure all images being used by the model are of a workable size. - -The training module is comprised of several tabs. - - -1) The first one, **Data**, will let you set : - -* The path to the images folder (3D image files) -* The path to the labels folder (3D image files) -* The path to the results folder - -* Whether to copy results to a zip file (for easier transferability) - -* Whether to use pre-trained weights that are provided; if you choose to do so, the model will be initialized with the specified weights, possibly improving performance (transfer learning). - You can also load custom weights; simply ensure they are compatible with the model. - -* The proportion of the dataset to keep for training versus validation; if you have a large dataset, you can set it to a lower value to have more accurate validation steps. - -2) The second tab, **Augmentation**, lets you define dataset and augmentation parameters such as : - -* Whether to use images "as is" (**requires all images to be of the same size and cubic**) or extract patches. - -.. important:: - | **All image sizes used should be as close to a power of two as possible, or equal to a power of two.** - | Images are automatically padded; a 64 pixels cube will be used as is, but a 65 pixel cube will be padded up to 128 pixels, resulting in much higher memory use. - -* If you're extracting patches : - - * The size of patches to be extracted (ideally, please use a value **close or equal to a power of two**, such as 120 or 60 to ensure correct size. See above note.) - * The number of samples to extract from each of your images. A larger number will likely mean better performances, but longer training and larger memory usage. - -.. note:: If you're using a single image (preferably large) it is recommended to enable patch extraction. - -* Whether to perform data augmentation or not (elastic deforms, intensity shifts. random flipping,etc). - Ideally it should always be enabled, but you can disable it if it causes issues. - - -3) The third contains training related parameters : - -* The **model** to use for training (see table above) -* The **loss function** used for training (see table below) -* The **learning rate** of the optimizer. Setting it to a lower value if you're using pre-trained weights can improve performance. -* The **batch size** (larger means quicker training and possibly better performance but increased memory usage) -* The **number of epochs** (a possibility is to start with 60 epochs, and decrease or increase depending on performance.) -* The **epoch interval** for validation (for example, if set to two, the module will use the validation dataset to evaluate the model with the dice metric every two epochs.) -* The **schedular patience**, which is the amount of epoch at a plateau that is waited for until the learning rate is reduced -* The **scheduler factor**, which is the factor by which to reduce the learning rate once a plateau is reached -* Whether to use deterministic training, and the seed to use. - -.. note:: - If the dice metric is better on a given validation interval, the model weights will be saved in the results folder. - -The available loss functions are : - -======================== ================================================================================================ -Function Reference -======================== ================================================================================================ -Dice loss `Dice Loss from MONAI`_ with ``sigmoid=true`` -Generalized Dice loss `Generalized dice Loss from MONAI`_ with ``sigmoid=true`` -Dice-CE loss `Dice-CrossEntropy Loss from MONAI`_ with ``sigmoid=true`` -Tversky loss `Tversky Loss from MONAI`_ with ``sigmoid=true`` -======================== ================================================================================================ - -.. _Dice Loss from MONAI: https://docs.monai.io/en/stable/losses.html#diceloss -.. _Focal Loss from MONAI: https://docs.monai.io/en/stable/losses.html#focalloss -.. _Dice-focal Loss from MONAI: https://docs.monai.io/en/stable/losses.html#dicefocalloss -.. _Generalized dice Loss from MONAI: https://docs.monai.io/en/stable/losses.html#generalizeddiceloss -.. _Dice-CrossEntropy Loss from MONAI: https://docs.monai.io/en/stable/losses.html#diceceloss -.. _Tversky Loss from MONAI: https://docs.monai.io/en/stable/losses.html#tverskyloss - -Once you are ready, press the Start button to begin training. The module will automatically load your dataset, -perform data augmentation if you chose to, select a CUDA device if one is present, and train the model. - -.. note:: - You can stop the training at any time by clicking on the start button again. - - **The training will stop after the next batch has been processed, and will try to save the model. Please note that results might be broken if you stop the training.** - -.. note:: - You can save the log with the button underneath it to record the losses and validation metrics numerical values at each step. This log is autosaved as well when training completes. - -After two validations steps have been performed (depending on the interval you set), -the training loss values and validation metrics will be automatically plotted -and shown on napari every time a validation step completes. -This plot automatically saved each time validation is performed for now. -The final version is stored separately in the results folder. - -.. figure:: ../images/plots_train.png - :align: center - - Example of plots displayed by the training module after 40 epochs - -Source code --------------------------------- -* :doc:`../code/plugin_model_training` -* :doc:`../code/model_framework` -* :doc:`../code/workers` diff --git a/docs/res/guides/training_wnet.rst b/docs/res/guides/training_wnet.rst deleted file mode 100644 index 974a90e9..00000000 --- a/docs/res/guides/training_wnet.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. _training_wnet: - -WNet model training -=================== - -This plugin provides a reimplemented, custom version of the WNet model from `WNet, A Deep Model for Fully Unsupervised Image Segmentation`_. -In order to train your own model, you may use the provided Jupyter notebook; support for in-plugin training might be added in the future. - -The WNet uses brightness to cluster objects vs background; to get the most out of the model please use image regions with minimal -artifacts. You may then train one of the supervised models in order to achieve more resilient segmentation if you have many artifacts. - -The WNet should not require a very large amount of data to train, but during inference images should be similar to those -the model was trained on; you can retrain from our pretrained model to your set of images to quickly reach good performance. - -The model has two losses, the SoftNCut loss which clusters pixels according to brightness, and a reconstruction loss, either -Mean Square Error (MSE) or Binary Cross Entropy (BCE). -Unlike the original paper, these losses are added in a weighted sum and the backward pass is performed for the whole model at once. -The SoftNcuts is bounded between 0 and 1; the MSE may take large positive values. - -For good performance, one should wait for the SoftNCut to reach a plateau; the reconstruction loss must also diminish but it's generally less critical. - -Parameters -------------------------------- - -When using the WNet training module, additional options will be provided in the Advanced tab of the training module: - -- Number of classes : number of classes to segment (default 2). Additional classes will result in a more progressive segmentation according to brightness; can be useful if you have "halos" around your objects or artifacts with a significantly different brightness. -- Reconstruction loss : either MSE or BCE (default MSE). MSE is more sensitive to outliers, but can be more precise; BCE is more robust to outliers but can be less precise. - -- NCuts parameters: - - Intensity sigma : standard deviation of the feature similarity term (brightness here, default 1) - - Spatial sigma : standard deviation of the spatial proximity term (default 4) - - Radius : radius of the loss computation in pixels (default 2) - -.. note:: - Intensity sigma depends on pixel values in the image. The default of 1 is tailored to images being mapped between 0 and 100, which is done automatically by the plugin. -.. note:: - Raising the radius might improve performance in some cases, but will also greatly increase computation time. - -- Weights for the sum of losses : - - NCuts weight : weight of the NCuts loss (default 0.5) - - Reconstruction weight : weight of the reconstruction loss (default 0.5*1e-2) - -.. note:: - The weight of the reconstruction loss should be adjusted according to its empirical value; ideally the reconstruction loss should be of the same order of magnitude as the NCuts loss after being multiplied by its weight. - -Common issues troubleshooting ------------------------------- -If you do not find a satisfactory answer here, please do not hesitate to `open an issue`_ on GitHub. - -- **The NCuts loss explodes after a few epochs** : Lower the learning rate, first by a factor of two, then ten. - -- **The NCuts loss does not converge and is unstable** : - The normalization step might not be adapted to your images. Disable normalization and change intensity_sigma according to the distribution of values in your image. For reference, by default images are remapped to values between 0 and 100, and intensity_sigma=1. - -- **Reconstruction (decoder) performance is poor** : switch to BCE and set the scaling factor of the reconstruction loss ot 0.5, OR adjust the weight of the MSE loss to make it closer to 1 in the weighted sum. - - -.. _WNet, A Deep Model for Fully Unsupervised Image Segmentation: https://arxiv.org/abs/1711.08506 -.. _open an issue: https://github.com/AdaptiveMotorControlLab/CellSeg3d/issues diff --git a/docs/res/guides/utils_module_guide.rst b/docs/res/guides/utils_module_guide.rst deleted file mode 100644 index 64e8a3ce..00000000 --- a/docs/res/guides/utils_module_guide.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. _utils_module_guide: - -Label conversion utility guide -================================== - -This utility will let you convert labels to various different formats. - -You will have to specify the results directory for saving; afterwards you can run each action on a folder or on the currently selected layer. - -You can : - -* Crop 3D volumes : - Please refer to :ref:`cropping_module_guide` for a guide on using the cropping utility. - -* Convert to instance labels : - This will convert 0/1 semantic labels to instance label, with a unique ID for each object. - The available methods for this are : - - * Connected components : simple method that will assign a unique ID to each connected component. Does not work well for touching objects (objects will often be fused), works for anisotropic volumes. - * Watershed : method based on topographic maps. Works well for touching objects and anisotropic volumes; touching objects may be fused. - * Voronoi-Otsu : method based on Voronoi diagrams. Works well for touching objects but only for isotropic volumes. -* Convert to semantic labels : - This will convert instance labels with unique IDs per object into 0/1 semantic labels, for example for training. - -* Remove small objects : - You can specify a size threshold in pixels; all objects smaller than this size will be removed in the image. - -* Resize anisotropic images : - Specify the resolution of your microscope to remove anisotropy from images. - -.. important:: Does not work for instance labels currently. - -* Threshold images : - Remove all values below a threshold in an image. - -.. figure:: ../images/converted_labels.png - :scale: 30 % - :align: center - - Example of instance labels (left) converted to semantic labels (right) - -Source code -------------------------------------------------- - -* :doc:`../code/plugin_base` -* :doc:`../code/plugin_convert` diff --git a/docs/res/images/WNet_architecture.svg b/docs/res/images/WNet_architecture.svg deleted file mode 100644 index e513996a..00000000 --- a/docs/res/images/WNet_architecture.svg +++ /dev/null @@ -1,817 +0,0 @@ - - - - - - -model - - - -0 - - -input-tensor -depth:0 - -(1, 1, 64, 64, 64) - - - -1 - - -Sequential -depth:3 - -input: - -(1, 1, 64, 64, 64) - -output: - -(1, 64, 64, 64, 64) - - - -0->1 - - - - - -2 - - -MaxPool3d -depth:2 - -input: - -(1, 64, 64, 64, 64) - -output: - -(1, 64, 32, 32, 32) - - - -1->2 - - - - - -15 - - -cat -depth:2 - -input: - -2 x (1, 64, 64, 64, 64) - -output: - -(1, 128, 64, 64, 64) - - - -1->15 - - - - - -3 - - -Sequential -depth:3 - -input: - -(1, 64, 32, 32, 32) - -output: - -(1, 128, 32, 32, 32) - - - -2->3 - - - - - -4 - - -MaxPool3d -depth:2 - -input: - -(1, 128, 32, 32, 32) - -output: - -(1, 128, 16, 16, 16) - - - -3->4 - - - - - -12 - - -cat -depth:2 - -input: - -2 x (1, 128, 32, 32, 32) - -output: - -(1, 256, 32, 32, 32) - - - -3->12 - - - - - -5 - - -Sequential -depth:3 - -input: - -(1, 128, 16, 16, 16) - -output: - -(1, 256, 16, 16, 16) - - - -4->5 - - - - - -6 - - -MaxPool3d -depth:2 - -input: - -(1, 256, 16, 16, 16) - -output: - -(1, 256, 8, 8, 8) - - - -5->6 - - - - - -9 - - -cat -depth:2 - -input: - -2 x (1, 256, 16, 16, 16) - -output: - -(1, 512, 16, 16, 16) - - - -5->9 - - - - - -7 - - -Sequential -depth:3 - -input: - -(1, 256, 8, 8, 8) - -output: - -(1, 512, 8, 8, 8) - - - -6->7 - - - - - -8 - - -ConvTranspose3d -depth:2 - -input: - -(1, 512, 8, 8, 8) - -output: - -(1, 256, 16, 16, 16) - - - -7->8 - - - - - -8->9 - - - - - -10 - - -Sequential -depth:3 - -input: - -(1, 512, 16, 16, 16) - -output: - -(1, 256, 16, 16, 16) - - - -9->10 - - - - - -11 - - -ConvTranspose3d -depth:2 - -input: - -(1, 256, 16, 16, 16) - -output: - -(1, 128, 32, 32, 32) - - - -10->11 - - - - - -11->12 - - - - - -13 - - -Sequential -depth:3 - -input: - -(1, 256, 32, 32, 32) - -output: - -(1, 128, 32, 32, 32) - - - -12->13 - - - - - -14 - - -ConvTranspose3d -depth:2 - -input: - -(1, 128, 32, 32, 32) - -output: - -(1, 64, 64, 64, 64) - - - -13->14 - - - - - -14->15 - - - - - -16 - - -Sequential -depth:3 - -input: - -(1, 128, 64, 64, 64) - -output: - -(1, 2, 64, 64, 64) - - - -15->16 - - - - - -17 - - -Softmax -depth:2 - -input: - -(1, 2, 64, 64, 64) - -output: - -(1, 2, 64, 64, 64) - - - -16->17 - - - - - -18 - - -Sequential -depth:3 - -input: - -(1, 2, 64, 64, 64) - -output: - -(1, 64, 64, 64, 64) - - - -17->18 - - - - - -35 - - -output-tensor -depth:0 - -(1, 2, 64, 64, 64) - - - -17->35 - - - - - -19 - - -MaxPool3d -depth:2 - -input: - -(1, 64, 64, 64, 64) - -output: - -(1, 64, 32, 32, 32) - - - -18->19 - - - - - -32 - - -cat -depth:2 - -input: - -2 x (1, 64, 64, 64, 64) - -output: - -(1, 128, 64, 64, 64) - - - -18->32 - - - - - -20 - - -Sequential -depth:3 - -input: - -(1, 64, 32, 32, 32) - -output: - -(1, 128, 32, 32, 32) - - - -19->20 - - - - - -21 - - -MaxPool3d -depth:2 - -input: - -(1, 128, 32, 32, 32) - -output: - -(1, 128, 16, 16, 16) - - - -20->21 - - - - - -29 - - -cat -depth:2 - -input: - -2 x (1, 128, 32, 32, 32) - -output: - -(1, 256, 32, 32, 32) - - - -20->29 - - - - - -22 - - -Sequential -depth:3 - -input: - -(1, 128, 16, 16, 16) - -output: - -(1, 256, 16, 16, 16) - - - -21->22 - - - - - -23 - - -MaxPool3d -depth:2 - -input: - -(1, 256, 16, 16, 16) - -output: - -(1, 256, 8, 8, 8) - - - -22->23 - - - - - -26 - - -cat -depth:2 - -input: - -2 x (1, 256, 16, 16, 16) - -output: - -(1, 512, 16, 16, 16) - - - -22->26 - - - - - -24 - - -Sequential -depth:3 - -input: - -(1, 256, 8, 8, 8) - -output: - -(1, 512, 8, 8, 8) - - - -23->24 - - - - - -25 - - -ConvTranspose3d -depth:2 - -input: - -(1, 512, 8, 8, 8) - -output: - -(1, 256, 16, 16, 16) - - - -24->25 - - - - - -25->26 - - - - - -27 - - -Sequential -depth:3 - -input: - -(1, 512, 16, 16, 16) - -output: - -(1, 256, 16, 16, 16) - - - -26->27 - - - - - -28 - - -ConvTranspose3d -depth:2 - -input: - -(1, 256, 16, 16, 16) - -output: - -(1, 128, 32, 32, 32) - - - -27->28 - - - - - -28->29 - - - - - -30 - - -Sequential -depth:3 - -input: - -(1, 256, 32, 32, 32) - -output: - -(1, 128, 32, 32, 32) - - - -29->30 - - - - - -31 - - -ConvTranspose3d -depth:2 - -input: - -(1, 128, 32, 32, 32) - -output: - -(1, 64, 64, 64, 64) - - - -30->31 - - - - - -31->32 - - - - - -33 - - -Sequential -depth:3 - -input: - -(1, 128, 64, 64, 64) - -output: - -(1, 2, 64, 64, 64) - - - -32->33 - - - - - -34 - - -output-tensor -depth:0 - -(1, 2, 64, 64, 64) - - - -33->34 - - - - - diff --git a/docs/res/images/cropping_process_example.png b/docs/res/images/cropping_process_example.png deleted file mode 100644 index d691650d..00000000 Binary files a/docs/res/images/cropping_process_example.png and /dev/null differ diff --git a/docs/res/images/inference_plugin_layout.png b/docs/res/images/inference_plugin_layout.png deleted file mode 100644 index 760b572d..00000000 Binary files a/docs/res/images/inference_plugin_layout.png and /dev/null differ diff --git a/docs/res/images/plots_train.png b/docs/res/images/plots_train.png deleted file mode 100644 index ebbf9351..00000000 Binary files a/docs/res/images/plots_train.png and /dev/null differ diff --git a/docs/res/images/review_process_example.png b/docs/res/images/review_process_example.png deleted file mode 100644 index bbe786c0..00000000 Binary files a/docs/res/images/review_process_example.png and /dev/null differ diff --git a/docs/res/welcome.rst b/docs/res/welcome.rst deleted file mode 100644 index dbe2b849..00000000 --- a/docs/res/welcome.rst +++ /dev/null @@ -1,123 +0,0 @@ -Introduction -=================== - - -Here you will find instructions on how to use the plugin for direct segmentation in 3D. -If the installation was successful, you'll see the napari-cellseg3D plugin -in the Plugins section of napari. - -This plugin was initially developed for the review of labeled cell volumes [#]_ from mice whole-brain samples -imaged by mesoSPIM microscopy [#]_ , and for training and using segmentation models from the MONAI project [#]_, -or any custom model written in PyTorch. -It should be adaptable to other tasks related to detection of 3D objects, as long as labels are available. - - -From this page you can access the guides on the several modules available for your tasks, such as : - -* Main modules : - * Training : :ref:`training_module_guide` - * Inference: :ref:`inference_module_guide` - * Review : :ref:`loader_module_guide` -* Utilities : - * Cropping (3D) : :ref:`cropping_module_guide` - * Other utilities : :ref:`utils_module_guide` - -.. - * Convert labels : :ref:`utils_module_guide` -.. - * Compute scores : :ref:`metrics_module_guide` - -* Advanced : - * Training WNet (in jupyter, support might be added for plugin later) : :ref:`training_wnet` - * Defining custom models directly in the plugin (WIP) : :ref:`custom_model_guide` - - -Installation --------------------------------------------- - -You can install `napari-cellseg3d` via [pip]: - - ``pip install napari-cellseg3d`` - -For local installation after cloning, please run in the CellSeg3D folder: - - ``pip install -e .`` - -Requirements --------------------------------------------- - -.. note:: - A **CUDA-capable GPU** is not needed but **very strongly recommended**, especially for training and possibly inference. - -.. important:: - This package requires you have napari installed with PyQt5 or PySide2 first. - If you do not have a Qt backend you can use : - ``pip install napari-cellseg3d[all]`` - to install PyQt5 by default. - -It also depends on PyTorch and some optional dependencies of MONAI. These come in the pip package as requirements, but if -you need further assistance see below. - -* For help with PyTorch, please see `PyTorch's website`_ for installation instructions, with or without CUDA depending on your hardware. - Depending on your setup, you might wish to install torch first. - -* If you get errors from MONAI regarding missing readers, please see `MONAI's optional dependencies`_ page for instructions on getting the readers required by your images. - -.. _MONAI's optional dependencies: https://docs.monai.io/en/stable/installation.html#installing-the-recommended-dependencies -.. _PyTorch's website: https://pytorch.org/get-started/locally/ - - -Usage --------------------------------------------- - -To use the plugin, please run: - - ``napari`` - -Then go into Plugins > napari-cellseg3d, and choose which tool to use: - -- **Review**: This module allows you to review your labels, from predictions or manual labeling, and correct them if needed. It then saves the status of each file in a csv, for easier monitoring -- **Inference**: This module allows you to use pre-trained segmentation algorithms on volumes to automatically label cells -- **Training**: This module allows you to train segmentation algorithms from labeled volumes -- **Utilities**: This module allows you to use several utilities, e.g. to crop your volumes and labels, compute prediction scores or convert labels -- **Help/About...** : Quick access to version info, Github page and docs - -See above for links to detailed guides regarding the usage of the modules. - -Acknowledgments & References ---------------------------------------------- -This plugin has been developed by Cyril Achard and Maxime Vidal, supervised by Mackenzie Mathis for the `Mathis Laboratory of Adaptive Motor Control`_. - -We also greatly thank Timokleia Kousi for her contributions to this project and the `Wyss Center`_ for project funding. - -The TRAILMAP models and original weights used here were ported to PyTorch but originate from the `TRAILMAP project on GitHub`_ [1]_. -We also provide a model that was trained in-house on mesoSPIM nuclei data in collaboration with Dr. Stephane Pages and Timokleia Kousi. - -This plugin mainly uses the following libraries and software: - -* `napari`_ - -* `PyTorch`_ - -* `MONAI project`_ (various models used here are credited `on their website`_) - -* `pyclEsperanto`_ (for the Voronoi Otsu labeling) by Robert Haase - -* A custom re-implementation of the `WNet model`_ by Xia and Kulis [#]_ - -.. _Mathis Laboratory of Adaptive Motor Control: http://www.mackenziemathislab.org/ -.. _Wyss Center: https://wysscenter.ch/ -.. _TRAILMAP project on GitHub: https://github.com/AlbertPun/TRAILMAP -.. _napari: https://napari.org/ -.. _PyTorch: https://pytorch.org/ -.. _MONAI project: https://monai.io/ -.. _on their website: https://docs.monai.io/en/stable/networks.html#nets -.. _pyclEsperanto: https://github.com/clEsperanto/pyclesperanto_prototype -.. _WNet model: https://arxiv.org/abs/1711.08506 - -.. rubric:: References - -.. [#] Mapping mesoscale axonal projections in the mouse brain using a 3D convolutional network, Friedmann et al., 2020 ( https://pnas.org/cgi/doi/10.1073/pnas.1918465117 ) -.. [#] The mesoSPIM initiative: open-source light-sheet microscopes for imaging cleared tissue, Voigt et al., 2019 ( https://doi.org/10.1038/s41592-019-0554-0 ) -.. [#] MONAI Project website ( https://monai.io/ ) -.. [#] W-Net: A Deep Model for Fully Unsupervised Image Segmentation, Xia and Kulis, 2018 ( https://arxiv.org/abs/1711.08506 ) diff --git a/docs/source/code/api.rst b/docs/source/code/api.rst new file mode 100644 index 00000000..77a2036f --- /dev/null +++ b/docs/source/code/api.rst @@ -0,0 +1,11 @@ +API reference +================= + +.. autosummary:: + :toctree: _autosummary + :recursive: + + napari_cellseg3d.interface + napari_cellseg3d.code_models + napari_cellseg3d.code_plugins + napari_cellseg3d.utils diff --git a/docs/source/guides/cropping_module_guide.rst b/docs/source/guides/cropping_module_guide.rst new file mode 100644 index 00000000..701a0b4e --- /dev/null +++ b/docs/source/guides/cropping_module_guide.rst @@ -0,0 +1,83 @@ +.. _cropping_module_guide: + +Cropping✂️ +========== + +.. figure:: ../images/plugin_crop.png + :align: center + + Layout of the cropping module + +**Cropping** allows you to crop your volumes and labels dynamically, +by selecting a fixed size volume and moving it around the image. + +To access it: + - Navigate to **`Plugins -> Utilities`**. + - Choose **`Crop`** from the bottom menu. + +Once cropped, you have multiple options to save the volumes and labels: + - Use the **`Quicksave`** button in Napari. + - Select the layer and then go to **`File` -> `Save selected layers`**. + - With the correct layer highlighted, simply press **`CTRL + S`**. + +.. Note:: + For more on utility tools, see :doc:`utils_module_guide`. + +Launching the cropping process +------------------------------ +1. From the layer selection dropdown menu, select your image. If you want to crop a second image with the same dimensions simultaneously, +check the **`Crop another image simultaneously`** option and then select the relevant layer. + +2. Define your desired cropped volume size. This size will remain fixed for the duration of the session. +To update the size, you will need to restart the process. + +3. You can also correct the anisotropy, if you work with anisotropic data: simply set your microscope's resolution in microns. + +.. important:: + This will scale the image in the viewer, but saved images will **still be anisotropic.** To resize your image, see :doc:`utils_module_guide`. + +4. Press **`Start`** to start the cropping process. +If you'd like to modify the volume size, change the parameters as described and hit **`Start`** again. + +Creating new layers +------------------- +To "zoom in" on a specific portion of your volume: + +- Use the `Create new layers` checkbox next time you hit `Start`. This option lets you make an additional cropping layer instead of replacing the current one. + +- This way, you can first select your region of interest by using the tool as described above, then enable the option, select the cropped region produced before as the input layer, and define a smaller crop size in order to further crop within your region of interest. + +Interface & functionalities +--------------------------- + +.. figure:: ../images/cropping_process_example.png + :align: center + + Example of the cropping process interface. + +Once you have launched the review process, you will gain control over three sliders, which will let +you to **adjust the position** of the cropped volumes and labels in the x,y and z positions. + +.. note:: + * If your **cropped volume isnt visible**, consider changing the **colormap** of the image and the cropped + volume to improve their visibility. + * You may want to adjust the **opacity** and **contrast thresholds** depending on your image. + * If the image appears empty: + - Right-click on the contrast limits sliders. + - Select **`Full Range`** and then **`Reset`**. + +Saving your cropped volume +-------------------------- +- When you are done, you can save the cropped volume and labels directly with the **`Quicksave`** button located at the bottom left. Your work will be saved in the same folder as the image you choose. + +- If you want more options (name, format) when saving: + - Select the desired layer. + - Navigate in the napari menu to **`File -> Save selected layer`**. + - Press **`CTRL+S`** once you have selected the correct layer. + + +Source code +------------------------------------------------- + +* :doc:`../code/_autosummary/napari_cellseg3d.code_plugins.plugin_crop` +* :doc:`../code/_autosummary/napari_cellseg3d.code_plugins.plugin_base` diff --git a/docs/res/guides/custom_model_template.rst b/docs/source/guides/custom_model_template.rst similarity index 81% rename from docs/res/guides/custom_model_template.rst rename to docs/source/guides/custom_model_template.rst index b7eb65e3..7d7f2264 100644 --- a/docs/res/guides/custom_model_template.rst +++ b/docs/source/guides/custom_model_template.rst @@ -1,6 +1,6 @@ .. _custom_model_guide: -Advanced : Declaring a custom model +Advanced : Custom models ============================================= .. warning:: @@ -11,7 +11,6 @@ Advanced : Declaring a custom model To add a custom model, you will need a **.py** file with the following structure to be placed in the *napari_cellseg3d/models* folder:: class ModelTemplate_(ABC): # replace ABC with your PyTorch model class name - use_default_training = True # not needed for now, will serve for WNet training if added to the plugin weights_file = ( "model_template.pth" # specify the file name of the weights file only ) # download URL goes in pretrained_models.json @@ -30,6 +29,6 @@ To add a custom model, you will need a **.py** file with the following structure .. note:: - **WIP** : Currently you must modify :ref:`model_framework.py` as well : import your model class and add it to the ``model_dict`` attribute + **WIP** : Currently you must modify :doc:`model_framework.py <../code/_autosummary/napari_cellseg3d.code_models.model_framework>` as well : import your model class and add it to the ``model_dict`` attribute .. _file an issue: https://github.com/AdaptiveMotorControlLab/CellSeg3d/issues diff --git a/docs/source/guides/detailed_walkthrough.rst b/docs/source/guides/detailed_walkthrough.rst new file mode 100644 index 00000000..2858c3f7 --- /dev/null +++ b/docs/source/guides/detailed_walkthrough.rst @@ -0,0 +1,271 @@ +.. _detailed_walkthrough: + +Detailed walkthrough - Supervised learning +========================================== + +This guide will show you step-by-step how to use the plugin's workflow, beginning with human annotated datasets, to generating predictions on new volumes. + +Setting up images and labels +---------------------------- + +CellSeg3D is designed for cleared-brain tissue data (collected using mesoSPIM ligthsheet systems). +Here's what we offer: + +- **Ready-to-use deep learning models**: Optimised for whole-neuron imaging in the cortex. +- **MONAI models support** +- **Trailmap in Pytorch**: We've integrated TRAILMAP into PyTorch, harnessing mesoSPIM data. + +Ready to get started? Ensure you have part of a cleared brain from mesoSPIM imaging as a big **.tif** file and its label at hand. + +For quick model checks, check the "Inference" sections in our docs. + + +.. figure:: ../images/init_image_labels.png + :scale: 40 % + :align: center + + Example of an anisotropic volume (i.e., often times the z resolution is not the same as x and y) and its associated labels. + + +.. note:: + This guide emphasizes a human-in-the-loop review of labels. + If you need to start labeling volumes from scratch or correct initial labels, we recommend consulting the sections on :ref:`Review` section right after :ref:`Cropping `. + + +Cropping +********* +.. _walkthrough_cropping: + +To reduce memory requirements and build a dataset from a single, large volume, +you can use the **cropping** tool to extract multiple smaller images from a large volume for training. + +1. Load your primary image and any corresponding labels. If cropping labels, ensure "Crop labels simultaneously" is selected. +2. Choose your desired volume size for extraction. + +.. note:: + For optimal training, opt for cubic images set to powers of two : a default of :math:`64^3` should be a good start if you're unsure. + Stick to this size across your dataset. + However, if specific regions need varied sizes, you can compensate for it during training. + When running inference on multiple images in a folder, try to maintain size uniformity. + + +1. Use the slider to choose the exact areas you want to extract. +2. Options for saving: + - Use the **quicksave** feature + - Or, select the intended layer and press **`CTRL+S`** + +.. figure:: ../images/cropping_process_example.png + :align: center + + Cropping module layout + +Label conversion utility +************************ + +Assuming you have instance labels, you'll need to convert them to semantic labels before using them for training. + +.. note:: + Instance labels used in training will be converted to semantic labels automatically, but this might not always result in the desired behavior. + +Step-by-Step Instructions: + 1. Launch the *Convert* tab within Utilities. + 2. Specify your preferred output directory. + 3. Load the folder with your cropped volumes under **`Convert Folder`**. + 4. Click on **`Convert to semantic labels`**. + +.. figure:: ../images/converted_labels.png + :scale: 40 % + :align: center + + Example of instance labels from above converted to semantic labels + +To remove small objects, or to convert a single image, use the **`CTRL+O`** shortcut to open the image you wish to manipulate. +Then, select its corresponding layer, and start the process using layer-specific controls. + +Models for object detection +--------------------------- + +Training Guide +************** + +1. Preparation: + + - **Size**: Ensure that your images are appropriately sized. Please see the cropping section for guidelines. + - **Data paths**: Input the paths for your images and labels. Additionally, specify an output location where the results will be saved. + +2. Training Options and Features: + + - **Transfer weights**: While we offer pre-trained weights designed specifically for cleared brain tissue imagery, the flexibility to incorporate your own weights exists. If you're choosing the latter, ensure they are compatible with the model you selected (see : :ref:`custom_model_guide`). + - **Validation proportion**: Decide on a specific percentage to determine the number of images which will be used for training versus validation. While validation can in theory work with even one image, the richness of data in validation will greatly improve model's performance. Use 90% only if you have a very small dataset (less than 5 images). + - **Save as zip** : Copies the results in a zip archive for easier transfer. + +3. Data augmentation: + + * If you have cropped cubic images with a power of two as the edge length, you do not need to extract patches, your images are usable as is. + * However, if you are using larger images or with variable sizes, you can use this option to auto-extract smaller patches that will be automatically padded back to a power of two no matter the size you choose. For optimal performance, make sure to use a value close or equal to a power of two still, such as 64 or 120. + +.. important:: + Using a large value for the size will cause memory issues. If this happens, restart the work with smaller volumes. + +You also have the option to use data augmentation, which can improve performance and generalization. +In most cases this should left enabled. + +1. Model selection: You can choose from a variety of models, based on the needs of your project: + + * **SegResNet** is a lightweight model (low memory requirements) from MONAI originally designed for 3D fMRI data. + * **VNet** is a larger (than SegResNet) CNN from MONAI designed for medical image segmentation. + * **TRAILMAP** is our implementation in PyTorch additionally trained on mouse cortical neural nuclei from mesoSPIM data. + * **SwinUNetR** is a MONAI implementation of the SwinUNetR model. It is costly in compute and memory, but can achieve high performance. + * **WNet** is our reimplementation of an unsupervised model, which can be used to produce segmentation without labels. + + +* **The loss** : For 3D volume object detection, the Dice or Dice-focal Loss is the most efficient. + +* **Batch size** : Chose a value suited to your memory. To avoid memory issues, leave it to one. + +* **Learning rate** : Default to 1e-3 unless using specific weights, then adjust. + +* **Number of epochs** : More epochs mean longer training but potentially better results. Begin with 40 epochs. + +.. note:: + During training, you can monitor the process using plots : ideally the validation curve should ascend + whereas the loss curve should descend. If the validation starts lowering after reaching a maximum, but the loss still decreases, + it could indicate over-fitting, which will negatively impact generalization for the given weights. + You might want use weights generated from the epoch with the maximum validation score if that is the case. + +.. figure:: ../images/plots_train.png + :align: center + + Plots displayed by the training module after 40 epochs + +* **Validation interval** : Dictates how frequently the model halts training to validate its current performance. If the value is e.g. 2, the training will stop every 2 epochs to perform validation and save the results if the score is better than the previous one.Pausing frequently (smaller value) ensures you capture the best model state more often. Yet, it extends the overall training time. + +* **Deterministic training** : To guarantee reproducibility in results across training sessions. When deterministic training is enabled, remember the seed you've inputted. Using the same seed with the same model, images, and parameters should consistently yield similar results. See `MONAI deterministic training`_. + +.. _MONAI deterministic training: https://docs.monai.io/en/stable/utils.html#module-monai.utils.misc + +Once you set all these parameters, you can start the training. You can monitor progress with the plots; should you want to stop +the training you can do so anytime by pressing the **Start** button again, whose text should change to **Click to stop**. + +In the results folder, you will have access to the weights from training (**.pth** files), +which you can then use in inference. + +Inference +********* + +To start, choose the folder with images ready for inference, and the location you want to store your results. + +Then, select the model you trained (see note below for SegResNet), and load your weights from training. + +.. note:: + If you already trained a SegResNet, set the counter below the model choice to the size of the images you trained the model on. + (Either use the size of the image itself if you did not extract patches, or the size of the nearest superior power of two of the patches you extracted) + + Example : + + * If you used :math:`64^3` whole volumes to train the model, enter :math:`64` in the counter. + * If you extracted :math:`120^3` patches from larger images, enter :math:`128` + + +Use **window inference** when the size of your images is substantial. Ensure the size aligns with your images, as under-sizing might impact the quality of your results. You can keep the dataset on the CPU to reduce memory usage, but this might decelerate the process. + +If you have **anisotropic volumes**, you can compensate by entering the resolution of your microscope. + +By default, inference will calculate and display probability maps (values between 0 and 1). For a segmentation output with distinct labels, modify the threshold to the desired probability. + +If instead you'd prefer instance labels, you can enable instance segmentation and select : + +* The method: + + * **Voronoi-Otsu** : objects will be assigned an ID by using the Voronoi diagram of the centroids of each object, then using Otsu's thresholding to separate them. The sigmas should roughly match cell diameter. + * **Connected components** : Every seperated object above the threshold will be labeled as an instance. + * **Watershed** : Assigns identifiers to objects based on the gradient probability at the their center (set the threshold to a decently high value). + +* **The threshold** : Objects above this threshold will be retained as single instances. +* **Small object removal** : To filter small artifacts; all objects below this volume in pixels will be removed. + +Using instance segmentation, you can also analyze the results by checking the *Save stats to CSV* option. + +This will compute : + +* The volume of each cell in pixels. +* The centroid coordinates in :math:`X,Y,Z`. +* The sphericity of each cell. +* The original size of the image. +* The total volume in pixels. +* The total volume occupied by objects. +* The ratio of :math:`\frac {Volume_{label}} {Volume_{total}}`. +* The total number of unique object instance. + +To visualise some of the results when running on a folder, you can leave the **View results in napari** option checked. + +.. note:: + Too plot your results, check out the `provided notebooks`_ + +.. _provided notebooks: https://github.com/AdaptiveMotorControlLab/CellSeg3d/tree/main/notebooks + + +You can then launch inference and the results will be saved in your specified folder. + +.. figure:::: ../image/inference_results_example.png + + Example of results from inference with original volumes, as well as semantic and instance predictions. + + + +Scoring, review, analysis +---------------------------- + +.. Using the metrics utility module, you can compare the model's predictions to any ground truth labels you might have. + Simply provide your prediction and ground truth labels, and compute the results. + A Dice metric of 1 indicates perfect matching, whereas a score of 0 indicates complete mismatch. + Select which score **you consider as sub-optimal**, and all results below this will be **shown in napari**. + If at any time the **orientation of your prediction labels changed compared to the ground truth**, check the + "Find best orientation" option to compensate for it. + + +Labels review +************************ +.. _walkthrough_reviewing: + +Using the review module, you can correct the model's predictions. +Load your images and labels, and enter the name of the csv file, keeps tracking of the review process( it +records which slices have been checked or not and the time taken). + +See the `napari tutorial on annotation`_ for instruction on correcting and adding labels. + +.. _napari tutorial on annotation: https://napari.org/howtos/layers/labels.html#selecting-a-label + +If you wish to see the surroundings of an object to ensure it should be labeled, +you can use **`Shift+Click`** on the location you wish to see; this will plot +the surroundings of this location for easy viewing. + +.. figure:: ../images/review_process_example.png + :align: center + + Layout of the review module + +Once you finish reviewing, press the **Not checked** button to switch the status to +**checked** and save the time spent in the csv file. + +once satisfied with your review, press the **Save** button to record your work. + +Analysis : Jupyter notebooks +********************************* + +In the `notebooks folder of the repository`_, you can find notebooks for plotting +labels (full_plot.ipynb), and notebooks for plotting the inference results (csv_cell_plot.ipynb). + +Simply enter your folder or csv file path and the notebooks will plot your results. +Make sure you have all required libraries installed and jupyter extensions set up as explained +for the plots to work. + +.. figure:: ../images/stat_plots.png + :align: center + + Example of the plot present in the notebooks. + Coordinates are based on centroids, the size represents the volume, the color, and the sphericity. + +.. _notebooks folder of the repository: https://github.com/AdaptiveMotorControlLab/CellSeg3d/tree/main/notebooks + +With this complete, you can repeat the workflow as needed. diff --git a/docs/source/guides/inference_module_guide.rst b/docs/source/guides/inference_module_guide.rst new file mode 100644 index 00000000..4fd995e0 --- /dev/null +++ b/docs/source/guides/inference_module_guide.rst @@ -0,0 +1,170 @@ +.. _inference_module_guide: + +Inference📊 +============== + +.. figure:: ../images/plugin_inference.png + :align: center + + Layout of the inference module + +**Inference** allows you to use pre-trained segmentation algorithms, written in Pytorch, +to automatically label cells in 3D volumes. + +.. important:: + Currently, the module supports inference on **3D volumes**. When running on folders, make sure that your image folder + only contains a set of **3D image files** saved with the **`.tif`** extension. + Otherwise you can run inference directly on layers within napari. Stacks of 2D files can be loaded as 3D volumes in napari. + +At present, the following pre-trained models are available : + +============== ================================================================================================ +Model Link to original paper +============== ================================================================================================ +SwinUNetR `Swin Transformers for Semantic Segmentation of Brain Tumors in MRI Images`_ +SegResNet `3D MRI brain tumor segmentation using autoencoder regularization`_ +WNet `WNet, A Deep Model for Fully Unsupervised Image Segmentation`_ +TRAILMAP_MS An implementation of the `TRAILMAP project on GitHub`_ using `3DUNet for PyTorch`_ +VNet `Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation`_ +============== ================================================================================================ + +.. _Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation: https://arxiv.org/pdf/1606.04797.pdf +.. _3D MRI brain tumor segmentation using autoencoder regularization: https://arxiv.org/pdf/1810.11654.pdf +.. _TRAILMAP project on GitHub: https://github.com/AlbertPun/TRAILMAP +.. _3DUnet for Pytorch: https://github.com/wolny/pytorch-3dunet +.. _Swin Transformers for Semantic Segmentation of Brain Tumors in MRI Images: https://arxiv.org/abs/2201.01266 +.. _WNet, A Deep Model for Fully Unsupervised Image Segmentation: https://arxiv.org/abs/1711.08506 + +.. note:: + For WNet-specific instruction please refer to the appropriate section below. + + +Interface and functionalities +----------------------------- + +.. figure:: ../images/inference_plugin_layout.png + :align: right + + Inference parameters + +* **Loading data** : + + | When launching the module, select either an **image layer** or an **image folder** containing the 3D volumes you wish to label. + | When loading from folder : All images with the chosen extension ( currently **.tif**) will be labeled. + | Specify an **output folder**, where the labelled results will be saved. + +* **Model selection** : + + | You can then choose from the listed **models** for inference. + | You may also **load custom weights** rather than the pre-trained ones. Make sure these weights are **compatible** (e.g. produced from the training module for the same model). + | For SegResNet or SwinUNetR with custom weights, you will have to provide the size of images it was trained on to ensure compatibility. (See note below) + +.. note:: + Currently the SegResNet and SwinUNetR models require you to provide the size of the images the model was trained with. + Provided weights use a size of 64, please leave it on the default value if you're not using custom weights. + +* **Inference parameters** : + + * **Window inference**: You can choose to use inference on the entire image at once (disabled) or divide the image (enabled) on smaller chunks, based on your memory constraints. + * **Window overlap**: Define the overlap between windows to reduce border effects; + recommended values are 0.1-0.3 for 3D inference. + * **Keep on CPU**: You can choose to keep the dataset in RAM rather than VRAM to avoid running out of VRAM if you have several images. + * **Device Selection**: You can choose to run inference on either CPU or GPU. A GPU is recommended for faster inference. + +* **Anisotropy** : + + For **anisotropic images** you may set the **resolution of your volume in micron**, to view and save the results without anisotropy. + +* **Thresholding** : + + You can perform thresholding to **binarize your labels**. + All values below the **confidence threshold** will be set to 0. + +.. hint:: + It is recommended to first run without thresholding. You can then use the napari contrast limits to find a good threshold value, + and run inference later with your chosen threshold. + +* **Instance segmentation** : + + | You can convert the semantic segmentation into instance labels by using either the `Voronoi-Otsu`_, `Watershed`_ or `Connected Components`_ method, as detailed in :ref:`utils_module_guide`. + | Instance labels will be saved (and shown if applicable) separately from other results. + + +.. _Watershed: https://scikit-image.org/docs/dev/auto_examples/segmentation/plot_watershed.html +.. _Connected Components: https://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.label +.. _Voronoi-Otsu: https://haesleinhuepf.github.io/BioImageAnalysisNotebooks/20_image_segmentation/11_voronoi_otsu_labeling.html + + +* **Computing objects statistics** : + + You can choose to compute various stats from the labels and save them to a **`.csv`** file for later use. + Statistics include individual object details and general metrics. + For each object : + + * Object volume (pixels) + * :math:`X,Y,Z` coordinates of the centroid + * Sphericity + + + Global metrics : + + * Image size + * Total image volume (pixels) + * Total object (labeled) volume (pixels) + * Filling ratio (fraction of the volume that is labeled) + * The number of labeled objects + + +* **Display options** : + + When running inference on a folder, you can choose to display the results in napari. + If selected, you may choose the display quantity, and whether to display the original image alongside the results. + +Once you are ready, hit the **`Start`** button to begin inference. +The log will keep you updated on the progress. + +.. note:: + You can save the log to keep track of the parameters you ran inference with. + +Once the job has finished, the semantic segmentation will be saved in the output folder. + +| The files will be saved using the following format : +| ``{original_name}_{model}_{date & time}_pred{id}.file_ext`` + +.. hint:: + | Adjust **colormap** or **contrast** to enhance the visibility of labels. + | Experiment with **3D view** and **grid mode** in napari when checking your results. + +Plotting results +---------------- + +In the ``notebooks`` folder you will find a plotting guide for cell statistics derived from the inference module. +Simply load the csv file in the notebook and use the provided functions to plot the desired statistics. + + +Unsupervised model - WNet +------------------------- + +| The `WNet model` is a fully unsupervised model used to segment images without any labels. +| It functions similarly to the above models, with a few notable differences. + +.. _WNet model: https://arxiv.org/abs/1711.08506 + +.. note:: + Our provided, pre-trained model uses an input size of 64x64x64. As such, window inference is always enabled + and set to 64. If you want to use a different size, you will have to train your own model using the options listed in :ref:`training_wnet`. + +For the best inference performance, the model should be retrained on images of the same modality as the ones you want to segment. +Please see :ref:`training_wnet` for more details on how to train your own model. + +.. hint:: + | WNet, as an unsupervised model, may not always output the background class in the same dimension. + | This might cause the result from inference to appear densely populated. + | The plugin will automatically attempt to show the foreground class, but this might not always succeed. + | If the displayed output seems dominated by the background, you can manually adjust the visible class. To do this, **use the slider positioned at the bottom of the napari window**. + +Source code +-------------------------------- +* :doc:`../code/_autosummary/napari_cellseg3d.code_plugins.plugin_model_inference` +* :doc:`../code/_autosummary/napari_cellseg3d.code_models.worker_inference` +* :doc:`../code/_autosummary/napari_cellseg3d.code_models.models` diff --git a/docs/source/guides/installation_guide.rst b/docs/source/guides/installation_guide.rst new file mode 100644 index 00000000..ccedcaca --- /dev/null +++ b/docs/source/guides/installation_guide.rst @@ -0,0 +1,111 @@ +Installation guide ⚙ +====================== +This guide outlines the steps for installing CellSeg3D and its dependencies. The plugin is compatible with Windows, Linux, and MacOS. + +**Note for M1/M2 (ARM64) Mac Users:** +Please refer to the :ref:`section below ` for specific instructions. + +.. warning:: + If you encounter any issues during installation, feel free to open an issue on our `GitHub repository`_. + +.. _GitHub repository: https://github.com/AdaptiveMotorControlLab/CellSeg3d/issues + + +Installing pre-requisites +--------------------------- + +PyQt5 or PySide2 +_____________________ + +CellSeg3D requires either **PyQt5** or **PySide2** as a Qt backend for napari. If you don't have a Qt backend installed: + +.. code-block:: + + pip install napari[all] + +This command installs PyQt5 by default. + +PyTorch +_____________________ + +For PyTorch installation, refer to `PyTorch's website`_ , with or without CUDA according to your hardware. +Select the installation criteria that match your OS and hardware (GPU or CPU). + +.. note:: + While a **CUDA-capable GPU** is not mandatory, it is highly recommended for both training and inference. + + +* Running into MONAI-related errors? Consult MONAI’s optional dependencies for solutions. Please see `MONAI's optional dependencies`_ page for instructions on getting the readers required by your images. + +.. _MONAI's optional dependencies: https://docs.monai.io/en/stable/installation.html#installing-the-recommended-dependencies +.. _PyTorch's website: https://pytorch.org/get-started/locally/ + + + +Installing CellSeg3D +-------------------------------------------- + +.. warning:: + For M1 Mac users, please see the :ref:`section below ` + +**Via pip**: + +.. code-block:: + + pip install napari-cellseg3d + +**Directly in napari**: + +- Navigate to **Plugins > Install/Uninstall Packages** +- Search for ``napari-cellseg3d`` + +**For local installation** (after cloning from GitHub) +Navigate to the cloned CellSeg3D folder and run: + +.. code-block:: + + pip install -e . + +Successful installation will add the napari-cellseg3D plugin to napari’s Plugins section. + + +M1/M2 (ARM64) Mac installation +------------------------------- +.. _ARM64_Mac_installation: + +For ARM64 Macs, we recommend using our custom CONDA environment. This is particularly important for M1 or M2 MacBooks. + +Start by installing `miniconda3`_. + +.. _miniconda3: https://docs.conda.io/projects/conda/en/latest/user-guide/install/macos.html + +1. **Clone the repository** (`link `_): + +.. code-block:: + + git clone https://github.com/AdaptiveMotorControlLab/CellSeg3d.git + +2. **Create the Conda Environment** : +In the terminal, navigate to the CellSeg3D folder: + +.. code-block:: + + conda env create -f conda/napari_cellseg3d_m1.yml + +3. **Activate the environment** : + +.. code-block:: + + conda activate napari_cellseg3d_m1 + +4. **Install PyQt5 via conda** : + +.. code-block:: + + conda install -c anaconda pyqt + +5. **Install the plugin** : + +.. code-block:: + + pip install napari-cellseg3d diff --git a/docs/source/guides/metrics_module_guide.rst b/docs/source/guides/metrics_module_guide.rst new file mode 100644 index 00000000..b31f0e14 --- /dev/null +++ b/docs/source/guides/metrics_module_guide.rst @@ -0,0 +1,40 @@ +.. _metrics_module_guide: + +Metrics utility guide 📈 +======================== + +.. figure:: ../images/plot_example_metrics.png + :scale: 35 % + :align: right + + Dice metric plot result + +This tool computes the Dice coefficient, a similarity measure, between two sets of label folders. +Ranges from 0 (no similarity) to 1 (perfect similarity). + +The Dice coefficient is defined as : + +.. math:: \frac {2|X \cap Y|} {|X|+|Y|} + +Required parameters: +-------------------- + +* Ground Truth Labels folder +* Prediction Labels folder +* Threshold for sufficient score. Pairs below this score are highlighted in the viewer and marked in red on the plot. +* Whether to automatically determine the best orientation for the computation by rotating and flipping; + useful if your images have varied orientation. + +.. note:: + - The tool might rotate and flip images randomly to find the best Dice coefficient. If you have small images with a large number of labels, this might lead to metric inaccuracies. Low score images might be in the wrong orientation when displayed for comparison. + - This tool assumes that **predictions are padded to a power of two.** Ground truth labels can be smaller, as they will be padded to match the prediction size. + - Your files should have names that can be sorted numerically; please ensure that each ground truth label has a matching prediction label. + +To begin, press the **`Compute Dice`** button. This will plot the Dice score for each ground truth-prediction labels pair. +Pairs below the threshold will be displayed on the viewer for verification, ground truth appears in **blue**, and low score predictions in **red**. + +Source code +------------------------------------------------- + +* :doc:`../code/plugin_base` +* :doc:`../code/plugin_metrics` diff --git a/docs/source/guides/review_module_guide.rst b/docs/source/guides/review_module_guide.rst new file mode 100644 index 00000000..907aa1f4 --- /dev/null +++ b/docs/source/guides/review_module_guide.rst @@ -0,0 +1,76 @@ +.. _review_module_guide: + +Review🔍 +================================= + +.. figure:: ../images/plugin_review.png + :align: center + + Layout of the review module + +**Review** allows you to inspect your labels, which may be manually created or predicted by a model, and make necessary corrections. +The system will save the updated status of each file in a csv file. +Additionally, the time taken per slice review is logged, enabling efficient monitoring. + +Launching the review process +--------------------------------- +.. figure:: ../images/Review_Parameters.png + :align: right + :width: 300px + + +1. **Data paths:** + - *Starting a new review:* Choose the **`New review`** option, and select the corresponding layers within Napari. + - *Continuing an existing review:* Select the **`Existing review`** option, and choose the folder that contains the image, labels, and CSV file. + +.. note:: + Cellseg3D supports 3D **`.tif`** files at the moment. + If you have a stack, open it as a folder in Napari, then save it as a single **`.tif`** file. + +2. **Managing anisotropic data:** + Check this option to scale your images to visually remove the anisotropy, so as to make review easier. + +.. note:: + The results will be saved as anisotropic images. If you want to resize them, check the :doc:`utils_module_guide` + +3. **CSV file naming:** + - Select a name for your review, which will be used for the CSV file that logs the status of each slice. + - If an identical CSV file already exists, it will be used. If not, a new one will be generated. + - If you choose to create a new dataset, a new CSV will always be created. If multiple copies already exist, a sequential number will be appended to the new file's name. + +4. **Beginning the Review:** + Press **`Start reviewing`** once you are ready to start the review process. + +.. warning:: + Starting a review session opens a new window and closes the current one. + Make sure you have saved your work before starting the review session. + +Interface & functionalities +--------------------------- + +.. figure:: ../images/review_process_example.png + :align: center + + Interface of the review process. + +Once you have launched the review process, you will have access to the following functionalities: + +.. hlist:: + :columns: 1 + + * A dialog to choose where to save the verified and/or corrected annotations, and a button to save the labels. They will be using the provided file format. + * A button to update the status of the slice in the csv file (in this case : checked/not checked) + * A graph with projections in the x-y, y-z and x-z planes, to allow the reviewer to better understand the context of the volume and decide whether the image should be labeled or not. Use **shift-click** anywhere on the image or label layer to update the plot to the location being reviewed. + +To recap, you can check your labels, correct them, save them and keep track of which slices have been checked or not. + +.. note:: + You can find the csv file containing the annotation status **in the same folder as the labels**. + It will also keep track of the time taken to review each slice, which can be useful to monitor the progress of the review. + +Source code +------------------------------------------------- + +* :doc:`../code/_autosummary/napari_cellseg3d.code_plugins.plugin_review` +* :doc:`../code/_autosummary/napari_cellseg3d.code_plugins.plugin_review_dock` +* :doc:`../code/_autosummary/napari_cellseg3d.code_plugins.plugin_base` diff --git a/docs/source/guides/training_module_guide.rst b/docs/source/guides/training_module_guide.rst new file mode 100644 index 00000000..7668c0b9 --- /dev/null +++ b/docs/source/guides/training_module_guide.rst @@ -0,0 +1,243 @@ +.. _training_module_guide: + +Training📉 +---------------- + +.. figure:: ../images/plugin_train.png + :align: center + + Layout of the training module + + +**Training** allows you to train models for cell segmentation. +Whenever necessary, pre-trained weights will be automatically downloaded and integrated. + +.. important:: + At present, only inference on **3D volumes is supported**. Ensure that both your image and label folders contain a set of + **3D image files**, in either **`.tif`** or **`.tiff`** format. Loading a folder of 2D images as a stack is supported only if + you use napari to load the stack as a 3D image, and save it as a 3D image file. + +Models +=================== +Currently, we provide the following pre-defined models: + +============== ================================================================================================ +Model Link to original paper +============== ================================================================================================ +SegResNet `3D MRI brain tumor segmentation using autoencoder regularization`_ +SwinUNetR `Swin UNETR, Swin Transformers for Semantic Segmentation of Brain Tumors in MRI Images`_ +WNet `WNet, A Deep Model for Fully Unsupervised Image Segmentation`_ +TRAILMAP_MS An implementation of the `TRAILMAP project on GitHub`_ using `3DUNet for PyTorch`_ +VNet `Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation`_ +============== ================================================================================================ + +.. _Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation: https://arxiv.org/pdf/1606.04797.pdf +.. _3D MRI brain tumor segmentation using autoencoder regularization: https://arxiv.org/pdf/1810.11654.pdf +.. _TRAILMAP project on GitHub: https://github.com/AlbertPun/TRAILMAP +.. _3DUnet for Pytorch: https://github.com/wolny/pytorch-3dunet +.. _Swin UNETR, Swin Transformers for Semantic Segmentation of Brain Tumors in MRI Images: https://arxiv.org/abs/2201.01266 +.. _WNet, A Deep Model for Fully Unsupervised Image Segmentation: https://arxiv.org/abs/1711.08506 + +Training +=================== + +.. important:: + | For the optimal performance of the machine learning models within this program, it is crucial that all images in a dataset have the same dimensions. + | Before starting loading, please ensure that all images are of the **same size**. + | If there is a variance of size, you can use the ``Extract patches`` option located under the augmentation tab, please see below. + | This will let you define a reduced, consistent size for all the images. + | If you need to fragment a large file into cubes, please refer to the Fragment utility in :ref:`utils_module_guide`. + +The training module is comprised of several tabs : + +1) **Model** tab +___________________ + +.. figure:: ../images/training_tab_1.png + :align: right + + Model tab + +* Select which model to use (see table above). +* Decide on using pre-trained weights. + +.. note:: + The model will be initialized with our pre-trained weights, + possibly improving performance via transfer learning. + Custom weights may also be loaded; + simply ensure they are compatible with the chosen model. + +* Select between CPU and GPU (if CUDA is available). + +2) **Data** tab +___________________ + +.. figure:: ../images/training_tab_2.png + :align: right + + Data tab + +For Supervised Models: +********************** +1. **Paths**: + - Image Folder (3D image files) + - Labels Folder (3D image files) + - Results Folder + +2. **Options**: + - Save a copy of results as a **`zip`** file + - Either use images "as is" (requires uniform size and cubic volume) or extract patches. + +.. note:: + Preferably, the image dimensions should be equal to a power of two. Images are automatically padded; a 64 pixels cube will be used as is, while a 65 pixel cube will be padded up to 128 pixels, resulting in much higher memory consumption. + +3. If you're extracting patches: + - Define patches (ideally, please use a value close or equal to a power of two. See above note.) + - Decide on the number of samples to extract from each image. A larger number will likely improve performances, but will also extend training time and increase memory usage. + +If you're using a single image (preferably large) it is recommended to enable patch extraction. + +4. Decide on executing data augmentation (elastic deforms, intensity shifts. random flipping,etc). +5. Define the training versus validation proportion according to your dataset. + +For Unsupervised models +*********************** +1. **Paths**: + - Training Images Folder (3D image files) + - Validation Images Folder (3D image files - **OPTIONAL**) + - Validation Labels Folder (3D image files - **OPTIONAL**) + - Results Folder + +2. **Options**: + - Save a copy of results as a **`zip`** file + - Either use images "as is" (requires uniform size and cubic volume) or extract patches. + +3. Decide on executing data augmentation (elastic deforms, intensity shifts. random flipping,etc). + +3) **Training** tab +____________________ + +.. figure:: ../images/training_tab_3.png + :align: right + + Training tab + + +* **Loss function** : + - `Dice Loss from MONAI`_ + - `Generalized dice Loss from MONAI`_ + - `Dice-CrossEntropy Loss from MONAI`_ + - `Tversky Loss from MONAI`_ + +.. _Dice Loss from MONAI: https://docs.monai.io/en/stable/losses.html#diceloss +.. _Focal Loss from MONAI: https://docs.monai.io/en/stable/losses.html#focalloss +.. _Dice-focal Loss from MONAI: https://docs.monai.io/en/stable/losses.html#dicefocalloss +.. _Generalized dice Loss from MONAI: https://docs.monai.io/en/stable/losses.html#generalizeddiceloss +.. _Dice-CrossEntropy Loss from MONAI: https://docs.monai.io/en/stable/losses.html#diceceloss +.. _Tversky Loss from MONAI: https://docs.monai.io/en/stable/losses.html#tverskyloss + +* **Batch size** : + The batch size determines the number of samples that will be propagated through the network simultaneously. + Larger values can lead to quicker training and potentially better performance, but they will also require more memory. Adjust based on your system's capabilities. + +* **Learning rate of the optimizer** : + This parameter controls the step size during the optimization process. + When using pre-trained weights, setting a lower learning rate can enhance performance. + +* **Number of epochs** : + Refers to the number of times the algorithm will work through the entire training dataset. + A starting suggestion could be 100 epochs, but this might need to be adjusted based on the speed of convergence. + +* **Validation epoch interval** : + Determines how frequently the model is evaluated on the validation dataset. + For instance, if set to two, the module will assess the model's performance using the dice metric every two epochs. + +* **Scheduler patience** : + It defines how many epochs at a plateau the algorithm should wait before reducing the learning rate. + +* **Scheduler factor** : + Once a plateau in model performance is detected, the learning rate is reduced by this factor. + +* **Deterministic training** : + If enabled, the training process becomes reproducible. You can also specify a seed value. + +.. note:: + If the dice metric is better on a given validation interval, the model weights will be saved in the results folder. + +1) **Advanced** tab +___________________ + +This tab is only available with WNet training. For more information please see the :ref:`WNet parameters list ` section. + +Running the training +____________________ + +Once you are ready, press the **`Start`** button to begin training. The module will automatically train the model. + +.. note:: + You can stop the training process at any moment by clicking on the **`Start`** button again. + **The training will stop after processing the upcoming batch, and will try to save the model. However, be aware that interrupting will result in partial results.** + +After conducting at least two validation steps (which depends on the interval you set), +the training loss values and validation metrics will be plotted +and shown on napari every time a validation step completes. +This plot is automatically saved each time validation is performed and the final version is stored separately in the results folder. +The model's inputs (image, label) and outputs (raw & binarized) will also be displayed in the napari viewer. + +.. figure:: ../images/plots_train.png + :align: center + + Example of plots displayed by the training module after 40 epochs + +.. note:: + You can save the log with the button underneath it to record the losses and validation metrics numerical values at each step. This log is autosaved as well when training completes. + +Unsupervised model +============================================== + +The training of our custom WNet implementation is now available as part of the Training module. + +Please see the :ref:`training_wnet` section for more information. + +WandB integration (optional) +============================================== + +.. _wandb_integration: + +You can use the `Weights and Biases `_ platform to track your training metrics and results. + +.. note:: + WandB integration is available for all provided models. + +To use wandb, you will need to create an account [HERE](https://wandb.ai/site) and install the wandb python package. + +* Install : + +.. code-block:: + + pip install wandb + +* Alternatively, you can install it as an optional requirement with the following command : + +.. code-block:: + + pip install napari-cellseg3d[wandb] + +* Connect your account : + +.. code-block:: + + wandb login + +Your API key will be requested. You can find it on your account page on the website. +Once this is done, your training runs will be automatically logged to WandB. +You can find them under **CellSeg3D {MODEL NAME}** on your project page. + +.. note:: + User parameters for WandB as well as improved model comparisons might be added in the future. + +Source code +============================================== +* :doc:`../code/_autosummary/napari_cellseg3d.code_plugins.plugin_model_training` +* :doc:`../code/_autosummary/napari_cellseg3d.code_models.worker_training` +* :doc:`../code/_autosummary/napari_cellseg3d.code_models.models` diff --git a/docs/source/guides/training_wnet.rst b/docs/source/guides/training_wnet.rst new file mode 100644 index 00000000..35aedd2d --- /dev/null +++ b/docs/source/guides/training_wnet.rst @@ -0,0 +1,65 @@ +.. _training_wnet: + +Advanced : WNet training +======================== + +This plugin provides a reimplemented, custom version of the WNet model from `WNet, A Deep Model for Fully Unsupervised Image Segmentation`_. +For training your model, you can choose among: + +* Directly within the plugin +* The provided Jupyter notebook (locally) +* Our Colab notebook (inspired by ZeroCostDL4Mic) + +The WNet does not require a large amount of data to train, but during inference images should be similar to those +the model was trained on; you can retrain from our pretrained model to your image dataset to quickly reach good performance. + +.. note:: + - The WNet relies on brightness to distinguish objects from the background. For better results, use image regions with minimal artifacts. If you notice many artifacts, consider training on one of the supervised models. + - The model has two losses, the **`SoftNCut loss`**, which clusters pixels according to brightness, and a reconstruction loss, either **`Mean Square Error (MSE)`** or **`Binary Cross Entropy (BCE)`**. Unlike the method described in the original paper, these losses are added in a weighted sum and the backward pass is performed for the whole model at once. The SoftNcuts and BCE are bounded between 0 and 1; the MSE may take large positive values. It is recommended to watch for the weighted sum of losses to be **close to one on the first epoch**, for training stability. + - For good performance, you should wait for the SoftNCut to reach a plateau; the reconstruction loss must also decrease but is generally less critical. + +Parameters +---------- + +.. figure:: ../images/training_tab_4.png + :scale: 100 % + :align: right + + Advanced tab + +_`When using the WNet training module`, the **Advanced** tab contains a set of additional options: + +- **Number of classes** : Dictates the segmentation classes (default is 2). Increasing the number of classes will result in a more progressive segmentation according to brightness; can be useful if you have "halos" around your objects or artifacts with a significantly different brightness. +- **Reconstruction loss** : Choose between MSE or BCE (default is MSE). MSE is more precise but also sensitive to outliers; BCE is more robust against outliers at the cost of precision. + +- NCuts parameters: + - **Intensity sigma** : Standard deviation of the feature similarity term, focusing on brightness (default is 1). + - **Spatial sigma** : Standard deviation for the spatial proximity term (default is 4). + - **Radius** : Pixel radius for the loss computation (default is 2). + +.. note:: + - The **Intensity Sigma** depends on image pixel values. The default of 1 is optimised for images being mapped between 0 and 100, which is done automatically by the plugin. + - Raising the **Radius** might improve performance in certain cases, but will also greatly increase computation time. + +- Weights for the sum of losses : + - **NCuts weight** : Sets the weight of the NCuts loss (default is 0.5). + - **Reconstruction weight** : Sets the weight for the reconstruction loss (default is 0.5*1e-2). + +.. note:: + The weight of the reconstruction loss should be adjusted to ensure the weighted sum is around one during the first epoch; + ideally the reconstruction loss should be of the same order of magnitude as the NCuts loss after being multiplied by its weight. + +Common issues troubleshooting +------------------------------ +If you do not find a satisfactory answer here, please do not hesitate to `open an issue`_ on GitHub. + +- **The NCuts loss explodes after a few epochs** : Lower the learning rate, first by a factor of two, then ten. + +- **The NCuts loss does not converge and is unstable** : + The normalization step might not be adapted to your images. Disable normalization and change intensity_sigma according to the distribution of values in your image. For reference, by default images are remapped to values between 0 and 100, and intensity_sigma=1. + +- **Reconstruction (decoder) performance is poor** : switch to BCE and set the scaling factor of the reconstruction loss to 0.5, OR adjust the weight of the MSE loss to make it closer to 1 in the weighted sum. + + +.. _WNet, A Deep Model for Fully Unsupervised Image Segmentation: https://arxiv.org/abs/1711.08506 +.. _open an issue: https://github.com/AdaptiveMotorControlLab/CellSeg3d/issues diff --git a/docs/source/guides/utils_module_guide.rst b/docs/source/guides/utils_module_guide.rst new file mode 100644 index 00000000..37bbd9d5 --- /dev/null +++ b/docs/source/guides/utils_module_guide.rst @@ -0,0 +1,97 @@ +.. _utils_module_guide: + +Utilities 🛠 +============ + +Here you will find a range of tools for image processing and analysis. + +.. note:: + The utility selection menu is found at the bottom of the plugin window. + +You may specify the results directory for saving; afterwards you can run each action on a folder or on the currently selected layer. + +Available actions +__________________ + +1. Crop 3D volumes +------------------ +Please refer to :ref:`cropping_module_guide` for a guide on using the cropping utility. + +2. Convert to instance labels +----------------------------- +This will convert semantic (binary) labels to instance labels (with a unique ID for each object). +The available methods for this are: + +* `Connected Components`_ : simple method that will assign a unique ID to each connected component. Does not work well for touching objects (objects will often be fused). +* `Watershed`_ : method based on topographic maps. Works well for clumped objects and anisotropic volumes depending on the quality of topography; clumed objects may be fused if this is not true. +* `Voronoi-Otsu`_ : method based on Voronoi diagrams and Otsu thresholding. Works well for clumped objects but only for "round" objects. + +3. Convert to semantic labels +----------------------------- +Transforms instance labels into 0/1 semantic labels, useful for training purposes. + +4. Remove small objects +----------------------- +Input a size threshold (in pixels) to eliminate objects below this size. + +5. Resize anisotropic images +---------------------------- +Input your microscope's resolution to remove anisotropy in images. + +6. Threshold images +------------------- +Removes values beneath a certain threshold. + +7. Fragment image +----------------- +Break down large images into smaller cubes, optimal for training. + +8. Conditional Random Field (CRF) +--------------------------------- + +.. note:: + This utility is only available if you have installed the `pydensecrf` package. + You may install it by using the command ``pip install cellseg3d[crf]``. + +| Refines semantic predictions by pairing them with the original image. +| For a list of parameters, see the :doc:`CRF API page<../code/_autosummary/napari_cellseg3d.code_models.crf>`. + +9. Labels statistics +------------------------------------------------ +| Computes statistics for each object in the image. +| Enter the name of the csv file to save the results, then select your layer or folder of labels to compute the statistics. + +.. note:: + Images that are not only integer labels will be ignored. + +The available statistics are: + +For each object : + +* Object volume (pixels) +* :math:`X,Y,Z` coordinates of the centroid +* Sphericity + +Global metrics : + +* Image size +* Total image volume (pixels) +* Total object (labeled) volume (pixels) +* Filling ratio (fraction of the volume that is labeled) +* The number of labeled objects + +.. hint:: + Check the ``notebooks`` folder for examples of plots using the statistics CSV file. + +Source code +___________ + +* :doc:`../code/_autosummary/napari_cellseg3d.code_plugins.plugin_convert` +* :doc:`../code/_autosummary/napari_cellseg3d.code_plugins.plugin_crf` + + +.. links + +.. _Watershed: https://scikit-image.org/docs/dev/auto_examples/segmentation/plot_watershed.html +.. _Connected Components: https://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.label +.. _Voronoi-Otsu: https://haesleinhuepf.github.io/BioImageAnalysisNotebooks/20_image_segmentation/11_voronoi_otsu_labeling.html diff --git a/docs/source/images/Review_Parameters.png b/docs/source/images/Review_Parameters.png new file mode 100644 index 00000000..38435460 Binary files /dev/null and b/docs/source/images/Review_Parameters.png differ diff --git a/docs/source/images/WNet_architecture.svg b/docs/source/images/WNet_architecture.svg new file mode 100644 index 00000000..08553384 --- /dev/null +++ b/docs/source/images/WNet_architecture.svg @@ -0,0 +1,3607 @@ + + + + + + +model + + +cluster_2 + +UNet + + +cluster_3 + +InBlock + + +cluster_4 + +Sequential + + +cluster_5 + +Block + + +cluster_6 + +Sequential + + +cluster_9 + +Block + + +cluster_10 + +Sequential + + +cluster_11 + +Block + + +cluster_12 + +Sequential + + +cluster_7 + +Block + + +cluster_8 + +Sequential + + +cluster_13 + +Block + + +cluster_14 + +Sequential + + +cluster_15 + +OutBlock + + +cluster_16 + +Sequential + + +cluster_17 + +UNet + + +cluster_18 + +InBlock + + +cluster_19 + +Sequential + + +cluster_20 + +Block + + +cluster_21 + +Sequential + + +cluster_22 + +Block + + +cluster_23 + +Sequential + + +cluster_24 + +Block + + +cluster_25 + +Sequential + + +cluster_28 + +Block + + +cluster_29 + +Sequential + + +cluster_26 + +Block + + +cluster_27 + +Sequential + + +cluster_30 + +OutBlock + + +cluster_31 + +Sequential + + + +0 + + +input-tensor +depth:0 + +(1, 1, 64, 64, 64) + + + +1 + + +Conv3d +depth:4 + +input: + +(1, 1, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +0->1 + + + + + +2 + + +ReLU +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +1->2 + + + + + +3 + + +Dropout +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +2->3 + + + + + +4 + + +GroupNorm +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +3->4 + + + + + +5 + + +Conv3d +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +4->5 + + + + + +6 + + +ReLU +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +5->6 + + + + + +7 + + +Dropout +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +6->7 + + + + + +8 + + +GroupNorm +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +7->8 + + + + + +9 + + +MaxPool3d +depth:2 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 32, 32, 32) + + + +8->9 + + + + + +67 + + +cat +depth:2 + +input: + +2 x (1, 64, 64, 64, 64) + +output: + +(1, 128, 64, 64, 64) + + + +8->67 + + + + + +10 + + +Conv3d +depth:4 + +input: + +(1, 64, 32, 32, 32) + +output: + +(1, 64, 32, 32, 32) + + + +9->10 + + + + + +11 + + +Conv3d +depth:4 + +input: + +(1, 64, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +10->11 + + + + + +12 + + +ReLU +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +11->12 + + + + + +13 + + +Dropout +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +12->13 + + + + + +14 + + +GroupNorm +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +13->14 + + + + + +15 + + +Conv3d +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +14->15 + + + + + +16 + + +Conv3d +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +15->16 + + + + + +17 + + +ReLU +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +16->17 + + + + + +18 + + +Dropout +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +17->18 + + + + + +19 + + +GroupNorm +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +18->19 + + + + + +20 + + +MaxPool3d +depth:2 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 16, 16, 16) + + + +19->20 + + + + + +55 + + +cat +depth:2 + +input: + +2 x (1, 128, 32, 32, 32) + +output: + +(1, 256, 32, 32, 32) + + + +19->55 + + + + + +21 + + +Conv3d +depth:4 + +input: + +(1, 128, 16, 16, 16) + +output: + +(1, 128, 16, 16, 16) + + + +20->21 + + + + + +22 + + +Conv3d +depth:4 + +input: + +(1, 128, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +21->22 + + + + + +23 + + +ReLU +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +22->23 + + + + + +24 + + +Dropout +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +23->24 + + + + + +25 + + +GroupNorm +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +24->25 + + + + + +26 + + +Conv3d +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +25->26 + + + + + +27 + + +Conv3d +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +26->27 + + + + + +28 + + +ReLU +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +27->28 + + + + + +29 + + +Dropout +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +28->29 + + + + + +30 + + +GroupNorm +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +29->30 + + + + + +31 + + +MaxPool3d +depth:2 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 8, 8, 8) + + + +30->31 + + + + + +43 + + +cat +depth:2 + +input: + +2 x (1, 256, 16, 16, 16) + +output: + +(1, 512, 16, 16, 16) + + + +30->43 + + + + + +32 + + +Conv3d +depth:4 + +input: + +(1, 256, 8, 8, 8) + +output: + +(1, 256, 8, 8, 8) + + + +31->32 + + + + + +33 + + +Conv3d +depth:4 + +input: + +(1, 256, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +32->33 + + + + + +34 + + +ReLU +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +33->34 + + + + + +35 + + +Dropout +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +34->35 + + + + + +36 + + +GroupNorm +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +35->36 + + + + + +37 + + +Conv3d +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +36->37 + + + + + +38 + + +Conv3d +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +37->38 + + + + + +39 + + +ReLU +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +38->39 + + + + + +40 + + +Dropout +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +39->40 + + + + + +41 + + +GroupNorm +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +40->41 + + + + + +42 + + +ConvTranspose3d +depth:2 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 256, 16, 16, 16) + + + +41->42 + + + + + +42->43 + + + + + +44 + + +Conv3d +depth:4 + +input: + +(1, 512, 16, 16, 16) + +output: + +(1, 512, 16, 16, 16) + + + +43->44 + + + + + +45 + + +Conv3d +depth:4 + +input: + +(1, 512, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +44->45 + + + + + +46 + + +ReLU +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +45->46 + + + + + +47 + + +Dropout +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +46->47 + + + + + +48 + + +GroupNorm +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +47->48 + + + + + +49 + + +Conv3d +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +48->49 + + + + + +50 + + +Conv3d +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +49->50 + + + + + +51 + + +ReLU +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +50->51 + + + + + +52 + + +Dropout +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +51->52 + + + + + +53 + + +GroupNorm +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +52->53 + + + + + +54 + + +ConvTranspose3d +depth:2 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 128, 32, 32, 32) + + + +53->54 + + + + + +54->55 + + + + + +56 + + +Conv3d +depth:4 + +input: + +(1, 256, 32, 32, 32) + +output: + +(1, 256, 32, 32, 32) + + + +55->56 + + + + + +57 + + +Conv3d +depth:4 + +input: + +(1, 256, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +56->57 + + + + + +58 + + +ReLU +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +57->58 + + + + + +59 + + +Dropout +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +58->59 + + + + + +60 + + +GroupNorm +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +59->60 + + + + + +61 + + +Conv3d +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +60->61 + + + + + +62 + + +Conv3d +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +61->62 + + + + + +63 + + +ReLU +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +62->63 + + + + + +64 + + +Dropout +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +63->64 + + + + + +65 + + +GroupNorm +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +64->65 + + + + + +66 + + +ConvTranspose3d +depth:2 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 64, 64, 64, 64) + + + +65->66 + + + + + +66->67 + + + + + +68 + + +Conv3d +depth:4 + +input: + +(1, 128, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +67->68 + + + + + +69 + + +ReLU +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +68->69 + + + + + +70 + + +Dropout +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +69->70 + + + + + +71 + + +GroupNorm +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +70->71 + + + + + +72 + + +Conv3d +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +71->72 + + + + + +73 + + +ReLU +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +72->73 + + + + + +74 + + +Dropout +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +73->74 + + + + + +75 + + +GroupNorm +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +74->75 + + + + + +76 + + +Conv3d +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 2, 64, 64, 64) + + + +75->76 + + + + + +77 + + +Softmax +depth:2 + +input: + +(1, 2, 64, 64, 64) + +output: + +(1, 2, 64, 64, 64) + + + +76->77 + + + + + +78 + + +Conv3d +depth:4 + +input: + +(1, 2, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +77->78 + + + + + +155 + + +output-tensor +depth:0 + +(1, 2, 64, 64, 64) + + + +77->155 + + + + + +79 + + +ReLU +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +78->79 + + + + + +80 + + +Dropout +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +79->80 + + + + + +81 + + +GroupNorm +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +80->81 + + + + + +82 + + +Conv3d +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +81->82 + + + + + +83 + + +ReLU +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +82->83 + + + + + +84 + + +Dropout +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +83->84 + + + + + +85 + + +GroupNorm +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +84->85 + + + + + +86 + + +MaxPool3d +depth:2 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 32, 32, 32) + + + +85->86 + + + + + +144 + + +cat +depth:2 + +input: + +2 x (1, 64, 64, 64, 64) + +output: + +(1, 128, 64, 64, 64) + + + +85->144 + + + + + +87 + + +Conv3d +depth:4 + +input: + +(1, 64, 32, 32, 32) + +output: + +(1, 64, 32, 32, 32) + + + +86->87 + + + + + +88 + + +Conv3d +depth:4 + +input: + +(1, 64, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +87->88 + + + + + +89 + + +ReLU +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +88->89 + + + + + +90 + + +Dropout +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +89->90 + + + + + +91 + + +GroupNorm +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +90->91 + + + + + +92 + + +Conv3d +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +91->92 + + + + + +93 + + +Conv3d +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +92->93 + + + + + +94 + + +ReLU +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +93->94 + + + + + +95 + + +Dropout +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +94->95 + + + + + +96 + + +GroupNorm +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +95->96 + + + + + +97 + + +MaxPool3d +depth:2 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 16, 16, 16) + + + +96->97 + + + + + +132 + + +cat +depth:2 + +input: + +2 x (1, 128, 32, 32, 32) + +output: + +(1, 256, 32, 32, 32) + + + +96->132 + + + + + +98 + + +Conv3d +depth:4 + +input: + +(1, 128, 16, 16, 16) + +output: + +(1, 128, 16, 16, 16) + + + +97->98 + + + + + +99 + + +Conv3d +depth:4 + +input: + +(1, 128, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +98->99 + + + + + +100 + + +ReLU +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +99->100 + + + + + +101 + + +Dropout +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +100->101 + + + + + +102 + + +GroupNorm +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +101->102 + + + + + +103 + + +Conv3d +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +102->103 + + + + + +104 + + +Conv3d +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +103->104 + + + + + +105 + + +ReLU +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +104->105 + + + + + +106 + + +Dropout +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +105->106 + + + + + +107 + + +GroupNorm +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +106->107 + + + + + +108 + + +MaxPool3d +depth:2 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 8, 8, 8) + + + +107->108 + + + + + +120 + + +cat +depth:2 + +input: + +2 x (1, 256, 16, 16, 16) + +output: + +(1, 512, 16, 16, 16) + + + +107->120 + + + + + +109 + + +Conv3d +depth:4 + +input: + +(1, 256, 8, 8, 8) + +output: + +(1, 256, 8, 8, 8) + + + +108->109 + + + + + +110 + + +Conv3d +depth:4 + +input: + +(1, 256, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +109->110 + + + + + +111 + + +ReLU +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +110->111 + + + + + +112 + + +Dropout +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +111->112 + + + + + +113 + + +GroupNorm +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +112->113 + + + + + +114 + + +Conv3d +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +113->114 + + + + + +115 + + +Conv3d +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +114->115 + + + + + +116 + + +ReLU +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +115->116 + + + + + +117 + + +Dropout +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +116->117 + + + + + +118 + + +GroupNorm +depth:4 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 512, 8, 8, 8) + + + +117->118 + + + + + +119 + + +ConvTranspose3d +depth:2 + +input: + +(1, 512, 8, 8, 8) + +output: + +(1, 256, 16, 16, 16) + + + +118->119 + + + + + +119->120 + + + + + +121 + + +Conv3d +depth:4 + +input: + +(1, 512, 16, 16, 16) + +output: + +(1, 512, 16, 16, 16) + + + +120->121 + + + + + +122 + + +Conv3d +depth:4 + +input: + +(1, 512, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +121->122 + + + + + +123 + + +ReLU +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +122->123 + + + + + +124 + + +Dropout +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +123->124 + + + + + +125 + + +GroupNorm +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +124->125 + + + + + +126 + + +Conv3d +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +125->126 + + + + + +127 + + +Conv3d +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +126->127 + + + + + +128 + + +ReLU +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +127->128 + + + + + +129 + + +Dropout +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +128->129 + + + + + +130 + + +GroupNorm +depth:4 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 256, 16, 16, 16) + + + +129->130 + + + + + +131 + + +ConvTranspose3d +depth:2 + +input: + +(1, 256, 16, 16, 16) + +output: + +(1, 128, 32, 32, 32) + + + +130->131 + + + + + +131->132 + + + + + +133 + + +Conv3d +depth:4 + +input: + +(1, 256, 32, 32, 32) + +output: + +(1, 256, 32, 32, 32) + + + +132->133 + + + + + +134 + + +Conv3d +depth:4 + +input: + +(1, 256, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +133->134 + + + + + +135 + + +ReLU +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +134->135 + + + + + +136 + + +Dropout +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +135->136 + + + + + +137 + + +GroupNorm +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +136->137 + + + + + +138 + + +Conv3d +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +137->138 + + + + + +139 + + +Conv3d +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +138->139 + + + + + +140 + + +ReLU +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +139->140 + + + + + +141 + + +Dropout +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +140->141 + + + + + +142 + + +GroupNorm +depth:4 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 128, 32, 32, 32) + + + +141->142 + + + + + +143 + + +ConvTranspose3d +depth:2 + +input: + +(1, 128, 32, 32, 32) + +output: + +(1, 64, 64, 64, 64) + + + +142->143 + + + + + +143->144 + + + + + +145 + + +Conv3d +depth:4 + +input: + +(1, 128, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +144->145 + + + + + +146 + + +ReLU +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +145->146 + + + + + +147 + + +Dropout +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +146->147 + + + + + +148 + + +GroupNorm +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +147->148 + + + + + +149 + + +Conv3d +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +148->149 + + + + + +150 + + +ReLU +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +149->150 + + + + + +151 + + +Dropout +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +150->151 + + + + + +152 + + +GroupNorm +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 64, 64, 64, 64) + + + +151->152 + + + + + +153 + + +Conv3d +depth:4 + +input: + +(1, 64, 64, 64, 64) + +output: + +(1, 2, 64, 64, 64) + + + +152->153 + + + + + +154 + + +output-tensor +depth:0 + +(1, 2, 64, 64, 64) + + + +153->154 + + + + + diff --git a/docs/res/images/converted_labels.png b/docs/source/images/converted_labels.png similarity index 100% rename from docs/res/images/converted_labels.png rename to docs/source/images/converted_labels.png diff --git a/docs/source/images/cropping_process_example.png b/docs/source/images/cropping_process_example.png new file mode 100644 index 00000000..23ee6f07 Binary files /dev/null and b/docs/source/images/cropping_process_example.png differ diff --git a/docs/source/images/inference_plugin_layout.png b/docs/source/images/inference_plugin_layout.png new file mode 100644 index 00000000..b2a556fd Binary files /dev/null and b/docs/source/images/inference_plugin_layout.png differ diff --git a/docs/res/images/inference_results_example.png b/docs/source/images/inference_results_example.png similarity index 100% rename from docs/res/images/inference_results_example.png rename to docs/source/images/inference_results_example.png diff --git a/docs/res/images/init_image_labels.png b/docs/source/images/init_image_labels.png similarity index 100% rename from docs/res/images/init_image_labels.png rename to docs/source/images/init_image_labels.png diff --git a/docs/res/images/plot_example_metrics.png b/docs/source/images/plot_example_metrics.png similarity index 100% rename from docs/res/images/plot_example_metrics.png rename to docs/source/images/plot_example_metrics.png diff --git a/docs/source/images/plots_train.png b/docs/source/images/plots_train.png new file mode 100644 index 00000000..a6063ff2 Binary files /dev/null and b/docs/source/images/plots_train.png differ diff --git a/docs/source/images/plugin_crop.png b/docs/source/images/plugin_crop.png new file mode 100644 index 00000000..affc0408 Binary files /dev/null and b/docs/source/images/plugin_crop.png differ diff --git a/docs/source/images/plugin_inference.png b/docs/source/images/plugin_inference.png new file mode 100644 index 00000000..43844532 Binary files /dev/null and b/docs/source/images/plugin_inference.png differ diff --git a/docs/source/images/plugin_menu.png b/docs/source/images/plugin_menu.png new file mode 100644 index 00000000..29ebfe24 Binary files /dev/null and b/docs/source/images/plugin_menu.png differ diff --git a/docs/source/images/plugin_review.png b/docs/source/images/plugin_review.png new file mode 100644 index 00000000..306459cb Binary files /dev/null and b/docs/source/images/plugin_review.png differ diff --git a/docs/source/images/plugin_train.png b/docs/source/images/plugin_train.png new file mode 100644 index 00000000..2d5aae36 Binary files /dev/null and b/docs/source/images/plugin_train.png differ diff --git a/docs/source/images/plugin_welcome.png b/docs/source/images/plugin_welcome.png new file mode 100644 index 00000000..8cc8164c Binary files /dev/null and b/docs/source/images/plugin_welcome.png differ diff --git a/docs/source/images/review_process_example.png b/docs/source/images/review_process_example.png new file mode 100644 index 00000000..1188a839 Binary files /dev/null and b/docs/source/images/review_process_example.png differ diff --git a/docs/res/images/stat_plots.png b/docs/source/images/stat_plots.png similarity index 100% rename from docs/res/images/stat_plots.png rename to docs/source/images/stat_plots.png diff --git a/docs/source/images/training_tab_1.png b/docs/source/images/training_tab_1.png new file mode 100644 index 00000000..f1bb777a Binary files /dev/null and b/docs/source/images/training_tab_1.png differ diff --git a/docs/source/images/training_tab_2.png b/docs/source/images/training_tab_2.png new file mode 100644 index 00000000..1b54c180 Binary files /dev/null and b/docs/source/images/training_tab_2.png differ diff --git a/docs/source/images/training_tab_3.png b/docs/source/images/training_tab_3.png new file mode 100644 index 00000000..5569a8c3 Binary files /dev/null and b/docs/source/images/training_tab_3.png differ diff --git a/docs/source/images/training_tab_4.png b/docs/source/images/training_tab_4.png new file mode 100644 index 00000000..b08053f4 Binary files /dev/null and b/docs/source/images/training_tab_4.png differ diff --git a/docs/res/logo/logo_alpha.png b/docs/source/logo/logo_alpha.png similarity index 100% rename from docs/res/logo/logo_alpha.png rename to docs/source/logo/logo_alpha.png diff --git a/docs/welcome.rst b/docs/welcome.rst new file mode 100644 index 00000000..573ddc14 --- /dev/null +++ b/docs/welcome.rst @@ -0,0 +1,179 @@ +Welcome to CellSeg3D! +===================== + + +.. figure:: ./source/images/plugin_welcome.png + :align: center + +**CellSeg3D** is a toolbox for 3D segmentation of cells in light-sheet microscopy images, using napari. +Use CellSeg3D to: + +* Review labeled cell volumes from whole-brain samples of mice imaged by mesoSPIM microscopy [1]_ +* Train and use segmentation models from the MONAI project [2]_ or implement your own custom 3D segmentation models using PyTorch. + +No labeled data? Try our unsupervised model to automate your data labelling. + +The models provided should be adaptable to other tasks related to detection of 3D objects, +outside of whole-brain light-sheet microscopy. + +.. figure:: https://images.squarespace-cdn.com/content/v1/57f6d51c9f74566f55ecf271/0d16a71b-3ff2-477a-9d83-18d96cb1ce28/full_demo.gif?format=500w + :alt: CellSeg3D demo + :width: 500 + :align: center + + Demo of the plugin + + +Requirements +-------------------------------------------- + +.. important:: + This package requires **PyQt5** or **PySide2** to be installed first for napari to run. + If you do not have a Qt backend installed you can use : + ``pip install napari[all]`` + to install PyQt5 by default. + +This package depends on PyTorch and certain optional dependencies of MONAI. These come as requirements, but if +you need further assistance, please see below. + +.. note:: + A **CUDA-capable GPU** is not needed but **very strongly recommended**, especially for training and to a lesser degree inference. + +* For help with PyTorch, please see `PyTorch's website`_ for installation instructions, with or without CUDA according to your hardware. + **Depending on your setup, you might wish to install torch first.** + +* If you get errors from MONAI regarding missing readers, please see `MONAI's optional dependencies`_ page for instructions on getting the readers required by your images. + +.. _MONAI's optional dependencies: https://docs.monai.io/en/stable/installation.html#installing-the-recommended-dependencies +.. _PyTorch's website: https://pytorch.org/get-started/locally/ + + + +Installation +-------------------------------------------- +CellSeg3D can be run on Windows, Linux, or MacOS. +For detailed installation instructions, including installing pre-requisites, +please see :ref:`source/guides/installation_guide:Installation guide ⚙` + +.. warning:: + **M1/M2 MacOS users**, please refer to the :ref:`dedicated section ` + +You can install ``napari-cellseg3d`` via pip: + +.. code-block:: + + pip install napari-cellseg3d + +For local installation after cloning from GitHub, please run the following in the CellSeg3D folder: + +.. code-block:: + + pip install -e . + +If the installation was successful, you will find the napari-cellseg3D plugin in the Plugins section of napari. + + + +Usage +-------------------------------------------- + +To use the plugin, please run: + +.. code-block:: + + napari + +Then go into **Plugins > CellSeg3D** + +.. figure:: ./source/images/plugin_menu.png + :align: center + + +and choose the correct tool to use: + +- :ref:`review_module_guide`: Examine and refine your labels, whether manually annotated or predicted by a pre-trained model. +- :ref:`training_module_guide`: Train segmentation algorithms on your own data. +- :ref:`inference_module_guide`: Use pre-trained segmentation algorithms on volumes to automate cell labelling. +- :ref:`utils_module_guide`: Leverage various utilities, including cropping your volumes and labels, converting semantic to instance labels, and more. +- **Help/About...** : Quick access to version info, Github pages and documentation. + +.. hint:: + Many buttons have tooltips to help you understand what they do. + Simply hover over them to see the tooltip. + + +Documentation contents +-------------------------------------------- +_`From this page you can access the guides on the several modules available for your tasks`, such as : + + +* Main modules : + * :ref:`review_module_guide` + * :ref:`training_module_guide` + * :ref:`inference_module_guide` +* Utilities : + * :ref:`cropping_module_guide` + * :ref:`utils_module_guide` + +.. + * Convert labels : :ref:`utils_module_guide` +.. + * Compute scores : :ref:`metrics_module_guide` + +* Advanced : + * :ref:`training_wnet` + * :ref:`custom_model_guide` **(WIP)** + +Other useful napari plugins +--------------------------------------------- + +.. important:: + | Please note that these plugins are not developed by us, and we cannot guarantee their compatibility, functionality or support. + | Installing napari plugins in separated environments is recommended. + +* `brainreg-napari`_ : Whole-brain registration in napari +* `napari-brightness-contrast`_ : Adjust brightness and contrast of your images, visualize histograms and more +* `napari-pyclesperanto-assistant`_ : Image processing workflows using pyclEsperanto +* `napari-skimage-regionprops`_ : Compute region properties on your labels + +.. _napari-pyclesperanto-assistant: https://www.napari-hub.org/plugins/napari-pyclesperanto-assistant +.. _napari-brightness-contrast: https://www.napari-hub.org/plugins/napari-brightness-contrast +.. _brainreg-napari: https://www.napari-hub.org/plugins/brainreg-napari +.. _napari-skimage-regionprops: https://www.napari-hub.org/plugins/napari-skimage-regionprops + +Acknowledgments & References +--------------------------------------------- +This plugin has been developed by Cyril Achard and Maxime Vidal, supervised by Mackenzie Mathis for the `Mathis Laboratory of Adaptive Motor Control`_. + +We also greatly thank Timokleia Kousi for her contributions to this project and the `Wyss Center`_ for project funding. + +The TRAILMAP models and original weights used here were ported to PyTorch but originate from the `TRAILMAP project on GitHub`_. +We also provide a model that was trained in-house on mesoSPIM nuclei data in collaboration with Dr. Stephane Pages and Timokleia Kousi. + +This plugin mainly uses the following libraries and software: + +* `napari`_ + +* `PyTorch`_ + +* `MONAI project`_ (various models used here are credited `on their website`_) + +* `pyclEsperanto`_ (for the Voronoi Otsu labeling) by Robert Haase + +* A custom re-implementation of the `WNet model`_ by Xia and Kulis [3]_ + +.. _Mathis Laboratory of Adaptive Motor Control: http://www.mackenziemathislab.org/ +.. _Wyss Center: https://wysscenter.ch/ +.. _TRAILMAP project on GitHub: https://github.com/AlbertPun/TRAILMAP +.. _napari: https://napari.org/ +.. _PyTorch: https://pytorch.org/ +.. _MONAI project: https://monai.io/ +.. _on their website: https://docs.monai.io/en/stable/networks.html#nets +.. _pyclEsperanto: https://github.com/clEsperanto/pyclesperanto_prototype +.. _WNet model: https://arxiv.org/abs/1711.08506 + +.. rubric:: References + +.. [1] The mesoSPIM initiative: open-source light-sheet microscopes for imaging cleared tissue, Voigt et al., 2019 ( https://doi.org/10.1038/s41592-019-0554-0 ) +.. [2] MONAI Project website ( https://monai.io/ ) +.. [3] W-Net: A Deep Model for Fully Unsupervised Image Segmentation, Xia and Kulis, 2018 ( https://arxiv.org/abs/1711.08506 ) diff --git a/napari_cellseg3d/_tests/fixtures.py b/napari_cellseg3d/_tests/fixtures.py index 4dba351f..acd2f977 100644 --- a/napari_cellseg3d/_tests/fixtures.py +++ b/napari_cellseg3d/_tests/fixtures.py @@ -5,7 +5,7 @@ class LogFixture(QTextEdit): - """Fixture for testing, replaces napari_cellseg3d.interface.Log in model_workers during testing""" + """Fixture for testing, replaces napari_cellseg3d.interface.Log in model_workers during testing.""" def __init__(self): super(LogFixture, self).__init__() @@ -21,57 +21,79 @@ def error(self, e): class WNetFixture(torch.nn.Module): + """Fixture for testing, replaces napari_cellseg3d.models.WNet during testing.""" + def __init__(self): super().__init__() self.mock_conv = torch.nn.Conv3d(1, 1, 1) self.mock_conv.requires_grad_(False) def forward_encoder(self, x): + """Forward pass through encoder.""" return x def forward_decoder(self, x): + """Forward pass through decoder.""" return x def forward(self, x): + """Forward pass through WNet.""" return self.forward_encoder(x), self.forward_decoder(x) class ModelFixture(torch.nn.Module): + """Fixture for testing, replaces napari_cellseg3d models during testing.""" + def __init__(self): + """Fixture for testing, replaces models during testing.""" super().__init__() self.mock_conv = torch.nn.Conv3d(1, 1, 1) self.mock_conv.requires_grad_(False) def forward(self, x): + """Forward pass through model.""" return x class OptimizerFixture: + """Fixture for testing, replaces optimizers during testing.""" + def __init__(self): self.param_groups = [] self.param_groups.append({"lr": 0}) def zero_grad(self): + """Dummy function for zero_grad.""" pass def step(self, *args): + """Dummy function for step.""" pass class SchedulerFixture: + """Fixture for testing, replaces schedulers during testing.""" + def step(self, *args): + """Dummy function for step.""" pass class LossFixture: + """Fixture for testing, replaces losses during testing.""" + def __call__(self, *args): + """Dummy function for __call__.""" return self def backward(self, *args): + """Dummy function for backward.""" pass def item(self): + """Dummy function for item.""" return 0 def detach(self): + """Dummy function for detach.""" return self diff --git a/napari_cellseg3d/_tests/test_utils.py b/napari_cellseg3d/_tests/test_utils.py index 65388172..5d4677ac 100644 --- a/napari_cellseg3d/_tests/test_utils.py +++ b/napari_cellseg3d/_tests/test_utils.py @@ -1,6 +1,7 @@ import random from functools import partial from pathlib import Path + import numpy as np import pytest import torch diff --git a/napari_cellseg3d/code_models/__init__.py b/napari_cellseg3d/code_models/__init__.py index e69de29b..6ee556c2 100644 --- a/napari_cellseg3d/code_models/__init__.py +++ b/napari_cellseg3d/code_models/__init__.py @@ -0,0 +1,11 @@ +"""This folder contains the code used by models in the plugin. + +* ``models`` folder: contains the model classes, which are wrappers for the actual models. The wrappers are used to ensure that the models are compatible with the plugin. +* model_framework.py: contains the code for the model framework, used by training and inference plugins +* worker_inference.py: contains the code for the inference worker +* worker_training.py: contains the code for the training worker +* instance_segmentation.py: contains the code for instance segmentation +* crf.py: contains the code for the CRF postprocessing +* worker_utils.py: contains functions used by the workers + +""" diff --git a/napari_cellseg3d/code_models/crf.py b/napari_cellseg3d/code_models/crf.py index e90529ce..d59698e6 100644 --- a/napari_cellseg3d/code_models/crf.py +++ b/napari_cellseg3d/code_models/crf.py @@ -1,7 +1,16 @@ -""" -Implements the CRF post-processing step for the W-Net. -Inspired by https://arxiv.org/abs/1606.00915 and https://arxiv.org/abs/1711.08506. +"""Implements the CRF post-processing step for the W-Net. + +The CRF requires the following parameters: + +* images : Array of shape (N, C, H, W, D) containing the input images. +* predictions: Array of shape (N, K, H, W, D) containing the predicted class probabilities for each pixel. +* sa: alpha standard deviation, the scale of the spatial part of the appearance/bilateral kernel. +* sb: beta standard deviation, the scale of the color part of the appearance/bilateral kernel. +* sg: gamma standard deviation, the scale of the smoothness/gaussian kernel. +* w1: weight of the appearance/bilateral kernel. +* w2: weight of the smoothness/gaussian kernel. +Inspired by https://arxiv.org/abs/1606.00915 and https://arxiv.org/abs/1711.08506. Also uses research from: Efficient Inference in Fully Connected CRFs with Gaussian Edge Potentials Philipp Krähenbühl and Vladlen Koltun @@ -55,6 +64,7 @@ def correct_shape_for_crf(image, desired_dims=4): + """Corrects the shape of the image to be compatible with the CRF post-processing step.""" logger.debug(f"Correcting shape for CRF, desired_dims={desired_dims}") logger.debug(f"Image shape: {image.shape}") if len(image.shape) > desired_dims: @@ -78,6 +88,9 @@ def crf_batch(images, probs, sa, sb, sg, w1, w2, n_iter=5): sa (float): alpha standard deviation, the scale of the spatial part of the appearance/bilateral kernel. sb (float): beta standard deviation, the scale of the color part of the appearance/bilateral kernel. sg (float): gamma standard deviation, the scale of the smoothness/gaussian kernel. + w1 (float): weight of the appearance/bilateral kernel. + w2 (float): weight of the smoothness/gaussian kernel. + n_iter (int, optional): Number of iterations for the CRF post-processing step. Defaults to 5. Returns: np.ndarray: Array of shape (N, K, H, W, D) containing the refined class probabilities for each pixel. @@ -96,6 +109,7 @@ def crf_batch(images, probs, sa, sb, sg, w1, w2, n_iter=5): def crf(image, prob, sa, sb, sg, w1, w2, n_iter=5): """Implements the CRF post-processing step for the W-Net. + Inspired by https://arxiv.org/abs/1210.5644, https://arxiv.org/abs/1606.00915 and https://arxiv.org/abs/1711.08506. Implemented using the pydensecrf library. @@ -107,11 +121,11 @@ def crf(image, prob, sa, sb, sg, w1, w2, n_iter=5): sg (float): gamma standard deviation, the scale of the smoothness/gaussian kernel. w1 (float): weight of the appearance/bilateral kernel. w2 (float): weight of the smoothness/gaussian kernel. + n_iter (int, optional): Number of iterations for the CRF post-processing step. Defaults to 5. Returns: np.ndarray: Array of shape (K, H, W, D) containing the refined class probabilities for each pixel. """ - if not CRF_INSTALLED: return None @@ -154,6 +168,14 @@ def crf(image, prob, sa, sb, sg, w1, w2, n_iter=5): def crf_with_config(image, prob, config: CRFConfig = None, log=logger.info): + """Implements the CRF post-processing step for the W-Net. + + Args: + image (np.ndarray): Array of shape (C, H, W, D) containing the input image. + prob (np.ndarray): Array of shape (K, H, W, D) containing the predicted class probabilities for each pixel. + config (CRFConfig, optional): Configuration for the CRF post-processing step. Defaults to None. + log (function, optional): Logging function. Defaults to logger.info. + """ if config is None: config = CRFConfig() if image.shape[-3:] != prob.shape[-3:]: @@ -192,6 +214,14 @@ def __init__( config: CRFConfig = None, log=None, ): + """Initializes the CRFWorker. + + Args: + images_list (list): List of images to process. + labels_list (list): List of labels to process. + config (CRFConfig, optional): Configuration for the CRF post-processing step. Defaults to None. + log (function, optional): Logging function. Defaults to None. + """ super().__init__(self._run_crf_job) self.images = images_list diff --git a/napari_cellseg3d/code_models/instance_segmentation.py b/napari_cellseg3d/code_models/instance_segmentation.py index 018d385e..1736f5a4 100644 --- a/napari_cellseg3d/code_models/instance_segmentation.py +++ b/napari_cellseg3d/code_models/instance_segmentation.py @@ -1,3 +1,4 @@ +"""Instance segmentation methods for 3D images.""" import abc from dataclasses import dataclass from functools import partial @@ -10,6 +11,7 @@ from skimage.morphology import remove_small_objects from skimage.segmentation import watershed from tifffile import imread +from tqdm import tqdm # local from napari_cellseg3d import interface as ui @@ -27,10 +29,13 @@ VORONOI_OTSU = "Voronoi-Otsu" ################ -USE_EXPERIMENTAL_VORONOI_OTSU_WITH_SLIDING_WINDOW = False +USE_SLIDING_WINDOW = True +"""If True, uses a sliding window to perform instance segmentation to avoid memory issues.""" class InstanceMethod: + """Base class for instance segmentation methods. Contains the method name, the function to use, and the corresponding UI elements.""" + def __init__( self, name: str, @@ -39,8 +44,7 @@ def __init__( num_counters: int, widget_parent: QWidget = None, ): - """ - Methods for instance segmentation + """Methods for instance segmentation. Args: name: Name of the instance segmentation method (for UI) @@ -58,13 +62,16 @@ def __init__( num_counters, num_sliders, widget_parent=widget_parent ) + self.recorded_parameters = {} + """Stores the parameters when calling self.record_parameters()""" + def _setup_widgets(self, num_counters, num_sliders, widget_parent=None): - """Initializes the needed widgets for the instance segmentation method, adding sliders and counters to the - instance segmentation widget. + """Initializes the needed widgets for the instance segmentation method, adding sliders and counters to the instance segmentation widget. + Args: num_counters: Number of DoubleIncrementCounter UI elements needed to set the parameters of the function num_sliders: Number of Slider UI elements needed to set the parameters of the function - widget_parent: parent for the declared widgets + widget_parent: parent for the declared widgets. """ if num_sliders > 0: for i in range(num_sliders): @@ -97,6 +104,7 @@ def _setup_widgets(self, num_counters, num_sliders, widget_parent=None): @abc.abstractmethod def run_method(self, image): + """Runs the method on the image with the parameters set in the widget.""" raise NotImplementedError() def _make_list_from_channels( @@ -116,14 +124,116 @@ def _make_list_from_channels( return [im for im in image] return [image] + def record_parameters(self): + """Records all the parameters of the instance segmentation method from the current values of the widgets.""" + if len(self.sliders) > 0: + for slider in self.sliders: + self.recorded_parameters[ + slider.label.text() + ] = slider.slider_value + if len(self.counters) > 0: + for counter in self.counters: + self.recorded_parameters[ + counter.label.text() + ] = counter.value() + + def run_method_from_params(self, image): + """Runs the method on the image with the RECORDED parameters set in the widget. + + See self.record_parameters() and self.run_method() + + Args: + image: image data to run method on + + Returns: processed image from self._method + """ + if len(self.recorded_parameters) == 0: + logger.warning( + "No parameters recorded, running with values from widgets" + ) + self.record_parameters() + + parameters = [ + self.recorded_parameters[key] for key in self.recorded_parameters + ] + + assert len(parameters) == len(self.sliders) + len(self.counters), ( + f"Number of parameters recorded ({len(parameters)}) " + f"does not match number of sliders ({len(self.sliders)}) " + f"and counters ({len(self.counters)})" + ) + + return self.function(image, *parameters) + def run_method_on_channels(self, image): + """Runs the method on each channel of the image with the parameters set in the widget. + + Args: + image: image data to run method on + + Returns: processed image from self._method + """ image_list = self._make_list_from_channels(image) result = np.array([self.run_method(im) for im in image_list]) return result.squeeze() + def run_method_on_channels_from_params(self, image): + """Runs the method on each channel of the image with the RECORDED parameters set in the widget. + + Args: + image: image data to run method on + + Returns: processed image from self._method + """ + image_list = self._make_list_from_channels(image) + result = np.array( + [self.run_method_from_params(im) for im in image_list] + ) + return result.squeeze() + + @staticmethod + def sliding_window(volume, func, patch_size=512): + """Given a volume of dimensions HxWxD, runs the provided function segmentation on the volume using a sliding window of size patch_size. + + If the edge has been reached, the patch size is reduced to fit the remaining space. + The result is a segmentation of the same size as the input volume. + + Args: + volume (np.array): The volume to segment + func (callable): Function to use for instance segmentation. Should be a partial function with the parameters already set. + patch_size (int): The size of the sliding window. + + Returns: + np.array: Instance segmentation labels from + """ + result = np.zeros(volume.shape, dtype=np.uint32) + max_label_id = 0 + x, y, z = volume.shape + for i in tqdm(range(0, x, patch_size)): + for j in range(0, y, patch_size): + for k in range(0, z, patch_size): + patch = volume[ + i : min(i + patch_size, x), + j : min(j + patch_size, y), + k : min(k + patch_size, z), + ] + patch_result = func(patch) + patch_result = np.array(patch_result) + # make sure labels are unique, only where result is not 0 + patch_result[patch_result > 0] += max_label_id + result[ + i : min(i + patch_size, x), + j : min(j + patch_size, y), + k : min(k + patch_size, z), + ] = patch_result + max_label_id = np.max(patch_result) + return result + @dataclass class ImageStats: + """Dataclass containing various statistics from instance labels.""" + volume: List[float] centroid_x: List[float] centroid_y: List[float] @@ -136,6 +246,7 @@ class ImageStats: number_objects: int def get_dict(self): + """Returns a dict containing the statistics.""" return { "Volume": self.volume, "Centroid x": self.centroid_x, @@ -152,7 +263,7 @@ def get_dict(self): def threshold(volume, thresh): - """Remove all values smaller than the specified threshold in the volume""" + """Remove all values smaller than the specified threshold in the volume.""" im = np.squeeze(volume) binary = im > thresh return np.where(binary, im, np.zeros_like(im)) @@ -162,46 +273,35 @@ def voronoi_otsu( volume: np.ndarray, spot_sigma: float, outline_sigma: float, - # remove_small_size: float, + remove_small_size: float = None, ): - """ - Voronoi-Otsu labeling from pyclesperanto. + """Voronoi-Otsu labeling from pyclesperanto. + BASED ON CODE FROM : napari_pyclesperanto_assistant by Robert Haase https://github.com/clEsperanto/napari_pyclesperanto_assistant Original code at : - https://github.com/clEsperanto/pyclesperanto_prototype/blob/master/pyclesperanto_prototype/_tier9/_voronoi_otsu_labeling.py + https://github.com/clEsperanto/pyclesperanto_prototype/blob/master/pyclesperanto_prototype/_tier9/_voronoi_otsu_labeling.py. Args: volume (np.ndarray): volume to segment spot_sigma (float): parameter determining how close detected objects can be outline_sigma (float): determines the smoothness of the segmentation + remove_small_size (float): remove all objects smaller than the specified size in pixel Returns: Instance segmentation labels from Voronoi-Otsu method """ - if USE_EXPERIMENTAL_VORONOI_OTSU_WITH_SLIDING_WINDOW: - from napari_cellseg3d.dev_scripts.sliding_window_voronoi import ( - sliding_window_voronoi_otsu, - ) - - instance = sliding_window_voronoi_otsu( - volume, - spot_sigma=spot_sigma, - outline_sigma=outline_sigma, - patch_size=1024, - ) - return np.array(instance) - # remove_small_size (float): remove all objects smaller than the specified size in pixels - # semantic = np.squeeze(volume) logger.debug( f"Running voronoi otsu segmentation with spot_sigma={spot_sigma} and outline_sigma={outline_sigma}" ) instance = cle.voronoi_otsu_labeling( volume, spot_sigma=spot_sigma, outline_sigma=outline_sigma ) - # instance = remove_small_objects(instance, remove_small_size) - return np.array(instance) + instance = np.array(instance) + if remove_small_size is not None: + instance = remove_small_objects(instance, remove_small_size) + return instance def binary_connected( @@ -209,8 +309,7 @@ def binary_connected( thres=0.5, thres_small=3, ): - r"""Convert binary foreground probability maps to instance masks via - connected-component labeling. + r"""Convert binary foreground probability maps to instance masks via connected-component labeling. Args: volume (numpy.ndarray): foreground probability of shape :math:`(C, Z, Y, X)`. @@ -220,26 +319,11 @@ def binary_connected( logger.debug( f"Running connected components segmentation with thres={thres} and thres_small={thres_small}" ) - # if len(volume.shape) > 3: semantic = np.squeeze(volume) foreground = np.where(semantic > thres, volume, 0) # int(255 * thres) segm = label(foreground) segm = remove_small_objects(segm, thres_small) - # if not all(x == 1.0 for x in scale_factors): - # target_size = ( - # int(semantic.shape[0] * scale_factors[0]), - # int(semantic.shape[1] * scale_factors[1]), - # int(semantic.shape[2] * scale_factors[2]), - # ) - # segm = resize( - # segm, - # target_size, - # order=0, - # anti_aliasing=False, - # preserve_range=True, - # ) - return segm @@ -250,8 +334,7 @@ def binary_watershed( thres_small=10, rem_seed_thres=3, ): - r"""Convert binary foreground probability maps to instance masks via - watershed segmentation algorithm. + r"""Convert binary foreground probability maps to instance masks via watershed segmentation algorithm. Note: This function uses the `skimage.segmentation.watershed `_ @@ -265,10 +348,10 @@ def binary_watershed( rem_seed_thres (int): threshold for small seeds removal. Default : 3 """ - # logger.debug( - # f"Running watershed segmentation with thres_objects={thres_objects}, thres_seeding={thres_seeding}," - # f" thres_small={thres_small} and rem_seed_thres={rem_seed_thres}" - # ) + logger.debug( + f"Running watershed segmentation with thres_objects={thres_objects}, thres_seeding={thres_seeding}," + f" thres_small={thres_small} and rem_seed_thres={rem_seed_thres}" + ) semantic = np.squeeze(volume) seed_map = semantic > thres_seeding foreground = semantic > thres_objects @@ -277,20 +360,6 @@ def binary_watershed( segm = watershed(-semantic.astype(np.float64), seed, mask=foreground) segm = remove_small_objects(segm, thres_small) - # if not all(x == 1.0 for x in scale_factors): - # target_size = ( - # int(semantic.shape[0] * scale_factors[0]), - # int(semantic.shape[1] * scale_factors[1]), - # int(semantic.shape[2] * scale_factors[2]), - # ) - # segm = resize( - # segm, - # target_size, - # order=0, - # anti_aliasing=False, - # preserve_range=True, - # ) - return np.array(segm) @@ -305,7 +374,6 @@ def clear_small_objects(image, threshold, is_file_path=False): Returns: array: The image with small objects removed """ - if is_file_path: image = imread(image) @@ -327,25 +395,6 @@ def clear_small_objects(image, threshold, is_file_path=False): return result -# def to_instance(image, is_file_path=False): -# """Converts a **ground-truth** label to instance (unique id per object) labels. Does not remove small objects. -# -# Args: -# image: image or path to image -# is_file_path: if True, will consider ``image`` to be a string containing a path to a file, if not treats it as an image data array. -# -# Returns: resulting converted labels -# -# """ -# if is_file_path: -# image = [imread(image)] -# image = image.compute() -# -# return binary_watershed( -# image, thres_small=0, thres_seeding=0.3, rem_seed_thres=0 -# ) - - def to_semantic(image, is_file_path=False): """Converts a **ground-truth** label to semantic (binary 0/1) labels. @@ -366,6 +415,7 @@ def to_semantic(image, is_file_path=False): def volume_stats(volume_image): """Computes various statistics from instance labels and returns them in a dict. + Currently provided : * "Volume": volume of each object @@ -383,10 +433,13 @@ def volume_stats(volume_image): Returns: dict: Statistics described above """ + # check if empty or all 0 + if np.sum(volume_image) == 0: + logger.debug("Skipped empty label image") + return None properties = regionprops(volume_image) - # sphericity_va = [] def sphericity(region): try: return sphericity_axis( @@ -410,15 +463,13 @@ def sphericity(region): volume = [region.area for region in properties] - # def fill(lst, n=len(properties) - 1): - # return fill_list_in_between(lst, n, "") - fill = partial(fill_list_in_between, n=len(properties) - 1, fill_value="") if len(volume_image.flatten()) != 0: ratio = fill([np.sum(volume) / len(volume_image.flatten())]) else: - ratio = 0 + ratio = [0] + ratio = fill(ratio) return ImageStats( volume, @@ -435,9 +486,10 @@ def sphericity(region): class Watershed(InstanceMethod): - """Widget class for Watershed segmentation. Requires 4 parameters, see binary_watershed""" + """Widget class for Watershed segmentation. Requires 4 parameters, see binary_watershed.""" def __init__(self, widget_parent=None): + """Creates a Watershed widget.""" super().__init__( name=WATERSHED, function=binary_watershed, @@ -470,7 +522,61 @@ def __init__(self, widget_parent=None): ) self.counters[1].setValue(3) + @property + def foreground_threshold(self): + """Returns the value of the foreground threshold slider.""" + return self.sliders[0].slider_value + + @foreground_threshold.setter + def foreground_threshold(self, value): + """Sets the value of the foreground threshold slider.""" + self.sliders[0].setValue(value) + + @property + def seed_threshold(self): + """Returns the value of the seed threshold slider.""" + return self.sliders[1].slider_value + + @seed_threshold.setter + def seed_threshold(self, value): + """Sets the value of the seed threshold slider.""" + self.sliders[1].setValue(value) + + @property + def small_object_removal(self): + """Returns the value of the small object removal counter.""" + return self.counters[0].value() + + @small_object_removal.setter + def small_object_removal(self, value): + """Sets the value of the small object removal counter.""" + self.counters[0].setValue(value) + + @property + def small_seed_removal(self): + """Returns the value of the small seed removal counter.""" + return self.counters[1].value() + + @small_seed_removal.setter + def small_seed_removal(self, value): + """Sets the value of the small seed removal counter.""" + self.counters[1].setValue(value) + def run_method(self, image): + """Runs the method on the image with the parameters set in the widget. + + If USE_SLIDING_WINDOW is True, uses a sliding window to perform instance segmentation to avoid memory issues. + """ + if USE_SLIDING_WINDOW: + func = partial( + self.function, + thres_objects=self.sliders[0].slider_value, + thres_seeding=self.sliders[1].slider_value, + thres_small=self.counters[0].value(), + rem_seed_thres=self.counters[1].value(), + ) + return self.sliding_window(image, func) + return self.function( image, self.sliders[0].slider_value, @@ -484,6 +590,7 @@ class ConnectedComponents(InstanceMethod): """Widget class for Connected Components instance segmentation. Requires 2 parameters, see binary_connected.""" def __init__(self, widget_parent=None): + """Creates a ConnectedComponents widget.""" super().__init__( name=CONNECTED_COMP, function=binary_connected, @@ -505,21 +612,54 @@ def __init__(self, widget_parent=None): ) self.counters[0].setValue(3) + @property + def foreground_threshold(self): + """Returns the value of the foreground threshold slider.""" + return self.sliders[0].slider_value + + @foreground_threshold.setter + def foreground_threshold(self, value): + """Sets the value of the foreground threshold slider.""" + self.sliders[0].setValue(value) + + @property + def small_object_removal(self): + """Returns the value of the small object removal counter.""" + return self.counters[0].value() + + @small_object_removal.setter + def small_object_removal(self, value): + """Sets the value of the small object removal counter.""" + self.counters[0].setValue(value) + def run_method(self, image): + """Runs the method on the image with the parameters set in the widget. + + If USE_SLIDING_WINDOW is True, uses a sliding window to perform instance segmentation to avoid memory issues. + """ + if USE_SLIDING_WINDOW: + func = partial( + self.function, + thres=self.sliders[0].slider_value, + thres_small=self.counters[0].value(), + ) + return self.sliding_window(image, func) + return self.function( image, self.sliders[0].slider_value, self.counters[0].value() ) class VoronoiOtsu(InstanceMethod): - """Widget class for Voronoi-Otsu labeling from pyclesperanto. Requires 2 parameter, see voronoi_otsu""" + """Widget class for Voronoi-Otsu labeling from pyclesperanto. Requires 2 parameter, see voronoi_otsu.""" def __init__(self, widget_parent=None): + """Creates a VoronoiOtsu widget.""" super().__init__( name=VORONOI_OTSU, function=voronoi_otsu, num_sliders=0, - num_counters=2, + num_counters=3, widget_parent=widget_parent, ) self.counters[0].label.setText("Spot sigma") # closeness @@ -536,38 +676,70 @@ def __init__(self, widget_parent=None): self.counters[1].setMaximum(100) self.counters[1].setValue(2) - # self.counters[2].label.setText("Small object removal") - # self.counters[2].tooltips = ( - # "Volume/size threshold for small object removal." - # "\nAll objects with a volume/size below this value will be removed." - # ) - # self.counters[2].setValue(30) + self.counters[2].label.setText("Small object removal") + self.counters[2].tooltips = ( + "Volume/size threshold for small object removal." + "\nAll objects with a volume/size below this value will be removed." + ) + self.counters[2].setValue(1) + + @property + def spot_sigma(self): + """Returns the value of the spot sigma counter.""" + return self.counters[0].value() + + @spot_sigma.setter + def spot_sigma(self, value): + """Sets the value of the spot sigma counter.""" + self.counters[0].setValue(value) + + @property + def outline_sigma(self): + """Returns the value of the outline sigma counter.""" + return self.counters[1].value() + + @outline_sigma.setter + def outline_sigma(self, value): + """Sets the value of the outline sigma counter.""" + self.counters[1].setValue(value) + + @property + def small_object_removal(self): + """Returns the value of the small object removal counter.""" + return self.counters[2].value() + + @small_object_removal.setter + def small_object_removal(self, value): + """Sets the value of the small object removal counter.""" + self.counters[2].setValue(value) def run_method(self, image): - ################ - # For debugging - # import napari - # view = napari.Viewer() - # view.add_image(image) - # napari.run() - ################ + """Runs the method on the image with the parameters set in the widget. + + If USE_SLIDING_WINDOW is True, uses a sliding window to perform instance segmentation to avoid memory issues. + """ + if USE_SLIDING_WINDOW: + func = partial( + self.function, + spot_sigma=self.counters[0].value(), + outline_sigma=self.counters[1].value(), + remove_small_size=self.counters[2].value(), + ) + return self.sliding_window(image, func) return self.function( image, - self.counters[0].value(), - self.counters[1].value(), - # self.counters[2].value(), + spot_sigma=self.counters[0].value(), + outline_sigma=self.counters[1].value(), + remove_small_size=self.counters[2].value(), ) class InstanceWidgets(QWidget): - """ - Base widget with several sliders, for use in instance segmentation parameters - """ + """Base widget with several sliders, for use in instance segmentation parameters.""" def __init__(self, parent=None): - """ - Creates an InstanceWidgets widget + """Creates an InstanceWidgets widget. Args: parent: parent widget @@ -622,8 +794,7 @@ def _set_visibility(self): widget.set_visibility(True) def run_method(self, volume): - """ - Calls instance function with chosen parameters + """Calls instance function with chosen parameters. Args: volume: image data to run method on diff --git a/napari_cellseg3d/code_models/model_framework.py b/napari_cellseg3d/code_models/model_framework.py index d4e7af06..2faf5020 100644 --- a/napari_cellseg3d/code_models/model_framework.py +++ b/napari_cellseg3d/code_models/model_framework.py @@ -1,3 +1,4 @@ +"""Basic napari plugin framework for inference and training.""" from pathlib import Path from typing import TYPE_CHECKING @@ -18,7 +19,7 @@ class ModelFramework(BasePluginFolder): - """A framework with buttons to use for loading images, labels, models, etc. for both inference and training""" + """A framework with buttons to use for loading images, labels, models, etc. for both inference and training.""" def __init__( self, @@ -28,7 +29,7 @@ def __init__( loads_labels=True, has_results=True, ): - """Creates a plugin framework with the following elements : + """Creates a plugin framework with the following elements. * A button to choose an image folder containing the images of a dataset (e.g. dataset/images) @@ -128,12 +129,12 @@ def __init__( self.btn_save_log.setVisible(False) def send_log(self, text): - """Emit a signal to print in a Log""" + """Emit a signal to print in a Log.""" if self.log is not None: self.log.print_and_log(text) def save_log(self, do_timestamp=True): - """Saves the worker's log to disk at self.results_path when called""" + """Saves the worker's log to disk at self.results_path when called.""" if self.log is not None: log = self.log.toPlainText() @@ -163,8 +164,8 @@ def save_log_to_path(self, path, do_timestamp=True): Args: path (str): path to save folder + do_timestamp (bool, optional): whether to add a timestamp to the log name. Defaults to True. """ - log = self.log.toPlainText() if do_timestamp: @@ -187,9 +188,7 @@ def save_log_to_path(self, path, do_timestamp=True): ) def display_status_report(self): - """Adds a text log, a progress bar and a "save log" button on the left side of the viewer - (usually when starting a worker)""" - + """Adds a text log, a progress bar and a "save log" button on the left side of the viewer (usually when starting a worker).""" # if self.container_report is None or self.log is None: # logger.warning( # "Status report widget has been closed. Trying to re-instantiate..." @@ -240,7 +239,7 @@ def display_status_report(self): self.progress.setValue(0) def _toggle_weights_path(self): - """Toggle visibility of weight path""" + """Toggle visibility of weight path.""" ui.toggle_visibility( self.custom_weights_choice, self.weights_filewidget ) @@ -273,12 +272,8 @@ def create_train_dataset_dict(self): """Creates data dictionary for MONAI transforms and training. Returns: - A dict with the following keys - - * "image": image - * "label" : corresponding label + A dict with the following keys: "image", "label" """ - logger.debug(f"Images : {self.images_filepaths}") logger.debug(f"Labels : {self.labels_filepaths}") @@ -310,7 +305,7 @@ def create_train_dataset_dict(self): @staticmethod def get_available_models(): - """Getter for module (class and functions) associated to currently selected model""" + """Getter for module (class and functions) associated to currently selected model.""" return config.MODEL_LIST # def load_model_path(self): # TODO add custom models @@ -330,8 +325,7 @@ def _update_weights_path(self, file): self._default_weights_folder = str(Path(file[0]).parent) def _load_weights_path(self): - """Show file dialog to set :py:attr:`model_path`""" - + """Show file dialog to set :py:attr:`model_path`.""" # logger.debug(self._default_weights_folder) file = ui.open_file_dialog( @@ -342,6 +336,7 @@ def _load_weights_path(self): self._update_weights_path(file) def check_device_choice(self): + """Checks the device choice in the UI and returns the corresponding torch device.""" choice = self.device_choice.currentText() if choice == "CPU": device = "cpu" @@ -355,10 +350,11 @@ def check_device_choice(self): @staticmethod def get_device(show=True): - """ - Tries to use the device specified by user and uses it for tensor operations. + """Tries to use the device specified by user and uses it for tensor operations. + If not available, automatically discovers any cuda device. - If none is available (CUDA not installed), uses cpu instead.""" + If none is available (CUDA not installed), uses cpu instead. + """ device = torch.device("cuda" if torch.cuda.is_available() else "cpu") if show: logger.info(f"Using {device} device") @@ -367,7 +363,7 @@ def get_device(show=True): return device def empty_cuda_cache(self): - """Empties the cuda cache if the device is a cuda device""" + """Empties the cuda cache if the device is a cuda device.""" if self.get_device(show=False).type == "cuda": logger.info("Emptying cache...") torch.cuda.empty_cache() diff --git a/napari_cellseg3d/code_models/models/TEMPLATE_model.py b/napari_cellseg3d/code_models/models/TEMPLATE_model.py index f68e5f4f..0586c0b4 100644 --- a/napari_cellseg3d/code_models/models/TEMPLATE_model.py +++ b/napari_cellseg3d/code_models/models/TEMPLATE_model.py @@ -1,8 +1,13 @@ +"""This is a template for a model class. It is not used in the plugin, but is here to show how to implement a model class. + +Please note that custom model implementations are not fully supported out of the box yet, but might be in the future. +""" from abc import ABC, abstractmethod class ModelTemplate_(ABC): - use_default_training = True # not needed for now, will serve for WNet training if added to the plugin + """Template for a model class. This is not used in the plugin, but is here to show how to implement a model class.""" + weights_file = ( "model_template.pth" # specify the file name of the weights file only ) diff --git a/napari_cellseg3d/code_models/models/__init__.py b/napari_cellseg3d/code_models/models/__init__.py index e69de29b..0be67101 100644 --- a/napari_cellseg3d/code_models/models/__init__.py +++ b/napari_cellseg3d/code_models/models/__init__.py @@ -0,0 +1 @@ +"""Contains model code and wrappers for the models, as classes.""" diff --git a/napari_cellseg3d/code_models/models/model_SegResNet.py b/napari_cellseg3d/code_models/models/model_SegResNet.py index 99f8cbfc..58b932e8 100644 --- a/napari_cellseg3d/code_models/models/model_SegResNet.py +++ b/napari_cellseg3d/code_models/models/model_SegResNet.py @@ -1,13 +1,23 @@ +"""SegResNet wrapper for napari_cellseg3d.""" from monai.networks.nets import SegResNetVAE class SegResNet_(SegResNetVAE): - use_default_training = True + """SegResNet_ wrapper for napari_cellseg3d.""" + weights_file = "SegResNet_latest.pth" def __init__( self, input_img_size, out_channels=1, dropout_prob=0.3, **kwargs ): + """Create a SegResNet model. + + Args: + input_img_size (tuple): input image size + out_channels (int): number of output channels + dropout_prob (float): dropout probability. + **kwargs: additional arguments to SegResNetVAE. + """ super().__init__( input_img_size, out_channels=out_channels, @@ -15,6 +25,7 @@ def __init__( ) def forward(self, x): + """Forward pass of the SegResNet model.""" res = SegResNetVAE.forward(self, x) # logger.debug(f"SegResNetVAE.forward: {res[0].shape}") return res[0] diff --git a/napari_cellseg3d/code_models/models/model_SwinUNetR.py b/napari_cellseg3d/code_models/models/model_SwinUNetR.py index bce316e8..286defb9 100644 --- a/napari_cellseg3d/code_models/models/model_SwinUNetR.py +++ b/napari_cellseg3d/code_models/models/model_SwinUNetR.py @@ -1,3 +1,4 @@ +"""SwinUNetR wrapper for napari_cellseg3d.""" from monai.networks.nets import SwinUNETR from napari_cellseg3d.utils import LOGGER @@ -6,7 +7,8 @@ class SwinUNETR_(SwinUNETR): - use_default_training = True + """SwinUNETR wrapper for napari_cellseg3d.""" + weights_file = "SwinUNetR_latest.pth" def __init__( @@ -17,6 +19,15 @@ def __init__( use_checkpoint=True, **kwargs, ): + """Create a SwinUNetR model. + + Args: + in_channels (int): number of input channels + out_channels (int): number of output channels + input_img_size (tuple): input image size + use_checkpoint (bool): whether to use checkpointing during training. + **kwargs: additional arguments to SwinUNETR. + """ try: super().__init__( input_img_size, diff --git a/napari_cellseg3d/code_models/models/model_TRAILMAP.py b/napari_cellseg3d/code_models/models/model_TRAILMAP.py index 118e1e85..6673d1d1 100644 --- a/napari_cellseg3d/code_models/models/model_TRAILMAP.py +++ b/napari_cellseg3d/code_models/models/model_TRAILMAP.py @@ -1,3 +1,4 @@ +"""Legacy version of adapted TRAILMAP model, not used in the current version of the plugin.""" # import torch # from torch import nn # @@ -90,7 +91,6 @@ # # # class TRAILMAP_(TRAILMAP): -# use_default_training = True # weights_file = "TRAILMAP_PyTorch.pth" # model additionally trained on Mathis/Wyss mesoSPIM data # # FIXME currently incorrect, find good weights from TRAILMAP_test and upload them # diff --git a/napari_cellseg3d/code_models/models/model_TRAILMAP_MS.py b/napari_cellseg3d/code_models/models/model_TRAILMAP_MS.py index 4ee971e2..2aacc333 100644 --- a/napari_cellseg3d/code_models/models/model_TRAILMAP_MS.py +++ b/napari_cellseg3d/code_models/models/model_TRAILMAP_MS.py @@ -1,14 +1,23 @@ +"""TRAILMAP model, reimplemented in PyTorch.""" from napari_cellseg3d.code_models.models.unet.model import UNet3D from napari_cellseg3d.utils import LOGGER as logger class TRAILMAP_MS_(UNet3D): - use_default_training = True + """TRAILMAP_MS wrapper for napari_cellseg3d.""" + weights_file = "TRAILMAP_MS_best_metric.pth" # original model from Liqun Luo lab, transferred to pytorch and trained on mesoSPIM-acquired data (mostly TPH2 as of July 2022) def __init__(self, in_channels=1, out_channels=1, **kwargs): + """Create a TRAILMAP_MS model. + + Args: + in_channels (int): number of input channels + out_channels (int): number of output channels. + **kwargs: additional arguments to UNet3D. + """ try: super().__init__( in_channels=in_channels, out_channels=out_channels, **kwargs diff --git a/napari_cellseg3d/code_models/models/model_VNet.py b/napari_cellseg3d/code_models/models/model_VNet.py index 8fe18e2b..2e2e618f 100644 --- a/napari_cellseg3d/code_models/models/model_VNet.py +++ b/napari_cellseg3d/code_models/models/model_VNet.py @@ -1,11 +1,20 @@ +"""VNet wrapper for napari_cellseg3d.""" from monai.networks.nets import VNet class VNet_(VNet): - use_default_training = True + """VNet wrapper for napari_cellseg3d.""" + weights_file = "VNet_latest.pth" def __init__(self, in_channels=1, out_channels=1, **kwargs): + """Create a VNet model. + + Args: + in_channels (int): number of input channels + out_channels (int): number of output channels. + **kwargs: additional arguments to VNet. + """ try: super().__init__( in_channels=in_channels, diff --git a/napari_cellseg3d/code_models/models/model_WNet.py b/napari_cellseg3d/code_models/models/model_WNet.py index ae16e9bb..e80884e8 100644 --- a/napari_cellseg3d/code_models/models/model_WNet.py +++ b/napari_cellseg3d/code_models/models/model_WNet.py @@ -1,10 +1,19 @@ +"""Wrapper for the W-Net model, with the decoder weights removed. + +.. important:: Used for inference only. For training the base class is used. +""" + # local from napari_cellseg3d.code_models.models.wnet.model import WNet_encoder from napari_cellseg3d.utils import remap_image class WNet_(WNet_encoder): - use_default_training = False + """W-Net wrapper for napari_cellseg3d. + + ..important:: Used for inference only, therefore only the encoder is used. For training the base class is used. + """ + weights_file = "wnet_latest.pth" def __init__( @@ -14,6 +23,13 @@ def __init__( # num_classes=2, **kwargs, ): + """Create a W-Net model. + + Args: + in_channels (int): number of input channels + out_channels (int): number of output channels. + **kwargs: additional arguments to WNet_encoder. + """ super().__init__( in_channels=in_channels, out_channels=out_channels, diff --git a/napari_cellseg3d/code_models/models/model_test.py b/napari_cellseg3d/code_models/models/model_test.py index 28f3a05b..39f81392 100644 --- a/napari_cellseg3d/code_models/models/model_test.py +++ b/napari_cellseg3d/code_models/models/model_test.py @@ -1,16 +1,20 @@ +"""Model for testing purposes.""" import torch from torch import nn class TestModel(nn.Module): - use_default_training = True + """For tests only.""" + weights_file = "test.pth" def __init__(self, **kwargs): + """Create a TestModel model.""" super().__init__() self.linear = nn.Linear(8, 8) def forward(self, x): + """Forward pass of the TestModel model.""" return self.linear(torch.tensor(x, requires_grad=True)) # def get_output(self, _, input): diff --git a/napari_cellseg3d/code_models/models/pretrained/__init__.py b/napari_cellseg3d/code_models/models/pretrained/__init__.py index e69de29b..06fc9e2d 100644 --- a/napari_cellseg3d/code_models/models/pretrained/__init__.py +++ b/napari_cellseg3d/code_models/models/pretrained/__init__.py @@ -0,0 +1,5 @@ +"""Hosts the downloaded pretrained model weights. + +Please feel free to delete weights if you do not need them. +They will be downloaded again automatically if needed. +""" diff --git a/napari_cellseg3d/code_models/models/unet/__init__.py b/napari_cellseg3d/code_models/models/unet/__init__.py index e69de29b..ab9eb0b0 100644 --- a/napari_cellseg3d/code_models/models/unet/__init__.py +++ b/napari_cellseg3d/code_models/models/unet/__init__.py @@ -0,0 +1,4 @@ +"""Building block of a UNet model. + +Used mostly by the TRAILMAP model. +""" diff --git a/napari_cellseg3d/code_models/models/wnet/__init__.py b/napari_cellseg3d/code_models/models/wnet/__init__.py index e69de29b..0dc6d0e4 100644 --- a/napari_cellseg3d/code_models/models/wnet/__init__.py +++ b/napari_cellseg3d/code_models/models/wnet/__init__.py @@ -0,0 +1 @@ +"""Building blocks for WNet model.""" diff --git a/napari_cellseg3d/code_models/models/wnet/model.py b/napari_cellseg3d/code_models/models/wnet/model.py index 6c1fcee7..4817e307 100644 --- a/napari_cellseg3d/code_models/models/wnet/model.py +++ b/napari_cellseg3d/code_models/models/wnet/model.py @@ -1,7 +1,4 @@ -""" -Implementation of a 3D W-Net model, based on the 2D version from https://arxiv.org/abs/1711.08506. -The model performs unsupervised segmentation of 3D images. -""" +"""Implementation of a 3D W-Net model, based on the 2D version from https://arxiv.org/abs/1711.08506. The model performs unsupervised segmentation of 3D images.""" from typing import List @@ -29,6 +26,7 @@ def __init__( # num_classes=2, softmax=True, ): + """Initialize the W-Net encoder.""" super().__init__() self.encoder = UNet( in_channels=in_channels, @@ -43,6 +41,7 @@ def forward(self, x): class WNet(nn.Module): """Implementation of a 3D W-Net model, based on the 2D version from https://arxiv.org/abs/1711.08506. + The model performs unsupervised segmentation of 3D images. It first encodes the input image into a latent space using the U-Net UEncoder, then decodes it back to the original image using the U-Net UDecoder. """ @@ -54,6 +53,7 @@ def __init__( num_classes=2, dropout=0.65, ): + """Initialize the W-Net model.""" super(WNet, self).__init__() self.encoder = UNet( in_channels, num_classes, softmax=True, dropout=dropout @@ -88,6 +88,7 @@ def __init__( softmax: bool = True, dropout: float = 0.65, ): + """Creates a U-Net model, which is half of the W-Net model.""" if channels is None: channels = [64, 128, 256, 512, 1024] if len(channels) != 5: @@ -181,6 +182,13 @@ class InBlock(nn.Module): """Input block of the U-Net architecture.""" def __init__(self, in_channels, out_channels, dropout=0.65): + """Create the input block. + + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + dropout (float, optional): Dropout probability. Defaults to 0.65. + """ super(InBlock, self).__init__() # self.device = device self.module = nn.Sequential( @@ -205,6 +213,13 @@ class Block(nn.Module): """Basic block of the U-Net architecture.""" def __init__(self, in_channels, out_channels, dropout=0.65): + """Initialize the basic block. + + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + dropout (float, optional): Dropout probability. Defaults to 0.65. + """ super(Block, self).__init__() # self.device = device self.module = nn.Sequential( @@ -231,6 +246,13 @@ class OutBlock(nn.Module): """Output block of the U-Net architecture.""" def __init__(self, in_channels, out_channels, dropout=0.65): + """Initialize the output block. + + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + dropout (float, optional): Dropout probability. Defaults to 0.65. + """ super(OutBlock, self).__init__() # self.device = device self.module = nn.Sequential( diff --git a/napari_cellseg3d/code_models/models/wnet/soft_Ncuts.py b/napari_cellseg3d/code_models/models/wnet/soft_Ncuts.py index 866c844d..48cf905e 100644 --- a/napari_cellseg3d/code_models/models/wnet/soft_Ncuts.py +++ b/napari_cellseg3d/code_models/models/wnet/soft_Ncuts.py @@ -1,5 +1,5 @@ -""" -Implementation of a 3D Soft N-Cuts loss based on https://arxiv.org/abs/1711.08506 and https://ieeexplore.ieee.org/document/868688. +"""Implementation of a 3D Soft N-Cuts loss based on https://arxiv.org/abs/1711.08506 and https://ieeexplore.ieee.org/document/868688. + The implementation was adapted and approximated to reduce computational and memory cost. This faster version was proposed on https://github.com/fkodom/wnet-unsupervised-image-segmentation. """ @@ -40,6 +40,15 @@ class SoftNCutsLoss(nn.Module): def __init__( self, data_shape, device, intensity_sigma, spatial_sigma, radius=None ): + """Initialize the Soft N-Cuts loss. + + Args: + data_shape (H, W, D): shape of the images as a tuple. + device (torch.device): device on which the loss is computed. + intensity_sigma (scalar): scale of the gaussian kernel of pixels brightness. + spatial_sigma (scalar): scale of the gaussian kernel of pixels spacial distance. + radius (scalar): radius of pixels for which we compute the weights + """ super(SoftNCutsLoss, self).__init__() self.intensity_sigma = intensity_sigma self.spatial_sigma = spatial_sigma diff --git a/napari_cellseg3d/code_models/worker_inference.py b/napari_cellseg3d/code_models/worker_inference.py index f5d3e5a1..f849b437 100644 --- a/napari_cellseg3d/code_models/worker_inference.py +++ b/napari_cellseg3d/code_models/worker_inference.py @@ -1,3 +1,4 @@ +"""Contains the :py:class:`~InferenceWorker` class, which is a custom worker to run inference jobs in.""" import platform from pathlib import Path @@ -8,7 +9,7 @@ from monai.data import DataLoader, Dataset from monai.inferers import sliding_window_inference from monai.transforms import ( - AddChannel, + # AddChannel, # AsDiscrete, Compose, EnsureChannelFirstd, @@ -42,15 +43,18 @@ logger = utils.LOGGER # experimental code to auto-remove erroneously over-labeled empty regions from instance segmentation EXPERIMENTAL_AUTO_DISCARD_EMPTY_REGIONS = False +"""Whether to automatically discard erroneously over-labeled empty regions from semantic segmentation or not.""" EXPERIMENTAL_AUTO_DISCARD_FRACTION_THRESHOLD = 0.9 -EXPERIMENTAL_AUTO_DISCARD_VALUE = 0.2 +"""The fraction of pixels above which a region is considered wrongly labeled.""" +EXPERIMENTAL_AUTO_DISCARD_VALUE = 0.35 +"""The value above which a pixel is considered to contribute to over-labeling.""" -""" -Writing something to log messages from outside the main thread needs specific care, -Following the instructions in the guides below to have a worker with custom signals, -a custom worker function was implemented. -""" +# Writing something to log messages from outside the main thread needs specific care, +# Following the instructions in the guides below to have a worker with custom signals, +# a custom worker function was implemented. + +# References: # https://python-forum.io/thread-31349.html # https://www.pythoncentral.io/pysidepyqt-tutorial-creating-your-own-signals-and-slots/ # https://napari-staging-site.github.io/guides/stable/threading.html @@ -58,7 +62,9 @@ class InferenceWorker(GeneratorWorker): """A custom worker to run inference jobs in. - Inherits from :py:class:`napari.qt.threading.GeneratorWorker`""" + + Inherits from :py:class:`napari.qt.threading.GeneratorWorker`. + """ def __init__( self, @@ -66,6 +72,8 @@ def __init__( ): """Initializes a worker for inference with the arguments needed by the :py:func:`~inference` function. + Note: See :py:func:`~self.inference` for more details on the arguments. + The config contains the following attributes: * device: cuda or cpu device to use for torch * model_dict: the :py:attr:`~self.models_dict` dictionary to obtain the model name, class and instance @@ -82,11 +90,10 @@ def __init__( * layer: the layer to run inference on Args: - * worker_config (config.InferenceWorkerConfig): dataclass containing the proper configuration elements + worker_config (config.InferenceWorkerConfig): dataclass containing the proper configuration elements - Note: See :py:func:`~self.inference` - """ + """ super().__init__(self.inference) self._signals = LogSignal() # add custom signals self.log_signal = self._signals.log_signal @@ -102,17 +109,19 @@ def __init__( @staticmethod def create_inference_dict(images_filepaths): - """Create a dict for MONAI with "image" keys with all image paths in :py:attr:`~self.images_filepaths` + """Create a dict for MONAI with "image" keys with all image paths in :py:attr:`~self.images_filepaths`. Returns: - dict: list of image paths from loaded folder""" + dict: list of image paths from loaded folder + """ return [{"image": image_name} for image_name in images_filepaths] def set_download_log(self, widget): + """Sets the log widget for the downloader.""" self.downloader.log_widget = widget def log(self, text): - """Sends a signal that ``text`` should be logged + """Sends a signal that ``text`` should be logged. Args: text (str): text to logged @@ -120,11 +129,11 @@ def log(self, text): self.log_signal.emit(text) def warn(self, warning): - """Sends a warning to main thread""" + """Sends a warning to main thread.""" self.warn_signal.emit(warning) def _raise_error(self, exception, msg): - """Raises an error in main thread""" + """Raises an error in main thread.""" logger.error(msg, exc_info=True) logger.error(exception, exc_info=True) @@ -139,6 +148,7 @@ def _raise_error(self, exception, msg): yield exception def log_parameters(self): + """Logs the parameters of the inference.""" config = self.config self.log("-" * 20) @@ -183,16 +193,19 @@ def log_parameters(self): self.log("-" * 20) def load_folder(self): + """Loads the folder specified in :py:attr:`~self.images_filepaths` and returns a MONAI DataLoader.""" images_dict = self.create_inference_dict(self.config.images_filepaths) - data_check = LoadImaged(keys=["image"])(images_dict[0]) + data_check = LoadImaged(keys=["image"], image_only=True)( + images_dict[0] + ) check = data_check["image"].shape pad = utils.get_padding_dim(check) if self.config.sliding_window_config.is_enabled(): load_transforms = Compose( [ - LoadImaged(keys=["image"]), + LoadImaged(keys=["image"], image_only=True), # AddChanneld(keys=["image"]), #already done EnsureChannelFirstd(keys=["image"]), # Orientationd(keys=["image"], axcodes="PLI"), @@ -204,7 +217,7 @@ def load_folder(self): else: load_transforms = Compose( [ - LoadImaged(keys=["image"]), + LoadImaged(keys=["image"], image_only=True), # AddChanneld(keys=["image"]), #already done EnsureChannelFirstd(keys=["image"]), QuantileNormalizationd(keys=["image"]), @@ -224,6 +237,7 @@ def load_folder(self): return inference_loader def load_layer(self): + """Loads the layer specified in :py:attr:`~self.layer` and returns a MONAI DataLoader.""" self.log("Loading layer") image = np.squeeze(self.config.layer.data) volume = image.astype(np.float32) @@ -235,9 +249,8 @@ def load_layer(self): f"Data array is not 3-dimensional but {volume_dims}-dimensional," f" please check for extra channel/batch dimensions" ) - volume = np.swapaxes( - volume, 0, 2 - ) # for dims to be monai-like, i.e. xyz, from napari zyx + volume = utils.correct_rotation(volume) + # volume = np.reshape(volume, newshape=(1, 1, *volume.shape)) dims_check = volume.shape @@ -249,6 +262,7 @@ def load_layer(self): if self.config.model_info.name != "WNet" else lambda x: x ) + volume = np.reshape(volume, newshape=(1, *volume.shape)) if self.config.sliding_window_config.is_enabled(): load_transforms = Compose( [ @@ -256,9 +270,9 @@ def load_layer(self): normalization, ToTensor(), # anisotropic_transform, - AddChannel(), + # AddChannel(), # SpatialPad(spatial_size=pad), - AddChannel(), + # AddChannel(), EnsureType(), ], map_items=False, @@ -273,9 +287,9 @@ def load_layer(self): normalization, ToTensor(), # anisotropic_transform, - AddChannel(), + # AddChannel(), SpatialPad(spatial_size=pad), - AddChannel(), + # AddChannel(), EnsureType(), ], map_items=False, @@ -283,6 +297,7 @@ def load_layer(self): ) input_image = load_transforms(volume) + input_image = input_image.unsqueeze(0) logger.debug(f"INPUT IMAGE SHAPE : {input_image.shape}") logger.debug(f"INPUT IMAGE TYPE : {input_image.dtype}") self.log("Done") @@ -295,6 +310,14 @@ def model_output( post_process_transforms, aniso_transform=None, ): + """Runs the model on the inputs and returns the output. + + Args: + inputs (torch.Tensor): the input tensor to run the model on + model (torch.nn.Module): the model to run + post_process_transforms (monai.transforms.Compose): the transforms to apply to the output + aniso_transform (monai.transforms.Zoom): the anisotropic transform to apply to the output + """ inputs = inputs.to("cpu") dataset_device = ( "cpu" if self.config.keep_on_cpu else self.config.device @@ -385,6 +408,23 @@ def model_output_wrapper(inputs): # sys.stdout = old_stdout # sys.stderr = old_stderr + def _correct_results_rotation(self, array, shape): + """Corrects the shape of the array if needed.""" + if array is None: + return None + if array.shape[-3:] != shape[-3:]: + logger.debug( + f"Correcting rotation due to results shape mismatch: target {shape}, got {array.shape}" + ) + array = utils.correct_rotation(array) + if ( + array.shape[-3:] != shape[-3:] + ): # check only non-channel dimensions + logger.warning( + f"Results shape mismatch: target {shape}, got {array.shape}" + ) + return array + def create_inference_result( self, semantic_labels, @@ -395,23 +435,34 @@ def create_inference_result( stats=None, i=0, ) -> InferenceResult: + """Creates an :py:class:`~InferenceResult` object from the inference results. + + Args: + semantic_labels (np.ndarray): the semantic labels + instance_labels (np.ndarray): the instance labels + crf_results (np.ndarray): the CRF results + from_layer (bool, optional): whether the inference was run on a layer or not. Defaults to False. + original (np.ndarray, optional): the original image. Defaults to None. + stats (list, optional): the stats of the instance labels. Defaults to None. + i (int, optional): the index of the image. Defaults to 0. + + Raises: + ValueError: if the image is not from a layer and no original is provided + + Returns: + InferenceResult: the inference result. See :py:class:`~InferenceResult` for more details. + """ if not from_layer and original is None: raise ValueError( "If the image is not from a layer, an original should always be available" ) - if from_layer: - if i != 0: - raise ValueError( - "A layer's ID should always be 0 (default value)" - ) + if from_layer and i != 0: + raise ValueError("A layer's ID should always be 0 (default value)") - if semantic_labels is not None: - semantic_labels = utils.correct_rotation(semantic_labels) - if crf_results is not None: - crf_results = utils.correct_rotation(crf_results) - if instance_labels is not None: - instance_labels = utils.correct_rotation(instance_labels) + # semantic_labels = self._correct_results_rotation(semantic_labels, shape) # done at the level of model_output already + # instance_labels = self._correct_results_rotation(instance_labels, shape) + # crf_results = self._correct_results_rotation(crf_results, shape) return InferenceResult( image_id=i + 1, @@ -424,9 +475,25 @@ def create_inference_result( ) def get_original_filename(self, i): + """Gets the original filename from the :py:attr:`~self.images_filepaths` attribute.""" return Path(self.config.images_filepaths[i]).stem def get_instance_result(self, semantic_labels, from_layer=False, i=-1): + """Gets the instance segmentation result. + + Args: + semantic_labels (np.ndarray): the semantic labels + from_layer (bool, optional): whether the inference was run on a layer or not. Defaults to False. + i (int, optional): the index of the image. Defaults to -1. + + Raises: + ValueError: if the image is not from a layer and no ID is provided + + Returns: + tuple: a tuple containing: + * the instance labels + * the stats of the instance labels + """ if not from_layer and i == -1: raise ValueError( "An ID should be provided when running from a file" @@ -437,11 +504,11 @@ def get_instance_result(self, semantic_labels, from_layer=False, i=-1): semantic_labels, i + 1, ) - data_dict = self.stats_csv(instance_labels) + stats = self.stats_csv(instance_labels) else: instance_labels = None - data_dict = None - return instance_labels, data_dict + stats = None + return instance_labels, stats def save_image( self, @@ -450,6 +517,14 @@ def save_image( i=0, additional_info="", ): + """Save the image to the :py:attr:`~self.results_path` folder. + + Args: + image (np.ndarray): the image to save + from_layer (bool, optional): whether the inference was run on a layer or not. Defaults to False. + i (int, optional): the index of the image. Defaults to 0. + additional_info (str, optional): additional info to add to the filename. Defaults to "". + """ if not from_layer: original_filename = "_" + self.get_original_filename(i) + "_" filetype = self.config.filetype @@ -483,6 +558,7 @@ def save_image( self.log(f"File n°{i+1} saved as : {filename}") def aniso_transform(self, image): + """Applies an anisotropic transform to the image.""" if self.config.post_process_config.zoom.enabled: zoom = self.config.post_process_config.zoom.zoom_values anisotropic_transform = Zoom( @@ -496,12 +572,21 @@ def aniso_transform(self, image): def instance_seg( self, semantic_labels, image_id=0, original_filename="layer" ): + """Runs the instance segmentation on the semantic labels. + + Args: + semantic_labels (np.ndarray): the semantic labels + image_id (int, optional): the index of the image. Defaults to 0. + original_filename (str, optional): the original filename. Defaults to "layer". + """ if image_id is not None: self.log(f"Running instance segmentation for image n°{image_id}") method = self.config.post_process_config.instance.method - instance_labels = method.run_method_on_channels(semantic_labels) - self.log(f"DEBUG instance results shape : {instance_labels.shape}") + instance_labels = method.run_method_on_channels_from_params( + semantic_labels + ) + logger.debug(f"DEBUG instance results shape : {instance_labels.shape}") filetype = ( ".tif" @@ -528,6 +613,7 @@ def instance_seg( return instance_labels def inference_on_folder(self, inf_data, i, model, post_process_transforms): + """Runs inference on a folder.""" self.log("-" * 10) self.log(f"Inference started on image n°{i + 1}...") @@ -540,6 +626,15 @@ def inference_on_folder(self, inf_data, i, model, post_process_transforms): aniso_transform=self.aniso_transform, ) + out = utils.correct_rotation(out) + extra_dims = len(inputs.shape) - 3 + inputs_shape_corrected = np.swapaxes( + inputs, extra_dims, 2 + extra_dims + ).shape + if out.shape[-3:] != inputs_shape_corrected[-3:]: + logger.debug( + f"Output shape {out.shape[-3:]} does not match input shape {inputs_shape_corrected[-3:]} on HWD dims even after rotation" + ) self.save_image(out, i=i) instance_labels, stats = self.get_instance_result(out, i=i) if self.config.use_crf: @@ -572,9 +667,18 @@ def inference_on_folder(self, inf_data, i, model, post_process_transforms): ) def run_crf(self, image, labels, aniso_transform, image_id=0): + """Runs CRF on the image and labels.""" try: if aniso_transform is not None: image = aniso_transform(image) + + if image.shape[-3:] != labels.shape[-3:]: + image = utils.correct_rotation(image) + if image.shape[-3:] != labels.shape[-3:]: + logger.warning( + f"Labels shape mismatch: target {image.shape}, got {labels.shape}. CRF will likely fail." + ) + crf_results = crf_with_config( image, labels, config=self.config.crf_config, log=self.log ) @@ -590,8 +694,12 @@ def run_crf(self, image, labels, aniso_transform, image_id=0): return None def stats_csv(self, instance_labels): + """Computes the stats of the instance labels.""" try: if self.config.compute_stats: + logger.debug( + f"Stats csv instance labels shape : {instance_labels.shape}" + ) if len(instance_labels.shape) == 4: stats = [volume_stats(c) for c in instance_labels] else: @@ -604,15 +712,26 @@ def stats_csv(self, instance_labels): return None def inference_on_layer(self, image, model, post_process_transforms): + """Runs inference on a layer.""" self.log("-" * 10) self.log("Inference started on layer...") - + logger.debug(f"Layer shape @ inference input: {image.shape}") out = self.model_output( image, model, post_process_transforms, aniso_transform=self.aniso_transform, ) + logger.debug(f"Inference on layer result shape : {out.shape}") + out = utils.correct_rotation(out) + extra_dims = len(image.shape) - 3 + layer_shape_corrected = np.swapaxes( + image, extra_dims, 2 + extra_dims + ).shape + if out.shape[-3:] != layer_shape_corrected[-3:]: + logger.debug( + f"Output shape {out.shape[-3:]} does not match input shape {layer_shape_corrected[-3:]} on HWD dims even after rotation" + ) self.save_image(out, from_layer=True) instance_labels, stats = self.get_instance_result( @@ -634,9 +753,10 @@ def inference_on_layer(self, image, model, post_process_transforms): # @thread_worker(connect={"errored": self._raise_error}) def inference(self): - """ + """Main inference function. + Requires: - * device: cuda or cpu device to use for torch + * device: cuda or cpu device to use for torch. * model_dict: the :py:attr:`~self.models_dict` dictionary to obtain the model name, class and instance @@ -705,7 +825,7 @@ def inference(self): raise ValueError("Model is None") # try: self.log("Loading weights...") - if weights_config.custom: + if weights_config.use_custom: weights = weights_config.path else: self.downloader.download_weights( diff --git a/napari_cellseg3d/code_models/worker_training.py b/napari_cellseg3d/code_models/worker_training.py index 95ea6aec..9ba8be40 100644 --- a/napari_cellseg3d/code_models/worker_training.py +++ b/napari_cellseg3d/code_models/worker_training.py @@ -1,3 +1,4 @@ +"""Contains the workers used to train the models.""" import platform import time from abc import abstractmethod @@ -88,11 +89,14 @@ class TrainingWorkerBase(GeneratorWorker): """A basic worker abstract class, to run training jobs in. - Contains the minimal common elements required for training models.""" + + Contains the minimal common elements required for training models. + """ wandb_config = config.WandBConfig() def __init__(self): + """Initializes the worker.""" super().__init__(self.train) self._signals = LogSignal() self.log_signal = self._signals.log_signal @@ -107,12 +111,13 @@ def __init__(self): ################################ def set_download_log(self, widget): - """Sets the log widget for the downloader to output to""" + """Sets the log widget for the downloader to output to.""" self.downloader.log_widget = widget def log(self, text): - """Sends a Qt signal that the provided text should be logged - Goes in a Log object, defined in :py:mod:`napari_cellseg3d.interface + """Sends a Qt signal that the provided text should be logged. + + Goes in a Log object, defined in :py:mod:`napari_cellseg3d.interface`. Sends a signal to the main thread to log the text. Signal is defined in napari_cellseg3d.workers_utils.LogSignal. @@ -122,11 +127,11 @@ def log(self, text): self.log_signal.emit(text) def warn(self, warning): - """Sends a warning to main thread""" + """Sends a warning to main thread.""" self.warn_signal.emit(warning) def raise_error(self, exception, msg): - """Sends an error to main thread""" + """Sends an error to main thread.""" logger.error(msg, exc_info=True) logger.error(exception, exc_info=True) self.error_signal.emit(exception, msg) @@ -135,18 +140,19 @@ def raise_error(self, exception, msg): @abstractmethod def log_parameters(self): - """Logs the parameters of the training""" + """Logs the parameters of the training.""" raise NotImplementedError @abstractmethod def train(self): - """Starts a training job""" + """Starts a training job.""" raise NotImplementedError class WNetTrainingWorker(TrainingWorkerBase): """A custom worker to run WNet (unsupervised) training jobs in. - Inherits from :py:class:`napari.qt.threading.GeneratorWorker` via :py:class:`TrainingWorkerBase` + + Inherits from :py:class:`napari.qt.threading.GeneratorWorker` via :py:class:`TrainingWorkerBase`. """ # TODO : add wandb parameters @@ -155,6 +161,11 @@ def __init__( self, worker_config: config.WNetTrainingWorkerConfig, ): + """Initializes the worker. + + Args: + worker_config (config.WNetTrainingWorkerConfig): The configuration object + """ super().__init__() self.config = worker_config @@ -174,15 +185,14 @@ def __init__( self.data_shape = None def get_patch_dataset(self, train_transforms): - """Creates a Dataset from the original data using the tifffile library + """Creates a Dataset from the original data using the tifffile library. Args: - train_data_dict (dict): dict with the Paths to the directory containing the data + train_transforms (monai.transforms.Compose): The transforms to apply to the data Returns: (tuple): A tuple containing the shape of the data and the dataset """ - patch_func = Compose( [ LoadImaged(keys=["image"], image_only=True), @@ -216,6 +226,7 @@ def get_patch_dataset(self, train_transforms): return self.config.sample_size, dataset def get_dataset_eval(self, eval_dataset_dict): + """Creates a Dataset applying some transforms/augmentation on the data using the MONAI library.""" eval_transforms = Compose( [ LoadImaged(keys=["image", "label"]), @@ -248,10 +259,10 @@ def get_dataset_eval(self, eval_dataset_dict): ) def get_dataset(self, train_transforms): - """Creates a Dataset applying some transforms/augmentation on the data using the MONAI library + """Creates a Dataset applying some transforms/augmentation on the data using the MONAI library. Args: - config (WNetTrainingWorkerConfig): The configuration object + train_transforms (monai.transforms.Compose): The transforms to apply to the data Returns: (tuple): A tuple containing the shape of the data and the dataset @@ -339,6 +350,7 @@ def _get_data(self): return self.dataloader, self.eval_dataloader, self.data_shape def log_parameters(self): + """Logs the parameters of the training.""" self.log("*" * 20) self.log("-- Parameters --") self.log(f"Device: {self.config.device}") @@ -346,7 +358,7 @@ def log_parameters(self): self.log(f"Epochs: {self.config.max_epochs}") self.log(f"Learning rate: {self.config.learning_rate}") self.log(f"Validation interval: {self.config.validation_interval}") - if self.config.weights_info.custom: + if self.config.weights_info.use_custom: self.log(f"Custom weights: {self.config.weights_info.path}") elif self.config.weights_info.use_pretrained: self.log(f"Pretrained weights: {self.config.weights_info.path}") @@ -388,6 +400,15 @@ def log_parameters(self): def train( self, provided_model=None, provided_optimizer=None, provided_loss=None ): + """Main training function. + + Note : args are mainly used for testing purposes. Model is otherwise initialized in the function. + + Args: + provided_model (WNet, optional): A model to use for training. Defaults to None. + provided_optimizer (torch.optim.Optimizer, optional): An optimizer to use for training. Defaults to None. + provided_loss (torch.nn.Module, optional): A loss function to use for training. Defaults to None. + """ try: if self.config is None: self.config = config.WNetTrainingWorkerConfig() @@ -400,7 +421,7 @@ def train( logger.debug(f"wandb config : {config_dict}") wandb.init( config=config_dict, - project="CellSeg3D WNet", + project="CellSeg3D", mode=self.wandb_config.mode, ) @@ -445,7 +466,7 @@ def train( if WANDB_INSTALLED: wandb.watch(model, log_freq=100) - if self.config.weights_info.custom: + if self.config.weights_info.use_custom: if self.config.weights_info.use_pretrained: weights_file = "wnet.pth" self.downloader.download_weights("WNet", weights_file) @@ -768,6 +789,15 @@ def train( raise e def eval(self, model, epoch) -> TrainingReport: + """Evaluates the model on the validation set. + + Args: + model (WNet): The model to evaluate + epoch (int): The current epoch + + Returns: + TrainingReport: A training report containing the results of the evaluation. See :py:class:`napari_cellseg3d.workers_utils.TrainingReport` + """ with torch.no_grad(): device = self.config.device for _k, val_data in enumerate(self.eval_dataloader): @@ -893,16 +923,19 @@ def eval(self, model, epoch) -> TrainingReport: class SupervisedTrainingWorker(TrainingWorkerBase): """A custom worker to run supervised training jobs in. - Inherits from :py:class:`napari.qt.threading.GeneratorWorker` via :py:class:`TrainingWorkerBase` + + Inherits from :py:class:`napari.qt.threading.GeneratorWorker` via :py:class:`TrainingWorkerBase`. """ + labels_not_semantic = False + def __init__( self, worker_config: config.SupervisedTrainingWorkerConfig, ): - """Initializes a worker for inference with the arguments needed by the :py:func:`~train` function. Note: See :py:func:`~train` + """Initializes a worker for inference with the arguments needed by the :py:func:`~train` function. Note: See :py:func:`~train`. - Args: + Config provides the following attributes: * device : device to train on, cuda or cpu * model_dict : dict containing the model's "name" and "class" @@ -935,7 +968,6 @@ def __init__( * deterministic : dict with "use deterministic" : bool, whether to use deterministic training, "seed": seed for RNG - """ super().__init__() # worker function is self.train in parent class self.config = worker_config @@ -952,7 +984,7 @@ def __init__( } self.loss_function = None - def set_loss_from_config(self): + def _set_loss_from_config(self): try: self.loss_function = self.loss_dict[self.config.loss_function] except KeyError as e: @@ -960,11 +992,12 @@ def set_loss_from_config(self): return self.loss_function def log_parameters(self): + """Logs the parameters of the training.""" self.log("-" * 20) self.log("Parameters summary :\n") self.log( - f"Percentage of dataset used for validation : {self.config.validation_percent * 100}%" + f"Percentage of dataset used for training : {self.config.training_percent * 100}%" ) # self.log("-" * 10) @@ -1003,7 +1036,7 @@ def log_parameters(self): if self.config.do_augmentation: self.log("Data augmentation is enabled") - if not self.config.weights_info.use_pretrained: + if self.config.weights_info.use_custom: self.log(f"Using weights from : {self.config.weights_info.path}") if self._weight_error: self.log( @@ -1023,9 +1056,10 @@ def train( provided_loss=None, provided_scheduler=None, ): - """Trains the PyTorch model for the given number of epochs, with the selected model and data, - using the chosen batch size, validation interval, loss function, and number of samples. - Will perform validation once every :py:obj:`val_interval` and save results if the mean dice is better + """Trains the PyTorch model for the given number of epochs. + + Uses the selected model and data, using the chosen batch size, validation interval, loss function, and number of samples. + Will perform validation once every :py:obj:`val_interval` and save results if the mean dice is better. Requires: @@ -1061,7 +1095,6 @@ def train( * deterministic : dict with "use deterministic" : bool, whether to use deterministic training, "seed": seed for RNG """ - ######################### # error_log = open(results_path +"/error_log.log" % multiprocessing.current_process().name, 'x') # faulthandler.enable(file=error_log, all_threads=True) @@ -1073,6 +1106,15 @@ def train( start_time = time.time() try: + if WANDB_INSTALLED: + config_dict = self.config.__dict__ + logger.debug(f"wandb config : {config_dict}") + wandb.init( + config=config_dict, + project="CellSeg3D", + mode=self.wandb_config.mode, + ) + if deterministic_config.enabled: set_determinism( seed=deterministic_config.seed @@ -1088,6 +1130,17 @@ def train( model_name = model_config.name model_class = model_config.get_model() + ######## Check that labels are semantic, not instance + check_labels = LoadImaged(keys=["label"])( + self.config.train_data_dict[0] + ) + if check_labels["label"].max() > 1: + self.warn( + "Labels are not semantic, but instance. Converting to semantic, this might cause errors." + ) + self.labels_not_semantic = True + ######## + if not self.config.sampling: data_check = LoadImaged(keys=["image"])( self.config.train_data_dict[0] @@ -1106,6 +1159,9 @@ def train( device = torch.device(self.config.device) model = model.to(device) + if WANDB_INSTALLED: + wandb.watch(model, log_freq=100) + epoch_loss_values = [] val_metric_values = [] @@ -1114,13 +1170,13 @@ def train( self.config.train_data_dict[ 0 : int( len(self.config.train_data_dict) - * self.config.validation_percent + * self.config.training_percent ) ], self.config.train_data_dict[ int( len(self.config.train_data_dict) - * self.config.validation_percent + * self.config.training_percent ) : ], ) @@ -1177,6 +1233,7 @@ def train( ) def get_patch_loader_func(num_samples): + """Returns a function that will be used to extract patches from the images.""" return Compose( [ LoadImaged(keys=["image", "label"]), @@ -1207,12 +1264,11 @@ def get_patch_loader_func(num_samples): # TODO(cyril) : maybe implement something in user config to toggle this behavior if len(self.config.train_data_dict) < 2: num_train_samples = ceil( - self.config.num_samples - * self.config.validation_percent + self.config.num_samples * self.config.training_percent ) num_val_samples = ceil( self.config.num_samples - * (1 - self.config.validation_percent) + * (1 - self.config.training_percent) ) if num_train_samples < 2: self.log( @@ -1279,7 +1335,7 @@ def get_patch_loader_func(num_samples): logger.debug("Cache dataset : train") train_dataset = CacheDataset( data=self.train_files, - transform=Compose(load_whole_images, train_transforms), + transform=Compose([load_whole_images, train_transforms]), ) logger.debug("Cache dataset : val") validation_dataset = CacheDataset( @@ -1335,7 +1391,7 @@ def get_patch_loader_func(num_samples): # time = utils.get_date_time() logger.debug("Weights") - if weights_config.custom: + if weights_config.use_custom: if weights_config.use_pretrained: weights_file = model_class.weights_file self.downloader.download_weights(model_name, weights_file) @@ -1373,7 +1429,7 @@ def get_patch_loader_func(num_samples): self.log_parameters() # device = torch.device(self.config.device) - self.set_loss_from_config() + self._set_loss_from_config() if provided_loss is not None: self.loss_function = provided_loss @@ -1407,9 +1463,12 @@ def get_patch_loader_func(num_samples): ) # logger.debug(f"Inputs shape : {inputs.shape}") # logger.debug(f"Labels shape : {labels.shape}") + if self.labels_not_semantic: + labels = labels.clamp(0, 1) + optimizer.zero_grad() outputs = model(inputs) - # self.log(f"Output dimensions : {outputs.shape}") + # logger.debug(f"Output dimensions : {outputs.shape}") if outputs.shape[1] > 1: outputs = outputs[ :, 1:, :, : @@ -1418,6 +1477,10 @@ def get_patch_loader_func(num_samples): outputs = outputs.unsqueeze(0) # logger.debug(f"Outputs shape : {outputs.shape}") loss = self.loss_function(outputs, labels) + + if WANDB_INSTALLED: + wandb.log({"Training/Loss": loss.item()}) + loss.backward() optimizer.step() epoch_loss += loss.detach().item() @@ -1447,7 +1510,15 @@ def get_patch_loader_func(num_samples): supervised=True, ) - # return + if WANDB_INSTALLED: + wandb.log({"Training/Epoch loss": epoch_loss / step}) + wandb.log( + { + "LR/Model learning rate": optimizer.param_groups[ + 0 + ]["lr"] + } + ) epoch_loss /= step epoch_loss_values.append(epoch_loss) @@ -1560,6 +1631,10 @@ def get_patch_loader_func(num_samples): ) metric = dice_metric.aggregate().detach().item() + + if WANDB_INSTALLED: + wandb.log({"Validation/Dice metric": metric}) + dice_metric.reset() val_metric_values.append(metric) @@ -1622,6 +1697,11 @@ def get_patch_loader_func(num_samples): f"Train completed, best_metric: {best_metric:.4f} " f"at epoch: {best_metric_epoch}" ) + + if WANDB_INSTALLED: + wandb.log({"Validation/Best metric": best_metric}) + wandb.log({"Validation/Best metric epoch": best_metric_epoch}) + # Save last checkpoint weights_filename = f"{model_name}_latest.pth" self.log("Saving last model") diff --git a/napari_cellseg3d/code_models/workers_utils.py b/napari_cellseg3d/code_models/workers_utils.py index 4c197c28..c8ba6655 100644 --- a/napari_cellseg3d/code_models/workers_utils.py +++ b/napari_cellseg3d/code_models/workers_utils.py @@ -1,3 +1,4 @@ +"""Several worker-related utilities for inference and training.""" import typing as t from dataclasses import dataclass from pathlib import Path @@ -27,8 +28,7 @@ class WeightsDownloader: """A utility class the downloads the weights of a model when needed.""" def __init__(self, log_widget: t.Optional[ui.Log] = None): - """ - Creates a WeightsDownloader, optionally with a log widget to display the progress. + """Creates a WeightsDownloader, optionally with a log widget to display the progress. Args: log_widget (log_utility.Log): a Log to display the progress bar in. If None, uses logger.info() @@ -36,8 +36,8 @@ def __init__(self, log_widget: t.Optional[ui.Log] = None): self.log_widget = log_widget def download_weights(self, model_name: str, model_weights_filename: str): - """ - Downloads a specific pretrained model. + """Downloads a specific pretrained model. + This code is adapted from DeepLabCut with permission from MWMathis. Args: @@ -137,14 +137,16 @@ class LogSignal(WorkerBaseSignals): # Should not be an instance variable but a class variable, not defined in __init__, see # https://stackoverflow.com/questions/2970312/pyqt4-qtcore-pyqtsignal-object-has-no-attribute-connect - def __init__(self): - super().__init__() + def __init__(self, parent=None): + """Creates a LogSignal.""" + super().__init__(parent=parent) class ONNXModelWrapper(torch.nn.Module): - """Class to replace torch model by ONNX Runtime session""" + """Class to replace torch model by ONNX Runtime session.""" def __init__(self, file_location): + """Creates an ONNXModelWrapper.""" super().__init__() try: import onnxruntime as ort @@ -161,18 +163,24 @@ def __init__(self, file_location): ) def forward(self, modeL_input): - """Wraps ONNX output in a torch tensor""" + """Wraps ONNX output in a torch tensor.""" outputs = self.ort_session.run( None, {"input": modeL_input.cpu().numpy()} ) return torch.tensor(outputs[0]) def eval(self): - """Dummy function to replace model.eval()""" + """Dummy function. + + Replaces model.eval(). + """ pass def to(self, device): - """Dummy function to replace model.to(device)""" + """Dummy function. + + Replaces model.to(device). + """ pass @@ -180,9 +188,11 @@ class QuantileNormalizationd(MapTransform): """MONAI-style dict transform to normalize each image in a batch individually by quantile normalization.""" def __init__(self, keys, allow_missing_keys: bool = False): + """Creates a QuantileNormalizationd transform.""" super().__init__(keys, allow_missing_keys) def __call__(self, data): + """Normalize each image in a batch individually by quantile normalization.""" d = dict(data) for key in self.keys: d[key] = self.normalizer(d[key]) @@ -204,16 +214,26 @@ class QuantileNormalization(Transform): """MONAI-style transform to normalize each image in a batch individually by quantile normalization.""" def __call__(self, img): + """Normalize each image in a batch individually by quantile normalization.""" return utils.quantile_normalization(img) class RemapTensor(Transform): + """Remap the values of a tensor to a new range.""" + def __init__(self, new_max, new_min): + """Creates a RemapTensor transform. + + Args: + new_max (float): new maximum value + new_min (float): new minimum value + """ super().__init__() self.max = new_max self.min = new_min def __call__(self, img): + """Remap the values of a tensor to a new range.""" return utils.remap_image(img, new_max=self.max, new_min=self.min) @@ -237,17 +257,26 @@ def __call__(self, img): class Threshold(Transform): + """Threshold a tensor to 0 or 1.""" + def __init__(self, threshold=0.5): + """Creates a Threshold transform. + + Args: + threshold (float): threshold value + """ super().__init__() self.threshold = threshold def __call__(self, img): - return torch.where(img > self.threshold, 1, 0) + """Threshold a tensor to 0 or 1.""" + res = torch.where(img > self.threshold, 1, 0) + return torch.Tensor(res).float() @dataclass class InferenceResult: - """Class to record results of a segmentation job""" + """Class to record results of a segmentation job.""" image_id: int = 0 original: np.array = None @@ -260,6 +289,8 @@ class InferenceResult: @dataclass class TrainingReport: + """Class to record results of a training job.""" + show_plot: bool = True epoch: int = 0 loss_1_values: t.Dict = None # example : {"Loss" : [0.1, 0.2, 0.3]} diff --git a/napari_cellseg3d/code_plugins/__init__.py b/napari_cellseg3d/code_plugins/__init__.py index e69de29b..24b044f6 100644 --- a/napari_cellseg3d/code_plugins/__init__.py +++ b/napari_cellseg3d/code_plugins/__init__.py @@ -0,0 +1 @@ +"""This folder contains all plugin-related code.""" diff --git a/napari_cellseg3d/code_plugins/plugin_base.py b/napari_cellseg3d/code_plugins/plugin_base.py index 90c61adf..2e2807d9 100644 --- a/napari_cellseg3d/code_plugins/plugin_base.py +++ b/napari_cellseg3d/code_plugins/plugin_base.py @@ -1,3 +1,4 @@ +"""Base classes for napari_cellseg3d plugins.""" from functools import partial from pathlib import Path @@ -15,7 +16,7 @@ class BasePluginSingleImage(QTabWidget): - """A basic plugin template for working with **single images**""" + """A basic plugin template for working with **single images**.""" def __init__( self, @@ -25,8 +26,7 @@ def __init__( loads_labels=True, has_results=True, ): - """ - Creates a Base plugin with several buttons pre-defined + """Creates a Base plugin with several buttons pre-defined. Args: viewer: napari viewer to display in @@ -107,9 +107,9 @@ def __init__( qInstallMessageHandler(ui.handle_adjust_errors_wrapper(self)) def enable_utils_menu(self): - """ - Enables the usage of the CTRL+right-click shortcut to the utilities. - Should only be used in "high-level" widgets (provided in napari Plugins menu) to avoid multiple activation + """Enables the usage of the CTRL+right-click shortcut to the utilities. + + Should only be used in "high-level" widgets (provided in napari Plugins menu) to avoid multiple activation. """ viewer = self._viewer @@ -185,10 +185,11 @@ def _set_io_visibility(self): @staticmethod def _show_io_element(widget: QWidget, toggle: QWidget = None): - """ + """Show widget and connect it to toggle if any. + Args: widget: Widget to be shown or hidden - toggle: Toggle to be used to determine whether widget should be shown (Checkbox or RadioButton) + toggle: Toggle to be used to determine whether widget should be shown (Checkbox or RadioButton). """ widget.setVisible(True) @@ -199,13 +200,12 @@ def _show_io_element(widget: QWidget, toggle: QWidget = None): @staticmethod def _hide_io_element(widget: QWidget, toggle: QWidget = None): - """ - Attempts to disconnect widget from toggle and hide it. + """Attempts to disconnect widget from toggle and hide it. + Args: widget: Widget to be hidden - toggle: Toggle to be disconnected from widget, if any + toggle: Toggle to be disconnected from widget, if any. """ - if toggle is not None: try: toggle.toggled.disconnect() @@ -217,11 +217,11 @@ def _hide_io_element(widget: QWidget, toggle: QWidget = None): widget.setVisible(False) def _build(self): - """Method to be defined by children classes""" + """Method to be defined by children classes.""" raise NotImplementedError("To be defined in child classes") def _show_file_dialog(self): - """Open file dialog and process path for a single file""" + """Open file dialog and process path for a single file.""" # if self.load_as_stack_choice.isChecked(): # return ui.open_folder_dialog( # self, @@ -239,7 +239,7 @@ def _show_file_dialog(self): return choice def _show_dialog_images(self): - """Show file dialog and set image path""" + """Show file dialog and set image path.""" f_name = self._show_file_dialog() if type(f_name) is str and Path(f_name).is_file(): self.image_path = f_name @@ -248,7 +248,7 @@ def _show_dialog_images(self): self._update_default_paths() def _show_dialog_labels(self): - """Show file dialog and set label path""" + """Show file dialog and set label path.""" f_name = self._show_file_dialog() if isinstance(f_name, str) and Path(f_name).is_file(): self.label_path = f_name @@ -257,7 +257,7 @@ def _show_dialog_labels(self): self._update_default_paths() def _check_results_path(self, folder: str): - """Check if results folder exists, create it if not""" + """Check if results folder exists, create it if not.""" logger.debug(f"Checking results folder : {folder}") if folder != "" and isinstance(folder, str): if not Path(folder).is_dir(): @@ -274,7 +274,7 @@ def _check_results_path(self, folder: str): return False def _load_results_path(self): - """Show file dialog to set :py:attr:`~results_path`""" + """Show file dialog to set :py:attr:`~results_path`.""" self._update_default_paths() folder = ui.open_folder_dialog(self, self._default_path) @@ -285,7 +285,7 @@ def _load_results_path(self): self._update_default_paths() def _update_default_paths(self): - """Updates default path for smoother navigation when opening file dialogs""" + """Updates default path for smoother navigation when opening file dialogs.""" self._default_path = [ self.image_path, self.label_path, @@ -311,12 +311,14 @@ def _make_next_button(self): def remove_from_viewer(self): """Removes the widget from the napari window. - Can be re-implemented in children classes if needed""" + + Must be re-implemented in children classes where needed. + """ self.remove_docked_widgets() self._viewer.window.remove_dock_widget(self) def remove_docked_widgets(self): - """Removes all docked widgets from napari window""" + """Removes all docked widgets from napari window.""" try: if len(self.docked_widgets) != 0: [ @@ -332,7 +334,7 @@ def remove_docked_widgets(self): class BasePluginFolder(BasePluginSingleImage): - """A basic plugin template for working with **folders of images**""" + """A basic plugin template for working with **folders of images**.""" def __init__( self, @@ -342,7 +344,7 @@ def __init__( loads_labels=True, has_results=True, ): - """Creates a plugin template with the following widgets defined but not added in a layout : + """Creates a plugin template with the following widgets defined but not added in a layout. * A button to load a folder of images @@ -401,7 +403,7 @@ def __init__( # self._set_io_visibility() def load_dataset_paths(self): - """Loads all image paths (as str) in a given folder for which the extension matches the set filetype + """Loads all image paths (as str) in a given folder for which the extension matches the set filetype. Returns: array(str): all loaded file paths @@ -419,7 +421,7 @@ def load_dataset_paths(self): return file_paths def load_image_dataset(self): - """Show file dialog to set :py:attr:`~images_filepaths`""" + """Show file dialog to set :py:attr:`~images_filepaths`.""" filenames = self.load_dataset_paths() if filenames: logger.info("Images loaded :") @@ -432,7 +434,7 @@ def load_image_dataset(self): self._update_default_paths(path) def load_unsup_images_dataset(self): - """Show file dialog to set :py:attr:`~val_images_filepaths`""" + """Show file dialog to set :py:attr:`~val_images_filepaths`.""" filenames = self.load_dataset_paths() if filenames: logger.info("Images loaded (unsupervised training) :") @@ -447,7 +449,7 @@ def load_unsup_images_dataset(self): self._update_default_paths(path) def load_label_dataset(self): - """Show file dialog to set :py:attr:`~labels_filepaths`""" + """Show file dialog to set :py:attr:`~labels_filepaths`.""" filenames = self.load_dataset_paths() if filenames: logger.info("Labels loaded :") @@ -460,7 +462,7 @@ def load_label_dataset(self): self._update_default_paths(path) def _update_default_paths(self, path=None): - """Update default path for smoother file dialogs""" + """Update default path for smoother file dialogs.""" logger.debug(f"Updating default paths with {path}") if path is None: self._default_path = [ @@ -476,7 +478,7 @@ def _update_default_paths(self, path=None): @staticmethod def extract_dataset_paths(paths): - """Gets the parent folder name of the first image and label paths""" + """Gets the parent folder name of the first image and label paths.""" if len(paths) == 0: return None if paths[0] is None: @@ -491,7 +493,7 @@ def _check_all_filepaths(self): class BasePluginUtils(BasePluginFolder): - """Small subclass used to have centralized widgets layer and result path selection in utilities""" + """Small subclass used to have centralized widgets layer and result path selection in utilities.""" save_path = None utils_default_paths = [Path.home() / "cellseg3d"] @@ -503,6 +505,7 @@ def __init__( loads_images=True, loads_labels=True, ): + """Creates a plugin template with the following widgets defined but not added in a layout.""" super().__init__( viewer=viewer, loads_images=loads_images, @@ -517,7 +520,7 @@ def __init__( """Should contain the layer associated with the results of the utility widget""" def _update_default_paths(self, path=None): - """Override to also update utilities' pool of default paths""" + """Override to also update utilities' pool of default paths.""" default_path = super()._update_default_paths(path) logger.debug(f"Trying to update default with {default_path}") if default_path is not None: diff --git a/napari_cellseg3d/code_plugins/plugin_convert.py b/napari_cellseg3d/code_plugins/plugin_convert.py index edfe3c89..6567e918 100644 --- a/napari_cellseg3d/code_plugins/plugin_convert.py +++ b/napari_cellseg3d/code_plugins/plugin_convert.py @@ -1,8 +1,11 @@ +"""Several image processing utilities.""" from pathlib import Path +from warnings import warn import napari import numpy as np -from qtpy.QtWidgets import QSizePolicy +import pandas as pd +from qtpy.QtWidgets import QLineEdit, QSizePolicy from tifffile import imread import napari_cellseg3d.interface as ui @@ -12,6 +15,7 @@ clear_small_objects, threshold, to_semantic, + volume_stats, ) from napari_cellseg3d.code_plugins.plugin_base import BasePluginUtils from napari_cellseg3d.dev_scripts.crop_data import crop_3d_image @@ -23,12 +27,12 @@ class FragmentUtils(BasePluginUtils): - """Class to crop large 3D volumes into smaller fragments""" + """Class to crop large 3D volumes into smaller fragments.""" save_path = Path.home() / "cellseg3d" / "fragmented" def __init__(self, viewer: "napari.Viewer.viewer", parent=None): - """Creates a FragmentUtils widget + """Creates a FragmentUtils widget. Args: viewer: viewer in which to process data @@ -115,13 +119,12 @@ def _start(self): class AnisoUtils(BasePluginUtils): - """Class to correct anisotropy in images""" + """Class to correct anisotropy in images.""" save_path = Path.home() / "cellseg3d" / "anisotropy" def __init__(self, viewer: "napari.Viewer.viewer", parent=None): - """ - Creates a AnisoUtils widget + """Creates a AnisoUtils widget. Args: viewer: viewer in which to process data @@ -214,14 +217,12 @@ def _start(self): class RemoveSmallUtils(BasePluginUtils): + """Widget to remove small objects.""" + save_path = Path.home() / "cellseg3d" / "small_removed" - """ - Widget to remove small objects - """ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): - """ - Creates a RemoveSmallUtils widget + """Creates a RemoveSmallUtils widget. Args: viewer: viewer in which to process data @@ -238,10 +239,10 @@ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): self.label_layer_loader.layer_list.label.setText("Layer :") self.start_btn = ui.Button("Start", self._start) - self.size_for_removal_counter = ui.IntIncrementCounter( - lower=1, - upper=100000, - default=10, + self.size_for_removal_counter = ui.DoubleIncrementCounter( + lower=0.0, + upper=100000.0, + default=10.0, text_label="Remove all smaller than (pxs):", ) @@ -316,14 +317,12 @@ def _start(self): class ToSemanticUtils(BasePluginUtils): + """Widget to create semantic labels from instance labels.""" + save_path = Path.home() / "cellseg3d" / "semantic_labels" - """ - Widget to create semantic labels from instance labels - """ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): - """ - Creates a ToSemanticUtils widget + """Creates a ToSemanticUtils widget. Args: viewer: viewer in which to process data @@ -407,14 +406,12 @@ def _start(self): class ToInstanceUtils(BasePluginUtils): + """Widget to convert semantic labels to instance labels.""" + save_path = Path.home() / "cellseg3d" / "instance_labels" - """ - Widget to convert semantic labels to instance labels - """ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): - """ - Creates a ToInstanceUtils widget + """Creates a ToInstanceUtils widget. Args: viewer: viewer in which to process data @@ -501,15 +498,17 @@ def _start(self): class ThresholdUtils(BasePluginUtils): - save_path = Path.home() / "cellseg3d" / "threshold" - """ - Creates a ThresholdUtils widget + """Creates a ThresholdUtils widget. + Args: viewer: viewer in which to process data - parent: parent widget + parent: parent widget. """ + save_path = Path.home() / "cellseg3d" / "threshold" + def __init__(self, viewer: "napari.viewer.Viewer", parent=None): + """Creates a ThresholdUtils widget.""" super().__init__( viewer, parent=parent, @@ -596,3 +595,100 @@ def _start(self): images, self.images_filepaths, ) + + +class StatsUtils(BasePluginUtils): + """Widget to save statistics of a labels layer.""" + + save_path = Path.home() / "cellseg3d" / "stats" + + def __init__(self, viewer: "napari.viewer.Viewer", parent=None): + """Creates a StatsUtils widget. + + Args: + viewer: viewer in which to process data + parent: parent widget + """ + super().__init__( + viewer, + parent=parent, + loads_images=False, + ) + + self.data_panel = self._build_io_panel() + + self.csv_name = QLineEdit("volume_stats", parent=self) + self.csv_name.setToolTip( + "Name of the csv file.\nThe extension is added automatically;\nif running on a folder, the id of the image will be added to the name." + ) + + self.start_btn = ui.Button("Start", self._start) + + self.results_path = str(self.save_path) + self.results_filewidget.text_field.setText(self.results_path) + self.results_filewidget.check_ready() + + self.container = self._build() + + def _build(self): + container = ui.ContainerWidget() + + ui.add_widgets( + self.data_panel.layout, + [ + self.csv_name, + self.start_btn, + ], + ) + container.layout.addWidget(self.data_panel) + + ui.ScrollArea.make_scrollable( + container.layout, self, max_wh=[MAX_W, MAX_H] + ) + self._set_io_visibility() + container.setSizePolicy( + QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding + ) + return container + + def _start(self): + utils.mkdir_from_str(self.results_path) + if self.layer_choice.isChecked(): + if self.label_layer_loader.layer_data() is not None: + layer = self.label_layer_loader.layer() + + data = np.array(layer.data) + stats = volume_stats(data) + if stats is None: + logger.warning( + "No stats to save, please ensure your label array is not empty" + ) + return + + stats_df = pd.DataFrame(stats.get_dict()) + csv_name = self.csv_name.text() + ".csv" + stats_df.to_csv( + self.results_path + "/" + csv_name, index=False + ) + elif ( + self.folder_choice.isChecked() and len(self.labels_filepaths) != 0 + ): + images = [imread(file) for file in self.labels_filepaths] + for i, image in enumerate(images): + if image.sum() == 0: + m = f"Image {i} is empty, skipping." + logger.warning(m) + warn(m, stacklevel=0) + continue + if not np.issubdtype(image.dtype, np.integer): + m = f"Image {i} is not integer, skipping. Make sure your labels are saved as integer values" + logger.warning(m) + warn(m, stacklevel=0) + continue + stats_df = pd.DataFrame(stats.get_dict()) + csv_name = self.csv_name.text() + f"_{i}.csv" + stats_df.to_csv( + self.results_path + "/" + csv_name, index=False + ) + else: + logger.warning("Please specify a layer or a folder") diff --git a/napari_cellseg3d/code_plugins/plugin_crf.py b/napari_cellseg3d/code_plugins/plugin_crf.py index 64503e10..424a6fd5 100644 --- a/napari_cellseg3d/code_plugins/plugin_crf.py +++ b/napari_cellseg3d/code_plugins/plugin_crf.py @@ -1,3 +1,4 @@ +"""CRF plugin for napari_cellseg3d.""" import contextlib from functools import partial from pathlib import Path @@ -19,9 +20,10 @@ # TODO add CRF on folder class CRFParamsWidget(ui.GroupedWidget): - """Use this widget when adding the crf as part of another widget (rather than a standalone widget)""" + """Use this widget when adding the crf as part of another widget (rather than a standalone widget).""" def __init__(self, parent=None): + """Create a widget to set CRF parameters.""" super().__init__(title="CRF parameters", parent=parent) ####### # CRF params # @@ -57,7 +59,7 @@ def _build(self): ), ], ) - self.set_layout() + self._set_layout() return ui.add_widgets( self.layout, @@ -76,7 +78,7 @@ def _build(self): self.n_iter_choice, ], ) - self.set_layout() + self._set_layout() def _set_tooltips(self): self.sa_choice.setToolTip( @@ -97,6 +99,7 @@ def _set_tooltips(self): self.n_iter_choice.setToolTip("Number of iterations of the CRF.") def make_config(self): + """Make a CRF config from the widget values.""" return config.CRFConfig( sa=self.sa_choice.value(), sb=self.sb_choice.value(), @@ -108,13 +111,13 @@ def make_config(self): class CRFWidget(BasePluginUtils): - """Widget to run CRF post-processing""" + """Widget to run CRF post-processing.""" save_path = Path.home() / "cellseg3d" / "crf" def __init__(self, viewer, parent=None): - """ - Create a widget for CRF post-processing. + """Create a widget for CRF post-processing. + Args: viewer: napari viewer to display the widget parent: parent widget. Defaults to None. @@ -185,9 +188,11 @@ def _build(self): return self._container def make_config(self): + """Make a CRF config from the widget values.""" return self.crf_params_widget.make_config() def print_config(self): + """Print the CRF config to the logger.""" logger.info("CRF config:") for item in self.make_config().__dict__.items(): logger.info(f"{item[0]}: {item[1]}") @@ -216,6 +221,7 @@ def _check_ready(self): return True def run_crf_on_batch(self, images_list: list, labels_list: list, log=None): + """Run CRF on a batch of images and labels.""" self.crf_results = [] for image, label in zip(images_list, labels_list): tqdm( @@ -229,6 +235,7 @@ def run_crf_on_batch(self, images_list: list, labels_list: list, log=None): return self.crf_results def _prepare_worker(self, images_list: list, labels_list: list): + """Prepare the CRF worker.""" self.worker = CRFWorker( images_list=images_list, labels_list=labels_list, diff --git a/napari_cellseg3d/code_plugins/plugin_crop.py b/napari_cellseg3d/code_plugins/plugin_crop.py index c4889249..e8bad56d 100644 --- a/napari_cellseg3d/code_plugins/plugin_crop.py +++ b/napari_cellseg3d/code_plugins/plugin_crop.py @@ -1,3 +1,4 @@ +"""Crop utility plugin for napari_cellseg3d.""" from math import floor from pathlib import Path @@ -26,7 +27,7 @@ class Cropping( utils_default_paths = [] def __init__(self, viewer: "napari.viewer.Viewer", parent=None): - """Creates a Cropping plugin with several buttons : + """Creates a Cropping plugin with several buttons. * Open file prompt to select volumes directory @@ -40,7 +41,6 @@ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): * A button to close the widget """ - super().__init__(viewer) if parent is not None: @@ -58,7 +58,7 @@ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): # ) self.image_layer_loader.layer_list.currentIndexChanged.connect( - self.auto_set_dims + self._auto_set_dims ) # ui.LayerSelecter(self._viewer, "Image 1") # self.layer_selection2 = ui.LayerSelecter(self._viewer, "Image 2") @@ -125,7 +125,7 @@ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): self._build() self._toggle_second_image_io_visibility() self._check_image_list() - self.auto_set_dims() + self._auto_set_dims() def _toggle_second_image_io_visibility(self): crop_2nd = self.crop_second_image_choice.isChecked() @@ -146,7 +146,7 @@ def _check_image_list(self): except IndexError: return - def auto_set_dims(self): + def _auto_set_dims(self): logger.debug(self.image_layer_loader.layer_name()) data = self.image_layer_loader.layer_data() if data is not None: @@ -159,8 +159,7 @@ def auto_set_dims(self): box.setValue(floor(data.shape[i] / 2)) def _build(self): - """Build buttons in a layout and add them to the napari Viewer""" - + """Build buttons in a layout and add them to the napari Viewer.""" container = ui.ContainerWidget(0, 0, 1, 11) layout = container.layout @@ -237,7 +236,6 @@ def quicksave(self): * If labels are present, saves the cropped version as a single file or 2D stacks folder depending on what was loaded. """ - viewer = self._viewer self._check_results_path(str(self.results_path)) @@ -270,9 +268,7 @@ def _check_ready(self): return False def _start(self): - """Launches cropping process by loading the files from the chosen folders, - and adds control widgets to the napari Viewer for moving the cropped volume. - """ + """Launches cropping process by loading the files from the chosen folders, and adds control widgets to the napari Viewer for moving the cropped volume.""" if not self._check_ready(): logger.warning("Please select at least one valid layer !") return @@ -324,10 +320,10 @@ def _start(self): layer.visible = False # hide other layers, because of anisotropy - self.image_layer1 = self.add_isotropic_layer(self.image_layer1) + self.image_layer1 = self._add_isotropic_layer(self.image_layer1) if self.crop_second_image: - self.image_layer2 = self.add_isotropic_layer( + self.image_layer2 = self._add_isotropic_layer( self.image_layer2, visible=False ) else: @@ -355,7 +351,7 @@ def save_widget(): self._add_crop_sliders() - def add_isotropic_layer( + def _add_isotropic_layer( self, layer, colormap="inferno", @@ -503,7 +499,7 @@ def set_slice( labels_crop_layer=None, crop_lbls=False, ): - """ "Update cropped volume position""" + """Update cropped volume position.""" # self._check_for_empty_layer(highres_crop_layer, highres_crop_layer.data) # logger.debug(f"axis : {axis}") @@ -539,6 +535,7 @@ def set_slice( i : i + cropx, j : j + cropy, k : k + cropz ] highres_crop_layer.translate = scale * izyx + highres_crop_layer.reset_contrast_limits() highres_crop_layer.refresh() # self._check_for_empty_layer( @@ -550,6 +547,7 @@ def set_slice( i : i + cropx, j : j + cropy, k : k + cropz ] labels_crop_layer.translate = scale * izyx + highres_crop_layer.reset_contrast_limits() labels_crop_layer.refresh() self._x = i diff --git a/napari_cellseg3d/code_plugins/plugin_helper.py b/napari_cellseg3d/code_plugins/plugin_helper.py index 552f70ea..f787f3c4 100644 --- a/napari_cellseg3d/code_plugins/plugin_helper.py +++ b/napari_cellseg3d/code_plugins/plugin_helper.py @@ -1,3 +1,4 @@ +"""Tiny plugin showing link to documentation and about page.""" import pathlib from typing import TYPE_CHECKING @@ -14,7 +15,10 @@ class Helper(QWidget, metaclass=ui.QWidgetSingleton): + """Tiny plugin showing link to documentation and about page.""" + def __init__(self, viewer: "napari.viewer.Viewer"): + """Creates a widget with links to documentation and about page.""" super().__init__() self.help_url = "https://adaptivemotorcontrollab.github.io/CellSeg3d/" diff --git a/napari_cellseg3d/code_plugins/plugin_metrics.py b/napari_cellseg3d/code_plugins/plugin_metrics.py index b0aa3df8..ae58314e 100644 --- a/napari_cellseg3d/code_plugins/plugin_metrics.py +++ b/napari_cellseg3d/code_plugins/plugin_metrics.py @@ -1,3 +1,4 @@ +"""CURRENTLY UNUSED.""" from typing import TYPE_CHECKING import matplotlib.pyplot as plt @@ -21,13 +22,14 @@ class MetricsUtils(BasePluginFolder): - """Plugin to evaluate metrics between two sets of labels, ground truth and prediction""" + """Plugin to evaluate metrics between two sets of labels, ground truth and prediction.""" def __init__(self, viewer: "napari.viewer.Viewer", parent=None): """Creates a MetricsUtils widget for computing and plotting dice metrics between labels. + Args: viewer: viewer to display the widget in - parent : parent widget + parent : parent widget. """ super().__init__(viewer, parent, has_results=False) @@ -76,7 +78,6 @@ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): def _build(self): """Builds the layout of the widget.""" - # self.filetype_choice.label.setVisible(False) w = ui.ContainerWidget() @@ -132,7 +133,7 @@ def _build(self): ui.ScrollArea.make_scrollable(self.layout, self) def plot_dice(self, dice_coeffs, threshold=DEFAULT_THRESHOLD): - """Plots the dice loss for each pair of labels on viewer""" + """Plots the dice loss for each pair of labels on viewer.""" self.btn_reset_plot.setVisible(True) colors = [] @@ -171,7 +172,7 @@ def plot_dice(self, dice_coeffs, threshold=DEFAULT_THRESHOLD): self.canvas.draw_idle() def remove_plots(self): - """Clears plots from window view""" + """Clears plots from window view.""" if len(self.plots) != 0: for p in self.plots: p.setVisible(False) @@ -180,7 +181,9 @@ def remove_plots(self): def compute_dice(self): """Computes the dice metric between pairs of labels. - Rotates the prediction label to find matching orientation as well.""" + + Rotates the prediction label to find matching orientation as well. + """ # u = 0 # t = 0 diff --git a/napari_cellseg3d/code_plugins/plugin_model_inference.py b/napari_cellseg3d/code_plugins/plugin_model_inference.py index cc3e6ede..49a365e6 100644 --- a/napari_cellseg3d/code_plugins/plugin_model_inference.py +++ b/napari_cellseg3d/code_plugins/plugin_model_inference.py @@ -1,3 +1,4 @@ +"""Inference plugin for napari_cellseg3d.""" from functools import partial from typing import TYPE_CHECKING @@ -23,12 +24,10 @@ class Inferer(ModelFramework, metaclass=ui.QWidgetSingleton): - """A plugin to run already trained models in evaluation mode to preform inference and output a label on all - given volumes.""" + """A plugin to run already trained models in evaluation mode to preform inference and output a label on all given volumes.""" def __init__(self, viewer: "napari.viewer.Viewer", parent=None): - """ - Creates an Inference loader plugin with the following widgets : + """Creates an Inference loader plugin with the following widgets. * Data : * A file extension choice for the images to load from selected folders @@ -61,6 +60,7 @@ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): Args: viewer (napari.viewer.Viewer): napari viewer to display the widget in + parent (QWidget, optional): Defaults to None. """ super().__init__( viewer, @@ -287,8 +287,7 @@ def _set_tooltips(self): ################## def check_ready(self): - """Checks if the paths to the files are properly set""" - + """Checks if the paths to the files are properly set.""" if self.layer_choice.isChecked(): if self.image_layer_loader.layer_data() is not None: return True @@ -300,14 +299,18 @@ def check_ready(self): return False def _restrict_window_size_for_model(self): - """Sets the window size to a value that is compatible with the chosen model""" + """Sets the window size to a value that is compatible with the chosen model.""" self.wnet_enabled = False if self.model_choice.currentText() == "WNet": - self.window_size_choice.setCurrentIndex(self._default_window_size) self.wnet_enabled = True + self.window_size_choice.setCurrentIndex(self._default_window_size) self.window_infer_box.setChecked(self.wnet_enabled) - self.window_size_choice.setDisabled(self.wnet_enabled) - self.window_infer_box.setDisabled(self.wnet_enabled) + self.window_size_choice.setDisabled( + self.wnet_enabled and not self.custom_weights_choice.isChecked() + ) + self.window_infer_box.setDisabled( + self.wnet_enabled and not self.custom_weights_choice.isChecked() + ) def _toggle_display_model_input_size(self): if ( @@ -321,30 +324,29 @@ def _toggle_display_model_input_size(self): self.model_input_size.label.setVisible(False) def _toggle_display_number(self): - """Shows the choices for viewing results depending on whether :py:attr:`self.view_checkbox` is checked""" + """Shows the choices for viewing results depending on whether :py:attr:`self.view_checkbox` is checked.""" ui.toggle_visibility(self.view_checkbox, self.view_results_container) def _toggle_display_thresh(self): - """Shows the choices for thresholding results depending on whether :py:attr:`self.thresholding_checkbox` is checked""" + """Shows the choices for thresholding results depending on whether :py:attr:`self.thresholding_checkbox` is checked.""" ui.toggle_visibility( self.thresholding_checkbox, self.thresholding_slider.container ) def _toggle_display_crf(self): - """Shows the choices for CRF post-processing depending on whether :py:attr:`self.use_crf` is checked""" + """Shows the choices for CRF post-processing depending on whether :py:attr:`self.use_crf` is checked.""" ui.toggle_visibility(self.use_crf, self.crf_widgets) def _toggle_display_instance(self): - """Shows or hides the options for instance segmentation based on current user selection""" + """Shows or hides the options for instance segmentation based on current user selection.""" ui.toggle_visibility(self.use_instance_choice, self.instance_widgets) def _toggle_display_window_size(self): - """Show or hide window size choice depending on status of self.window_infer_box""" + """Show or hide window size choice depending on status of self.window_infer_box.""" ui.toggle_visibility(self.window_infer_box, self.window_infer_params) def _load_weights_path(self): - """Show file dialog to set :py:attr:`model_path`""" - + """Show file dialog to set :py:attr:`model_path`.""" # logger.debug(self._default_weights_folder) file = ui.open_file_dialog( @@ -355,8 +357,7 @@ def _load_weights_path(self): self._update_weights_path(file) def _build(self): - """Puts all widgets in a layout and adds them to the napari Viewer""" - + """Puts all widgets in a layout and adds them to the napari Viewer.""" # ui.add_blank(self.view_results_container, view_results_layout) ui.add_widgets( self.view_results_container.layout, @@ -555,7 +556,7 @@ def _display_results(self, result: InferenceResult): image_id = result.image_id model_name = self.model_choice.currentText() - viewer.dims.ndisplay = 3 + # viewer.dims.ndisplay = 3 # let user choose viewer.scale_bar.visible = True if self.config.show_original and result.original is not None: @@ -584,12 +585,18 @@ def _display_results(self, result: InferenceResult): fractions_per_channel = utils.channels_fraction_above_threshold( result.result, 0.5 ) - index_channel_least_labelled = np.argmin(fractions_per_channel) + index_channel_sorted = np.argsort(fractions_per_channel) + for channel in index_channel_sorted: + if result.result[channel].sum() > 0: + index_channel_least_labelled = channel + break viewer.dims.set_point( 0, index_channel_least_labelled ) # TODO(cyril: check if this is always the right axis - if result.crf_results is not None: + if result.crf_results is not None and not isinstance( + result.crf_results, Exception + ): logger.debug(f"CRF results shape : {result.crf_results.shape}") viewer.add_image( result.crf_results, @@ -598,15 +605,41 @@ def _display_results(self, result: InferenceResult): ) if ( result.instance_labels is not None + and not isinstance(result.instance_labels, Exception) and self.worker_config.post_process_config.instance.enabled ): method_name = ( self.worker_config.post_process_config.instance.method.name ) - number_cells = ( - np.unique(result.instance_labels.flatten()).size - 1 - ) # remove background + if len(result.instance_labels.shape) >= 4: + channels_by_labels = np.argsort( + result.instance_labels.sum(axis=(1, 2, 3)) + ) + min_objs_channel = channels_by_labels[0] + # if least labeled is empty, use next least labeled channel + for i in range(1, len(channels_by_labels)): + if ( + np.unique( + result.instance_labels[ + channels_by_labels[i] + ].flatten() + ).size + > 1 + ): + min_objs_channel = channels_by_labels[i] + break + + number_cells = ( + np.unique( + result.instance_labels[min_objs_channel].flatten() + ).size + - 1 + ) + else: + number_cells = ( + np.unique(result.instance_labels.flatten()).size - 1 + ) # remove background with -1 name = f"({number_cells} objects)_{method_name}_instance_labels_{image_id}" @@ -615,28 +648,32 @@ def _display_results(self, result: InferenceResult): if result.stats is not None and isinstance( result.stats, list ): # list for several channels - # logger.debug(f"len stats : {len(result.stats)}") + logger.debug(f"len stats : {len(result.stats)}") for i, stats in enumerate(result.stats): # stats = result.stats if self.worker_config.compute_stats and stats is not None: - stats_dict = stats.get_dict() - stats_df = pd.DataFrame(stats_dict) - - self.log.print_and_log( - f"Number of instances in channel {i} : {stats.number_objects[0]}" - ) - - csv_name = f"/{method_name}_seg_results_{image_id}_channel_{i}_{utils.get_date_time()}.csv" - stats_df.to_csv( - self.worker_config.results_path + csv_name, - index=False, - ) - - # self.log.print_and_log( - # f"OBJECTS DETECTED : {number_cells}\n" - # ) + try: + stats_dict = stats.get_dict() + stats_df = pd.DataFrame(stats_dict) + + self.log.print_and_log( + f"Number of instances in channel {i} : {stats.number_objects[0]}" + ) + + csv_name = f"/{model_name}_{method_name}_seg_results_{image_id}_channel_{i}_{utils.get_date_time()}.csv" + + stats_df.to_csv( + self.worker_config.results_path + csv_name, + index=False, + ) + except ValueError as e: + logger.warning(f"Error saving stats to csv : {e}") + logger.debug( + f"Length of stats array : {[len(s) for s in stats.get_dict().values()]}" + ) + # logger.debug(f"Stats dict : {stats.get_dict()}") def _setup_worker(self): if self.folder_choice.isChecked(): @@ -658,7 +695,7 @@ def _setup_worker(self): self.worker.warn_signal.connect(self.log.warn) self.worker.error_signal.connect(self.log.error) - self.worker.yielded.connect(partial(self.on_yield)) # + self.worker.yielded.connect(partial(self.on_yield)) self.worker.errored.connect(partial(self.on_error)) self.worker.finished.connect(self.on_finish) @@ -667,7 +704,7 @@ def _setup_worker(self): return self.worker def start(self): - """Start the inference process, enables :py:attr:`~self.worker` and does the following: + """Start the inference process, enables :py:attr:`~self.worker` and does the following. * Checks if the output and input folders are correctly set @@ -684,11 +721,7 @@ def start(self): * If the option has been selected, display the results in napari, up to the maximum number selected * Runs instance segmentation, thresholding, and stats computing if requested - - Args: - on_layer: if True, will start inference on a selected layer """ - if not self.check_ready(): err = "Aborting, please choose valid inputs" self.log.print_and_log(err) @@ -745,7 +778,7 @@ def _set_worker_config(self) -> config.InferenceWorkerConfig: model_input_size=self.model_input_size.value(), ) - self.weights_config.custom = self.custom_weights_choice.isChecked() + self.weights_config.use_custom = self.custom_weights_choice.isChecked() save_path = self.results_filewidget.text_field.text() if not self._check_results_path(save_path): @@ -771,6 +804,7 @@ def _set_worker_config(self) -> config.InferenceWorkerConfig: self.instance_widgets.method_choice.currentText() ], ) + self.instance_config.method.record_parameters() # keep parameters set when Start is clicked self.post_process_config = config.PostProcessConfig( zoom=zoom_config, @@ -803,7 +837,7 @@ def _set_worker_config(self) -> config.InferenceWorkerConfig: return self.worker_config def on_start(self): - """Catches start signal from worker to call :py:func:`~display_status_report`""" + """Catches start signal from worker to call :py:func:`~display_status_report`.""" self.display_status_report() self._set_self_config() self.log.print_and_log(f"Worker started at {utils.get_time()}") @@ -831,15 +865,13 @@ def on_finish(self): return True # signal clean exit def on_yield(self, result: InferenceResult): - """ - Displays the inference results in napari as long as data["image_id"] is lower than nbr_to_show, - and updates the status report docked widget (namely the progress bar) + """Displays the inference results in napari. + + Works as long as data["image_id"] is lower than nbr_to_show, and updates the status report docked widget (namely the progress bar). Args: - data (dict): dict yielded by :py:func:`~inference()`, contains : "image_id" : index of the returned image, "original" : original volume used for inference, "result" : inference result - widget (QWidget): widget for accessing attributes + result (InferenceResult): results from the worker """ - if isinstance(result, Exception): self.on_error(result) # raise result diff --git a/napari_cellseg3d/code_plugins/plugin_model_training.py b/napari_cellseg3d/code_plugins/plugin_model_training.py index 766c2c89..5d727956 100644 --- a/napari_cellseg3d/code_plugins/plugin_model_training.py +++ b/napari_cellseg3d/code_plugins/plugin_model_training.py @@ -1,3 +1,5 @@ +"""Training plugin for napari_cellseg3d.""" + import shutil import warnings from functools import partial @@ -36,8 +38,10 @@ class Trainer(ModelFramework, metaclass=ui.QWidgetSingleton): """A plugin to train pre-defined PyTorch models for one-channel segmentation directly in napari. + Features parameter selection for training, dynamic loss plotting and automatic saving of the best weights during - training through validation.""" + training through validation. + """ default_config = config.SupervisedTrainingWorkerConfig() @@ -45,7 +49,7 @@ def __init__( self, viewer: "napari.viewer.Viewer", ): - """Creates a Trainer tab widget with the following functionalities : + """Creates a Trainer tab widget with the following functionalities. * First tab : Dataset parameters * A choice for the file extension of images to be loaded @@ -104,7 +108,6 @@ def __init__( val_interval (uint) : epoch interval for validation """ - super().__init__(viewer) # self.master = parent @@ -183,10 +186,10 @@ def __init__( ########### self.zip_choice = ui.CheckBox("Compress results") - self.validation_percent_choice = ui.Slider( + self.train_split_percent_choice = ui.Slider( lower=10, upper=90, - default=self.default_config.validation_percent * 100, + default=self.default_config.training_percent * 100, step=5, parent=self, ) @@ -328,7 +331,7 @@ def _set_tooltips(self): self.zip_choice.setToolTip( "Save a copy of the results as a zip folder" ) - self.validation_percent_choice.tooltips = "The percentage of images to retain for training.\nThe remaining images will be used for validation" + self.train_split_percent_choice.tooltips = "The percentage of images to retain for training.\nThe remaining images will be used for validation" self.epoch_choice.tooltips = "The number of epochs to train for.\nThe more you train, the better the model will fit the training data" self.loss_choice.setToolTip( "The loss function to use for training.\nSee the list in the training guide for more info" @@ -424,11 +427,9 @@ def _toggle_deterministic_param(self): self.container_seed.setVisible(False) def check_ready(self): - """ - Checks that the paths to the images and labels are correctly set + """Checks that the paths to the images and labels are correctly set. Returns: - * True if paths are set correctly * False and displays a warning if not @@ -449,7 +450,7 @@ def check_ready(self): return True def _toggle_unsupervised_mode(self, enabled=False): - """Change all the UI elements needed for unsupervised learning mode""" + """Change all the UI elements needed for unsupervised learning mode.""" if self.model_choice.currentText() == "WNet" or enabled: unsupervised = True self.start_btn = self.start_button_unsupervised @@ -494,7 +495,7 @@ def _toggle_unsupervised_mode(self, enabled=False): self._check_all_filepaths() def _build(self): - """Builds the layout of the widget and creates the following tabs and prompts: + """Builds the layout of the widget and creates the following tabs and prompts. * Model parameters : @@ -526,8 +527,8 @@ def _build(self): * Previous tab - * Start (see :py:func:`~start`)""" - + * Start (see :py:func:`~start`) + """ # for w in self.children(): # w.setToolTip(f"{w}") @@ -681,8 +682,8 @@ def _build(self): ui.add_blank(data_tab_w, data_tab_l) ####################### self.validation_group = ui.GroupedWidget.create_single_widget_group( - "Validation (%)", - self.validation_percent_choice.container, + "Training split (%)", + self.train_split_percent_choice.container, data_tab_l, ) ####################### @@ -919,12 +920,11 @@ def _build(self): self.results_path = default_results_path def send_log(self, text): - """Sends a message via the Log attribute""" + """Sends a message via the Log attribute.""" self.log.print_and_log(text) def start(self): - """ - Initiates the :py:func:`train` function as a worker and does the following : + """Initiates the :py:func:`train` function as a worker and does the following. * Checks that filepaths are set correctly using :py:func:`check_ready` @@ -936,8 +936,7 @@ def start(self): * When the worker finishes, clears the memory (tries to for now) - TODO: - + Todo: * Fix memory allocation from torch @@ -948,6 +947,8 @@ def start(self): if self._stop_requested: self.log.print_and_log("Worker is already stopping !") + if self.worker is None: + self._stop_requested = False return if not self.check_ready(): # issues a warning if not ready @@ -1042,9 +1043,10 @@ def _set_worker_config( self, additional_description=None, ) -> config.TrainingWorkerConfig: - """Creates a worker config for supervised or unsupervised training + """Creates a worker config for supervised or unsupervised training. + Args: - additional_description: Additional description to add to the results folder name + additional_description: Additional description to add to the results folder name. Returns: A worker config @@ -1053,11 +1055,14 @@ def _set_worker_config( model_config = config.ModelInfo(name=self.model_choice.currentText()) self.weights_config.path = self.weights_config.path - self.weights_config.custom = self.custom_weights_choice.isChecked() + self.weights_config.use_custom = self.custom_weights_choice.isChecked() + self.weights_config.use_pretrained = ( self.use_transfer_choice.isChecked() and not self.custom_weights_choice.isChecked() ) + self.weights_config.use_custom = self.custom_weights_choice.isChecked() + deterministic_config = config.DeterministicConfig( enabled=self.use_deterministic_choice.isChecked(), seed=self.box_seed.value(), @@ -1113,23 +1118,24 @@ def _set_supervised_worker_config( patch_size, deterministic_config, ): - """Sets the worker config for supervised training + """Sets the worker config for supervised training. + Args: model_config: Model config results_path_folder: Path to results folder patch_size: Patch size - deterministic_config: Deterministic config + deterministic_config: Deterministic config. Returns: A worker config """ - validation_percent = self.validation_percent_choice.slider_value / 100 + validation_percent = self.train_split_percent_choice.slider_value / 100 self.worker_config = config.SupervisedTrainingWorkerConfig( device=self.check_device_choice(), model_info=model_config, weights_info=self.weights_config, train_data_dict=self.data, - validation_percent=validation_percent, + training_percent=validation_percent, max_epochs=self.epoch_choice.value(), loss_function=self.loss_choice.currentText(), learning_rate=self.learning_rate_choice.get_learning_rate(), @@ -1154,12 +1160,13 @@ def _set_unsupervised_worker_config( deterministic_config, eval_volume_dict, ) -> config.WNetTrainingWorkerConfig: - """Sets the worker config for unsupervised training + """Sets the worker config for unsupervised training. + Args: results_path_folder: Path to results folder patch_size: Patch size deterministic_config: Deterministic config - eval_volume_dict: Evaluation volume dictionary + eval_volume_dict: Evaluation volume dictionary. Returns: A worker config @@ -1205,8 +1212,7 @@ def _is_current_job_supervised( return True def on_start(self): - """Catches started signal from worker""" - + """Catches started signal from worker.""" self.remove_docked_widgets() self.display_status_report() self.log.clear() @@ -1216,7 +1222,7 @@ def on_start(self): self.log.print_and_log("\nWorker is running...") def on_finish(self): - """Catches finished signal from worker""" + """Catches finished signal from worker.""" self.log.print_and_log("*" * 20) self.log.print_and_log(f"\nWorker finished at {utils.get_time()}") @@ -1256,11 +1262,12 @@ def on_finish(self): self.worker = None def on_error(self): - """Catches errored signal from worker""" + """Catches errored signal from worker.""" self.log.print_and_log(f"WORKER ERRORED at {utils.get_time()}") self.worker = None def on_stop(self): + """Catches stop signal from worker.""" self._remove_result_layers() self.worker = None self._stop_requested = False @@ -1269,11 +1276,15 @@ def on_stop(self): def _remove_result_layers(self): for layer in self.result_layers: - self._viewer.layers.remove(layer) + try: + self._viewer.layers.remove(layer) + except ValueError: + logger.debug("Layer already removed ?") + pass self.result_layers = [] def _display_results(self, images_dict, complete_missing=False): - """Show various model input/outputs in napari viewer as a list of layers""" + """Show various model input/outputs in napari viewer as a list of layers.""" layer_list = [] if not complete_missing: for layer_name in list(images_dict.keys()): @@ -1309,6 +1320,7 @@ def _display_results(self, images_dict, complete_missing=False): self.result_layers[i].reset_contrast_limits() def on_yield(self, report: TrainingReport): + """Catches yielded signal from worker and plots the loss.""" if report == TrainingReport(): return # skip empty reports @@ -1433,7 +1445,7 @@ def _plot_loss( loss_values_2: list, show_plot_2_max: bool = True, ): - """Creates two subplots to plot the training loss and validation metric""" + """Creates two subplots to plot the training loss and validation metric.""" plot_key = ( "supervised" if self._is_current_job_supervised() @@ -1465,11 +1477,11 @@ def _plot_loss( # update plot 2 if self._is_current_job_supervised(): x = [ - self.worker_config.validation_interval * (i + 1) + int(self.worker_config.validation_interval * (i + 1)) for i in range(len(loss_values_2)) ] else: - x = [i + 1 for i in range(len(loss_values_2))] + x = [int(i + 1) for i in range(len(loss_values_2))] y = loss_values_2 self.plot_2.plot(x, y, zorder=1) @@ -1484,15 +1496,14 @@ def _plot_loss( self.canvas.draw_idle() def update_loss_plot(self, loss_1: dict, loss_2: list): - """ - Updates the plots on subsequent validation steps. + """Updates the plots on subsequent validation steps. + Creates the plot on the second validation step (epoch == val_interval*2). Updates the plot on subsequent validation steps. Epoch is obtained from the length of the loss vector. Returns: returns empty if the epoch is < than 2 * validation interval. """ - epoch = len(loss_1[list(loss_1.keys())[0]]) logger.debug(f"Updating loss plot for epoch {epoch}") plot_max = self._is_current_job_supervised() @@ -1554,7 +1565,10 @@ def _reset_loss_plot(self): class LearningRateWidget(ui.ContainerWidget): + """A widget to choose the learning rate.""" + def __init__(self, parent=None): + """Creates a widget to choose the learning rate.""" super().__init__(vertical=False, parent=parent) self.lr_exponent_dict = { @@ -1596,6 +1610,7 @@ def _build(self): ) def get_learning_rate(self) -> float: + """Return the learning rate as a float.""" return float( self.lr_value_choice.value() * self.lr_exponent_dict[self.lr_exponent_choice.currentText()] @@ -1603,11 +1618,12 @@ def get_learning_rate(self) -> float: class WNetWidgets: - """A collection of widgets for the WNet training GUI""" + """A collection of widgets for the WNet training GUI.""" default_config = config.WNetTrainingWorkerConfig() def __init__(self, parent): + """Creates a collection of widgets for the WNet training GUI.""" self.num_classes_choice = ui.DropdownMenu( entries=["2", "3", "4"], parent=parent, @@ -1689,6 +1705,7 @@ def _set_tooltips(self): ) def get_reconstruction_weight(self): + """Returns the reconstruction weight as a float.""" return float( self.reconstruction_weight_choice.value() / self.reconstruction_weight_divide_factor_choice.value() diff --git a/napari_cellseg3d/code_plugins/plugin_review.py b/napari_cellseg3d/code_plugins/plugin_review.py index 712b3193..cbdd3dd0 100644 --- a/napari_cellseg3d/code_plugins/plugin_review.py +++ b/napari_cellseg3d/code_plugins/plugin_review.py @@ -1,3 +1,4 @@ +"""Review plugin for 3D labeling of volumes.""" from pathlib import Path import matplotlib.pyplot as plt @@ -24,10 +25,12 @@ class Reviewer(BasePluginSingleImage, metaclass=ui.QWidgetSingleton): """A plugin for selecting volumes and labels file and launching the review process. - Inherits from : :doc:`plugin_base`""" + + Inherits from : :doc:`plugin_base`. + """ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): - """Creates a Reviewer plugin with several buttons : + """Creates a Reviewer plugin with several buttons. * Open file prompt to select volumes directory @@ -39,7 +42,6 @@ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): * A button to launch the review process """ - super().__init__( viewer, parent, @@ -95,13 +97,12 @@ def __init__(self, viewer: "napari.viewer.Viewer", parent=None): print(f"{self}") def _update_results_path(self): - p = self.image_filewidget.text_field.text() + p = self.labels_filewidget.text_field.text() if p is not None and Path(p).is_file(): self.results_filewidget.text_field.setText(str(Path(p).parent)) def _build(self): - """Build buttons in a layout and add them to the napari Viewer""" - + """Build buttons in a layout and add them to the napari Viewer.""" self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.MinimumExpanding) tab = ui.ContainerWidget(0, 0, 1, 1) @@ -168,8 +169,7 @@ def _build(self): self.results_path = self.results_filewidget.text_field.text() def check_image_data(self): - """Checks that images are present and that sizes match""" - + """Checks that images are present and that sizes match.""" cfg = self.config if cfg.image is None: @@ -195,8 +195,8 @@ def _prepare_data(self): self.check_image_data() self._check_results_path(self.results_filewidget.text_field.text()) - self.config.csv_path = self.results_filewidget.text_field.text() self.config.model_name = self.csv_textbox.text() + self.config.csv_path = self.results_filewidget.text_field.text() self.config.new_csv = self.new_csv_choice.isChecked() self.config.filetype = self.filetype @@ -208,13 +208,12 @@ def _prepare_data(self): self.config.zoom_factor = zoom def run_review(self): - """Launches review process by loading the files from the chosen folders, - and adds several widgets to the napari Viewer. + """Launches review process by loading the files from the chosen folders, and adds several widgets to the napari Viewer. + If the review process has been launched once before, closes the window entirely and launches the review process in a fresh window. - TODO: - + Todo: * Save work done before leaving See launch_review @@ -222,7 +221,6 @@ def run_review(self): Returns: napari.viewer.Viewer: self.viewer """ - print("New review session\n" + "*" * 20) previous_viewer = self._viewer try: @@ -240,8 +238,7 @@ def _reset(self): self.remove_docked_widgets() def launch_review(self): - """Launch the review process, loading the original image, the labels & the raw labels (from prediction) - in the viewer. + """Launch the review process, loading the original image, the labels & the raw labels (from prediction) in the viewer. Adds several widgets to the viewer : @@ -329,19 +326,19 @@ def quicksave(): "Shift-click on image for plot \n", fontsize=8 ) xy_axes.imshow(np.zeros((100, 100), np.int16)) - xy_axes.scatter(50, 50, s=10, c="green", alpha=0.25) - xy_axes.set_xlabel("x axis") - xy_axes.set_ylabel("y axis") + xy_axes.scatter(50, 50, s=30, c="green", alpha=0.6, marker="+") + xy_axes.set_xlabel("X axis") + xy_axes.set_ylabel("Y axis") yz_axes = canvas.figure.add_subplot(3, 1, 2) yz_axes.imshow(np.zeros((100, 100), np.int16)) - yz_axes.scatter(50, 50, s=10, c="green", alpha=0.25) - yz_axes.set_xlabel("y axis") - yz_axes.set_ylabel("z axis") + yz_axes.scatter(50, 50, s=30, c="green", alpha=0.6, marker="+") + yz_axes.set_xlabel("Y axis") + yz_axes.set_ylabel("Z axis") zx_axes = canvas.figure.add_subplot(3, 1, 3) zx_axes.imshow(np.zeros((100, 100), np.int16)) - zx_axes.scatter(50, 50, s=10, c="green", alpha=0.25) - zx_axes.set_xlabel("x axis") - zx_axes.set_ylabel("z axis") + zx_axes.scatter(50, 50, s=30, c="green", alpha=0.6, marker="+") + zx_axes.set_xlabel("X axis") + zx_axes.set_ylabel("Z axis") # canvas.figure.tight_layout() canvas.figure.subplots_adjust( @@ -419,6 +416,13 @@ def update_button(axis_event): viewer.dims.events.current_step.connect(update_button) def crop_volume_around_point(points, layer, zoom_factor): + """Crops a volume around a point. + + Args: + points (list): list of 3 integers, the coordinates of the point to crop around + layer (napari.layers.Image): the layer to crop + zoom_factor (list): list of 3 floats, the zoom factor to apply to the layer before cropping + """ if zoom_factor != [1, 1, 1]: data = np.array(layer.data, dtype=np.int16) volume = utils.resize(data, zoom_factor) diff --git a/napari_cellseg3d/code_plugins/plugin_review_dock.py b/napari_cellseg3d/code_plugins/plugin_review_dock.py index f634d117..e485b0a5 100644 --- a/napari_cellseg3d/code_plugins/plugin_review_dock.py +++ b/napari_cellseg3d/code_plugins/plugin_review_dock.py @@ -1,3 +1,4 @@ +"""Widget opened when a new Review session is started.""" from datetime import datetime, timedelta from pathlib import Path from typing import TYPE_CHECKING @@ -27,10 +28,7 @@ class Datamanager(QWidget): - """A widget with a single checkbox that allows to store the status of - a slice in csv file (checked/not checked) - - """ + """A widget with a single checkbox that allows to store the status of a slice in csv file (checked/not checked).""" def __init__(self, parent: "napari.viewer.Viewer"): """Creates the datamanager widget in the specified viewer window. @@ -38,7 +36,6 @@ def __init__(self, parent: "napari.viewer.Viewer"): Args: parent (napari.viewer.Viewer): napari Viewer for the widget to be displayed in """ - super().__init__() layout = QVBoxLayout() @@ -46,7 +43,9 @@ def __init__(self, parent: "napari.viewer.Viewer"): """napari.viewer.Viewer: viewer in which the widget is displayed""" # add some buttons - self.button = ui.Button("1", self.button_func, parent=self, fixed=True) + self.button = ui.Button( + "1", self._button_func, parent=self, fixed=True + ) self.time_label = ui.make_label("", self) self.time_label.setVisible(False) @@ -90,7 +89,7 @@ def __init__(self, parent: "napari.viewer.Viewer"): # self.pause_time = None def pause_timer(self): - """Pause the timer for the review time""" + """Pause the timer for the review time.""" if self.pause_box.isChecked(): self.time_label.setVisible(True) @@ -108,51 +107,48 @@ def pause_timer(self): # self.pause_time = datetime.now() - self.pause_start self.start_time = datetime.now() self.is_paused = False - self.update_time_csv() + self._update_time_csv() - def update_time_csv(self): + def _update_time_csv(self): if not self.is_paused: self.time_elapsed += datetime.now() - self.start_time self.start_time = datetime.now() str_time = utils.time_difference(timedelta(), self.time_elapsed) - print(f"Time elapsed : {str_time}") + logger.info(f"Time elapsed : {str_time}") self.df.at[0, "time"] = str_time self.df.to_csv(self.csv_path) def prepare(self, label_dir, filetype, model_type, checkbox): - """Initialize the Datamanager, which loads the csv file and updates it - with the index of the current slice. + """Initialize the Datamanager, which loads the csv file and updates it with the index of the current slice. Args: - label_dir (str): label path - filetype (str) : file extension - model_type (str): model type - checkbox (bool): create new dataset or not - as_folder (bool) : load as folder or as single file + label_dir (str): label path + filetype (str) : file extension + model_type (str): model type + checkbox (bool): create new dataset or not + as_folder (bool) : load as folder or as single file """ - # label_dir = os.path.dirname(label_dir) - print("csv path try :") - print(label_dir) + logger.debug("csv path try :") + logger.debug(label_dir) self.filetype = filetype if not self.as_folder: p = Path(label_dir) self.filename = p.name - label_dir = p.parent - print("Loading single image") - print(self.filename) - print(label_dir) + label_dir = p.parents[0] + logger.info(f"Loading single image : {self.filename}") + logger.debug(label_dir) self.df, self.csv_path = self.load_csv(label_dir, model_type, checkbox) - print(self.csv_path, checkbox) - # print(self.viewer.dims.current_step[0]) + logger.debug(f"csv path : {self.csv_path}") + logger.debug(f"Create new dataset : {checkbox}") + # logger.debug(self.viewer.dims.current_step[0]) self.update_dm(self.viewer.dims.current_step[0]) def load_csv(self, label_dir, model_type, checkbox): - """ - Loads newest csv or create new csv + """Loads newest csv or create new csv. Args: label_dir (str): label path @@ -164,8 +160,8 @@ def load_csv(self, label_dir, model_type, checkbox): """ # if not self.as_folder : # label_dir = os.path.dirname(label_dir) - print("label dir") - print(label_dir) + logger.debug("label dir") + logger.debug(label_dir) csvs = sorted(list(Path(str(label_dir)).glob(f"{model_type}*.csv"))) if len(csvs) == 0: df, csv_path = self.create_csv( @@ -186,25 +182,24 @@ def load_csv(self, label_dir, model_type, checkbox): pass recorded_time = df.at[0, "time"] - # print("csv load time") - # print(recorded_time) + # logger.debug("csv load time") + # logger.debug(recorded_time) t = datetime.strptime(recorded_time, TIMER_FORMAT) self.time_elapsed = timedelta( hours=t.hour, minutes=t.minute, seconds=t.second ) - # print(self.time_elapsed) + # logger.debug(self.time_elapsed) return df, csv_path - def create_csv(self, label_dir, model_type, filename=None): - """ - Create a new dataframe and save the csv + def create_csv(self, label_dir, model_type): + """Create a new dataframe and save the csv. + Args: label_dir (str): label path model_type (str): model type Returns: - (pandas.DataFrame, str): dataframe, csv path + (pandas.DataFrame, str): dataframe, csv path. """ - if self.as_folder: labels = sorted( list( @@ -215,7 +210,7 @@ def create_csv(self, label_dir, model_type, filename=None): ) ) else: - # print(self.image_dims[0]) + # logger.debug(self.image_dims[0]) filename = self.filename if self.filename is not None else "image" labels = [str(filename) for i in range(self.image_dims[0])] @@ -228,45 +223,47 @@ def create_csv(self, label_dir, model_type, filename=None): ) df.at[0, "time"] = "00:00:00" - csv_path = str(Path(label_dir) / Path(f"{model_type}_train0.csv")) - print("csv path for create") - print(csv_path) - df.to_csv(csv_path) + csv_path = Path(label_dir) / Path(f"{model_type}_train0.csv") + if not csv_path.parent.exists(): + csv_path.parent.mkdir(parents=True) + logger.debug(f"CSV path : {csv_path}") + df.to_csv(str(csv_path)) return df, csv_path - def update_button(self): + def _update_button(self): if len(self.df) > 1: self.button.setText( self.df.at[self.df.index[self.slice_num], "train"] ) # puts button values at value of 1st csv item def update_dm(self, slice_num): - """Updates the Datamanager with the index of the current slice, and updates - the text with the status contained in the csv (e.g. checked/not checked). + """Updates the Datamanager with the index of the current slice. + + Also updates the text with the status contained in the csv (e.g. checked/not checked). Args: slice_num (int): index of the current slice """ self.slice_num = slice_num - self.update_time_csv() + self._update_time_csv() - print(f"New slice review started at {utils.get_time()}") - # print(self.df) + logger.info(f"New slice review started at {utils.get_time()}") + # logger.debug(self.df) try: - self.update_button() + self._update_button() except IndexError: self.slice_num -= 1 - self.update_button() + self._update_button() - def button_func(self): # updates csv every time you press button... + def _button_func(self): # updates csv every time you press button... if self.viewer.dims.ndisplay != 2: # TODO test if undefined behaviour or if okay logger.warning("Please switch back to 2D mode !") return - self.update_time_csv() + self._update_time_csv() if self.button.text() == "Not checked": self.button.setText("Checked") diff --git a/napari_cellseg3d/code_plugins/plugin_utilities.py b/napari_cellseg3d/code_plugins/plugin_utilities.py index abe56699..c90734ca 100644 --- a/napari_cellseg3d/code_plugins/plugin_utilities.py +++ b/napari_cellseg3d/code_plugins/plugin_utilities.py @@ -1,3 +1,4 @@ +"""Central plugin for all utilities.""" from typing import TYPE_CHECKING if TYPE_CHECKING: @@ -15,6 +16,7 @@ AnisoUtils, FragmentUtils, RemoveSmallUtils, + StatsUtils, ThresholdUtils, ToInstanceUtils, ToSemanticUtils, @@ -32,11 +34,15 @@ "Convert to semantic labels": ToSemanticUtils, "Threshold": ThresholdUtils, "CRF": CRFWidget, + "Label statistics": StatsUtils, } class Utilities(QWidget, metaclass=ui.QWidgetSingleton): + """Central plugin for all utilities.""" + def __init__(self, viewer: "napari.viewer.Viewer"): + """Creates a widget with all utilities.""" super().__init__() self._viewer = viewer self.current_widget = None @@ -50,6 +56,7 @@ def __init__(self, viewer: "napari.viewer.Viewer"): "sem", "thresh", "crf", + "stats", ] self._create_utils_widgets(attr_names) self.utils_choice = ui.DropdownMenu( diff --git a/napari_cellseg3d/config.py b/napari_cellseg3d/config.py index 422fdc70..d3aa0eb1 100644 --- a/napari_cellseg3d/config.py +++ b/napari_cellseg3d/config.py @@ -1,3 +1,4 @@ +"""Module to store configuration parameters for napari_cellseg3d.""" import datetime from dataclasses import dataclass from pathlib import Path @@ -18,7 +19,6 @@ logger = LOGGER -# TODO(cyril) DOCUMENT !!! and add default values # TODO(cyril) add JSON load/save MODEL_LIST = { @@ -43,6 +43,18 @@ @dataclass class ReviewConfig: + """Class to record params for Review plugin. + + Args: + image (np.array): image to review + labels (np.array): labels to review + csv_path (str): path to csv to save results + model_name (str): name of the model (added to csv name) + new_csv (bool): whether to create a new csv + filetype (str): filetype to read & write review images + zoom_factor (List[int]): zoom factor to apply to image & labels, if selected + """ + image: np.array = None labels: np.array = None csv_path: str = Path.home() / "cellseg3d" / "review" @@ -54,6 +66,17 @@ class ReviewConfig: @dataclass # TODO create custom reader for JSON to load project class ReviewSession: + """Class to record params for Review session. + + Args: + project_name (str): name of the project + image_path (str): path to images + labels_path (str): path to labels + csv_path (str): path to csv + aniso_zoom (List[int]): anisotropy zoom + time_taken (datetime.timedelta): time taken to review + """ + project_name: str image_path: str labels_path: str @@ -69,18 +92,22 @@ class ReviewSession: @dataclass class ModelInfo: - """Dataclass recording supervised models info + """Dataclass recording supervised models info. + Args: name (str): name of the model model_input_size (Optional[List[int]]): input size of the model - num_classes (int): number of classes for the model + num_classes (int): number of classes for the model. """ name: str = next(iter(MODEL_LIST)) - model_input_size: Optional[List[int]] = None - num_classes: int = 2 + model_input_size: Optional[ + List[int] + ] = None # only used by SegResNet and SwinUNETR + num_classes: int = 2 # only used by WNets def get_model(self): + """Return model from model list.""" try: return MODEL_LIST[self.name] except KeyError as e: @@ -91,6 +118,7 @@ def get_model(self): @staticmethod def get_model_name_list(): + """Return list of model names.""" logger.info("Model list :") for model_name in MODEL_LIST: logger.info(f" * {model_name}") @@ -99,37 +127,54 @@ def get_model_name_list(): @dataclass class WeightsInfo: - path: str = PRETRAINED_WEIGHTS_DIR - custom: bool = False + """Class to record params for weights. + + Args: + path (Optional[str]): path to weights + use_custom (Optional[bool]): whether to use custom weights + use_pretrained (Optional[bool]): whether to use pretrained weights + """ + + path: Optional[str] = PRETRAINED_WEIGHTS_DIR use_pretrained: Optional[bool] = False + use_custom: Optional[bool] = False ############################################# # Post processing & instance segmentation # ############################################# +# Utils + @dataclass class Thresholding: - enabled: bool = True + """Class to record params for thresholding.""" + + enabled: bool = False threshold_value: float = 0.8 @dataclass class Zoom: - enabled: bool = True + """Class to record params for zoom.""" + + enabled: bool = False zoom_values: List[float] = None @dataclass class InstanceSegConfig: + """Class to record params for instance segmentation.""" + enabled: bool = False method: InstanceMethod = None +# Workers @dataclass class PostProcessConfig: - """Class to record params for post processing + """Class to record params for post processing. Args: zoom (Zoom): zoom config @@ -144,8 +189,15 @@ class PostProcessConfig: @dataclass class CRFConfig: - """ - Class to record params for CRF + """Class to record params for CRF. + + Args: + sa (float): alpha standard deviation, the scale of the spatial part of the appearance/bilateral kernel. + sb (float): beta standard deviation, the scale of the color part of the appearance/bilateral kernel. + sg (float): gamma standard deviation, the scale of the smoothness/gaussian kernel. + w1 (float): weight of the appearance/bilateral kernel. + w2 (float): weight of the smoothness/gaussian kernel. + n_iter (int, optional): Number of iterations for the CRF post-processing step. Defaults to 5. """ sa: float = 10 @@ -163,16 +215,19 @@ class CRFConfig: @dataclass class SlidingWindowConfig: + """Class to record params for sliding window inference.""" + window_size: int = None window_overlap: float = 0.25 def is_enabled(self): + """Return True if sliding window is enabled.""" return self.window_size is not None @dataclass class InfererConfig: - """Class to record params for Inferer plugin + """Class to record params for Inferer plugin. Args: model_info (ModelInfo): model info @@ -191,7 +246,7 @@ class InfererConfig: @dataclass class InferenceWorkerConfig: - """Class to record configuration for Inference job + """Class to record configuration for Inference job. Args: device (str): device to use for inference @@ -219,7 +274,7 @@ class InferenceWorkerConfig: use_crf: bool = False crf_config: CRFConfig = CRFConfig() - images_filepaths: str = None + images_filepaths: List[str] = None layer: napari.layers.Layer = None @@ -230,7 +285,7 @@ class InferenceWorkerConfig: @dataclass class DeterministicConfig: - """Class to record deterministic config""" + """Class to record deterministic config.""" enabled: bool = True seed: int = 34936339 # default seed from NP_MAX @@ -238,14 +293,33 @@ class DeterministicConfig: @dataclass class TrainerConfig: - """Class to record trainer plugin config""" + """Class to record trainer plugin config.""" save_as_zip: bool = False @dataclass class TrainingWorkerConfig: - """General class to record config for training""" + """General class to record config for training. + + Args: + device (str): device to use for training + max_epochs (int): max number of epochs + learning_rate (np.float64): learning rate + validation_interval (int): validation interval + batch_size (int): batch size + deterministic_config (DeterministicConfig): deterministic config + scheduler_factor (float): scheduler factor + scheduler_patience (int): scheduler patience + weights_info (WeightsInfo): weights info + results_path_folder (str): path to save results + sampling (bool): whether to sample data into patches + num_samples (int): number of patches + sample_size (List[int]): patch size + do_augmentation (bool): whether to do augmentation + num_workers (int): number of workers + train_data_dict (dict): dict of train data as {"image": np.array, "labels": np.array} + """ # model params device: str = "cpu" @@ -269,37 +343,61 @@ class TrainingWorkerConfig: @dataclass class SupervisedTrainingWorkerConfig(TrainingWorkerConfig): - """Class to record config for Trainer plugin""" + """Class to record config for Trainer plugin. + + Args: + model_info (ModelInfo): model info + loss_function (callable): loss function + validation_percent (float): validation percent + """ model_info: ModelInfo = None loss_function: callable = None - validation_percent: float = 0.8 + training_percent: float = 0.8 @dataclass class WNetTrainingWorkerConfig(TrainingWorkerConfig): - """Class to record config for WNet worker""" + """Class to record config for WNet worker. + + Args: + in_channels (int): encoder input channels + out_channels (int): decoder (reconstruction) output channels + num_classes (int): encoder output channels + dropout (float): dropout + learning_rate (np.float64): learning rate + use_clipping (bool): use gradient clipping + clipping (float): clipping value + weight_decay (float): weight decay + intensity_sigma (float): intensity sigma + spatial_sigma (float): spatial sigma + radius (int): pixel radius for loss computation; might be overriden depending on data shape + reconstruction_loss (str): reconstruction loss (MSE or BCE) + n_cuts_weight (float): weight for NCuts loss + rec_loss_weight (float): weight for reconstruction loss. Must be adjusted depending on images; compare to NCuts loss value + train_data_dict (dict): dict of train data as {"image": np.array, "labels": np.array} + eval_volume_dict (str): dict of eval volume (optional) + eval_batch_size (int): eval batch size (optional) + """ # model params - in_channels: int = 1 # encoder input channels - out_channels: int = 1 # decoder (reconstruction) output channels - num_classes: int = 2 # encoder output channels + in_channels: int = 1 + out_channels: int = 1 + num_classes: int = 2 dropout: float = 0.65 learning_rate: np.float64 = 2e-5 - use_clipping: bool = False # use gradient clipping - clipping: float = 1.0 # clipping value - weight_decay: float = 0.01 # 1e-5 # weight decay (used 0.01 historically) + use_clipping: bool = False + clipping: float = 1.0 + weight_decay: float = 0.01 # 1e-5 # NCuts loss params intensity_sigma: float = 1.0 spatial_sigma: float = 4.0 - radius: int = 2 # pixel radius for loss computation; might be overriden depending on data shape + radius: int = 2 # reconstruction loss params reconstruction_loss: str = "MSE" # or "BCE" # summed losses weights n_cuts_weight: float = 0.5 - rec_loss_weight: float = ( - 0.5 / 100 - ) # must be adjusted depending on images; compare to NCuts loss value + rec_loss_weight: float = 0.5 / 100 # normalization params # normalizing_function: callable = remap_image # FIXME: call directly in worker, not a param # data params @@ -313,25 +411,7 @@ class WNetTrainingWorkerConfig(TrainingWorkerConfig): ################ @dataclass class WandBConfig: - """Class to record parameters for WandB""" + """Class to record parameters for WandB.""" - mode: str = "disabled" # disabled, online, enabled + mode: str = "online" # disabled, online, offline save_model_artifact: bool = False - - -################ -# CRF config for WNet -################ - - -@dataclass -class WNetCRFConfig: - """Class to store parameters of WNet CRF post-processing""" - - # CRF - sa = 10 # 50 - sb = 10 - sg = 1 - w1 = 10 # 50 - w2 = 10 - n_iter = 5 diff --git a/napari_cellseg3d/dev_scripts/artefact_labeling.py b/napari_cellseg3d/dev_scripts/artefact_labeling.py index 93746eb6..a2935354 100644 --- a/napari_cellseg3d/dev_scripts/artefact_labeling.py +++ b/napari_cellseg3d/dev_scripts/artefact_labeling.py @@ -21,18 +21,20 @@ def map_labels(labels, artefacts): """Map the artefacts labels to the neurons labels. + Parameters ---------- labels : ndarray Label image with neurons labelled as mulitple values. artefacts : ndarray Label image with artefacts labelled as mulitple values. - Returns + + Returns: ------- map_labels_existing: numpy array The label value of the artefact and the label value of the neurone associated or the neurons associated new_labels: list - The labels of the artefacts that are not labelled in the neurons + The labels of the artefacts that are not labelled in the neurons. """ map_labels_existing = [] new_labels = [] @@ -75,6 +77,7 @@ def make_labels( augment_contrast_factor=2, ): """Detect nucleus. using a binary watershed algorithm and otsu thresholding. + Parameters ---------- image : str @@ -91,12 +94,12 @@ def make_labels( If True, use watershed algorithm to detect nucleus. augment_contrast_factor : int, optional Factor to augment the contrast of the image. - Returns + + Returns: ------- ndarray Label image with nucleus labelled with 1 value per nucleus. """ - # image = imread(image) image = (image - np.min(image)) / (np.max(image) - np.min(image)) @@ -129,6 +132,7 @@ def make_labels( def select_image_by_labels(image, labels, path_image_out, label_values): """Select image by labels. + Parameters ---------- image : np.array @@ -166,6 +170,7 @@ def crop_image(img): def crop_image_path(image, path_image_out): """Crop image. + Parameters ---------- image : np.array @@ -188,6 +193,7 @@ def make_artefact_labels( remove_true_labels=True, ): """Detect pseudo nucleus. + Parameters ---------- image : ndarray @@ -206,12 +212,12 @@ def make_artefact_labels( If True, each different artefact will be labelled as a different value. remove_true_labels : bool, optional If True, the true labels will be removed from the artefacts. - Returns + + Returns: ------- ndarray Label image with pseudo nucleus labelled with 1 value per artefact. """ - neurons = np.array(labels > 0) non_neurons = np.array(labels == 0) @@ -277,6 +283,7 @@ def make_artefact_labels( def select_artefacts_by_size(artefacts, min_size, is_labeled=False): """Select artefacts by size. + Parameters ---------- artefacts : ndarray @@ -285,7 +292,8 @@ def select_artefacts_by_size(artefacts, min_size, is_labeled=False): Minimum size of artefacts to keep is_labeled : bool, optional If True, the artefacts are already labelled. - Returns + + Returns: ------- ndarray Label image with artefacts labelled and small artefacts removed. @@ -308,6 +316,7 @@ def create_artefact_labels( contrast_power=20, ): """Create a new label image with artefacts labelled as 2 and neurons labelled as 1. + Parameters ---------- image : np.array @@ -339,6 +348,7 @@ def create_artefact_labels( def visualize_images(paths): """Visualize images. + Parameters ---------- paths : list @@ -360,6 +370,7 @@ def create_artefact_labels_from_folder( contrast_power=20, ): """Create a new label image with artefacts labelled as 2 and neurons labelled as 1 for all images in a folder. The images created are stored in a folder artefact_neurons. + Parameters ---------- path : str diff --git a/napari_cellseg3d/dev_scripts/classifier_test.ipynb b/napari_cellseg3d/dev_scripts/classifier_test.ipynb new file mode 100644 index 00000000..80486f5e --- /dev/null +++ b/napari_cellseg3d/dev_scripts/classifier_test.ipynb @@ -0,0 +1,587 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from tifffile import imread\n", + "import pandas as pd\n", + "import numpy as np\n", + "from sklearn.ensemble import RandomForestClassifier\n", + "from pathlib import Path\n", + "import napari\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded 162 images\n" + ] + } + ], + "source": [ + "DATA_PATH = Path.home() / \"Desktop/Code/CELLSEG_BENCHMARK/classifier_test/train\"\n", + "images_p = list(DATA_PATH.glob(\"*.tif\"))\n", + "images_p.sort()\n", + "print(f\"Loaded {len(images_p)} images\")\n", + "images = [imread(str(image)) for image in images_p]\n", + "\n", + "DATA_DF_PATH = DATA_PATH / \"train_data_df.csv\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
image_path012345678...919293949596979899label
0pred_1_SwinUNetR_fragmented_00.0000040.000000.0000000.0000000.0000000.0000000.0000000.0000040.000008...0.0041080.0046770.0051310.0041620.0026970.0015110.0003130.0000270.0000191
1pred_1_SwinUNetR_fragmented_10.0000040.000000.0000000.0000000.0000000.0000000.0000000.0000040.000000...0.0027010.0021670.0019570.0022810.0017970.0012860.0006640.0000190.0000151
2pred_1_SwinUNetR_fragmented_100.0000040.000000.0000000.0000000.0000000.0000000.0000000.0000000.000000...0.0097390.0086440.0044780.0038870.0026700.0009800.0001370.0001030.0001371
3pred_1_SwinUNetR_fragmented_110.0000150.000050.0000310.0000570.0000420.0000190.0000110.0000190.000011...0.0040780.0057140.0073590.0056150.0016100.0003280.0000800.0001030.0000651
4pred_1_SwinUNetR_fragmented_120.0000040.000000.0000000.0000000.0000000.0000000.0000000.0000000.000000...0.0097390.0086440.0044780.0038870.0026700.0009800.0001370.0001030.0001371
\n", + "

5 rows × 102 columns

\n", + "
" + ], + "text/plain": [ + " image_path 0 1 2 3 \\\n", + "0 pred_1_SwinUNetR_fragmented_0 0.000004 0.00000 0.000000 0.000000 \n", + "1 pred_1_SwinUNetR_fragmented_1 0.000004 0.00000 0.000000 0.000000 \n", + "2 pred_1_SwinUNetR_fragmented_10 0.000004 0.00000 0.000000 0.000000 \n", + "3 pred_1_SwinUNetR_fragmented_11 0.000015 0.00005 0.000031 0.000057 \n", + "4 pred_1_SwinUNetR_fragmented_12 0.000004 0.00000 0.000000 0.000000 \n", + "\n", + " 4 5 6 7 8 ... 91 92 \\\n", + "0 0.000000 0.000000 0.000000 0.000004 0.000008 ... 0.004108 0.004677 \n", + "1 0.000000 0.000000 0.000000 0.000004 0.000000 ... 0.002701 0.002167 \n", + "2 0.000000 0.000000 0.000000 0.000000 0.000000 ... 0.009739 0.008644 \n", + "3 0.000042 0.000019 0.000011 0.000019 0.000011 ... 0.004078 0.005714 \n", + "4 0.000000 0.000000 0.000000 0.000000 0.000000 ... 0.009739 0.008644 \n", + "\n", + " 93 94 95 96 97 98 99 label \n", + "0 0.005131 0.004162 0.002697 0.001511 0.000313 0.000027 0.000019 1 \n", + "1 0.001957 0.002281 0.001797 0.001286 0.000664 0.000019 0.000015 1 \n", + "2 0.004478 0.003887 0.002670 0.000980 0.000137 0.000103 0.000137 1 \n", + "3 0.007359 0.005615 0.001610 0.000328 0.000080 0.000103 0.000065 1 \n", + "4 0.004478 0.003887 0.002670 0.000980 0.000137 0.000103 0.000137 1 \n", + "\n", + "[5 rows x 102 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "if not DATA_DF_PATH.exists():\n", + " data_df = pd.DataFrame([i.name[:-4] for i in images_p], columns=[\"image_path\"])\n", + " # add 100 bins of the hist of each image\n", + " hists = []\n", + " for i, image in enumerate(images):\n", + " # hists.append(np.histogram(image, bins=100)[0])\n", + " hist = np.histogram(image, bins=100)[0]\n", + " hist = hist / hist.sum()\n", + " hists.append(hist)\n", + " \n", + " data_df = pd.concat([data_df, pd.DataFrame(hists)], axis=1)\n", + "else:\n", + " data_df = pd.read_csv(DATA_DF_PATH)\n", + " # make the hist a density\n", + " # data_df.iloc[:, 1:-1] = data_df.iloc[:, 1:-1].div(data_df.iloc[:, 1:-1].sum(axis=1), axis=0)\n", + " # make the hist a percentage\n", + " # data_df.iloc[:, 1:-1] = data_df.iloc[:, 1:-1] / 1000\n", + "data_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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YJmrwgNj3JEf4450UBV3/vdg7BHANo/0YNyRDuxrSRe2eaRDO+Ju2cm+6Wl3U/qRkZHQLoZWv+npafT29rb19QHGHdVi3JEO7Y47+R4AY49qsc0jHRh3pAP7WtKFbR7pEGbcLXsZ76ZNmzA6OorJyUlMTU15j9HR0Yav3bt3b9PX4POr9/nR0dGan/vk5CRGR0exadOmpv82LEHiLgqfz1p6PkrXFNW4i8rnw+fb87yuuAPY16p4PorXJJ+PapsX9Pr5/Op8PqpxF5XPJ6rPR/GalvL8aulrgWh9bnx+5c9Htc0Lev2d8nwUr2klz6uIu2VX9pmmiS1btgT62u7ubj6/xp7v6elpOCWm3bNuQLC4i8Lns5aej9I1RTXuovL58Pn2PK8r7gD2tSqej+I1yeej2uZJuj8fPs++ls9H473DeH619LVAtD43Pr/y56Pa5km6P5+oPB/Fa1rJ8yrijgd0EBERERERERERrRFM9hEREREREREREa0Ry17G20oymcTHP/5xlMtl9w0sCz09PTXP8fnV/Tzg/pyjRMYdAO2fz1p6PkrXZFlWJOPuk5/8ZCQ+Hz7fvuejFncA+9q12MbVP//JT34ycrHnjzvdnw+fZ18LROdz0/18FK9pKc9HMe6Axr4WiNbnxufZ13bK81G8ppU8D6jJpxhCxXnmRERERERERERE1HZcxktERERERERERLRGMNlHRERERERERES0RjDZR0REREREREREtEYw2UdERERERERERLRGMNnXgW666Sbccccdgb724YcfhmEYmJycXNF7btu2DZ/97GdX9Bq0ujHuSBfGHunAuCMdGHekC2OPdGDckQ6rJu5EiO644w5hWZYA4D0Mw6j5c6uHaZqBvo6PaD1isZh405veJPbv379gbGzdulV85jOfCTPcPI888ohYv379suKOj9X7GB4e1hp3Qghxww03MNY67BEk7tode836Wj7W9iMKcce+tjMfF198MftaPpQ/otDmsa/tvEdU4475lLX9aGc+JbTKvq9//ev44z/+Y/T39+O1r30tACCRSGDz5s3e1xiG0fLfO47T9PmF/k29WCzW8JxpLv1bXMp7tvr6pb4GAMTjcSQSiZrnMpnMkl+nXUzTRDabxXnnnYfh4WEAgBACAPCGN7wBs7OzWq7r/vvvx+nTp3H55ZcDAK644oqav2/1s2j1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Go3CNM2afWIoFFoSC430tZXnUCmTyQTe5LDeGK9yp3ep2kRhvb5W/r9f5fmdffbZANqjr23lfEo0Gq058dnb24sDBw6UHWtmX1tt5ZvsayX/fEplXyt1wnyKaZrIZDJL+lr/xjoAvMlAJfMpDS36rePee+8VkUhEXHXVVV69gUgkIl71qleJa665RgD1i2rWW09dufZaPirXfyeTSTE8PNyU4qNbtmypur5cZ62BnTt3LjnWSG2HlZx7tQ075PP85m/+pgiHwyKVSolQKCRuvfVW8dRTT4kXXnhBfO1rXxO33nqrFx+tqucihBD33HOPME3Ti68LLrhAhEIhcfnll9eNu1rHV/I+9fX1lRUqX8ljw4YNNc9TZ+2YavWjVlKHZDUP/2d11113ife9733eZ6Ur7u69915hmqaIxWJeUXXTNMUtt9xSNZY2b95c9WdbTXsViURET0/PqupR1KrfYhQ3NFLZ5umukWRUbKQjf3b5u/2Wt7xFABC7d+8W8XhcS+xV62tN0xTvec97lhT39xd09j+q9SWGYQTua8PhsNixY0fgmjG12jYZw9XaYt1FzJd7D5Z7NPp77X9++Xf5ZzvEnRDN72sbfcj6fc0Y41XWgfW/hq4Y09HX1tuUrZP62sqH3Oihme+T3CBspc/RTn2t/7Urj4VCoZbXdavsa/1/7+vrE+9973sF0J59ba0xXrVHtb42yPf54250dLShNnTjxo1Vj9caX63nvlZ+bzv1ta2aT2lkA85m9rW15lNWU3NwtQ8d8ynVxteq5lOaNtknhBC33XZbU98YPtr/0dfXJz74wQ+KRx99VNx0000imUyKrq4ucfHFF4uPfexjqwrOoB588EHG3Tp7WJYlbrzxRvHII49oizshlhZs5mNtP2TcZTIZ8fjjj2uLvXp9LR9r79Eucce+dn08/BNP7Gv50PFolzaPfe36enRC3LGvXZuPVs6nGEIEKAxAREREREREREREba+lu/ESERERERERERGROpzsIyIiIiIiIiIiWiM42UdERERERERERLRGcLKPiIiIiIiIiIhojeBkHxERERERERER0RrByT4iIiIiIiIiIqI1gpN9REREREREREREawQn+4iIiIiIiIiIiNYITvYRERERERERERGtEZzsIyIiIiIiIiIiWiM42UdERERERERERLRG/P8bnZYR6lnK1gAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# # plot all histograms\n", + "# fig, axs = plt.subplots(8, 8, figsize=(16, 16))\n", + "# for i, ax in enumerate(axs.flatten()):\n", + "# ax.plot(data_df.iloc[i, 1:])\n", + "# ax.set_yticklabels([])" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from napari.settings import get_settings\n", + "settings = get_settings()\n", + "settings.application.ipy_interactive = False\n", + "\n", + "# labels = []\n", + "\n", + "# for i, im in enumerate(images):\n", + "# viewer = napari.Viewer()\n", + " \n", + "# @viewer.bind_key(\"o\")\n", + "# def next_label(event):\n", + "# if len(labels) == i+1:\n", + "# print(\"You have labeled all images already!\")\n", + "# return\n", + "# labels.append(0)\n", + "# print(\"Added label 0\")\n", + " \n", + "# @viewer.bind_key(\"p\")\n", + "# def next_label(event):\n", + "# if len(labels) == i+1:\n", + "# print(\"You have labeled all images already!\")\n", + "# return\n", + "# labels.append(1)\n", + "# print(\"Added label 1\")\n", + " \n", + "# @viewer.bind_key(\"q\")\n", + "# def next_label(event):\n", + "# if len(labels) != i+1:\n", + "# print(\"You need to label the current image first!\")\n", + "# return\n", + "# else:\n", + "# viewer.close()\n", + "# @viewer.bind_key(\"u\")\n", + "# def undo_label(event):\n", + "# labels.pop()\n", + "# print(\"Removed last label\")\n", + "# print(labels)\n", + " \n", + "# print(f\"Image {i+1}/{len(images)} :\")\n", + "# viewer.add_image(im, colormap=\"turbo\")\n", + "# viewer.dims.ndisplay = 3\n", + "# napari.run()\n", + "\n", + "# data_df[\"label\"] = labels\n", + "# # save data_df as csv\n", + "# data_df.to_csv(DATA_PATH / \"train_data_df.csv\", index=False)\n", + "# display(data_df)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
RandomForestClassifier()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "RandomForestClassifier()" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "classifier = RandomForestClassifier()\n", + "classifier.fit(data_df.iloc[:, 1:-1].values, data_df[\"label\"].values)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.0" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# test performance on training data\n", + "classifier.score(data_df.iloc[:, 1:-1].values, data_df[\"label\"].values)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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iIiIyA3n119/5ZZbbqFDhw7s379fRQiRCrCysmLBggW88847/N///R+PPvooubm5xo4lIiLC8uXLCQoKYubMmcaOcs2bOXMmgYGBLF++3NhRROQ6oxkRIiIicsMwGAy89dZbvPPOO4wfP565c+diaWlp7Fgi15xFixYxfvx4evTowYoVK3BzczN2JBERuUEZDAa6dOlC3bp12bx5s7HjXBeGDh1KYmIihw8f1uxHEakymhEhIiIiN4ScnBwefPBB3nnnHT744AN++uknFSFErtB9993H9u3bOXv2LL169cLf39/YkURE5Aa1efNmjh07ptkQVWjmzJkcPXqULVu2GDuKiFxHNCNCRERErnvx8fGMGTOGI0eOsGDBAsaOHWvsSCLXhZCQEEaMGEFMTAwrVqxg4MCBxo4kIiI3mEGDBpGZmcmBAwf09H4VMRgM9OjRA3t7e7Zv327sOCJyndCMCBEREbmu+fn50bNnT4KCgtixY4eKECJVqGnTpuzbt49u3boxdOhQfv75Z2NHEhGRG4iPjw87duxg5syZKkJUIRMTE1555RV27NiBj4+PseOIyHVCMyJERETkurV161buueceGjVqxPr162nSpImxI4lcl/Lz85kyZQrff/89r7zyCu+99x6mpnrmSUREqteYMWM4e/YsZ86c0c+dKlZUVETbtm1p06YNK1euNHYcEbkO6G9pERERuS798MMPDB8+nF69erF3714VIUSqkYWFBd999x2fffYZH374IePGjSMrK8vYsURE5Dp25swZVq9ezcsvv6wiRDUwNTVlxowZrFq1Cj8/P2PHEZHrgGZEiIiIyHWlqKiIl19+mU8//ZSnn36ar776CnNzc2PHErlhrFq1igcffJD27duzevVq6tevb+xIIiJyHRo/fjxbt24lODgYS0tLY8e5LuXl5dGsWTMtvygiVUIlYxEREbluZGZmcvfdd/PZZ5/x5ZdfMmvWLBUhRGrYmDFj2L17NxEREfTs2ZOTJ08aO5KIiFxnwsPD+e2335g+fbqKENXI0tKS6dOn8+uvvxIeHm7sOCJyjVMhQkRERK4LUVFRDBgwgC1btrB69Wqef/55bVooYiRdunThwIED1KlTh759+7Jp0yZjRxIRkevIZ599hqOjI5MmTTJ2lOvepEmTcHBw4PPPPzd2FBG5xqkQISIiIte848eP07NnT2JjY9mzZw+jRo0ydiSRG16jRo3YvXs3AwcOZMSIEcyePdvYkURE5DqQkJDADz/8wLPPPou9vb2x41z37O3tefbZZ/nhhx9ISEgwdhwRuYapECEiIiLXtHXr1tG3b1/c3d05cOAAnTt3NnYkEfmbvb09K1eu5LnnnuOZZ55h6tSpFBYWGjuWiIhcw7755htMTEyYMmWKsaPcMJ599lkAZs2aZeQkInItUyFCRERErkkGg4GvvvqKO+64g6FDh7Jr1y4aNGhg7Fgi8h9mZmZ88cUXzJ49m1mzZnHHHXeQnp5u7FgiInINysjI4JtvvmHSpEm4ubkZO84Nw83NjUmTJvH111+TkZFh7Dgico1SIUJERESuOQUFBUyZMoWpU6cybdo0li9fjp2dnbFjicglPPXUU6xbt45du3bRr18/zp8/b+xIIiJyjfn+++9JT09n+vTpxo5yw5k2bRrp6en88MMPxo4iItcoE4PBYDB2CBEREZGKSktLY9y4cWzZsoXZs2fzxBNPGDuSiFTCqVOnGDlyJHl5eaxdu5auXbsaO5KIiFwDcnNzadasGcOGDePnn382dpwb0vjx49m6dSvBwcFYWloaO46IXGM0I0JERESuGWFhYfTt25f9+/ezadMmFSFErkHt27fnwIEDeHp60r9/f1atWmXsSCIicg347bffiIqKYsaMGcaOcsOaMWMGkZGR/Pbbb8aOIiLXIM2IEBERkWuCr68vo0ePxtbWlvXr19OmTRtjRxKRq5Cdnc2jjz7KsmXL+Pjjj5k+fTomJibGjiUiIrVQYWEh7dq1o02bNqxcudLYcW5oY8aM4ezZs5w+fRozMzNjxxGRa4hmRIiIiEitt2zZMgYMGECzZs3w8fFREULkOmBjY8OiRYt45ZVXeOmll5g8eTL5+fnGjiUiIrXQqlWr8Pf3Z+bMmcaOcsObOXMm/v7+rF692thRROQaoxkRIiIiUmsZDAY+/PBDXn31Ve6//35++uknrK2tjR1LRKrY/PnzeeKJJ+jfvz/Lli3D2dnZ2JFERKSWMBgM9OjRAwcHB7Zt22bsOAIMGjSIzMxMDhw4oNmMIlJhmhEhIiIitVJeXh4TJkzg1Vdf5Y033uC3335TEULkOjV+/Hi2bNnCkSNH6N27N8HBwcaOJCIitcS2bds4dOiQZkPUIjNnzuTgwYNs377d2FFE5BqiGREiIiJS6yQlJXH33Xezb98+5s2bx0MPPWTsSCJSA86dO8eIESNISUlh9erV9OnTx9iRRETEyIYOHUpiYiKHDx/W0/e1hMFgoGvXrri6urJlyxZjxxGRa4RmRIiIiEitEhgYSO/evTl58iRbt25VEULkBtKyZUt8fHxo27YtgwcP5o8//jB2JBERMaJDhw6xdetWXnnlFRUhahETExNmzpzJ1q1bOXTokLHjiMg1QjMiREREpNbYvXs3Y8aMwc3NjfXr19O8eXNjRxIRI8jNzeWJJ55gwYIFvP322/zf//2fbkCJiNyA7rnnHo4fP87Zs2cxMzMzdhz5l8LCQlq1asVNN93E0qVLjR1HRK4BmhEhIiIitcLChQu55ZZb6NSpEz4+PipCiNzArKysmD9/Pu+99x5vvvkmjzzyCLm5ucaOJSIiNcjf358VK1YwY8YMFSFqITMzM2bMmMHy5cs5d+6cseOIyDVAMyJERETEqAwGA2+++Sbvvvsujz/+OHPmzMHS0tLYsUSklliyZAmPPPII3bt3Z+XKlbi5uRk7koiI1ICJEyeyYcMGQkJCsLKyMnYcKUdOTg5NmzZlxIgR/Pjjj8aOIyK1nGZEiIiIiNHk5OTwwAMP8O677/Lhhx/y448/qgghIqXce++97NixA39/f3r16sXZs2eNHUlERKpZREQECxYsYNq0aSpC1GLW1tZMmzaNBQsWEBkZaew4IlLLqRAhIiIiRhEXF8fgwYNZtWoVy5Yt4+WXX9Ya8CJSrl69enHgwAGsrKzo3bs327ZtM3YkERGpRl988QV2dnY88cQTxo4ilzF58mRsbW354osvjB1FRGo5FSJERESkxp05c4aePXsSHBzMzp07ufvuu40dSURquaZNm7Jv3z66d+/Orbfeyk8//WTsSCIiUg2SkpKYO3cuzzzzDI6OjsaOI5fh6OjIM888w9y5c0lKSjJ2HBGpxVSIEBERkRq1ZcsWevfujYODA76+vvTo0cPYkUTkGuHk5MT69euZMGECEyZMYObMmRQVFRk7loiIVKFvv/2WwsJCnnvuOWNHkQp6/vnnKSgo4NtvvzV2FBGpxVSIEBERkRrz/fffc9ttt9G3b1/27NmDp6ensSOJyDXGwsKCOXPm8Pnnn/Pxxx9z7733kpWVZexYIiJSBTIzM/nqq6+YOHEi7u7uxo4jFeTu7s6ECRP46quvyMzMNHYcEamlVIgQERGRaldYWMiLL77I5MmTeeqpp1izZo2m2ovIFTMxMeGFF15g1apVbNy4kYEDBxIdHW3sWCIicpXmzZtHSkoK06dPN3YUqaTp06eTkpKipRNF5KJMDAaDwdghRERE5PqVmZnJgw8+yNq1a/nyyy959tlnjR1JRK4jR44cYdSoUZiZmbF+/Xo6dOhg7EgiInIF8vPz8fb2ZsCAASxcuNDYceQKPPTQQ+zevZvAwEAsLCyMHUdEahnNiBAREZFqExkZSf/+/fnrr79Ys2aNihAiUuW6dOmCr68vbm5u9O3bl40bNxo7koiIXIE//viD8+fP8/LLLxs7ilyhl19+mfDwcP744w9jRxGRWkgzIkRERKRaHD16lFGjRmFiYsK6devo1KmTsSOJyHUsIyODBx98kHXr1vHVV18xZcoUY0cSEZEKKioqon379jRv3pw1a9YYO45chVGjRhEcHMzJkycxNdXzzyLyD/2NICIiIlVu7dq19OvXj/r16+Pr66sihIhUO3t7e1asWMHUqVN59tlnee655ygsLDR2LBERqYC1a9fi5+fHzJkzjR1FrtLMmTM5c+YM69atM3YUEallNCNCREREqozBYOCrr75i2rRpjBkzhoULF2JnZ2fsWCJyg/nuu++YMmUKw4cP548//sDBwcHYkURE5CIMBgO9e/fG0tKSXbt2GTuOVIF+/fpRUFDAvn37MDExMXYcEaklNCNCREREqkRBQQHPPPMML7zwAi+99BLLli1TEUJEjOLJJ59kw4YN7N69m5tvvpnz588bO5KIiFzErl27OHDggGZDXEdmzpyJj4+PCksiUopmRIiIiMhVS01NZdy4cfz111/MmTOHiRMnGjuSiAinT59m5MiR5OTksHbtWrp162bsSCIi8h/Dhw8nOjqaY8eO6en564TBYKBTp040bNiQjRs3GjuOiNQSmhEhIiIiVyU0NJS+ffvi4+PDpk2bVIQQkVqjXbt2+Pj44OXlRf/+/Vm5cqWxI4mIyL8cPXqUP//8k5kzZ6oIcR0xMTFh5syZbNq0iWPHjhk7jojUEpoRISIiIlfswIEDjB49Gnt7e9avX0/r1q2NHUlEpIzs7Gwee+wxlixZwkcffcSLL76oG14iIrXAfffdh6+vL+fOncPc3NzYcaQKFRQU0KJFC3r16sUff/xh7DgiUgtoRoSIiIhckSVLljBw4EBatGjBgQMHVIQQkVrLxsaG33//nddee40ZM2bwxBNPkJ+fb+xYIiI3tMDAQJYuXcpLL72kIsR1yNzcnJdeeoklS5YQFBRk7DgiUgtoRoSIiIhUisFg4IMPPuC1117jgQceYN68eVhbWxs7lohIhSxYsICJEyfSr18/li1bhouLi7EjiYjckCZPnszq1asJDQ3VteR1Kjs7Gy8vL+68806+++47Y8cRESPTjAgRERGpsLy8PB577DFee+013nrrLX799Vf94igi15RHHnmErVu3cuzYMfr06aOnNEVEjCA6Opr58+czdepUXUtex2xsbJg6dSo///wz0dHRpdoCAgJIT083UjIRMQYVIkRERKRCkpKSGDZsGH/88Qe//vorb775ptZYF5FrUv/+/fHx8aGwsJBevXqxd+9eY0cSEbmhfPnll1hbW/PUU08ZO4pUs6eeegorKyu++uqrUsdvvfVWfvjhByOlEhFjUCFCREREAAgLC8Pf37/ctoCAAHr16sXp06fZtm0bDz74YA2nExGpWi1atMDHx4d27doxePBgfv/993L7paens3///hpOJyJy/UpJSWHOnDk89dRTODk5GTuOVDNnZ2eeeuop5syZQ2pqasnxlJQUCgoKjJhMRGqaChEiIiKCwWDgzjvv5MMPPyzTtnPnTnr16oWZmRk+Pj707dvXCAlFRKpenTp12Lx5M/fffz8PPvggb7/9Nv/dQm/37t306dOHgIAAI6UUEbm+zJ49m7y8PKZOnWrsKFJDpk6dSm5uLrNnzy45lpeXh5WVlRFTiUhNUyFCRERE2LdvH0ePHmXcuHGlji9YsIChQ4fSuXNn9u3bh7e3t5ESiohUD0tLS37++Wf+97//8dZbb/HQQw+Rk5NT0j5o0CBcXV1L3TwREZErk52dzZdffsljjz1G/fr1jR1HqklRURGbNm0iPz8fAA8PD8aPH8+XX35JdnY2UFyIsLS0NGZMEalhKkSIiIgI33zzDS1atGDYsGFA8S8Pr7/+Oo8++iiPPvoomzZtwsXFxcgpRUSqh4mJCa+88gpLlixhxYoVDBkyhPj4eKB4o81Jkybx008/kZGRYeSkIiLXtp9//pnExERefPFFY0eRahQbG8uoUaMYMmQIsbGxALz44oskJCQwf/58ioqKyM/PVyFC5Aaj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paWlREZGct111/HMM88YHU6H9euvvzJhwgSWLFnCRRddZHQ4IiKd1tVXX82qVatISEjAYrEYHU6HVF1dTWxsLBMnTuT99983OhwRERERERExkB7hkxPC66+/TklJCffdd5/RoXRop5xyChMmTGDevHkoBykicnz279/Pxx9/zP33368kxFFYLBbuv/9+Pv74Y5KSkowOR0RERERERAykRIR0elVVVcyfP5+rr76aiIgIo8Pp8ObOnctvv/3GqlWrjA5FRKRTeuqppwgICOCmm24yOpQO76abbsLf35/58+cbHYqIiIiIiIgYSIkI6fTef/990tPTmT17ttGhdArnn38+Q4YM4T//+Y/RoYiIdDpZWVm8+eab3H333Xh6ehodTofn5eXFXXfdxX//+1+ys7ONDkdEREREREQMokSEdGp2u50nnniCiy++mAEDBhgdTqdgMpmYO3cu3377LVu2bDE6HBGRTuX555/H1dWVO++80+hQOo2//OUvuLi48PzzzxsdioiIiIiIiBhEiQjp1L744gvi4uKYM2eO0aF0KpdffjnR0dE8/vjjRociItJpFBcX89JLL3HbbbcREBBgdDidRmBgILfddhsvvfQSxcXFRocjIiIiIiIiBlAiQjotp9PJvHnzOOOMMxgzZozR4XQqrq6uPPDAA3z66ackJiYaHY6ISKfw6quvUlFRwX333Wd0KJ3OvffeS1lZGa+99prRoYiIiIiIiIgBTE6n02l0ECLH48cff+Tss8/mu+++49xzzzU6nE6noqKC6OhoLrnkEl599VWjwxER6dAqKyuJiYnhwgsv5PXXXzc6nE7ppptuYtmyZezfvx93d3ejwxEREREREZF2pBUR0mnNmzePkSNHcs455xgdSqfk4eHBPffcw1tvvUVGRobR4YiIdGjvvvsuWVlZPPDAA0aH0mnNnj2bzMxM3n33XaNDERERERERkXamFRHSKW3YsIHRo0fz6aefMnXqVKPD6bQKCwuJjIzkjjvuYN68eUaHIyLSIdXU1NC/f39GjBjBwoULjQ6nU5syZQpbt25lz549uLi4GB2OiIiIiIiItBOtiJBO6fHHH6d3795ceumlRofSqfn7+zNjxgxeeeUVioqKjA5HRKRDWrRoEYmJicydO9foUDq9uXPnkpCQwOLFi40ORURERERERNqRVkRIpxMXF8eAAQNYsGABt9xyi9HhdHoZGRnExMTwyCOP8OCDDxodjohIh+J0Ohk5ciQhISF8//33RodzQjjnnHPIy8tj48aNmEwmo8MRERERERGRdqAVEdLpPPnkk3Tv3p1rr73W6FBOCGFhYVx//fU8++yzVFRUGB2OiEiH8v3337NlyxathmhFc+fOZfPmzfzwww9GhyIiIiIiIiLtRCsipFNJS0sjJiaGxx57jPvvv9/ocE4YCQkJ9OvXjxdffJEZM2YYHY6ISIdx+umnU15eztq1a/X0fitxOp2cfPLJ+Pj4sHz5cqPDERERERERkXagFRHSqTzzzDN4eXlx6623Gh3KCaV3795MnTqVJ598kpqaGqPDERHpENasWcPKlSt58MEHlYRoRSaTiblz5/LTTz+xdu1ao8MRERERERGRdqAVEdJp5OfnExkZyT333MO//vUvo8M54WzevJmRI0fy4YcfcsUVVxgdjoiI4S6++GL27NnDrl27MJv17EZrcjgcDBw4kAEDBvD5558bHY6IiIiIiIi0MX2qlk7jpZdewuFwcPfddxsdyglpxIgRTJo0iXnz5qH8pIh0dbt27eKLL75gzpw5SkK0AbPZzOzZs1myZAm7d+82OhwRERERERFpY1oRIZ1CWVkZUVFRXHHFFbzwwgtGh3PCWrlyJaeffjpff/01559/vtHhiIgY5vrrr+fHH38kMTERNzc3o8M5IdlsNmJjYznnnHN46623jA5HRERERERE2pAe8ZNO4c0336SwsJBZs2YZHcoJbeLEiYwdO5Z58+YZHYqIiGGSk5P54IMPmDVrlpIQbcjd3Z377ruP999/n5SUFKPDERERERERkTakRIR0eNXV1Tz11FNcccUVREdHGx3OCe1QA9FVq1bx66+/Gh2OiIgh5s+fj6+vLzfffLPRoZzwbr31Vnx8fJg/f77RoYiIiIiIiEgbUiJCOryPPvqI5ORk5syZY3QoXcLkyZMZOHCgVkWISJeUm5vL66+/zsyZM/H29jY6nBOet7c3M2fO5PXXXyc3N9focERERERERKSNKBEhHZrD4eDxxx9n8uTJDB482OhwugSz2cycOXP46quv2L59u9HhiIi0qxdeeAGTycTMmTONDqXLmDlzJk6nkxdffNHoUERERERERKSNKBEhHdpXX33Frl27mDt3rtGhdClXXHEFERERPPHEE0aHIiLSbkpKSnjhhRe49dZbCQoKMjqcLiM4OJhbbrmFF154gdLSUqPDERERERERkTagRIR0WE6nk//85z+ceuqpjB8/3uhwuhSLxcL999/PRx99RFJSktHhiIi0i9dff52SkhLuu+8+o0PpcmbNmkVxcTGvv/660aGIiIiIiIhIGzA5nU6n0UGINGblypWcfvrpfP3115x//vlGh9PllJWVERUVxfTp01UuQ0ROeDabjV69enHuuefy1ltvGR1Ol3T99dfzv//9j3379uHm5mZ0OCIiIiIiItKKtCJCOqx58+YxdOhQzjvvPKND6ZK8vLy4++67eeONN8jOzjY6HBGRNvXBBx+Qnp7O7NmzjQ6ly5o9ezZpaWl88MEHRociIiIiIiIirUwrIqRD2rJlCyNGjODDDz/kiiuuMDqcLis/P5/IyEjuuece/vWvfxkdjohIm7Db7QwcOJCBAwfy+eefGx1Ol3bxxRezZ88edu3ahdms52VEREREREROFPqEJx3SvHnziImJYerUqUaH0qUFBgZy22238dJLL1FcXGx0OCIibWLJkiXs3buXuXPnGh1Klzd37lzi4uJYsmSJ0aGIiIiIiIhIK9KKCOlwEhIS6NevHy+++CIzZswwOpwuLzU1lV69evHvf/+bBx54wOhwRERaldPp5OSTT8bHx4fly5cbHY4AZ5xxBmVlZaxduxaTyWR0OCIiIiIiItIKtCJCOpynnnqKkJAQbrjhBqNDEaBnz55ce+21PP3001RWVhodjohIq1q+fDkbNmzQaogOZO7cuaxfv56ffvrJ6FBERERERESklWhFhHQoGRkZREdH8/e//103hTqQuLg4BgwYwIIFC7jllluMDkdEpNWcffbZ5Ofns3HjRj1930E4nU5GjRpFcHAw33//vdHhiIiIiIiISCvQigjpUJ599lmsVqtKMnUw/fr149JLL+WJJ57AbrcbHY6ISKtYv349P/74Iw8++KCSEB2IyWRi7ty5/PDDD2zcuNHocERERERERKQVaEWEdBiFhYVERkZyxx13MG/ePKPDkd/ZsGEDo0eP5pNPPuHyyy83OhwRkT9sypQpbN26lT179uDi4mJ0OHIEu91Ov379GDFiBAsXLjQ6HBEREREREfmDtCJCOoxXXnmFqqoq7rnnHqNDkUacdNJJnH322cybNw/lL0Wks4uLi2Px4sXMnj1b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PdhsNl5++WWjQxEREREREZEmKBEhber7779ny5YtWg3RxVx77bV069aNJ5980uhQROQE5+bmVpeIqKio4Nlnn+WGG26ge/fuQO2KiW+//RaHw2FkmNKGwsLCuP7663n22WepqKgwOhwRERERERFphBIR0qbmzZvH6NGjOeOMM4wORdqR1Wrl3nvv5Z133iEtLc3ocETkBHYoEeF0OnnrrbfIy8vj/vvvByAzM5OzzjqLyZMnk5WVZXCk0pbuv/9+cnNzefvtt40ORURERERERBqhRIS0md9++40VK1bw4IMPYjKZjA5H2tntt9+Op6cnzzzzjNGhiMgJzM3NDahdDfHkk09y+eWXExsby5o1axg1ahTx8fGsWLGCsLAwgyOVttS7d2+mTp3Kk08+SU1NjdHhiIiIiIiIyO8oESFtZt68efTr14+LLrrI6FDEAL6+vtx5550sWLCA/Px8o8MRkRPUoUTERx99RFJSEnPmzOHVV1/ltNNOIyYmhk2bNnHKKacYHKW0h7lz57J//34+/fRTo0MRERERERGR31EiQtrErl27+OKLL5gzZw5ms77Nuqq77rqLmpoaNRAVkTbj7u4OwFNPPcW5557L888/z4wZM7jttttYvny5VkJ0IcOHD2fSpEnMmzcPp9NpdDgiIiIiIiJyBN0hljbxxBNP0KNHD6666iqjQxEDdevWjRtvvJHnnnuO8vJyo8MRkRPQoRURe/bs4cCBA3z00Ue88847vPDCC3X7pOuYO3cu27dvZ9myZUaHIiIiIiIiIkdQIkJaXXJyMh988AGzZs3STSDh/vvvp6CggDfeeMPoUETkBHTo74zZbMZms7F69WquvfZag6MSo0ycOJGxY8cyb948o0MRERERERGRIygRIa1u/vz5+Pr6cssttxgdinQAMTExTJ8+naeeeorq6mqjwxGRE0xpaSkAw4YNY8OGDYwYMcLgiMRIJpOJBx98kFWrVvHrr78aHY6IiIiIiIgcZHKqiK60otzcXCIjI5k9ezaPPvqo0eFIB7F9+3aGDh3Ku+++yzXXXGN0OCJyAqmpqeGNN97gpptuwtXV1ehwpANwOBwMGTKEXr168eWXXxodjoiIiIiIiKBEhLSyRx55hKeeeooDBw4QHBxsdDjSgVx44YUkJSWxbds2NTAXEZE29e6773Ldddexbds2hgwZYnQ4IiIiIiIiXZ7uBspxsdls9OrVi40bN9ZtKy0t5YUXXuCWW25REkIamDt3Ljt37uSrr76qt33o0KH88MMPBkUlIiInoiuuuILIyEieeOKJetsffvhh/vKXvxgUlYiIiIiISNelGgZyXKqqqti/fz8JCQmMGjUKgNdee42SkhJmzZplcHTSEU2YMIEJEybwn//8h8mTJ2MymbDb7Wzfvp2UlBSjw5NOJjk5mdzcXKPDEGl3wcHBREZGGh1Gh2exWLj//vu59957+cc//kFMTAwAu3btory83ODoREREREREuh4lIuS4uLu7A7UJCahdITF//nyuvvpqIiIijAxNOrC5c+dy4YUXsmrVKiZOnFj3/XPo+0mkOZKTkxnQvx/lFZVGhyLS7jw9rOzeE6dkRDPcdNNN/OMf/2D+/Pm8+OKLQO28RX9zRERERERE2p8SEXJcLBYLUJuAAPjggw9IT09n9uzZdcc4nU4cDgcuLi6GxCgdQ01NTV0D2fPPP5/Bgwczb948Jk6cWPf94+bmZmSI0snk5uZSXlHJC1P60CfE0+hwRNpNfE45Mz+LJzc3V4mIJhz5N8fT05O77rqLxx57jL/97W+EhoZis9nw9/c3NkgREREREZEuSIkIOS4mkwmLxUJVVRV2u50nnniCiy++mAEDBgCwdetWLrvsMq688kr+8Y9/GBytGGXbtm2cfPLJPPfcc9x6662YTCbmzp3L1VdfzZYtWwgPDweUiJDj0yfEkyHh3kaHISIdyODBgxk6dChvvPEGPj4+3HnnnTzxxBM8//zz/Otf/6Kqqkp/c0RERERERAygZtVy3Nzc3KiqqmLJkiXExcUxd+5cAN5//33GjRuHr68vN998s8FRipEGDhzILbfcwu23387NN99MZWUl06ZNIzo6mscff1ylmUREpFXNmzePZcuWMXbsWOLi4ggMDOS2227jxRdfpLi4WKWZREREREREDKJEhBw3d3d3bDYb8+bN44wzzmDkyJHcfffdXHPNNUydOpVff/1VpSO6OFdXV1544QXefvttPvzwQyZMmEB6ejoPPPAAn376KfHx8YBWRIiISOu4+OKLWbduHQ6Hg5NPPpkvvviCe++9l/LychYsWKAVESIiIiIiIgZRIkKOm5ubG3v27GHDhg3ceuutnHXWWbz88su89NJLvP3223h4eBgdonQQ1113HatXryYv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1t3nrHMHtHQl7r8Dqx1zsLXm39e05N9/28Hwd9Wd1zXAia4BtS+lNKClKwNaXrg9FIzWVjw8MICHBwZYOpQLiqX/zRM5V/qzKyIiIiLStDV4IsLLywuTvQMR3zzR0JcSaTAmewe8vLwa9ZpeXl442Jt4Yn5Eo15XpL442Jsa/ftGRM6NPq/JxcASn9dERERERKR2GjwR0aJFC44cPkRKSkpDX0qkwXh5edGiRYtGvWaLFi04dPiIvnfkgmWJ7xsROTf6vCYXA/27IyIiIiLSdDVKaaYWLVrohwKRc6DvHRERaSz6N0dEREREREQaipWlAxARERERERERERERkYuXEhEiIiIiIiIiIiIiItJglIgQEREREREREREREZEGo0SEiIiIiIiIiIiIiIg0GCUiRERERERERERERESkwSgRISIiIiIiIiIiIiIiDUaJCBERERERERERERERaTBKRIiIiIiIiIiIiIiISINRIkJERERERERERERERBqMjaUDEBERORfhyXmWDkGkUenPvIiIiIiIiFyolIgQEZELipeXFw72Jp6YF27pUEQanYO9CS8vL0uHISIiIiIiIlInBrPZbLZ0ECIiInURExNDSkqKpcNoFO+++y7Lli3jt99+w8HBwdLhNCn/93//x549e1i0aBE2NpfGsxVeXl60aNHC0mGIiIiIiIiI1IkSESIiIk1USkoKLVq0YPLkyfznP/+xdDhNzoEDB+jatSszZszgnnvusXQ4IiIiIiIiIlIDJSJERESaqJdffpn33nuP6OholeOpwQ033MCxY8c4cOAAVlZWlg5HRERERERERKqhn9hFRESaoJycHD799FMeeughJSHOYOrUqRw8eJAlS5ZYOhQRERERERERqYF2RIiIiDRBH3zwAVOmTCEyMlI9Ac5i8ODBlJSUsHnzZgwGg6XDEREREREREZF/0I4IERGRJqawsJD333+fu+++W0mIWpg6dSpbt25lw4YNlg5FRERERERERKqhHREiIiJNzPTp0xk/fjwHDx6kQ4cOlg6nyTObzXTr1o2AgACWL19u6XBERERERERE5B+UiBAREWlCSktL6dSpEx06dGDhwoWWDueC8fPPPzN27Fj27NlD9+7dLR2OiIiIiIiIiPyNEhEiIiJNyPz58xk1ahRbt26lb9++lg7nglFSUkKbNm3o168fs2bNsnQ4IiIiIiIiIvI3SkSIiIg0EWazmT59+uDs7MyaNWssHc4F54svvuCJJ57g6NGjhISEWDocERERERERETlFzapFRESaiDVr1rBz506mTp1q6VAuSOPGjcPLy4t3333X0qGIiIiIiIiIyN9oR4SIiEgTMXz4cFJTU9m1axcGg8HS4VyQ3nzzTf7zn/8QFRWFn5+fpcMREREREREREbQjQkREpEnYuXMnq1evZurUqUpCnIdHHnkEOzs7Pv74Y0uHIiIiIiIiIiKnaEeEiIhIEzBq1Cj27dvH4cOHsba2tnQ4F7QpU6bw1VdfERMTg6urq6XDEREREREREbnkaUeEiIiIhR05coQFCxYwefJkJSHqwdNPP01hYSFffPGFpUMREREREREREbQjQkRExOIefPBBli1bxvHjx7Gzs7N0OBeFiRMnsnDhQqKiorC3t7d0OCIiIiIiIiKXNO2IEBERsaATJ04wY8YMnnnmGSUh6tGkSZNISUnh+++/t3QoIiIiIiIiIpc87YgQERGxoOeee47p06cTHR2Ni4uLpcO5qIwZM4bt27dz9OhRbGxsLB2OiIiIiIiIyCVLOyJEREQsJC0tjWnTpvHYY48pCdEApkyZwvHjx5k7d66lQxERERERERG5pGlHhIiIiIX897//5Y033iA6OhofHx9Lh3NRuvbaa4mPj2fv3r0YDAZLhyMiIiIiIiJySdKOCBEREQvIzc3l448/Zvz48UpCNKCpU6eyf/9+li9fbulQRERERERERC5Z2hEhIiJiAZ988gnPPvssERERBAcHWzqci5bZbGbAgAEYjUb+/PNPS4cjIiIiIiIicklSIkJERKSRFRcXExISwuWXX87MmTMtHc5Fb9GiRdx8881s3LiRgQMHWjocERERERERkUuOEhEiIiKNbMaMGdx3333s37+fLl26WDqci15ZWRldunShVatWLFmyxNLhiIiIiIiIiFxylIgQERFpRLopbhlK/oiIiIiIiIhYjhIRIiIijeh0maBNmzYxYMAAS4dzyVA5LBERERERERHLUSJCRESkkZjNZvr374+tra0aJ1uAGoSLiIiIiIiIWIaVpQMQERG5VPz5559s27aNqVOnWjqUS9L48eNxc3Pjvffes3QoIiIiIiIiIpcU7YgQERFpJNdeey1xcXHs27cPg8Fg6XAuSf/973954403iI6OxsfHx9LhiIiIiIiIiFwStCNCRESkEezZs4fff/+dqVOnKglhQY899hjW1tZ88sknlg5FRERERERE5JKhHREiIiKNYMyYMWzfvp2jR49iY2Nj6XAuac899xzTp08nOjoaFxcXS4cjIiIiIiIictHTjggREZEGFhERwdy5c3n++eeVhGgCnnnmGXJzc5k2bZqlQxERERERERG5JGhHhIiISAObOHEiCxcuJCoqCnt7e0uHI8CDDz7Ib7/9xvHjxzGZTJYOR0REREREROSiph0RIiIiDSghIYHvvvuOp59+WkmIJuT5558nMTGRmTNnWjoUERERERERkYuedkSIiIg0oClTpvDVV18RExODq6urpcORvxk1ahT79u3j8OHDWFtbWzocERERERERkYuWdkSIiIg0kIyMDL788kseeeQRJSGaoKlTpxIREcH8+fMtHYqIiIiIiIjIRU07IkRERBrIm2++ySuvvMLx48fx8/OzdDhSjeHDh5OamsquXbswGAyWDkdERERERETkoqQdESIiIg0gPz+fjz76iPvvv19JiCZs6tSp7Nmzh1WrVlk6FBEREREREZGLlnZEiIiINIAvvviCJ554gqNHjxISEmLpcKQGZrOZPn364OzszJo1aywdjoiIiIiIiMhFSYkIERGRelZSUkKbNm3o168fs2bNsnQ4chbz589n1KhRbN26lb59+1o6HBEREREREZGLjhIRIiIi9eznn39m7Nix7Nmzh+7du1s6HDmLsrIyOnbsSIcOHVi4cKGlwxERERERERG56CgRISIiUo/MZjPdunUjICCA5cuXWzocqaXp06czfvx4Dh48SIcOHSwdjoiIiIiIiMhFRc2qRURE6tGyZcs4cOAAL7zwgqVDkToYO3YsAQEBvPPOO5YORUREREREROSiox0RIiIi9Wjw4MGUlpayadMmDAaDpcOROvjggw+YMmUKx44dIzAw0NLhiIiIiIiIiFw0tCNCRESknmzcuJGNGzcydepUJSEuQA899BDOzs68//77lg5FRERERERE5KKiHREiIiL15Prrr+f48eMcOHAAKyvl+i9EL7/8Mu+99x7R0dF4eXlZOhwRERERERGRi4LukoiIiNSD/fv389tvvzF16lQlIS5gTzzxBGazmc8++8zSoYiIiIiIiIhcNLQjQkREpB7cfffdbNiwgYiICIxGo6XDkfPw1FNP8eOPPxIdHY2Tk5OlwxERERERERG54OmRTRERkfN0/PhxZs+ezaRJk5SEuAg899xzZGVl8c0331g6FBEREREREZGLgnZEiIiInKfHHnuMX375hejoaBwcHCwdjtSD+++/n9WrV3Ps2DFsbW0tHY6IiIiIiIjIBU07IkRERM5DYmIi06dP56mnnlIS4iIyefJk4uLi+OmnnywdioiIiIiIiMgFTzsiREREzsOLL77IJ598QkxMDO7u7pYOR+rRzTffzOHDhzl48KAakIuIiIiIiIicB/1ULSIico6ysrL4/PPPefjhh5WEuAhNnTqVI0eO8Ouvv1o6FBEREREREZELmnZEiIiInKN3332XF198kePHjxMQEGDpcKQBDB06lNzcXLZt24bBYLB0OCIiIiIiIiIXJO2IEBEROQcFBQV88MEH3HfffUpCXMSmTp3Kjh07WLt2raVDEREREREREblgaUeEiIjIWURFReHq6lqp/NLXX3/NxIkTOXz4MG3btrVgdNKQzGYzPXv2xNvbm5UrV1o6HBEREREREZELknZEiIiInMWYMWN46623Kr4uLS3lnXfe4bbbblMS4iJnMBiYOnUqq1atYteuXZYOR0REREREROSCpESEiIjIWRQXF5OZmVnx9fz584mMjGTq1KkWjEoay6hRowgJCamUjBIRERERERGR2lMiQkRE5Czs7OwoKioCykv1vPnmmwwfPpxevXpZODJpDNbW1kyePJn58+dz9OhRS4cjIiIiIiIicsFRIkJEROQsbG1tKxIRK1euZO/evZV2Q8THx7Nz505LhSeN4N5778XX15d3333X0qGIiIiIiIiIXHCUiBARETkLW1tbCgsLAXjrrbe47LLLGDp0KAB//PEH3bp1Y/LkyZYMURqYyWTimWee4YcffiAuLs7S4YiIiIiIiIhcUJSIEBEROYvTpZm2bt3KunXrKnZDvPvuu4wYMYKePXsyd+5cC0cpDW3ixIk4ODjw4YcfWjoUERERERERkQuKEhEiIiJncbo001tvvUW7du0YNmwYd9xxB5MnT2bKlCksW7YMT09PS4cpDczFxYXHHnuMadOmkZaWZulwRERERERERC4YSkSIiIicha2tLWlpaSxatIh7772XAQMGsGLFChYsWMAbb7yBtbW1pUOURvLkk09SUlLCF198YelQRERERERERC4YSkSIiIichZ2dHVFRUXh4ePD2229TVlbG9u3bueWWWywdmjQyX19fHnjgAT7++GPy8vIsHY6IiIiIiIjIBUGJCBERkbMoKioiKSmJtLQ0rrrqKrZv30779u0tHZZYyKRJk0hPT+d///ufpUMRERERERERuSAoESEiInIWcXFxALzyyivMmzcPZ2dnC0ckltSyZUvGjBnDe++9R3FxsaXDEREREREREWnyDGaz2WzpIERERJqyw4cPEx4ezg033GDpUKSJOHDgAF27dmXGjBncc889lg5HREREREREpElTIkJERETkHFx//fVERUWxf/9+rKy0yVRERERERESkJvqpWUREROQcTJ06lbCwMJYuXVrpeNeuXVm1apWFohIRERERERFperQjQkTkHMTExJCSkmLpMETOmZeXFy1atLB0GBe8wYMHU1JSwubNmzEYDJSWlmJjY8P//vc/HnjgAUuHJyIiIiIiItIk2Fg6ABGRC01MTAwdOrQnLy/f0qGInDMHB3sOHTqsZMR5mjp1Ktdffz0bNmxgyJAhFBUVAWBnZ2fhyERERERERESaDiUiRETqKCUlhby8fL558UHaBflZOhyROjsSncBDr39LSkqKEhHnoKSkBBub8o9QI0eOpHPnzrz11lsMGTKEwsJCAGxtbS0ZooiIiIiIiEiTokSEiMg5ahfkR/e2QZYOQ0Qa0f79++nTpw8ff/wxEyZMwGAwMHXqVO6++2727t2Lv78/oESEiIiIiIiIyN+pWbWIiIhILXXs2JGHHnqIiRMn8uCDD1JQUMDo0aMJDg7m7bffVmkmERERERERkWooESEiIiJSSzY2Nnz66ad8//33/PzzzwwaNIj4+Hief/55fvnlF8LDwwHtiBARERERERH5OyUiREREROrovvvuY/PmzaSmptKrVy+Cg4Px9PRk2rRpgBIRIiIiIiIiIn+nRISIiIjIOejRowc7d+6kZ8+e3HDDDfTq1YsFCxYAKs0kIiIiIiIi8ndKRIiIiIicI09PT5YtW8aUKVP4/fffKS0tBbQjQkREREREROTvlIgQEREROQ/W1ta88cYbLFiwABsbGwDMZrOFoxIRERERERFpOmwsHYCIiJzdT8s38cjb31U69uWUcYy9dqCFIvrLwPGvcCAyttKxrHXfWigaEcu55ZZbWL9+Pc899xzt27e3dDgiIiIiIiIiTYYSESIiFxAXR3s6tgwAwNvDpcr47sNRbDkQzp4jUew+EkXkiSTMZjNvPjaax24fftb1F67byfdL/2Tv0Why8wvx9XBh2GWdeXbstQT7eVd7Ttc2gTja21FYXMKeI1Hn9fouRJv3H+WTOSvZHhZJdm4+/t7uXDeoO5Puvg4PF6cmt640rH79+rFp0yZLhyEiIiIiIiLSpCgRISJyAenaOpBlH0+ucfyJd3+osjuhNsrKynj4zenMWbUVgBa+nrT09yYyNpHvl/7J3NXbmPf2Uwzs1rbKuV9OfQCA6IQUutw5tc7XvpB9u2gtkz7+mbIyM35ebnRo6c+R6JN89ssqFq7dyYpPp9KimWeTWVdERERERERExBKUiBARuYgE+3vRpkUzerYLpke7IP7zzQJ2HDx21vM+mbOCOau24mCy5buXHubaAd0AKCwq5j/fLODzuasY++8v2P3ja3oa/5R94TE8//EsysrMvPvkXUy4ZSgGg4G0rBzu/8801u0+xP2vTGPNl/9qEus2lpiYGFJSUiwdhohFeHl50aJFC0uHISIiIiIi0uQoESEichH56b+PVfraznj2v+bLysr4ZM5KAJ4bO7IiCQFgZ2vkjUfvYPO+o+w5Gs1nv6zipQdvqd+gz0FRcQkrtu7nhsE9LRbDOzOWUFpWxu1X9eXhW6+sOO7h4sR3L02g610vsPPQMX7fsp9r+ne1+LqNISYmhg7t25GXX2DpUEQswsHexKHDR5SMEBERERER+QclIkREGtGUT2fz5fzVtAvyY/20/8PBZFdpfO/RaK567E2KS0pZ+O7TXNm7U4PHFB57kpSMbABuHXpZlXGDwcAtQ3uz52g08/7YZtFExI6Dx5i1cgsL1uwgLSvHYk2xc/IKWLUtFIAHb7yiyrinmzM3Xd6LH5dvYsHaHbVOGDTUuo0lJSWFvPwCPr2tNW287C0djkijCk/J54n5EaSkpCgRISIiIiIi8g9KRIiINKJXH76NjXuPcCAylhc+n8PHz91bMZabX8gD//2aouISnrhjRKMkIQDSs3Irfu3v7V7tnAAfDwCiElJITM3E19O1UWIDiE1MZfbKLcxeuZXw2JMAWFkZGNKjfaPF8E/7I2IoKCrG1mhD744tq50zsFtbfly+ie1hkRZft7G18bKni79KeImIiIiIiIhIOSUiREQakZ2tkekvPcTlD7/Gd0v+ZNhlnbhxSC8AJn86i4jYRLq3bcHLD93aaDG5OjlU/Do+OZ2Q5r5V5sQlpVX8+khMQoMnInLyCli0fhezVm5hw94jmM1mADq1CuCOq/pxx1V9K5Ijf5eYmsk9L395Ttd896m76Namdk8xR8QmAhDo64nRpvp/Slv5+wAQlZBMcUlJjfMaY10REREREREREUvS3QsRkUbWLsifNx4dzdMfzOTxd3+gZ/uW7Dh4jJnLNuJosuN//zcB21r0dqgvbQKb4eJoT1ZuPr+u38VzY0dWGjebzfy6flfF1xnZuf9col6UlZWxdtchZq3YzNKNe8grKALAz8uNUVf2YcyI/nRpHXjGNQqKitkaGnFO18/Kyav13PRT74G7s2ONc9xdysfKysxk5Rbg6Xr2HQINta6IiIiIiIiIiCUpESEiYgEP3Hg5f+wIZcmGPdz78ldEnCo59Nbjo2nTolmjxmJjY834Gy/nw1m/897M32jp713RK6KgsJh/ffkLuw9HVcw/nSCoL/HJ6Xw5fzW/rN5GQkoGAM4OJu66egCjh/fj8p7tsbKyqtVaQX5ejdI3oqCoGABbo3WNc+xsjX/NL6zde9ZQ64qIiIiIiIiIWJISESIiFvLp8/ex+3AUOw8dA+CmIb247/ohFonlhftvYtfhKP7cc5j7X5nGpI9/xs/TjYgTieQXFjHuhiF8t+RPAFwc67cJ8dqdB/l49goAAn09ePmh27hhcA/s7Wzr9Tr1yXQqGVBUXFrjnMJTSQUAUy1fS0OtKyIiIiIiIiJiSbV7xFREROqdh4sTXf/Wk+C+6wdbLBaTnZGF7z7NO0/eSa8OLSkoLCIyLpEOLf356oUHeOH+Gyvm+ni41Ou1/bzdKpIbsYlp/Pfbhbw7cylHouPr9Tr1ye1UX420rJwa55xuAm5lZcDF0WTRdUVERERERERELEk7IkRELGTGbxtYvnkfVlYGysrMPPfRT2z89mWcHSxzc9loY8PEW4cx8dZhVcbW7Tp0ao41XULO3Kehrq7s3YnwBe+zdOMeZq3YwtqdB3nvx2W89+MyurVpwejh/bjtyj74ebmdda3GalZ9unzWiaS0GhtGH4tPAiDYz7vWDaUbal0REREREREREUvSHQwREQsIjz3JlE9nA/C//3uIz+euZuehYzz30U98/a/xFo6uqt827QFgeN8ulXoU1Bd7O1tuH9aX24f1JTE1k19Wb2XWyi3sC49hX3gM//fVXC7v0Z47hvfjxiG9akzWNFaz6q6tW2BntKGwuIQdB48xoGvbKnM27TsKQJ9OIRZfV0RERERERETEkpSIEBFpZEXFJYz/79fkFhRy33WDue3KPvRoF8zgh15l9sotDO/bmduH9bV0mBUiTiQy47eNADw26qoGv56vpytPjL6aJ0ZfTWhkLD+v2Mzc1dtZu+sQa3cd4tkPf+LaAd0YPbwv1w7oXuncxmpW7eRg4qo+nflt017+t3h9lYRBakY2i9bvAuCWK3pbfF2pP5uPZ3L79wdp7mbHtmd6Ntk1RURERERERJoS9YgQEWlkr3yzgL1HY2gT2Iy3nxgDQKsAH9596i4Anv3gR6ITUho1prikNH76fRM5eQUVx8xmM2t2hnHjs+9XNKwe3KN9o8bVOSSQNx4dzeG57zL3rSe5dehlACxYu4PR//qsUWP5pyn33YCVlYG5q7cxbcEazGYzUN7fYdyrX5OdV0DP9sFc079rlXNHPP4WnUdP4fO5q+p1XZGGNmdPEjd9G0r7N7bT5vVtXP3Vfr7ZkkBpmblJrisiIiIiIiJNg3ZEiIg0ojU7w/hs7ipsjTZMf2kCDia7irG7rh7Aqm2hzF+znYde/5blH0/G2rpu+eKPZi3no1krKr7Oys0H4LX//cq7M3+rOL7x25do7uNR8XVqZg6PvPUdT7w7g+Y+7ni4OnEiMY2k9CwA7ry6P+8/NfacXnN9sLa24up+Xbm6X1eycvNZuHYHs1dttVg8AN3bBvH243cy+dNZPP/Jz3zw8zJ8PVw4En2S/MIi/Lzc+P7lhzEYDFXOjU9OJyYxlcxqykGdz7rS8OyNVoR4mWjmbNuk16xvZrOZJ+ZHsPBAeZI0xMuErbUVYSdzCU3IZfXRdGaObY+tTd3+zmqodUVERERERKRpUSJCRKSRpGZkM/HN6ZjNZl5+8JZqGyN/9Ozd7AiLZGtoBG/PWMK/xt1Up2vkFRSRlpVT5XhuQSG5BYUVX5eWllUaD/Dx4PE7hrNp71GiT6YSl5yOl5szNw3pxf03DGHYZZ3qFEdDcnG0577rh3Df9UMsHQoP33olnUOa88mcFWwLjeTg8Xj8vd0ZOaAbz99zPZ6uTk1qXTl/PZo78+cTPZr8mvVt+raTLDyQgqvJmul3tqdfsAsAhxPzuOenQ2w8lsm7a2J5cURQk1hXREREREREmhYlIkREGomnmzNH579/xjmuTg6Eznn7nK/xr3E31Tl5AeDp6sQbj44+5+teygZ2a8vAblWbSp9JbX6Pz2VdkYZQUmrm4z9PAPDi8KCKZAFAe18H3rsxhLtmHmL6tgQeGeSPh0PtGto31LoiIiIiIiLS9CgRISJyAdkfEcuIx98CYNI91zGibxcLRwSPvDWdyBNJFBaXWDoUkTpJyCrkvTWxrI3IICO/BD8XO27q7MmTQ5ozdekx5u5N5tkrmvPc0MCKc87UWLrvh7s5kVHI3Ps74udiy/trT7DxeCZZBSUEupkY08Obhwf4Y2VVuaxWU29WvTkqk9TcEhxsrbitm3eV8ctbuxHkbkd0eiErD6czpqePRdcVERERERGRpkeJCBGRC0hWbj5bQyMASE7LsnA05faHx3IgMtbSYYjUSWRKPrdODyMltxgbKwPtfR0oKC7j4z/j2HAskxbudmdfpAahCbk8MOsIpWYzrb3ssTJAREo+r62K4URmIa9f16oeX0nD2xVbXu6te4ATJmP1vRr6BrkQnZ7MrtjsWicMGmpdERERERERaXqUiBARuQCMvXYgY68daOkwqrXpfy9bOgSROilvkBxOSm4xPZs78fXotvi5lCceQhNyue+nQxxIyD3n9d9YHcOYHj68fHUQ9rbWAHy7JYGXf4/ihx2JPNDXjxAv+/N+HWvC0/nkz7hzOvfX8Z1rPfdYannT+5YephrnBJ0aizw115LrioiIiIiISNOjRISIiIhcUjYdz2JffC4mG0OlJARAZz9HPrylNXfOOHTO67f2sueN61pWKsH0YH8/ftmbRNjJPNaEZ9RLIiI5p5gdMdnnvc7ZZOSXl11zs6/5Y+Ppscz82pdoa6h1RUREREREpOlRIkJEREQuKesiMgC4orVbpSTEaUNC3GjuZseJjMJzWn9MD58qfSAAejR3JuxkHtFpBee07j+N7uHD6B4NX66osKQMAKN11dd0msmmvLRSwam5llxXREREREREmp7qC/KKiIiIXKROlwTq2MyxxjkdfR3Oef1gz+pLDXk5lj//kVtUes5rW4LdqWRAcam5xjmnEwWnEweWXFdERERERESaHv1UJyIiIpeU3KLym9uOp/o3VMfJruaxs3GoofGylaH8yf+ab7s3TafLI6Xn1Vwe6XSZJdczlFlqrHVFRERERESk6dFPdSIiInJJcbQtTxScaWdCTmHT37XQWM2qW3mW97M4foaSUqfLTYV41r73RUOtKyIiIiIiIk2PEhEiIhewDXsOc90z79HC15PQOW832TVFmpLyG+DpHErMq3HOmcaaisZqVt0r0AmAffE5FBSXYapmx8e26KxTc50tvq6IiIiIiIg0PUpEiIjIBeun5Zv4/rc/OXQ8ntLSMloH+jJmRH8m3joMa+v6qT74f1/O5ZM5KwB45LarePuJMbU6LyElgz73/ZvM3PJ+BDFLPsHNuXZ9B871mlI7V7R248tN8ayNyCAxuwhfZ9tK4xuOZRJ7jo2qG1NjNavuH+yCp6MNqbklzN+XzNjevpXG10dkEJ1eiJ2NgRHt3C2+roiIiIiIiDQ96hEhInIBszfZ0iawGS0DvJv0mvXNbDYz/rVveOTt79gWGomvhyvB/l7sj4jlhc/ncMvzH1JUXHPd+dracySKz+euOqdzn/3wx4okRGNdU2pnYEsXugc4UlBcxoQ5RzmZVVQxFpqQyzMLIzBaGywYYdNitLbiycHNAXh9VTRbo7Iqxg4n5jFpcSQA4/o0w8PRWOnc+MxC+n64m74f7mZXbOXdG+ezroiIiIiIiFxYtCNCROQC1rtDK3bNfK3Jr1nfvlrwB3NXb8PNyYFZrz/OwG5tATh4LI5RUz9m3e5DvDb9V159eNQ5X6O4pITH3/kBB5Mtvdq3ZN3uQ7U+d8HaHfy2aS/XD+rB0o17GuWaUnsGg4FPbm3DrdPD2BmbTb+PdtPOx4GikjKOJufTo7kTfYOc+fVAakWD6UvdA32bsetENotDU7ntuzBCvEzYWltxJCmPMnP57obJw1pUOa+0zMyJU7tLCkvK6m1dERERERERubBoR4SIiFxQSkpKeXfmbwC8OnFURRICoGOrAD59/j4Avpr/B6mZOed8nY9m/c6ByFj+b/zN+HvXvixMWlYOz3/yM819PPi/B25ulGtK3YV42bP84S6M6eGNu70N4cl5FJaU8fggf+be15HiUjMAznbWFo60abCyMvDFqDa8f1MIPZs7kZhdTHR6AR18HXj56iBm39sRO5u6f6xsqHVFRERERESkadGOCBGRJiI+OZ3Xv1vEqm0HSM/KJcDHg9uu7MPzd1/H0x/M5OcVm5l63w38a9xNFeecqbF059FTiElM5bcPJ+Hv7c4b3y9m/a5DZObkEeTnxT0jB/HEHSOwsqp8k6+pN6vesPcIKRnZOJrsGDO8f5XxYZd1Itjfm6j4ZJZt2ss9IwfV+RpHoxN4Z8ZSerYP5uFbruTRt7+v9bkvfD6H5PRs5rzxOI72do1yTTk3/q52vH9z62rHIlLKy2q1cK/8ezigpStxr1T9cwew7ZmeZ7zec0MDeW5oYJXjZ1qzKTEYDIzp6cOYnrXvSxHobjrrazuXdUVEREREROTCokfMRESagPDYkwye8Cozl20kJSOH9sH+2Fhb8e7MpVz3zLsUlZx7v4N9ETFc/vBrLNu4lwBvd9xdHDkac5J/fzWP5z+ZVY+vonFsP1heN75Xh5aY7KqvGz+wa5vyuWGRdV7fbDbz+Ls/UFpm5pPn7q2SqDmTP3aEMWvFFm4a0otrB3RvlGtK/dt9IpsjSfnYWBnoFehs6XBERERERERELnjaESEiYmFms5kHX/uW5PRsLuvYipmvPFJRlmdfeAx3vPAJe49Gn/P6L0+bz70jB/H6o3fgYCp/uvuLeauZ+tlsvl20jom3DaNNYLPzfh0rtx3gvVMlk+p87mdTaz03IjYRgFYBNT893dK/fCw89mSdY/l64Vq2hkbw5Oir6dqm9rXpc/MLeeq9Gbg42vPOk3c2yjXl3B1LzWfN0QxGdffGzf6vj0M7YrJ4bF44ADd08sRTTZJFREREREREzpsSESIiFvbnnsPsORKFydZYKQkB0K1NC76cOo6bJ314zuu3bdGM958eW+kp+0dHXcXPv29if0QsK7ceqJdERHJaFltDI857nbNJz84FwN3ZocY57i6OAGRk59Vp7djEVF75Zj5Bzbz417gb63TuK98uICYxlfefHoufl1ujXFPOXXZBKS//HsWrK6No5WmPk501J7OKSMgqAqCttz2vXBts2SBFRERERERELhJKRIiIWNjq7aEAXNWnc7UNiq/s3YkWvp7EJKae0/r3jBxcbamf3h1asT8iluPxyee07j+NvXYgY68dWC9rnUlhUTEARmPN/4SZbMufYs8vLKrT2k9/MJOc/EK+/8/Eit0jtbEtLJKvF67hso6tGH/j5Y1yTTk/QR4mnhoSwJ+RmZzILCQqrQA7Gyu6+jtybQcPxvf1w1GNqkVERERERETqhRIRIiIWdrrUUOeQ5jXO6dw68JwTETWVMPJyL699n5tfcE7rWordqSRDcXHNfTMKTiUr7O1sa73u7JVbWLUtlFuHXsaIvl1qfV5RcQlPvPsDVgYrPplUt/4O53pNOX9u9jZMHtaCycMsHYmIiIiIiIjIxU/dMEVELCw3vxAAZwdTjXOc7M/9SXlHU/U3460MBgDM5nNe2iLcnMpLMqVl5dY4J/3UmNsZyjdVmp+dy9TP5uDm5MDbj4+pUzwfzlrO4ah4nhw9gk6tak4m1ec1RUREREREREQuJNoRISJiYY6nkgzZeTXvTMg5laxoyhqrWXWbFuX9LI7FJdU453h8+Vhte1/EnkwlLSsHO6MNAx98pcp4Vm4+AD/89ifz12wHIGLhBwDsPVLeSPz7pRv4cfmmSueVlpVV/LrXvS9iwMCTo6/myTFXn9c1RUREREREREQuJEpEiIhYWOtAXwDCjp2ocU5YZM1jTUVjNavu0zEEgN2HoygoLMZkZ6wyZ9P+8PK5nULqtHZhcQlJ6Vk1jucVFJFXUH3fibSsnDOunZyeDUDOP0phnc815eI16rswtkRl8cHNIYzuUX15NREREREREZELhRIRIiIWdlWfznw8ewWrt4dxMjWDZp5ulcbX7TpE9MkUywRXB43VrHpQ97Z4uTmTkpHN7FVbuP/6IZXG/9gRRlR8MnZGG0YO6FarNbu2aUHWum9rHJ/45nR+XrGZR267irefqFxGadbrj9d4XnRCCl3uLN/tEbPkk0qlos7nmiKXis3HM7n9+4NnnHNjZ0++vL1tleNPL4xg7t7kM577493tGdrG/bxiFBERERERkbNTIkJExMKG9GhPz/bB7D4cxT0vf8mM/zyCn5cbAPvDY3jkrekYbawpLim1bKBNhNHGhkl3X8fUz2bz0lfzaBPYjIHdym9CHjwWxxPv/gDAw7cOw9PNudK5cUlpXP3E2wBMf2lCnXdMiIhl2NkY6OrvVO1Yay/7M57r72pLgGv1fXZc7fVRWEREREREpDHopy8REQszGAx88+KDXPPk22wLjaTzmCl0bBlAYXEJh6Pi6d2hFf27tmHeH9uxtraydLhNwsRbr2R7WCQL1u7g2qfeoU1gM2yN1hyKiqeszMzg7u349/ibq5xXUlpGTGIqAIVFxY0ctYicK28nW34d3/mczh3Tw4fnhgbWc0QiIiIiIiJSF7qjJSLSBLQJbMaf0/7NPSMH4eHixOGoeAqKinn2rmtZ+uFzlJzaDeHscOYnfy8VVlZWfPfSBD6ffD+XdWzFydQMouJT6NyqOW88dgeL3nsWO9uqvSNERERERERERKTxaUeEiEgTEeDjweeT76927Eh0AgDBfl6Vjg/u0b7GPgOhc94+4/X+Ne4m/jXupirHz7RmU2IwGLhn5CDuGTmo1ucE+Xmd02v76oUH+OqFB+p83rle73yueTFJyCrki43xrIvIID6zEAAPRyNB7iaGhLjyUH8/7I3WFfNDE3JZdjCVDccyic8sJDWvBGc7a7r4OXLPZb5c28Gz2uv0/XA3JzIKmXt/R7wcjby/7gRbojLJKyqjrbc9Tw5pzjUdPCpi+mh9HH8cTSctr5jmbnaM69OMcX39qqw7Z08Sz/4aSf9gF+bc15Fpm+OZuzeZmPQCHO2sGdTSleevDKSlZ90TjCcyCvlqUzzrIzOIzyrCxspAGy97RnX35u5evthYG6qcsy4ig++2nWRffA7peSU42lrh4Wikm78jN3XxYkQ7jzrHISIiIiIiIlIbSkSIiDRxOw4e41BUPDbW1uppIJeMuIxCRn59gJTcYozWBoLcTTjYWpGYXcS26Cy2RGUxqps39q5/JSKeXxzJ/vhcXE3W+Djb4uNsS0JWEesjM1kfmcnEAX78++rgGq+5Ly6HD9afwNpgoKWnidiMQvbF5/LgnCN8PqoNnZs5cvv3YWQWlNLW257SMjORKQX837IocgrLeGJIQLXrms1mJsw5wu+H0wlyt6ONtwNHk/NYFJrKH+EZzLmvI90Dqu9/UJ1VR9J5dN5R8orKMBmtaOlhIqewlL3xOeyJy2Hl4TS+v6s9tjZ/bXydseMkLyw9DoCbvQ3tfR0oLi0jIauIXw+kkpJb0qQTETmFJUxeHEl0eiG2p/48jGjvzpAQt7Oeu/l4JkeS8kjPL8HVZEMXP0du6+ZNc7fq+0aIiIiIiIhI/VMiQkSkCYg4kcjKrQe48+r+uDs7VhzfeiCc8a99A8AtQ3vj9Y/myyIXq2mb40nJLWZwK1e+GNUGD8e/Sm2l5hazODQFB1vrSudM6O9Hp2aOtPVxqHR847FMHpsXzlebE7imgyeXtaj+++jtNbHc09uXF4cHYTJaUVpm5oWlx/hpVxKvrYzGx8nIZS1cePfGVriYyj9CfbA2lvfXneCjP09wXx/fiuN/t+tEDrbWBn68uz1D27gDkJZXzBPzw1kXkcmjc4+y5rHumIxnr5gZnpzHI3OPUlhSxr+uasGD/f2wO5VwCDuZy6Nzw1kfmcmH608wZVgLAErLzLz9RywAr49syT2X+WJt9deOif3xORxOyjvrtf9uwpwjJOXUvc/KmB4+jOnpU+fzMvJL+WlXUqVj320/yaBWrnz5jz8f/7Q1OrvS18sPpfHh+hNMvjKQRwdVnzwSERERERGR+qVEhIhIE5CVk8/Uz2bz4he/0DrQF2cHexJS0olLTgegfbA/bz8+xsJRijSeyNR8AMb1bVblJrOno7HaUki3dPWudq1BrVyZMiyQ5xcfY/6+5BoTEW287XnlmmCsTt2kt7Yy8OLwIObvSyY+s4iSUjNz7+9UKQHy5JDm/LQrkZPZxWw+nlVRwunvikvNTB3WoiIJAeDhYOTzUW3p++FuotMLWRKWyu3dq4//795fe4L84jKeGBzAY4Mr30Tv1MyRz0e14Zpp+/lu20meGtIck9GK1NxiMvJLcDVZc3/fZlXW7OrvRFf/2u/IANgXn8uJjMI6nQMwuJVrnebbG6249zJfRnb0JMTThJejkaScYpaGpfL+ulg2Hsvk/lmHWfhA50rJFYCWHiZeujqIgS1dCXSzw9bGwKHEPKZtTmBpWCqvr4rBwdaa+/tUfU9ERERERESkfikRISLSBLQM8Ob5e65nzc4wYk+mciwuCZOtkR5tg7hhSE8m3joMJweTpcMUaTQBruVlc5YdTOPKNm4Yrc++WwAgJr2AXw+kEHYyj7S8YopLzQBkF5QAEHoyt8Zzx/TwqUhCnOZqb0Ogu4nw5Hxu6uJVZReGjbWBDr6OnMzOICqtoNp1jdYGxvaqugvAzd6G27p68cOORNaGp581EVFUUsaqo+XJybt7+1Y7p7OfI4FudsSkF3IgIZfLWjjj6WjEZGMgq7CUteHplRIi52rbMz3Pe43a6NHcmR7NKyeOmrvZMXGgP71bOHPr9FB2xebw64EUbutW+f176vLmVdbr2dyZaXc486+lx/hhRyLv/BHD7d28cbSzrjJXRERERERE6o8SESIiTYC7syP/Hn8z/x5/s6VDEWkSHujrx7x9yczbl8ya8HSuaO1G70Bn+ge7VCm9dNo3WxJ4fVV0RfKhOul5JTWOBXlUn+zzdLAhHAh2r2H81I6NvKLSasf9XWxxrqZkE0Bb7/LXEplafRLj746nFVBQXIbBAI/PD69xXtqp15iQVQg4Y21l4KH+/ny6IY67fzxMx2YODGrpymUtnOkX7IKHQ81ljZqy3oHOXNfRk8WhqSw/lFYlEXEmU69qwazdSWQWlLLpeCYj2jfd/hgiIiIiIiIXAyUiREREpMlp7+vAovGd+WDdCdZHZrBgfwoL9qcA0NrLninDAhnZ0bNi/o6YbP7zexQAD/bzY1Q3L4I8TDjZWmNlZWDjsUxG/3CQkrKakxQONfRoMBjKd0nY29Y0Xv7/mlb2PEP/Ai+n8rGcwuqTGH+XdWpXh9lc/nrPJr+4rOLXU4YF4u9qyw/bT3LwZB4HT+bx9ZYEbKwMDG/nzn+uCb4gmzf3DnRmcWgqx0+V8qotF5MNbX0cCE3I5VgtkkAiIiIiIiJyfpSIEBERkSapi78T393VnoLiMvbEZbMtOptlB1MJO5nHhF+O8vM9HRgS4gbAvH3JANzQyZNXrg2uslZ6fs07IRpaam7NTZ1TTjV8dqpFaaDTZaFsrQ0cf6lfnWIwGAzce1kz7r2sGYnZRWyPyWbz8cyK3QRHkvJYObEr9ra1K1HU2M2qa2K0Ls8ClZSdZeIZzi09Q3JKRERERERE6ocSESIiItKkmYxW9A92pX+wK09f3pyJvxxlSVgqM3cmViQiYtPLn2rvU0Mj6t2xZ99B0FASsorIKSytNtlwNDkPgBDPs/eAaeVhwtbaQFGpmWOp+bTytD+neHydbbmhkyc3dPLk6cubc8VnezmWWsDG41kMb1e7/hGN1az6bI4klb9/fi62dTqvpNRMZEr5Lgo/17qdKyIiIiIiInWnRISIiFjEyKfeYeO+o3w5ZRxjrx1o6XDkAtIr0JklYakkZhdVHLM/VVapuqf00/KKmXtqx4QlFJWa+WlXIg8P8K90PDO/hPmnyk1d0cbtrOvY21ozrK07yw+lMW1zAm/f0Oq8Y/N1tqW5mx0HT+ZVej/PprGaVZ/JyayiinJdl4fULcHx485EsgpKsbEyMLBl/SZHREREREREpKrqix2LiIhIo4g4kciHPy/n1skf0W7UJDyvepjm1z3BFRNf44OflpGTd2nWr5+8OJIF+5Or9E6ITivg512JAHT1c6o43jfIBYAZO05yID6n4nhcRiH3/3yY/BoaSTcGo7WhvNdFREbFsfS8Yh6fH05OYSkt3O24sZNXrdaafGUgDrZW/LgzkVd+jyLjHyWn8otKWX4olecXRVYcO5qUx6RFkeyIyabsb2WIzGYzvx5IqdhV0NXf8TxeZcN4+JejrI/IoOQfDcj3nMhmzIyDZBWU0szZyN29fSuN/xmZwesrozn2j94RRSVlTN+awCsrogC4p7cvvs7aESEiIiIiItLQtCNCRETEQkpLy+h594sVX/u4u9A5JJCktEx2H45i9+EofvhtA0s+mESLZp5nWOnisycuh592JWFlgCAPE272NmTml3A8rQCzGVp5mnjmiuYV88f28uXHXYlEphQw8usDtPK0x2ht4GhyHg5Ga14cHsS/l0dZ5LX0au6Em70Nd808RLCHHS4mG44m5VFQYsbR1orPbmuDqYZG2f/U1seB/41px8RfjvL1lgSmbztJiJcJB1trMvNLiE4voLSMSo2ni0rNzNqdxKzdSTjaWhHkYcJoZSAus4iUU/0rHuznR1d/p5ouazF/RmawNCwVk9GKYHc77G2tScwuIj6zfPeGn4stP4xtj7Op8kfavKIyvtgUzxeb4vF2MlaUbopMySe3qLyhxMiOHrx0dVDjviAREREREZFLlBIRIiIiFmI2m3FxtOeBGy/n7msG0jbIr2Jse1gkD772Dcfjk7n/lWms+fJfFoy08b1yTTCrjqSzPSaL+MwiYtMLMRmt6OLnyDXtPRjfz69SzwVHO2sWPtCZt/+IYdWRdKLTC/B0NHJLF2+euaI58Zl172dQXwwGA1+PbsdXm+KZuy+Zo0l52NtaM6K9K5OGBhLiVbdeD0NC3Fj/RHembzvJmvAMotIKKCguw8VkzWWBzgxt4861HTwq5od4mnjvxlZsPJ7JgYRc4jIKyS0qw93BhqvaujO2lw8j2nuc4YqW88JVLdgWnUXYyTxOZheTU1iAo60VvQOdGdHOnbt7++JqX/XjbBd/R56+PIBdsTkcTysgIiWfklIzHo5GLg9x4vYe3oxo1zRfs4iIiIiIyMVIiQgRERELsba2Yv+sN/Fwqfokep9OIXzz4oMMf/wtdh46xv7wGLq2aWGBKC1jQEtXBtSxdr+no5F3bgypdizYw0TcK/2rHTtbv4N54zqdcfyjW1rz0S2tzzjH2srAY4MDeGxwwBnn1faa3k62TBnWginDzv5nwt7Wmjt7+XJnL9+zzm1q7r2sGfde1qzO5wW42vH8lZfO94uIiIiIiEhTp0SEiIgFxSen8+Gs5fyxI4wTiWkAeLk509Lfm6G9O/LY7cOxt/urfvm+8BgW/7mbdbsOciIpjZSMbFwc7enWNojxN17ODYOrv6HaefQUYhJT+e3DSXi7u/Dm94vZsPcIeQWFtAvy5/m7r+P6wT0qYnpnxlJWbN1PSkY2LZp5MeGWK3n41iurrPvT8k088vZ3DOrWliUfTOLTX1bw84otRMUn4+Rg4vKeHfi/B24ipHndb4DGnEzlkzkrWLMzjLikdGysrWgb5MddVw9g3PVDsLGxrnLO6u2hfL1wDbsPR5GWlYuTvR2ebs70aBfE7cP6cO2A7nWOoyEZDIZqkxCn9e3cGldHezJz8wmPPXlJJSJERERERERE5OKhRISIiIXEJqZyxcTXSE7PxmhjTUt/bxxNdiSkZrBp/1E27D3CnSP6E+DzV/mQJ9/9gT1Ho3FzcsDX05VmHq7EJaezZkcYa3aE8eToq3ntkdtrvObuI1G89f0SrK2tCAnwIfpkKnuORDH2pS+Y/u+H6NqmBdc9/S6ZOfm0D/KjpLSM8NiTPP/Jz+TkF/Dc2JHVrmsG7nn5S5Zu3EOwvzftg/04dDye+Wu2s3LrfhZ/8By92res9XuzfPM+Hnj1a3ILCrG3s6VVgDc5eYXsPhzFrkPH+W3TXn554wlsjX/9M/a/Ret45sMfAXB3caRTqwCKikuIT05n3h/bSUnPbnKJiLMpKSmluLS8ybKDSQ11RUREREREROTCpESEiIiFfPrLSpLTsxnaqwPT/z0BTzfnirGUjGzmr9mBg71dpXMeu2MEXVsH0j7Yv9Lx9bsP8cB/v+aTOSu4YXAP+nauvkzMq98u5IEbL+e/D9+Oyc5IaWkZz3z4I98v/ZN/fzUPHw8X+ndpwyeT7sXVyQGAN79fzJvfL+adGUt58KYrKo7/3fawSOyMNsx/+2mG9+0MQGpmDg++9g1/7Ahj3Ktfs/27VzHZGc/6vhyJjmfcq9MoKCrmlQm38eioq7CzLT/vQEQs416dxpodYbz1wxJeevAWoLzp86v/WwjAe0/dxfgbr8Da+q/mv3uORHHweNxZr/139778JSdTM+t0DsA9Iwdxz8hBdT6vOr9t2kteQRE21tb06Vh9ySERERERERERkabO6uxTRESkIYTHnARgwi1XVkpCQHl5podvvRJ3Z8dKx++4qm+VJATA5T078NL48pvys1duqfGa7YP8efvxMRUJAWtrK159eBQmWyMnktKIS0rniynjKiUbnr/7Ovy83MgvLGLDniPVrltcUsrU+26sSEIAeLo6Mf2lCTg7mIiKT2bBuh1nejsqvPn9YvIKinj2rmt55q5rK5IQAF1aBzL93xPKm/8uXENBYTFQnrhJz8rFzcmBCbdcWSkJAdCjXTBjrxlYq+uftvtwFFtDI+r8X2xiap2uU5PMnDz+78u5ANw7clCVPyMiIiIiIiIiIhcK7YgQEbGQQF9PABZv2M2Ifl0w2tTur+SohGTm/bGdAxGxpGbmUFRcAkBWbj4A+8Jjazz37pEDsbKqfJPezdmBID8vjkQnMGpYHxz/sQvDxsaaTq2ak5CSwfH4pGrXNdpYc/8NQ6ocd3d2ZPSI/nz761pWbQvlrqsHnPG1FRWXsHzzfgDuv/7yaud0bdOCoGaeRCWksC88mr6dW+Pl5ozJ1khmbj6rtoVWSoicq9A5b5/3GueqtLSM8a99Q/TJFIKaefHKw7dZLBY5d6N7+DC6h4+lwxARERERERGxOCUiREQsZOKtw5i1YjOzVmxh5dYDDLusE/26tGZQt3bV7noA+HzuKl6aNo/iktIa103LyqlxrKV/9TdFvdycORKdQEt/72rHvd3Ln8bPyS+sdjzAxwMXR/tqx9oH+QEQEXuyxrhOizyRSH5hEQaDgQdf+6bGeamZ5a8xLjkdKN/Z8fgdw3nvx2XcNuUjuoQEcnmv9vTr3JqB3drh6VpzQ+imxmw28+T7M1i59QBuzg7MeeOJasthiYiIiIiIiIhcKJSIEBGxkI6tAlj1+Qu89cMS/tgeyi+rt/HL6m0AtG3RjJcevIUbh/SqmL8tNIIXPp8DwKOjrmLMiP609PfG2cGElZUV63cf4oZn36fkDEkKxxoaHhsqxu1qGC+fYTabqx33PkPZIB93FwCy8wpqnHNaZk5exXW2hkacdX5+QVHFr/89/hYCvD345te1HIiM5UBkLJ/9sgoba2uuHdCVNx8bQ4tmnmdd09Ke/2QWM5dtxNnBxMJ3n6FjqwBLhyQiIiIiIiIicl6UiBARsaDubYOY/frjFBQWs/PQMTbvD2fxn7vYHxHLPS9/xa/vPsPQ3h0BmLWivPfDrUN789bjY6qslZaV26ix/11yRnaNY0npWQA4O5jOuo6jffkcW6MNKau+qlMMBoOB8TddwfibruBkagZbDkTw557DLFi7gyUb9nAoKp6N37yEQw3Jln+yRLPqF7/4ha8XrsHBZMu8t56iV/uW57SOiIiIiIiIiEhTokSEiEgTYLIzMqh7OwZ1b8fke6/n/le+YsHanUxfvL4iERF1MgWAfl3aVLvGjoORjRbvP8Unp5OdV1BtsuFwdAIArQObnXWdkOY+2BptKCouIeJEIq2b+55TPM083bjlit7cckVvptx7PZfd+28iYhNZv/sw1w7oVqs1dh+OIuYcGk9f0atDnc8BePXbhXz6y0pMtkZmv/4E/btW//ss5yY2vYB+H+0BIO6V/haOpmmYsyeJZ3+t/PfGBzeHXLJ9LR6YdZgVh9MrHdv6dA8C3c+eRBUREREREZEzUyJCRKQJuqxjCAvW7iQhNaPimINdeVmlpLSqT+mnZubw8+9bGiu8KoqKS/hh6Z88fseISsczsvOYs7I8rqv6dDrrOg4mO67u14UlG/bw2ZyVfPTcPecdWzNPN1o08+JAZCwn//Z+nk1jNqt+78ffeO/H37A12jDz1UfOOZkhci6c7axp71veh8TbyVjtnAPxOXy9JYHtMdkkZRdhZWUg0M2OK1q7MXGAP81cqpZ9yy8u5c/ITPbG5bA/Pod98bmk55UAcHDqZbjaN9zH0PyiUr7cFM+SsFRiMgox2VjRxc+RB/o1Y0Q7j2rPaePtQNqp+HbE1LzLS0REREREROpOiQgREQt56v0ZDOjalpEDu1faSXA8PpkfftsAlJduOm1AtzYs3biHb39dx41DelWMxSamMu7Vr8krqL6RdGMw2ljz5veL6dAygGGXlScc0rJymPDG/8jOKyDYz4vbhvap1Vr/Hn8La3YcZPqS9TjY2/L8Pdfj7uxYMZ5XUMgfO8JYufUAnz5/HwCHo+L57JeV3DNyEJd1bIWVlRVQ3mti3prtHDweB1R+P5uKL+ev5tVvF2Jjbc13L03g6n5dLR2SXGI6+zkyb1zNicK5e5N5blEEpWXgYGtFiJc9hSVlHE8tIDw5gbl7k5h9b0e6+FduCh+ZUsADs440dPhVpOcVc9t3YRxJysdobaCttz1ZBaVsOJbJhmOZPDUkgMnDWlQ574Wr/joW8LLlErsiIiIiIiIXIyUiREQsZOfB43y35E+srAy09PfB3dmRjJxcIk8kYTabaR3oy9T7bqiYf/91Q/hu8Z+Ex57kiomv0bq5L7ZGGw4dj8fR3o5XJ45i8iezLPJa+nQKwd3ZkVue/5CW/t64OTlwKCqegqJinOzt+Pb/HsJkV/2T1v/UPtifn157lPv/M43PflnFV/PX0CbQF0d7Exk5uRyPS6a0rIwWvn81ni4qLmHGso3MWLYRJ3s7Wvr7YGNjzYmkVJLTy59sfnTUVfRoF9wQL/+cJaRkMPWz8gbkTg52fDpnJZ/OWVnt3PPpPSFyrlJzi3lh6TFKy2BsLx9evjoYRztroLzc1SNzw9kTl8Mzv0ay+tHKZc+M1gZ6BDjRLcCRrv5OeDsZuefHww0e8/OLj3EkKZ+OzRz4/q72BLiW94VZGpbK4/PD+fjPOHq3cObKNu4NHouIiIiIiIiUUyJCRMRC3np8NMu37GPz/nDiktKJTkjB3s5I9zYtuH5wDybedlWlnRJODiZWfDqF//5vIcs27eN4fDLebi7cMbwvU+69gbikNIu9FgMw85VH+GTOCn5esZlDUfE4mOwYObA7Lz5wE21q0R/i767s3YmdM/7LVwvWsGrbAY7FJZFfWIyrkz39urRmeJ/O3DCkZ8X81oG+fPb8fazbfYh9R2OITUwlJ78QDxdHrunflfuvH8LIgd3r90XXg6LiEsxmM1BexmpraESNc1WuSSxh4/FM8ovL8HS04Y3rWmFjbagYC3Q38dYNrbj6q/0cSswjPrMQf9e/msG383Fg6YQuFV/Hphc0eLxhJ3NZfigNKwN8OaptRRIC4PpOnhxIyOWzDXG8tyZWiQgREREREZFGpESEiIiFDO7RnsE92tfpHC83Zz5+7l4+fq7qWKsAH7LWfVvteWfrd7Ds48lnHP/qhQf46oUHzjjH2tqKZ+66lmfuuvaM82p7TR8PV1568BZeevCWs67lYLLj3usGc+91g2t17aYiyM+rxt+zi1l0WgEDPt6D0drA7km98HCofrfMtM3xvLoimoEtXfjl/vLSQWazmbURGaw6ks6OmGxOZheRW1iKl5ORvi1cmDjQn85+jtWuV5O+H+7mREYhc+/vyICWrlXG318bywfrTnB7d28+uqV1lfHcwlKmbzvJ8kOpHEstoLi0jAA3O65p78EjA/1xr+H1XQgKissACHC1q5SEOK2lx1/J0pIyc6PFVZOlYeUN5ge0dKW1t32V8Xt7+/LZhjj2xecSnVZAkIcaUYuIiIiIiDQGK0sHICIiIpeWIA8TvQOdKS41szg0tcZ58/clA3BbN++KY3lFZdzz42Fm7kwkOacYPxdbQrzsyS4oZeGBFK7/5gC/H2q83UHHU/MZ8dU+3vojhrCTeXg62tDC3URMeiGfb4zn2mkHGmUnQEPp1Kw8qROZkk96XnGV8e0xWQD4OBlp/rfdB5ayK7a8FFu/IOdqxwPc7Ah0K49z1wk1pBYREREREWks2hEhIiIije62bl7sjM1mwf5k7u9TtXTX0aQ8wk7mYTJacV3Hv/qBGK0NvHNDK4a3c8fH2bbieFFJGbP3JPF/y47z3KIIhoT0wsHWukFfQ0FxGeNmHSEqrZBbunjx8jVBeDuVx5SWW8xziyJZeSSdJxZE8Ov4zrVed/buJGbvSapzPD5ORr4e3a7O551JZz9HbunixcIDKdz382H+b3gQnZo5UlhSxobjmbzyexQ2Vgb+O7IlVlZVd0w0tmOp5Umf4DPsdAjyMBGbUUhkSn5jhSUiIiIiInLJUyJCREREGt0NnTx5eXkUu2JziEorqHLj+PRuiGvau+Nk91dCwdbGirG9fausZ2tjxb2XNWNHTDYL9qew6mg6N3X2atDXMGdPEuHJ+fQNcuaTW1tXuhHv4Wjk81FtGPLpXnbEZLMjJpvLWlT/lP4/xWUWsiOm7k/rN3drmB0JH9/amrY+9szYkcgt08MqjfULcmbaHS24rIVLg1y7rjLySwBws6/5I+7pscz80kaJSURERERERJSIEBEREQtwdzAyrK07yw+lsWBfMs8ODawYM5vNLDyQAlQuy/R3O2OzWXEojYiUfLILSyv6E8RlFgIQlpDb4ImI3w6Wl5Ua09On2t0ADrbWDAlxZc6eZLZEZdY6EfHc0ECe+9v7YWlZBSWcyCgku7AUk9GKlh4m8otLic0oZPeJHH7cmUQHX8dKCSNLKSwp72lhtK65+qidTfnvVcGpuSIiIiIiItLwlIgQEZFzNvbagYy9dqClw5AL1G3dvFh+KI35+1MqJSK2RmcRl1mEt5ORy0PcKp1TXFrGMwsjKxIVNUnPK2mIkCs5lJgHwNebE/h5V/WllE5klCdGErKKGjyehpCZX8L13xwgKq2QiQP8mDQ0EPtTJa/iMgp5blEk8/YlE5maz+LxnS1ensnOxor84jKKS2tOMhSWlCetTDZqlSYiIiIiItJYlIgQERERixjWxh03exui0grYFZtNr8DyHQML9pUnGW7q7IX1P25sf7kpnoUHUrA3WvHi8BYMCXHD38UWk9EKg8HAu2ti+Gh9HMWndkg0pKyC8tI+pxMSZ5JffGE+ff/phjii0goZ1MqVf18dXGkswM2Or+5oy8CP97DnRA5LD6ZyYwPvQjkbV3sb8ouLSM+vORF1unyTq73ld3CIiIiIiIhcKpSIEBEREYuwtbHihk6ezNyZyIL9yfQKdKawpKyi5NGoblVvas871Tvi3yOCuK+aJtfnshPidKqjptRFXlH1vQQcba3ILChl0YOd6R1Yu7JLtdGUmlVvjcoC4IoQ12rH3ext6NnciTXhGeyNy7F4IiLE08TJrCKiTjWtrk50WvlYiJd9Y4UlIiIiIiJyyVMiQkTkIhKdkEKXO6cCkLXuWwtH0zT8tHwTj7z9XaVjX04Zd0GXlPp87ipe+HxOpWMX6mu6rZs3M3cmsjg0lf9cE8zqo+lkFpTS1tueLv5OVebHppeXOuoTVP2N/90ncuocg4NteYmelNziasej0qq/qd3Ox4HtMdkcScyr10REU2pWnV1Y+4bOhU2g50KvQGc2Hc9ia3RWteNxGYXEniqX1bN5/f2eiYiIiIiIyJkpESEiIpcEF0d7OrYMAMDbw6XSWHZeAcs37+OPHaHsPhxFzMlUysrK8PN2Z3D3djw2ajgdWwXUe0yHo+LZsPcIe45EsedIFIejEigtK+OR267i7SfG1Hiev7c7/Tq3BuDg8TiycvPrPbbGclkLZ4I97IhKK2RtRAYLTu14qKlJtb3RiqLSUpJziungW3lsS1QmBxJy6xxDsIeJI0n57D2RU6XBdVxGIesiMqo97/pOnmyPyea77Se5vbs3tvXUc6ApNatu5WkiIiWfdZGZPDKo6vdARn5JRfInxNPyOwyu6+jJJ3/GsSUqi4jkfFp7V45pxs5EALr6OxLsYbJEiCIiIiIiIpckdekTEZFLQtfWgaz8bCorP5vKiL5dKo09++GPPPjaN8xasYWYk6mENPchpLkvCcnpzFy2kcETXuXH5RvrPaZXvlnAcx/9xI/LNxF2LI7Ssto9UX7LFb0rXkvX1k3jhvX5uLVredJh+taTrAnPwGCAW7pWX+Knb1B5EuntP2JIzvmrAfT26CwemRuOyabuzZKHtXEHYNbuJHbG/rUTIT6zkEfnhVNaQ82mu3r50MbbnkOJedz/82GOpVZOCJWWmdkencWkRZEkZBXWOa6mYFT38t+bjccy+e+KKPL/VqYqLqOQib8cJSO/BHujFdd38qy3687Zk0TAy1sIeHlLnc7r7OfINe3dKTPDI/OOEpf51/u+NCyVaZvjAXj2igv/+0ZERERERORCoh0RIiIiwNX9uvLgzVcwtFdHbI3l/zymZeXw/CezmLt6G0+8O4Me7YLp1Kp5vV2zmZcbNwzuQY92wfRoF8z3S/5k0Z+76m39C8WtXb34YN0JNhzLBGBASxcCXKsvMzTpykA2HMtkb1wu/T7cTSsve/KKyohKK6CDrwO3dvVi2uaEOl3/9u7ezNiZSGhCLjf/L5RgDxMmGyuOJufR1tuB+/s045stVde0N1ozc2x77vv5MOsjMxn8yV6C3O3wdDSSX1zG8bQCCk41qX5qSP3vqGkM13X05L7LfPlhRyJfbU7g+x2JtPQwkV9cRmxGAaVlYGtt4P2bQ/Bxtq1y/tVf7a9IBpjNf2V0Bny8B8OpnNFlgc58d1f7eov53ZtCiEwN4+DJPAZ+vIe23vZkFZRWlGR6fHAAw9u519v1RERERERE5OyUiBARkUveW4+PwdO1aj8CDxcnvpo6jtCIWA5FxTPjt41nLJlUVx8+c3elr+eu3lZva19IWnra0yvQiV2x5SV+butafVkmgE7NHPl1fGfeXRPL9pgsjqXk4+9qx+OD/HlySHO+OvXEe13Y2lgx+94OvLsmlhWH04jLKMTH2ZYH+/nx3BWBZ1wz0N3Esgldmb0niaVhqRxKzONEZiEORmtae9kzsKUL13bwaJD+DY3ljetbcVU7d37elcSeuBwiUvKxNkALdxMDgl14sJ8fbX0cqj03I7+k2gbiGfl/HauuD0VyTnm/js5+jnWO18PByLIJXfhiYzxLwlKJTMnHzsaKgS3LYx3R3qPOa4qIiIiIiMj5USJCRKSBHI9PpttdL2C0sebo/PervdEN8NkvK/nXF79wec/2LPlgElD+5PCq7aEs37yPbaERxCdnkJNfgI+7C/27tuHJ0VfTrU2LOsXTefQUYhJT+e3DSQzuUfXp4ze+W8RbPyzhrqsH8NULD1QZz8krYNrCNSz+czeRJxIpKi4h0NeT6wd156k7r8HDpfrXdyGo6fcGwGhjw+W9OnAoKp7w2JONGNWlZfGDXc4+6ZTOfo78MLb6J+hr6q8Q6G4i7pX+Na7p7mDkjetb8cb1rWq95mkmoxX392nG/X2a1SL6C9OVbdy5sk3ddxFse6bnOV1v26lm048PPredJA621ky6MpBJV6oEk4iIiIiISFOgRISISANp6e9N384hbAuNZMHaHTx089Bq581eWV4Dfczwv26S5uYXMmrKxxgMBrzcnAjwdqfMXEZsYhpzV2/j13U7+eHliVw/uEejvJbIE4ncOvkjjscnY2NtTaCvB3a2RiJPJPLhrN9ZsHYnSz+cRJBf9XX9L3QFheVPZzuYqpaeEbnQnS5JBfDkkIBzSjjUp7IyM7tis2nlaeK6Do23e+HN1TEVCRARERERERGpX0pEiIg0oDHD+7MtNJI5q7ZWm4g4HBXP/ohY7O1sufHyXhXHbY02fDLpXq7t3w1fT9eK40XFJcxctpFJH//Mo+98x9DeHXG0b9iSLwWFxYx58TOOxydz+1V9efPRO/DxKI8pNSObx979gWWb9vLQ69+y8rOptV535rKNzFxW9wbQzTxdmfHKI3U+71zlFRTy26Y9APTv0qbRrivSWLILS9kRU96k+3RJJEs6nJRHZkEp/zciCCurujcfP1fhyXkV74OIiIiIiIjULyUiREQa0C1DezPls9lsD4vkWFwSrQJ8Ko2f3g1x3aDuODuYKo7bGm24//ohVdazNdow/qYr2HIgnF9Wb+P3Lfu47co+Dfoafvx9I0eiExjQtQ3f/Gs8VlZWFWOebs787/8eove9/8fW0Ai2hUbQt3PrWq0bm5jK1tCIOsfTwtezzuecj1e/XUhyejZebs7cM3JQo15bpCGN7uHD6B4+Z5/YyDo2czxjGa2GMv3O+muYLSIiIiIiIpUpESEi0oA8XJy4ul8XlmzYw5xVW3nh/hsrxsxmM3P/KG9OPGZE9TfdtoVF8tvGPRyNOUlWTh4lpWUAnEhKA2B/eEyDJyIWrd8FwD0jB1VKQpzmaG/H0N4d+XH5JjbsPVLrRMS/xt3Ev8bdVK+x1re5f2zji3mrAfh00r24ONpbOCIRERERERERkQuPEhEiIg1szIj+1SYiNu07SmxiGj7uLgzr3anSOcUlJUx86zvmrt52xrXTsnIbJOa/C408AcDnc1fxw9IN1c6JTUwFIC45vcHjaSxrdobxyFvfAfDSg7dw3aDG6cchIiIiIiIiInKxUSJCRKSBXd2vK+4ujhyLS2J7WCR9OoUAMGfVVgBGDeuDtXXlnQYfz17B3NXbcDDZ8sqEUVx5WUcCvN2xt7PFYDDw2vRfeWfGUopLShs8/sycfOCvhMSZ5BcUNXQ4jWLTvqPc9X+fU1RcwrN3Xcuku6+zdEgiIiIiIiIiIhcsJSJERBqYrdGGW6/ozf8Wr2fOqq306RRCYVFxRcmj6soyzVpR3jvitUdu58Gbqja5PpedEAZDedNXcw3jeTUkEZzs7cjIyWPV5y/Q91QSpT401WbV28IiuX3qx+QVFDHxtmH8Z8JtDXYtEREREREREZFLgRIRIiKNYMyI/vxv8XoWrN3BW4+P5vct+8nIyaN9sD/d2wZVmR99MgWA/l3aVLvezoORdY7BwWQLQHJ6VrXjx+KSqj3eoWUAWw6Ec+h4XL0mIppis+o9R6IYNfkjcvILuf/6IbzzxJ0Ndi25cG0+nsnt3x+kuZsd257paelwRERERERERJo8JSJERBpB386taenvzfH4ZFZvD60oyzRmeL9q5zvY2VJUXEJiWiadWjWvNLZx7xH2Ho2pcwytAnw4FBXPrsPHqzS4jk1MZfX20GrPu/mKXmw5EM7XC9dw19UDsDXWzz8dTa1ZddixE9z8/Idk5uYzZkR/Pnr2bkuHJHJRKik18932k8zbl8yx1HysDQba+TgwtrcPd3T3sXR4IiIiIiIi0gCszj5FRETqw+hTSYev5v/Bym0HMBgM3FFDImJAt7YAvPrtQpLSMiuOb9kfzv2vTMNka6zz9a/u3xWAGb9tZFvYXzsq4pLSeOC/X1NaVlbtefdfP4R2QX6ERp7gjn99SsSJxErjpaVlbNkfzuPvfE/8BdqsOuJEIjc99wHpWbncOrQ3X04Zh5VV7f6JjE5IweWKB3G54kE27DncwJGKXNgKS8oYM+Mg//k9ioMncwlyN+HjbGRnbDbPLIzkyQXhmM01FZATERERERGRC5V2RIiINJLRw/vx1g9LWLvrEABDerSnuY9HtXNfHHcT63YdZPfhKDqPmUqbwGbkFhRyLC6JTq0CGD28H5/+srJO17/r6gH8b9E69oXHMOLxt2gV4IO9nZFDx+NpH+zHhFuu5PO5q6qcZ29ny7y3nuKOFz5hzY4wet79IsH+3ni7OZNXUMixuGTyC8v7Szx/z/V1fFeahkkf/0zSqZJVMSfTuPapd6qdV9/9Keb9sZ1JH/9c8XVufgEA3y1ZX7FrBmD264/Rr4YyXSIXkjdXx7AlKosAV1tmjO1Ae18HALZGZTFu1mHm70uhV3Nn7uvTzMKRioiIiIiISH3SjggRkUYS0tyXPn/rsTC6ht0QAF1aB7Ly06lc078rdkYbwmNPYmVl4Nm7rmXVZy/gaG9X5+vbGm1Y9P6zPHjzUJp5uhKbmEpWTj6PjrqKVZ+9gLODqcZzg/y8WD/t37z/9FgGd29HZk4euw9HEZuYRtsWzXjijhGs/HQKLZo1XP+GhlRUVFzx652HjrE1NKLa/3YfjqpybuKpHSsmWyPtg/3rdN3ComLSsnIq/issLgGg4B/Hi0tKz/3FiTQRqbnF/LD9JADv3RRSkYQA6BfswovDy/vlfLT+BKVl2hUhIiIiIiJyMdGOCBGRRrT68xdqPbdrmxb88uaT1Y7V1F8hyM+LrHXf1rimh4sTHzw9lg+eHlvrNU8z2Rl56OahPHTz0FpEf2FZ9vHkcz53y4FwAO4eOQhvd5c6nTv22oGMvXbgOV9b6k9ZmZklYanM25fM/vhcsgpK8HCwoaWnPde09+CuXj442FqfdZ3IlHyWHUxjfWQG0ekFpOQU42BrRXsfB0Z182Z0Dx+srAxVzsvIL+GrTfGsOpJGdHohpWVmPBxsCHCzY1BLVx7s54eH418l2RKyCvliYzzrIjKIzywEwMPRSJC7iSEhrjzU3w9749njbUwrDqdRVGom2MOOISFuVcZHdfPmP79HkZRTzJaoLAa1cm38IEVERERERKRBKBEhIiKXhP0RsYx4/C0AJt1zHSP6dqmXdTfvD8fG2pqnRl9dL+vVxsJ1O/ly3moADh6Pa7TrXqzyikqZMOcoayMyAPB2MtKxmQPJOcVsi85iS1QW/YJd6OzneNa13vojhmUH03C0tcLX2ZYOvg4k5RSzNTqbrdHZrIvMZNodbSudk11Qwg3fHOBYagFWBgjyMOFqsiYpp5i9cTnsis3hitZu9DmViIjLKGTk1wdIyS3GaG0gyN2Eg60VidlFFfGO6uaNvWvTSkTsis0GoG9Q9Qk7k9GK7gFObInKYldsthIRIiIiIiIiFxElIkRE5JKQlZvP1tAIAJLTsuplTbPZzLbQSG4d2psgP696WbM24pPTK16LnL/Ji4+xNiIDT0cbPry5NcPauleMZeSXMH9fMm72tfvINKqbN48PCqCrvyMGw187Hw7E5/DovHCWhqXy64EUbu7y15+XWbuTOJZaQAdfB364qz0Bbn+VXssuKGHZoTR8nG0rjk3bHE9KbjGDW7nyxag2lXZKpOYWszg0pVa7N06bvTuJ2XuSaj3/NB8nI1+Pblfr+cdSy3ugBHvUXAYu2MPElqgsIlPz6xyPiIiIiIiINF1KRIiIyEWtIcsfGQwGohZ/1CBrn8ljtw/nsduHN/p1L0ahCbksPJCCwQDf3dmeXoHOlcbd7G0Y38+v1utd3b76BvRd/J14/bqW3DnjEPP2JldKRESeukE/podPpSQEgLPJhtE9fCodO32TflzfZpWSEACejkbG9a19vABxmYXsiMmu0zkAzd3q1qsmI7+8B8qZkjqnxzLz1RdFRERERETkYqJEhIiIiFyylh9KBWBAsEuVJMS5Ssou4tcDKeyLzyElt4TCkjIAik79P/RkbqX5Aa7lux1WH02vVS+KANfyBMCyg2lc2cYNo7XVecX73NBAnhsaeF5r1Mbp98H2DPHa2ZTvIik4NVdEREREREQuDkpEiIiIyCXraFL57oL6SkIsCk1h0qJI8opqvpGenldS6esxPXyYtjmBDccy6fneLgaHuNKnhQt9g5zp4le5xBPAA339mLcvmXn7klkTns4Vrd3oHehM/2AX2vo41MvraAh2NuUJiKLSmt+bwhIzACab80uuiIiIiIiISNOiRISIiIhcsrILy0sAuZrO/yNRTHoBTy+IoKjUzK1dvbivTzNae9njbGeNtZWB6LQCBny8h5Iyc6XzfJxtWfpQZ95fe4IVR9JYdrD8PwB/V1ueGtKcu3v7Vsxv7+vAovGd+WDdCdZHZrBgfwoL9qcA0NrLninDAhnZ0fO8X099cz1VdumfiZi/O12+ydW+aTXaFhERERERkfOjRISIiIhcspztym94ZxXUfHO8thaHplJUaqZncyc+ubV1lZ0M6fk1X6Olpz2fjWpDSamZ/Qk5bI/OZuWRNLZFZzNlyTGsDXBnr7+SEV38nfjurvYUFJexJy6bbdHZLDuYStjJPCb8cpSf7+nAkBC3WsXdWM2qQzxN7IjJJiqtoMY5p8dCPO3rHI+IiIiIiIg0XUpEiIiIyCWrnY8Dyw6lsTO27s2a/ykmvfwmeu9A5ypJCIDdtbiGjbWBns2d6dncmYkD/XltZTRfbopnxs7ESomI00xGK/oHu9I/2JWnL2/OxF+OsiQslZk7E2udiGisZtW9Ap2ZvSeZ7TFZ1Y4XFJexNy6nYq6IiIiIiIhcPJSIEBG5hG3Yc5jrnnmPFr6ehM5529LhiDS6kR09+HD9CTZHZbHnRDY9mp/7DXB7Y/nuiuSc4ipjhSVlfL/jZJ3X7H3qhnxidlGt5vcKdGZJWGqt50PjNase0c6DF62PE5VWyJ+RGVUSJfP2JZNfXIa3k5F+QS4NHo+IiIiIiIg0HnUCFBEROUclJaV8PncVgx96Fb9rHqP5dU8w/PE3+en3TZYOTWqpYzNHbu3qhdkM42YdYV1ERqXxzPwSpm9N4ERG4VnX6hdcnjRYejC10jppecVM/OUocTWs8ebqGGbuSCQtt3ICIzmniG+3JgDQxc+p4vjkxZEs2J9Mzqn+FqdFpxXw865EALr+bX5T4eVk5N7LmgEwaVEkhxPzKsa2RmXx+qpoAJ4e0hwb66o7SkREREREROTCpR0RIiIi56CwqJhbJ3/Ehr1HsLIy0CHYn6LiUraFRrItNJL1uw8z7YUHqi3RI03L2ze0IjW3mPWRmYydeQgfJyP+rrak5JaQkFVIaRn0CXI5aymiEe086BvkzLbobMbOPESQux0uJhuOJudhNsNrI1syecmxKueFJ+fx2YY4XvjtGIFudng6GMkpKuV4agElZWa8nYy8dHVQxfw9cTn8tCsJKwMEeZhws7chM7+E42kFmM3QytPEM1c0r/f3qT68cFULQhNy2BqdzfAv99HOx4Gi0jIiU8rLWt3SxYv7+lQtQSUiIiIiIiIXNiUiREREzsF/vlnAhr1HCPT1YO6bT9GxVQAAm/YdZcy/PmX2yi306dSKB28aauFI5WwcbK358e4OLDyQwty9yYSezCXsZB6ejkb6BrkwsoMHIZ6ms65jbWXgx7s78P7aWJaEpRKfVURecRnD2rjz5JAA3Oyr/9j19OXNaefjwJaoLGIzCgk7mYu1lYE23vZc2caNCf398XIyVsx/5ZpgVh1JZ3tMFvGZRcSmF2IyWtHFz5Fr2nswvp8fTqeacDc1JqMVs+/ryPRtJ5m/L5ljqQVYWxnoFejE2F6+jO7hY+kQRUREREREpAEoESEiIlJHKRnZfPPrWgA+ff6+iiQEwMBubXl14iieen8mb/+wlHHXX461tSohNnVWVgZu6+bNbd28zzp3QEtX4l7pX+2Yg601/746mH9fHVzteHXndfV3oqt/7UspDWjpyoCWrrWe39QYra14eIA/Dw/wt3QoIiIiIiIi0kiUiBARuciUlZWxYO1OZq3czN6j0WTm5OPp6kTr5r5cN6gH9103GEf7M5eYAQiPPcniP3fzx/ZQohJSSErPwsFkS6dWzblzRH/uvnYgVlZVb7CnZ+fy6ZwVLNu0j6iEZEpKy/B0dSLQ15PLe3bg0duG4en2V0Pg+OR0Ppy1nD92hHEiMQ0ALzdnWvp7M7R3Rx67fTj2drb19wbVg9827qGouISW/t5c2btTlfE7Rwzghc/nkJiWycZ9R7i8ZwcLRCkiIiIiIiIi0jQoESEichHJzS/knpe/ZPX2UAB83F3oHNKc5PQsNu0/yoa9RxjUrS1d27Q461qvfrOQRX/uwsnejmZebnRq1ZyktEw27TvKpn1H+WNHGD/8Z2Klc7Jy8xn26BtExCZiZWWgpb8Prk72JKVlsevQcbaHRXLVZZ3ofyoREZuYyhUTXyM5PRujjTUt/b1xNNmRkJpREe+dI/oT4ONR/2/Wedh+sLzO/8BubasdN9kZ6dW+JRv2HmF7WKQSESIiIiIiIiJySVMiQkTkIvLk+zNYvT0ULzdnvpw6jqv7da0YS8/OZfbKLbg5O9ZqrTEj+vHMXdfSo11QpYbLe49G88B/v2bhup1c/8c2bh/Wt2JsxrINRMQm0jmkOXPeeIJAX8+KsazcfBb/uQtfz79Kynz6y0qS07MZ2qsD0/89odJOiZSMbOav2YFDLXZvnDZz2UZmLttY6/mnNfN0ZcYrj9R6fkRsIgCtAmquZ9/S35sNe48QfmquiIiIiIiIiMilSokIEZGLxP7wGOau3obBYGD264/Tp1NIpXF3Z0ceue2qWq933aAe1R7v3jaI958ay02TPmDWii2VEhERMeU33e++dlClJASAi6M9d187qNKx8JiTAEy45cpKSQgoL8/08K1X1jpeKN9hsTU0ok7nALT4R6xnk56dC5S/pzVxdykfyzg1V0RERERERETkUqVEhIjIRWLxht0ADOnRrkoS4lwlpmYyd802dh+OIiU9m4KiYgAKi0uA8uTH3zX3LS+htGLLvlr1ojidrFi8YTcj+nXBaHN+/yz9a9xN/GvcTee1Rm2cfh9sjTXHa2drLJ9bWNzg8YiIiIiIiIiINGVKRIiIXCQOR8UDcFnH+klCzF+zncff+YHcgsIa56RlVX7a/55rB/HpLytZu+sQ7UZNYmivjvTr0poBXdvQvW3lEk8AE28dxqwVm5m1Ygsrtx5g2GWd6NelNf/f3n2HR1Xm/R//zEwmmfSQRkJJAiH0jghYsLC66oquiopi77rqYkN83H3UfXRX17421F1Ze0NA8IeFFQSV3kNLgxTSe5vMJJmZ3x8h0WwSSCCTScL7dV1eLufc5z7fGTJZr/OZ+/6eNm6Yhsf165TX4Q6WwyFD7eFApjX2w2GFxcfcJTUBAAAAAAB0VwQRANBLVFbXSJJCAvyOe6703ELd/rd3VFtXryt+M0W3XnK2hsZEKcjPVyaTUQdzCjXu6kdU73A0u65vWLBWvf4/+uu/l2nFTzv05dqt+nLtVknSgMhQPXTt73TjzDOaxo8c3F8rX3tET7+7XN9v2q3P/rNRn/1noyRpaEyU/veWS3TR9EnH/Xo6W+N7XFJR1eaY0sMhTXt7cgAAAAAAAPRWBBEA0EsE+vtKksoPBxLHY/Gqzaqtq9fkkYP19qO3tFjJcKQH8PED+upff7pV9fUObU/O0PpdKVqxbofW7UrRH59/XyajUdf97vSm8eOHxuqTp+6WzV6nLfsOaN2uFC1bu1W7UrN07WMLtPTZ+3TWSSPbVXdXNatOiInSht2pOpBd0OaYgzmFDWMH9u1wPQAAAAAAAL0JQQQA9BIjBvXXsrXbtGlPx5s1/7eMvCJJ0pTR8S1CCEnavPfAUefw8jJp8sjBmjxysO6d/Vv9ecHnevmTb/WvL39oFkQ0sviYddr4YTpt/DDNu+5C3fDEAi1evUXvLFvT7iCiq5pVnzxysN5f8ZPW7Upp9bzNXqet+w82jO2kfh0AAAAAAAA9FUEEAPQSF0+fqGfeXa6125O0Zd8BnTRi8DHP5evjLUnKL6locc5eW6e3l6zu8JxTRg2R9K1yi8vaNX7yyHgtXr2l3eOlrmtWfcGp4/XAyx/pYE6hVm3Zo7NPGtXs/MffrZPVVqvIPkE6dexQt9cDAAAAAADQnRk9XQAAoHOMjh+oK34zRS6XS7P/51X9Z9PuZufLKq1asPh7ZeYVH3WuU8c1PDxf+sOWZvMUl1fp+ifeVFZ+63M88fZivbNsjYrLKpsdLygp1+uLVkpq2Iqp0R+ff0+frtygSqut2fiDOYV69//92GJ8dxHRJ0i3XHymJOmeZ9/V3gPZTed+3pms/12wSJI077oL5eVl8kSJAAAAAAAA3QYrIgCgF3n5getUVF6lVZv36NJ5L6lvaLD6R/ZRUWmlsgtL5XA6dcqYBMVEHXkrogtOGa9TxiZo3a4UXTrvJcX1i1BIgK/2HcyRS9Jzf7xa9z73Xovr9qfn6PkPV+i+Fz9QbFSYwkICVWW1Ke1QgeodDkX2CdJTd13RNH7L3oNauHytjEaDBvWLVJ9Af5VVVSvtUIFcLpeGDOyr+dfP7Oy3qVM8futl2pmSqZ93JuuUWx7XiLh+qq1zKCUrT5J0+W+m6Nbfn+XhKgEAAAAAADyPIAIAehF/Xx8tfuaP+uw/G/Xxt+u0MyVLialZiggJ0qnjhmrm6RM1pB3Nk00mo754Zq7+9u9lWvLDZmUXlMha46/fThurB6/5nfoE+rd63bzrLtSIQf31044kZeYVKzE1S14mo4bFRuncKWN09xXnKqJPUNP4p+++Ul+v36l1u1KUXVCqjNwi+fqYNT4hRheePkF3XPYbBfpZOu396UwWH7OWPX+/3ly8Sp98t16ph/JlMhp18qh43XDh6brm/NM8XSIAAAAAAEC3YHC5XC5PFwEAPcm2bds0adIkrX3rz91y2yDgaHYkZ2j6bf+nrVu3auLEiZ02b+Nn45XLhigh3LfT5gV6gpSiGt3zRWqnf64AAAAAoDdgRQQAAOgU4eHh8vO16J4vUj1dCuARfr4WhYeHe7oMAAAAAOh2CCIAAECniImJ0b79SSoqKvJ0KYBHhIeHKyYmxtNlAAAAAEC3QxABAAA6TUxMDA9iAQAAAABAM0ZPFwAAAAAAAAAAAHovgggAAAAAAAAAAOA2BBEAAAAAAAAAAMBtCCIAAAAAAAAAAIDbEEQAAAAAAAAAAAC3IYgAAAAAAAAAAABuQxABAAAAAAAAAADchiACAAAAAAAAAAC4DUEEAAAAAAAAAABwGy9PFwAAPVVSRq6nSwCOCT+7AAAAAACgKxlcLpfL00UAQE+SmZmpESOGy2qt8XQpwDHz8/PVvn37FRMT4+lSAAAAAABAL0cQAQDHIDMzU0VFRZ4uo1PU19froosu0sSJE/Xkk096upxuxWq16oILLtDMmTP1wAMPeLqcThUeHk4IAQAAAAAAugRBBACc4N577z1df/31SkxM1OjRoz1dTrfz2GOP6bnnnlNmZqbCwsI8XQ4AAAAAAECPQxABACcwp9Op0aNHa8iQIVq2bJmny+mWioqKFBsbq4ceekiPP/64p8sBAAAAAADocYyeLgAA4DnLly/Xvn37NH/+fE+X0m2Fh4fr1ltv1SuvvKKqqipPlwMAAAAAANDjsCICAE5QLpdL06ZNk9ls1o8//ujpcrq1zMxMxcfH69lnn9XcuXM9XQ4AAAAAAECPwooIADhBrV27Vhs3btQjjzzi6VK6vZiYGM2ZM0fPP/+8amtrPV0OAAAAAABAj8KKCAA4QZ133nnKzc3Vjh07ZDAYPF1Ot7d3716NGjVK77zzjm688UZPlwMAAAAAANBjEEQAwAlo+/btmjhxoj766CNdddVVni6nx7jkkku0b98+7d27V0YjiwoBAAAAAADagyACAE5As2fP1qZNm5ScnCwvLy9Pl9NjbNiwQdOmTdPixYt1ySWXeLocAAAAAACAHoEgAgBOMKmpqRo2bJheffVV3XnnnZ4up8c566yzZLVatWHDBra0AgAAAAAAaAf2lQCAE8yzzz6r8PBw3XDDDZ4upUeaP3++Nm3apNWrV3u6FAAAAAAAgB6BFREAcALJzc1VXFycnnjiCc2fP9/T5fRILpdLkyZNUnh4uL777jtPlwMAAAAAANDtsSICAE4gL730kiwWC1syHQeDwaD58+dr5cqV2rp1q6fLAQAAAAAA6PZYEQEAJ4iysjLFxMTorrvu0tNPP+3pcno0h8OhYcOGaeLEifrss888XQ4AAAAAAEC3xooIADhBvP7666qtrdXcuXM9XUqPZzKZNG/ePC1atEjJycmeLgcAAAAAAKBbY0UEAJwAampqFBsbq8suu0xvvPGGp8vpFex2uwYNGqTf/e53evvttz1dDgAAAAAAQLfFiggAOAEsXLhQxcXFevDBBz1dSq/h4+Oj++67T++++66ys7M9XQ4AAAAAAEC3xYoIAOjl6uvrlZCQoKlTp+rjjz/2dDm9SkVFhWJiYnTrrbfq2Wef9XQ5AAAAAAAA3RIrIgCgl/vss8+Unp6uhx9+2NOl9DpBQUH6wx/+oAULFqi0tNTT5QAAAAAAAHRLrIgAgF7M5XJp3LhxGjBggFasWOHpcnqlgoICxcbG6tFHH9Wf/vQnT5cDAAAAAADQ7bAiAgB6sRUrVigxMVHz58/3dCm9VmRkpG6++Wa9/PLLslqtni4HAAAAAACg22FFBAD0YqeffrocDod+/vlnGQwGT5fTax08eFAJCQl66aWXdPfdd3u6HAAAAAAAgG6FIAIAeqmffvpJp59+ur788ktddNFFni6n17vmmmv0448/KjU1VWaz2dPlAAAAAAAAdBsEEQDQS1144YVKT0/Xrl27ZDSyE5+7JSYmauzYsXrvvfd07bXXerocAAAAAACAboMgAgB6oV27dmncuHE8FO9iM2fO1MGDBwl/AAAAAAAAfoUgAgB6IbYJ8oyff/5Zp512mpYtW6aZM2d6uhwAAAAAAIBugSACAHqZxsbJL774ou655x5Pl3PCoUE4AAAAAABAc+wbAQC9zHPPPac+ffro5ptv9nQpJ6T58+dr/fr1+vHHHz1dCgAAAAAAQLfAiggA6EXy8/MVFxenRx99VH/60588Xc4JyeVyady4cRowYIBWrFjh6XIAAAAAAAA8jhURANCL/OMf/5CXl5f+8Ic/eLqUE5bBYND8+fP19ddfa+fOnZ4uBwAAAAAAwONYEQEAvURFRYViYmJ0yy236LnnnvN0OSe0+vp6JSQkaOrUqfr44489XQ4AAAAAAIBHsSICAHqJBQsWyGq16r777vN0KSc8Ly8vPfTQQ/rss8+Ulpbm6XIAAAAAAAA8ihURANAL2Gw2DRo0SBdeeKHefvttT5cDSTU1NYqLi9Oll16qN954w9PlAAAAAAAAeAwrIgCgF3jvvfeUn5+vhx56yNOl4DBfX1/NnTtXCxcuVF5enqfLAQAAAAAA8BhWRABAD+dwODRs2DBNmDBBn3/+uafLwa+UlZUpJiZGd911l55++mlPlwMAAAAAAOARrIgAgB5u0aJFSktL0/z58z1dCv5LSEiI7rzzTr3xxhsqLy/3dDkAAAAAAAAewYoIAOjBXC6XJk6cqIiICH333XeeLgetyM3N1aBBg/T4448TFgEAAAAAgBMSKyIAoAf77rvvtGPHDh5wd2PR0dG64YYb9NJLL6mmpsbT5QAAAAAAAHQ5VkQAQA921llnqbq6Whs3bpTBYPB0OWhDamqqhg0bpldffVV33nmnp8sBAAAAAADoUgQRANBDbdiwQdOmTdMXX3yhSy+91NPl4Chmz56tTZs2KTk5WV5eXp4uBwAAAAAAoMsQRABAD/X73/9e+/fv1969e2U0stNed7djxw5NmDBBH330ka666ipPlwMAAAAAANBlCCIAoAfau3evRo0apXfeeUc33nijp8tBO51//vnKycnRjh072EoLAAAAAACcMPgKLQD0QH//+9/Vv39/zZkzx9OloAPmz5+vXbt26euvv/Z0KQAAAAAAAF2GFREA0MNkZmYqPj5ef//733Xfffd5uhx0gMvl0imnnCKz2ay1a9d6uhwAAAAAAIAuwYoIAOhhnn/+eQUFBenWW2/1dCnoIIPBoPnz5+vHH3/Uzz//7OlyAAAAAAAAugQrIgCgBykqKlJMTIzmzZunxx9/3NPl4Bg4nU6NGTNG8fHxWrZsmafLAQAAAAAAcDtWRABAD/LKK6/IYDDo7rvv9nQpOEZGo1EPP/ywli9frt27d3u6HAAAAAAAALdjRQQA9BBVVVWKiYnRddddp5deesnT5eA41NXVKT4+XmeccYbef/99T5cDAAAAAADgVqyIAIAe4q233lJlZaXuv/9+T5eC42Q2m/Xggw/q448/Vnp6uqfLAQAAAAAAcCtWRABAD2C32zV48GCde+65WrhwoafLQSewWq2KjY3V7Nmz9corr3i6HAAAAAAAALdhRQQA9AAffvihcnJyNG/ePE+Xgk7i5+ene++9V//85z9VUFDg6XIAAAAAAADchhURANDNORwOjRo1SiNGjNCSJUs8XQ46UUlJiWJiYjR37lw9+eSTni4HAAAAAADALVgRAQDd3NKlS5WUlKT58+d7uhR0stDQUN1+++167bXXVFFR4elyAAAAAAAA3IIVEQDQjblcLp188skKDAzUqlWrPF0O3CA7O1uDBg3SX//6Vz344IOeLgcAAAAAAKDTsSICALqxVatWacuWLayG6MX69++v6667Ti+88ILsdrunywEAAAAAAOh0rIgAgG7snHPOUXFxsbZu3SqDweDpcuAmSUlJGjFihN58803deuutni4HAAAAAACgUxFEAEA3tWXLFk2ePFmffvqprrjiCk+XAzebNWuWdu7cqf3798tkMnm6HAAAAAAAgE5DEAEA3RQPpk8sjcHTZ599pssvv9zT5QAAAAAAAHQagggA6IbYqufExFZcAAAAAACgN6JZNQB0Q88++6yioqJ03XXXeboUdKH58+dr+/btWrlypadLAQAAAAAA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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# plot decision tree\n", + "from sklearn import tree\n", + "plt.figure(figsize=(20, 20))\n", + "tree.plot_tree(classifier.estimators_[5], filled=True,class_names=[\"0\", \"1\"])\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# TEST_CROPS_PATH = Path.home() / \"Desktop/Code/CELLSEG_BENCHMARK/classifier_test/test_crops_128\"\n", + "# test_images_p = list(TEST_CROPS_PATH.glob(\"*.tif\"))\n", + "# test_images_p.sort()\n", + "# print(f\"Loaded {len(test_images_p)} images\")\n", + "\n", + "# test_images = [imread(str(image)) for image in test_images_p]\n", + "\n", + "# for i, im in enumerate(test_images):\n", + "# # norm_im = (im - im.min()) / (im.max() - im.min())\n", + "# hist = np.histogram(im, bins=100)[0]\n", + "# hist = hist / hist.sum()\n", + "# pred = classifier.predict(hist.reshape(1, -1))\n", + "# print(f\"Image {i} is {pred}\")\n", + "# # view = napari.view_image(im,colormap=\"turbo\")\n", + "# # view.dims.ndisplay = 3\n", + "# # napari.run()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# TEST_CROPS_PATH = Path.home() / \"Desktop/Code/CELLSEG_BENCHMARK/classifier_test/crops_64\"\n", + "# test_images_p = list(TEST_CROPS_PATH.glob(\"*.tif\"))\n", + "# test_images_p.sort()\n", + "# print(f\"Loaded {len(test_images_p)} images\")\n", + "\n", + "# test_images = [imread(str(image)) for image in test_images_p]\n", + "\n", + "# for i, im in enumerate(test_images):\n", + "# # norm_im = (im - im.min()) / (im.max() - im.min())\n", + "# hist = np.histogram(im, bins=100)[0]\n", + "# hist = hist / hist.sum()\n", + "# pred = classifier.predict(hist.reshape(1, -1))\n", + "# print(f\"Image {i} is {pred}\")\n", + "# # view = napari.view_image(im,colormap=\"turbo\")\n", + "# # view.dims.ndisplay = 3\n", + "# # napari.run()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "TEST_DATA_PATH = Path.home() / \"Desktop/Code/CELLSEG_BENCHMARK/classifier_test/TEST/TEST_preds_128_overlap_0.tif\"\n", + "test_image = imread(str(TEST_DATA_PATH))\n", + "test_image = test_image.swapaxes(0, 2)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mc:\\Users\\Cyril\\Desktop\\Code\\CellSeg3d\\napari_cellseg3d\\dev_scripts\\classifier_test.ipynb Cell 12\u001b[0m line \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 31\u001b[0m preds[crop_location_i:crop_location_i\u001b[39m+\u001b[39mcube_size, crop_location_j:crop_location_j\u001b[39m+\u001b[39mcube_size, crop_location_k:crop_location_k\u001b[39m+\u001b[39mcube_size] \u001b[39m=\u001b[39m \u001b[39m0\u001b[39m\n\u001b[0;32m 32\u001b[0m rejected[crop_location_i:crop_location_i\u001b[39m+\u001b[39mcube_size, crop_location_j:crop_location_j\u001b[39m+\u001b[39mcube_size, crop_location_k:crop_location_k\u001b[39m+\u001b[39mcube_size] \u001b[39m=\u001b[39m crop\n\u001b[1;32m---> 34\u001b[0m view \u001b[39m=\u001b[39m napari\u001b[39m.\u001b[39;49mview_image(preds, colormap\u001b[39m=\u001b[39;49m\u001b[39m\"\u001b[39;49m\u001b[39mturbo\u001b[39;49m\u001b[39m\"\u001b[39;49m)\n\u001b[0;32m 35\u001b[0m view\u001b[39m.\u001b[39madd_image(test_image, colormap\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mturbo\u001b[39m\u001b[39m\"\u001b[39m, blending\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39madditive\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 36\u001b[0m view\u001b[39m.\u001b[39madd_image(rejected, colormap\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mturbo\u001b[39m\u001b[39m\"\u001b[39m, blending\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39madditive\u001b[39m\u001b[39m\"\u001b[39m)\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\view_layers.py:178\u001b[0m, in \u001b[0;36mview_image\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 176\u001b[0m \u001b[39m@_merge_layer_viewer_sigs_docs\u001b[39m\n\u001b[0;32m 177\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mview_image\u001b[39m(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs):\n\u001b[1;32m--> 178\u001b[0m \u001b[39mreturn\u001b[39;00m _make_viewer_then(\u001b[39m'\u001b[39;49m\u001b[39madd_image\u001b[39;49m\u001b[39m'\u001b[39;49m, args, kwargs)[\u001b[39m0\u001b[39m]\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\view_layers.py:156\u001b[0m, in \u001b[0;36m_make_viewer_then\u001b[1;34m(add_method, args, kwargs)\u001b[0m\n\u001b[0;32m 154\u001b[0m viewer \u001b[39m=\u001b[39m kwargs\u001b[39m.\u001b[39mpop(\u001b[39m\"\u001b[39m\u001b[39mviewer\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39mNone\u001b[39;00m)\n\u001b[0;32m 155\u001b[0m \u001b[39mif\u001b[39;00m viewer \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m--> 156\u001b[0m viewer \u001b[39m=\u001b[39m Viewer(\u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mvkwargs)\n\u001b[0;32m 157\u001b[0m kwargs\u001b[39m.\u001b[39mupdate(kwargs\u001b[39m.\u001b[39mpop(\u001b[39m\"\u001b[39m\u001b[39mkwargs\u001b[39m\u001b[39m\"\u001b[39m, {}))\n\u001b[0;32m 158\u001b[0m method \u001b[39m=\u001b[39m \u001b[39mgetattr\u001b[39m(viewer, add_method)\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\viewer.py:67\u001b[0m, in \u001b[0;36mViewer.__init__\u001b[1;34m(self, title, ndisplay, order, axis_labels, show)\u001b[0m\n\u001b[0;32m 63\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mnapari\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mwindow\u001b[39;00m \u001b[39mimport\u001b[39;00m Window\n\u001b[0;32m 65\u001b[0m _initialize_plugins()\n\u001b[1;32m---> 67\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_window \u001b[39m=\u001b[39m Window(\u001b[39mself\u001b[39;49m, show\u001b[39m=\u001b[39;49mshow)\n\u001b[0;32m 68\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_instances\u001b[39m.\u001b[39madd(\u001b[39mself\u001b[39m)\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\_qt\\qt_main_window.py:552\u001b[0m, in \u001b[0;36mWindow.__init__\u001b[1;34m(self, viewer, show)\u001b[0m\n\u001b[0;32m 549\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_unnamed_dockwidget_count \u001b[39m=\u001b[39m \u001b[39m1\u001b[39m\n\u001b[0;32m 551\u001b[0m \u001b[39m# Connect the Viewer and create the Main Window\u001b[39;00m\n\u001b[1;32m--> 552\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_qt_window \u001b[39m=\u001b[39m _QtMainWindow(viewer, \u001b[39mself\u001b[39;49m)\n\u001b[0;32m 553\u001b[0m qapp\u001b[39m.\u001b[39minstallEventFilter(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_qt_window)\n\u001b[0;32m 555\u001b[0m \u001b[39m# connect theme events before collecting plugin-provided themes\u001b[39;00m\n\u001b[0;32m 556\u001b[0m \u001b[39m# to ensure icons from the plugins are generated correctly.\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\_qt\\qt_main_window.py:114\u001b[0m, in \u001b[0;36m_QtMainWindow.__init__\u001b[1;34m(self, viewer, window, parent)\u001b[0m\n\u001b[0;32m 112\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_ev \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n\u001b[0;32m 113\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_window \u001b[39m=\u001b[39m window\n\u001b[1;32m--> 114\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_qt_viewer \u001b[39m=\u001b[39m QtViewer(viewer, show_welcome_screen\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m)\n\u001b[0;32m 115\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_quit_app \u001b[39m=\u001b[39m \u001b[39mFalse\u001b[39;00m\n\u001b[0;32m 117\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39msetWindowIcon(QIcon(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_window_icon))\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\_qt\\qt_viewer.py:205\u001b[0m, in \u001b[0;36mQtViewer.__init__\u001b[1;34m(self, viewer, show_welcome_screen)\u001b[0m\n\u001b[0;32m 200\u001b[0m QCoreApplication\u001b[39m.\u001b[39msetAttribute(\n\u001b[0;32m 201\u001b[0m Qt\u001b[39m.\u001b[39mAA_UseStyleSheetPropagationInWidgetStyles, \u001b[39mTrue\u001b[39;00m\n\u001b[0;32m 202\u001b[0m )\n\u001b[0;32m 204\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mviewer \u001b[39m=\u001b[39m viewer\n\u001b[1;32m--> 205\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdims \u001b[39m=\u001b[39m QtDims(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mviewer\u001b[39m.\u001b[39;49mdims)\n\u001b[0;32m 206\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_controls \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n\u001b[0;32m 207\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_layers \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\_qt\\widgets\\qt_dims.py:59\u001b[0m, in \u001b[0;36mQtDims.__init__\u001b[1;34m(self, dims, parent)\u001b[0m\n\u001b[0;32m 56\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39msetSizePolicy(QSizePolicy\u001b[39m.\u001b[39mPreferred, QSizePolicy\u001b[39m.\u001b[39mFixed)\n\u001b[0;32m 58\u001b[0m \u001b[39m# Update the number of sliders now that the dims have been added\u001b[39;00m\n\u001b[1;32m---> 59\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_update_nsliders()\n\u001b[0;32m 60\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdims\u001b[39m.\u001b[39mevents\u001b[39m.\u001b[39mndim\u001b[39m.\u001b[39mconnect(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_update_nsliders)\n\u001b[0;32m 61\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdims\u001b[39m.\u001b[39mevents\u001b[39m.\u001b[39mcurrent_step\u001b[39m.\u001b[39mconnect(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_update_slider)\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\_qt\\widgets\\qt_dims.py:125\u001b[0m, in \u001b[0;36mQtDims._update_nsliders\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 123\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mstop()\n\u001b[0;32m 124\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_trim_sliders(\u001b[39m0\u001b[39m)\n\u001b[1;32m--> 125\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_create_sliders(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mdims\u001b[39m.\u001b[39;49mndim)\n\u001b[0;32m 126\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_update_display()\n\u001b[0;32m 127\u001b[0m \u001b[39mfor\u001b[39;00m i \u001b[39min\u001b[39;00m \u001b[39mrange\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdims\u001b[39m.\u001b[39mndim):\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\_qt\\widgets\\qt_dims.py:190\u001b[0m, in \u001b[0;36mQtDims._create_sliders\u001b[1;34m(self, number_of_sliders)\u001b[0m\n\u001b[0;32m 188\u001b[0m \u001b[39mfor\u001b[39;00m slider_num \u001b[39min\u001b[39;00m \u001b[39mrange\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnsliders, number_of_sliders):\n\u001b[0;32m 189\u001b[0m dim_axis \u001b[39m=\u001b[39m number_of_sliders \u001b[39m-\u001b[39m slider_num \u001b[39m-\u001b[39m \u001b[39m1\u001b[39m\n\u001b[1;32m--> 190\u001b[0m slider_widget \u001b[39m=\u001b[39m QtDimSliderWidget(\u001b[39mself\u001b[39;49m, dim_axis)\n\u001b[0;32m 191\u001b[0m slider_widget\u001b[39m.\u001b[39maxis_label\u001b[39m.\u001b[39mtextChanged\u001b[39m.\u001b[39mconnect(\n\u001b[0;32m 192\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_resize_axis_labels\n\u001b[0;32m 193\u001b[0m )\n\u001b[0;32m 194\u001b[0m slider_widget\u001b[39m.\u001b[39mplay_button\u001b[39m.\u001b[39mplay_requested\u001b[39m.\u001b[39mconnect(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mplay)\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\_qt\\widgets\\qt_dims_slider.py:89\u001b[0m, in \u001b[0;36mQtDimSliderWidget.__init__\u001b[1;34m(self, parent, axis)\u001b[0m\n\u001b[0;32m 84\u001b[0m connect_setattr_value(\n\u001b[0;32m 85\u001b[0m settings\u001b[39m.\u001b[39mapplication\u001b[39m.\u001b[39mevents\u001b[39m.\u001b[39mplayback_mode, \u001b[39mself\u001b[39m, \u001b[39m\"\u001b[39m\u001b[39mloop_mode\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m 86\u001b[0m )\n\u001b[0;32m 88\u001b[0m layout \u001b[39m=\u001b[39m QHBoxLayout()\n\u001b[1;32m---> 89\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_create_axis_label_widget()\n\u001b[0;32m 90\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_create_range_slider_widget()\n\u001b[0;32m 91\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_create_play_button_widget()\n", + "File \u001b[1;32mc:\\Users\\Cyril\\anaconda3\\envs\\cellseg3d\\lib\\site-packages\\napari\\_qt\\widgets\\qt_dims_slider.py:127\u001b[0m, in \u001b[0;36mQtDimSliderWidget._create_axis_label_widget\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 125\u001b[0m label\u001b[39m.\u001b[39msetObjectName(\u001b[39m'\u001b[39m\u001b[39maxis_label\u001b[39m\u001b[39m'\u001b[39m) \u001b[39m# needed for _update_label\u001b[39;00m\n\u001b[0;32m 126\u001b[0m label\u001b[39m.\u001b[39msetText(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdims\u001b[39m.\u001b[39maxis_labels[\u001b[39mself\u001b[39m\u001b[39m.\u001b[39maxis])\n\u001b[1;32m--> 127\u001b[0m label\u001b[39m.\u001b[39;49mhome(\u001b[39mFalse\u001b[39;00m)\n\u001b[0;32m 128\u001b[0m label\u001b[39m.\u001b[39msetToolTip(trans\u001b[39m.\u001b[39m_(\u001b[39m'\u001b[39m\u001b[39mEdit to change axis label\u001b[39m\u001b[39m'\u001b[39m))\n\u001b[0;32m 129\u001b[0m label\u001b[39m.\u001b[39msetAcceptDrops(\u001b[39mFalse\u001b[39;00m)\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "cube_size = 128\n", + "preds = np.zeros(test_image.shape)\n", + "rejected = np.zeros(test_image.shape)\n", + "\n", + "for i in range(0, test_image.shape[0], cube_size):\n", + " for j in range(0, test_image.shape[1], cube_size):\n", + " for k in range(0, test_image.shape[2], cube_size):\n", + " if i + cube_size >= test_image.shape[0]:\n", + " crop_location_i = test_image.shape[0] - cube_size\n", + " else:\n", + " crop_location_i = i\n", + " if j + cube_size >= test_image.shape[1]:\n", + " crop_location_j = test_image.shape[1] - cube_size\n", + " else:\n", + " crop_location_j = j\n", + " if k + cube_size >= test_image.shape[2]:\n", + " crop_location_k = test_image.shape[2] - cube_size\n", + " else:\n", + " crop_location_k = k\n", + " \n", + " crop = test_image[crop_location_i:crop_location_i+cube_size, crop_location_j:crop_location_j+cube_size, crop_location_k:crop_location_k+cube_size]\n", + " # crop_normalized = (crop - crop.min()) / (crop.max() - crop.min())\n", + " hist = np.histogram(crop, bins=100)[0]\n", + " hist = hist / hist.sum()\n", + " pred = classifier.predict(hist.reshape(1, -1))[0]\n", + " \n", + " if pred == 0:\n", + " preds[crop_location_i:crop_location_i+cube_size, crop_location_j:crop_location_j+cube_size, crop_location_k:crop_location_k+cube_size] = crop\n", + " rejected[crop_location_i:crop_location_i+cube_size, crop_location_j:crop_location_j+cube_size, crop_location_k:crop_location_k+cube_size] = 0\n", + " else:\n", + " preds[crop_location_i:crop_location_i+cube_size, crop_location_j:crop_location_j+cube_size, crop_location_k:crop_location_k+cube_size] = 0\n", + " rejected[crop_location_i:crop_location_i+cube_size, crop_location_j:crop_location_j+cube_size, crop_location_k:crop_location_k+cube_size] = crop\n", + "\n", + "view = napari.view_image(preds, colormap=\"turbo\")\n", + "view.add_image(test_image, colormap=\"turbo\", blending=\"additive\")\n", + "view.add_image(rejected, colormap=\"turbo\", blending=\"additive\")\n", + "view.grid.enabled = True\n", + "view.dims.ndisplay = 3\n", + "napari.run()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['C:\\\\Users\\\\Cyril\\\\Desktop\\\\Code\\\\CELLSEG_BENCHMARK\\\\classifier_test\\\\train\\\\classifier_new.joblib']" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import joblib\n", + "joblib.dump(classifier, DATA_PATH / \"classifier_new.joblib\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cellseg3d", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/napari_cellseg3d/dev_scripts/colab_training.py b/napari_cellseg3d/dev_scripts/colab_training.py index 413cb25b..21c85f32 100644 --- a/napari_cellseg3d/dev_scripts/colab_training.py +++ b/napari_cellseg3d/dev_scripts/colab_training.py @@ -1,3 +1,4 @@ +"""Script to run WNet training in Google Colab.""" import time from pathlib import Path @@ -59,7 +60,8 @@ class WNetTrainingWorkerColab(TrainingWorkerBase): """A custom worker to run WNet (unsupervised) training jobs in. - Inherits from :py:class:`napari.qt.threading.GeneratorWorker` via :py:class:`TrainingWorkerBase` + + Inherits from :py:class:`napari.qt.threading.GeneratorWorker` via :py:class:`TrainingWorkerBase`. """ def __init__( @@ -67,6 +69,12 @@ def __init__( worker_config: config.WNetTrainingWorkerConfig, wandb_config: config.WandBConfig = None, ): + """Create a WNet training worker for Google Colab. + + Args: + worker_config: worker configuration + wandb_config: optional wandb configuration + """ super().__init__() self.config = worker_config self.wandb_config = ( @@ -74,7 +82,7 @@ def __init__( ) self.dice_metric = DiceMetric( - include_background=True, reduction="mean", get_not_nans=False + include_background=False, reduction="mean", get_not_nans=False ) self.normalize_function = utils.remap_image self.start_time = time.time() @@ -89,18 +97,18 @@ def __init__( self.data_shape = None def log(self, text): + """Log a message to the logger and to wandb if installed.""" logger.info(text) def get_patch_dataset(self, train_transforms): - """Creates a Dataset from the original data using the tifffile library + """Creates a Dataset from the original data using the tifffile library. Args: - train_data_dict (dict): dict with the Paths to the directory containing the data + train_transforms (Compose): The transforms to apply to the data Returns: (tuple): A tuple containing the shape of the data and the dataset """ - patch_func = Compose( [ LoadImaged(keys=["image"], image_only=True), @@ -134,6 +142,7 @@ def get_patch_dataset(self, train_transforms): return self.config.sample_size, dataset def get_dataset_eval(self, eval_dataset_dict): + """Creates a Dataset applying some transforms/augmentation on the data using the MONAI library.""" eval_transforms = Compose( [ LoadImaged(keys=["image", "label"]), @@ -166,10 +175,10 @@ def get_dataset_eval(self, eval_dataset_dict): ) def get_dataset(self, train_transforms): - """Creates a Dataset applying some transforms/augmentation on the data using the MONAI library + """Creates a Dataset applying some transforms/augmentation on the data using the MONAI library. Args: - config (WNetTrainingWorkerConfig): The configuration object + train_transforms (Compose): The transforms to apply to the data Returns: (tuple): A tuple containing the shape of the data and the dataset @@ -257,6 +266,7 @@ def _get_data(self): return self.dataloader, self.eval_dataloader, self.data_shape def log_parameters(self): + """Log the parameters of the training.""" self.log("*" * 20) self.log("-- Parameters --") self.log(f"Device: {self.config.device}") @@ -264,7 +274,7 @@ def log_parameters(self): self.log(f"Epochs: {self.config.max_epochs}") self.log(f"Learning rate: {self.config.learning_rate}") self.log(f"Validation interval: {self.config.validation_interval}") - if self.config.weights_info.custom: + if self.config.weights_info.use_custom: self.log(f"Custom weights: {self.config.weights_info.path}") elif self.config.weights_info.use_pretrained: self.log(f"Pretrained weights: {self.config.weights_info.path}") @@ -306,6 +316,7 @@ def log_parameters(self): def train( self, provided_model=None, provided_optimizer=None, provided_loss=None ): + """Train the model.""" try: if self.config is None: self.config = config.WNetTrainingWorkerConfig() @@ -318,7 +329,7 @@ def train( logger.debug(f"wandb config : {config_dict}") wandb.init( config=config_dict, - project="CellSeg3D WNet (Colab)", + project="CellSeg3D (Colab)", mode=self.wandb_config.mode, ) @@ -363,7 +374,7 @@ def train( if WANDB_INSTALLED: wandb.watch(model, log_freq=100) - if self.config.weights_info.custom: + if self.config.weights_info.use_custom: if self.config.weights_info.use_pretrained: weights_file = "wnet.pth" self.downloader.download_weights("WNet", weights_file) @@ -599,6 +610,7 @@ def train( raise e def eval(self, model, _): + """Evaluate the model on the validation set.""" with torch.no_grad(): device = self.config.device for _k, val_data in enumerate(self.eval_dataloader): @@ -712,6 +724,7 @@ def get_colab_worker( Args: worker_config (config.WNetTrainingWorkerConfig): config for the training worker + wandb_config (config.WandBConfig): config for wandb """ worker = WNetTrainingWorkerColab(worker_config) worker.wandb_config = wandb_config @@ -742,7 +755,6 @@ def create_eval_dataset_dict(image_directory, label_directory): * "image": image * "label" : corresponding label """ - images_filepaths = sorted(Path.glob(image_directory, "*.tif")) labels_filepaths = sorted(Path.glob(label_directory, "*.tif")) diff --git a/napari_cellseg3d/dev_scripts/correct_labels.py b/napari_cellseg3d/dev_scripts/correct_labels.py index 4f529abe..572ca429 100644 --- a/napari_cellseg3d/dev_scripts/correct_labels.py +++ b/napari_cellseg3d/dev_scripts/correct_labels.py @@ -25,13 +25,14 @@ def relabel_non_unique_i(label, save_path, go_fast=False): - """relabel the image labelled with different label for each neuron and save it in the save_path location + """Relabel the image labelled with different label for each neuron and save it in the save_path location. + Parameters ---------- label : np.array the label image save_path : str - the path to save the relabeld image + the path to save the relabeld image. """ value_label = 0 new_labels = np.zeros_like(label) @@ -67,7 +68,8 @@ def relabel_non_unique_i(label, save_path, go_fast=False): def add_label(old_label, artefact, new_label_path, i_labels_to_add): - """add the label to the label image + """Add the label to the label image. + Parameters ---------- old_label : np.array @@ -75,7 +77,7 @@ def add_label(old_label, artefact, new_label_path, i_labels_to_add): artefact : np.array the artefact image that contains some neurons new_label_path : str - the path to save the new label image + the path to save the new label image. """ new_label = old_label.copy() max_label = np.max(old_label) @@ -148,7 +150,8 @@ def relabel( viewer=None, test=False, ): - """relabel the image labelled with different label for each neuron and save it in the save_path location + """Relabel the image labelled with different label for each neuron and save it in the save_path location. + Parameters ---------- image_path : str @@ -162,7 +165,7 @@ def relabel( delay : float, optional the delay between each image for the visualization, by default 0.3 viewer : napari.Viewer, optional - the napari viewer, by default None + the napari viewer, by default None. """ global returns @@ -255,7 +258,8 @@ def relabel( def modify_viewer(old_label, new_label, args): - """modify the viewer to show the relabeling + """Modify the viewer to show the relabeling. + Parameters ---------- old_label : napari.layers.Labels @@ -263,7 +267,7 @@ def modify_viewer(old_label, new_label, args): new_label : napari.layers.Labels the layer of the new label args : list - the first element is the old label and the second element is the new label + the first element is the old label and the second element is the new label. """ if args == "hide new label": new_label.visible = False @@ -277,13 +281,14 @@ def modify_viewer(old_label, new_label, args): @thread_worker def to_show(map_labels_existing, delay=0.5): - """modify the viewer to show the relabeling + """Modify the viewer to show the relabeling. + Parameters ---------- map_labels_existing : list the list of the of the map between the old label and the new label delay : float, optional - the delay between each image for the visualization, by default 0.3 + the delay between each image for the visualization, by default 0.3. """ time.sleep(2) for i in map_labels_existing: @@ -303,7 +308,6 @@ def create_connected_widget( old_label, new_label, map_labels_existing, delay=0.5 ): """Builds a widget that can control a function in another thread.""" - worker = to_show(map_labels_existing, delay) worker.start() worker.yielded.connect( @@ -312,11 +316,12 @@ def create_connected_widget( def visualize_map(map_labels_existing, label_path, relabel_path, delay=0.5): - """visualize the map of the relabeling + """Visualize the map of the relabeling. + Parameters ---------- map_labels_existing : list - the list of the relabeling + the list of the relabeling. """ label = imread(label_path) relabel = imread(relabel_path) @@ -346,13 +351,14 @@ def visualize_map(map_labels_existing, label_path, relabel_path, delay=0.5): def relabel_non_unique_i_folder(folder_path, end_of_new_name="relabeled"): - """relabel the image labelled with different label for each neuron and save it in the save_path location + """Relabel the image labelled with different label for each neuron and save it in the save_path location. + Parameters ---------- folder_path : str the path to the folder containing the label images end_of_new_name : str - thename to add at the end of the relabled image + thename to add at the end of the relabled image. """ for file in Path.iterdir(folder_path): if file.suffix == ".tif": diff --git a/napari_cellseg3d/dev_scripts/evaluate_labels.py b/napari_cellseg3d/dev_scripts/evaluate_labels.py index 2830f4e7..48861dcd 100644 --- a/napari_cellseg3d/dev_scripts/evaluate_labels.py +++ b/napari_cellseg3d/dev_scripts/evaluate_labels.py @@ -16,6 +16,7 @@ def evaluate_model_performance( visualize=False, ): """Evaluate the model performance. + Parameters ---------- labels : ndarray @@ -26,7 +27,8 @@ def evaluate_model_performance( If True, print the results. visualize : bool If True, visualize the results. - Returns + + Returns: ------- neuron_found : float The number of neurons found by the model @@ -45,7 +47,7 @@ def evaluate_model_performance( mean_true_positive_ratio_model_fused: float The mean (over the model's labels that correspond to multiple true label) of (correctly labelled pixels in any fused neurons of this model's label)/(total number of pixels of the model's label) mean_ratio_false_pixel_artefact: float - The mean (over the model's labels that are not labelled in the neurons) of (wrongly labelled pixels)/(total number of pixels of the model's label) + The mean (over the model's labels that are not labelled in the neurons) of (wrongly labelled pixels)/(total number of pixels of the model's label). """ log.debug("Mapping labels...") map_labels_existing, map_fused_neurons, new_labels = map_labels( @@ -185,20 +187,22 @@ def evaluate_model_performance( def map_labels(gt_labels, model_labels, threshold_correct=PERCENT_CORRECT): """Map the model's labels to the neurons labels. + Parameters ---------- gt_labels : ndarray Label image with neurons labelled as mulitple values. model_labels : ndarray Label image from the model labelled as mulitple values. - Returns + + Returns: ------- map_labels_existing: numpy array The label value of the model and the label value of the neuron associated, the ratio of the pixels of the true label correctly labelled, the ratio of the pixels of the model's label correctly labelled map_fused_neurons: numpy array The neurones are considered fused if they are labelled by the same model's label, in this case we will return The label value of the model and the label value of the neurone associated, the ratio of the pixels of the true label correctly labelled, the ratio of the pixels of the model's label that are in one of the fused neurones new_labels: list - The labels of the model that are not labelled in the neurons, the ratio of the pixels of the model's label that are an artefact + The labels of the model that are not labelled in the neurons, the ratio of the pixels of the model's label that are an artefact. """ map_labels_existing = [] map_fused_neurons = [] @@ -259,8 +263,7 @@ def map_labels(gt_labels, model_labels, threshold_correct=PERCENT_CORRECT): def save_as_csv(results, path): - """ - Save the results as a csv file + """Save the results as a csv file. Parameters ---------- @@ -285,222 +288,3 @@ def save_as_csv(results, path): ], ) df.to_csv(path, index=False) - - -####################### -# Slower version that was used for debugging -####################### - -# from collections import Counter -# from dataclasses import dataclass -# from typing import Dict -# @dataclass -# class LabelInfo: -# gt_index: int -# model_labels_id_and_status: Dict = None # for each model label id present on gt_index in gt labels, contains status (correct/wrong) -# best_model_label_coverage: float = ( -# 0.0 # ratio of pixels of the gt label correctly labelled -# ) -# overall_gt_label_coverage: float = 0.0 # true positive ration of the model -# -# def get_correct_ratio(self): -# for model_label, status in self.model_labels_id_and_status.items(): -# if status == "correct": -# return self.best_model_label_coverage -# else: -# return None - - -# def eval_model(gt_labels, model_labels, print_report=False): -# -# report_list, new_labels, fused_labels = create_label_report( -# gt_labels, model_labels -# ) -# per_label_perfs = [] -# for report in report_list: -# if print_report: -# log.info( -# f"Label {report.gt_index} : {report.model_labels_id_and_status}" -# ) -# log.info( -# f"Best model label coverage : {report.best_model_label_coverage}" -# ) -# log.info( -# f"Overall gt label coverage : {report.overall_gt_label_coverage}" -# ) -# -# perf = report.get_correct_ratio() -# if perf is not None: -# per_label_perfs.append(perf) -# -# per_label_perfs = np.array(per_label_perfs) -# return per_label_perfs.mean(), new_labels, fused_labels - - -# def create_label_report(gt_labels, model_labels): -# """Map the model's labels to the neurons labels. -# Parameters -# ---------- -# gt_labels : ndarray -# Label image with neurons labelled as mulitple values. -# model_labels : ndarray -# Label image from the model labelled as mulitple values. -# Returns -# ------- -# map_labels_existing: numpy array -# The label value of the model and the label value of the neurone associated, the ratio of the pixels of the true label correctly labelled, the ratio of the pixels of the model's label correctly labelled -# map_fused_neurons: numpy array -# The neurones are considered fused if they are labelled by the same model's label, in this case we will return The label value of the model and the label value of the neurone associated, the ratio of the pixels of the true label correctly labelled, the ratio of the pixels of the model's label that are in one of the fused neurones -# new_labels: list -# The labels of the model that are not labelled in the neurons, the ratio of the pixels of the model's label that are an artefact -# """ -# -# map_labels_existing = [] -# map_fused_neurons = {} -# "background_labels contains all model labels where gt_labels is 0 and model_labels is not 0" -# background_labels = model_labels[np.where((gt_labels == 0))] -# "new_labels contains all labels in model_labels for which more than PERCENT_CORRECT% of the pixels are not labelled in gt_labels" -# new_labels = [] -# for lab in np.unique(background_labels): -# if lab == 0: -# continue -# gt_background_size_at_lab = ( -# gt_labels[np.where((model_labels == lab) & (gt_labels == 0))] -# .flatten() -# .shape[0] -# ) -# gt_lab_size = ( -# gt_labels[np.where(model_labels == lab)].flatten().shape[0] -# ) -# if gt_background_size_at_lab / gt_lab_size > PERCENT_CORRECT: -# new_labels.append(lab) -# -# label_report_list = [] -# # label_report = {} # contains a dict saying which labels are correct or wrong for each gt label -# # model_label_values = {} # contains the model labels value assigned to each unique gt label -# not_found_id = 0 -# -# for i in tqdm(np.unique(gt_labels)): -# if i == 0: -# continue -# -# gt_label = gt_labels[np.where(gt_labels == i)] # get a single gt label -# -# model_lab_on_gt = model_labels[ -# np.where(((gt_labels == i) & (model_labels != 0))) -# ] # all models labels on single gt_label -# info = LabelInfo(i) -# -# info.model_labels_id_and_status = { -# label_id: "" for label_id in np.unique(model_lab_on_gt) -# } -# -# if model_lab_on_gt.shape[0] == 0: -# info.model_labels_id_and_status[ -# f"not_found_{not_found_id}" -# ] = "not found" -# not_found_id += 1 -# label_report_list.append(info) -# continue -# -# log.debug(f"model_lab_on_gt : {np.unique(model_lab_on_gt)}") -# -# # create LabelInfo object and init model_labels_id_and_status with all unique model labels on gt_label -# log.debug( -# f"info.model_labels_id_and_status : {info.model_labels_id_and_status}" -# ) -# -# ratio = [] -# for model_lab_id in info.model_labels_id_and_status.keys(): -# size_model_label = ( -# model_lab_on_gt[np.where(model_lab_on_gt == model_lab_id)] -# .flatten() -# .shape[0] -# ) -# size_gt_label = gt_label.flatten().shape[0] -# -# log.debug(f"size_model_label : {size_model_label}") -# log.debug(f"size_gt_label : {size_gt_label}") -# -# ratio.append(size_model_label / size_gt_label) -# -# # log.debug(ratio) -# ratio_model_lab_for_given_gt_lab = np.array(ratio) -# info.best_model_label_coverage = ratio_model_lab_for_given_gt_lab.max() -# -# best_model_lab_id = model_lab_on_gt[ -# np.argmax(ratio_model_lab_for_given_gt_lab) -# ] -# log.debug(f"best_model_lab_id : {best_model_lab_id}") -# -# info.overall_gt_label_coverage = ( -# ratio_model_lab_for_given_gt_lab.sum() -# ) # the ratio of the pixels of the true label correctly labelled -# -# if info.best_model_label_coverage > PERCENT_CORRECT: -# info.model_labels_id_and_status[best_model_lab_id] = "correct" -# # info.model_labels_id_and_size[best_model_lab_id] = model_labels[np.where(model_labels == best_model_lab_id)].flatten().shape[0] -# else: -# info.model_labels_id_and_status[best_model_lab_id] = "wrong" -# for model_lab_id in np.unique(model_lab_on_gt): -# if model_lab_id != best_model_lab_id: -# log.debug(model_lab_id, "is wrong") -# info.model_labels_id_and_status[model_lab_id] = "wrong" -# -# label_report_list.append(info) -# -# correct_labels_id = [] -# for report in label_report_list: -# for i_lab in report.model_labels_id_and_status.keys(): -# if report.model_labels_id_and_status[i_lab] == "correct": -# correct_labels_id.append(i_lab) -# """Find all labels in label_report_list that are correct more than once""" -# duplicated_labels = [ -# item for item, count in Counter(correct_labels_id).items() if count > 1 -# ] -# "Sum up the size of all duplicated labels" -# for i in duplicated_labels: -# for report in label_report_list: -# if ( -# i in report.model_labels_id_and_status.keys() -# and report.model_labels_id_and_status[i] == "correct" -# ): -# size = ( -# model_labels[np.where(model_labels == i)] -# .flatten() -# .shape[0] -# ) -# map_fused_neurons[i] = size -# -# return label_report_list, new_labels, map_fused_neurons - -# if __name__ == "__main__": -# """ -# # Example of how to use the functions in this module. -# a = np.array([[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]) -# -# b = np.array([[5, 5, 0, 0], [5, 5, 2, 0], [0, 2, 2, 0], [0, 0, 2, 0]]) -# evaluate_model_performance(a, b) -# -# c = np.array([[2, 2, 0, 0], [2, 2, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]) -# -# d = np.array([[4, 0, 4, 0], [4, 4, 4, 0], [0, 4, 4, 0], [0, 0, 4, 0]]) -# -# evaluate_model_performance(c, d) -# -# from tifffile import imread -# labels=imread("dataset/visual_tif/labels/testing_im_new_label.tif") -# labels_model=imread("dataset/visual_tif/artefact_neurones/basic_model.tif") -# evaluate_model_performance(labels, labels_model,visualize=True) -# """ -# from tifffile import imread -# -# labels = imread("dataset_clean/VALIDATION/validation_labels.tif") -# try: -# labels_model = imread("results/watershed_based_model/instance_labels.tif") -# except: -# raise Exception( -# "you should download the model's label that are under results (output and statistics)/watershed_based_model/instance_labels.tif and put it in the folder results/watershed_based_model/" -# ) -# -# evaluate_model_performance(labels, labels_model, visualize=True) diff --git a/napari_cellseg3d/dev_scripts/remote_training.py b/napari_cellseg3d/dev_scripts/remote_training.py new file mode 100644 index 00000000..e2d05d12 --- /dev/null +++ b/napari_cellseg3d/dev_scripts/remote_training.py @@ -0,0 +1,138 @@ +"""Showcases how to train a model without napari.""" + +from pathlib import Path + +from napari_cellseg3d import config as cfg +from napari_cellseg3d.code_models.worker_training import ( + SupervisedTrainingWorker, +) +from napari_cellseg3d.utils import LOGGER as logger + +TRAINING_SPLIT = 0.2 # 0.4, 0.8 +MODEL_NAME = "SegResNet" # "SwinUNetR" +BATCH_SIZE = 10 if MODEL_NAME == "SegResNet" else 5 +# BATCH_SIZE = 1 + +SPLIT_FOLDER = "1_c15" # "2_c1_c4_visual" "3_c1245_visual" +RESULTS_PATH = ( + Path("/data/cyril") + / "CELLSEG_BENCHMARK/cellseg3d_train" + / f"{MODEL_NAME}_{SPLIT_FOLDER}_{int(TRAINING_SPLIT*100)}" +) + +IMAGES = ( + Path("/data/cyril") + / f"CELLSEG_BENCHMARK/TPH2_mesospim/SPLITS/{SPLIT_FOLDER}" +) +LABELS = ( + Path("/data/cyril") + / f"CELLSEG_BENCHMARK/TPH2_mesospim/SPLITS/{SPLIT_FOLDER}/labels/semantic" +) + + +class LogFixture: + """Fixture for napari-less logging, replaces napari_cellseg3d.interface.Log in model_workers. + + This allows to redirect the output of the workers to stdout instead of a specialized widget. + """ + + def __init__(self): + """Creates a LogFixture object.""" + super(LogFixture, self).__init__() + + def print_and_log(self, text, printing=None): + """Prints and logs text.""" + print(text) + + def warn(self, warning): + """Logs warning.""" + logger.warning(warning) + + def error(self, e): + """Logs error.""" + raise (e) + + +def prepare_data(images_path, labels_path): + """Prepares data for training.""" + assert images_path.exists(), f"Images path does not exist: {images_path}" + assert labels_path.exists(), f"Labels path does not exist: {labels_path}" + if not RESULTS_PATH.exists(): + RESULTS_PATH.mkdir(parents=True, exist_ok=True) + + images = sorted(Path.glob(images_path, "*.tif")) + labels = sorted(Path.glob(labels_path, "*.tif")) + + print(f"Images paths: {images}") + print(f"Labels paths: {labels}") + + logger.info("Images :\n") + for file in images: + logger.info(Path(file).name) + logger.info("*" * 10) + logger.info("Labels :\n") + for file in images: + logger.info(Path(file).name) + + assert len(images) == len( + labels + ), "Number of images and labels must be the same" + + return [ + {"image": str(image_path), "label": str(label_path)} + for image_path, label_path in zip(images, labels) + ] + + +def remote_training(): + """Function to train a model without napari.""" + # print(f"Results path: {RESULTS_PATH.resolve()}") + + wandb_config = cfg.WandBConfig( + mode="online", + save_model_artifact=True, + ) + + deterministic_config = cfg.DeterministicConfig( + seed=34936339, + ) + + worker_config = cfg.SupervisedTrainingWorkerConfig( + device="cuda:0", + max_epochs=50, + learning_rate=0.001, # 1e-3 + validation_interval=2, + batch_size=BATCH_SIZE, # 10 for SegResNet + deterministic_config=deterministic_config, + scheduler_factor=0.5, + scheduler_patience=10, # use default scheduler + weights_info=cfg.WeightsInfo(), # no pretrained weights + results_path_folder=str(RESULTS_PATH), + sampling=False, + do_augmentation=True, + train_data_dict=prepare_data(IMAGES, LABELS), + # supervised specific + model_info=cfg.ModelInfo( + name=MODEL_NAME, + model_input_size=(64, 64, 64), + ), + loss_function="Generalized Dice", + training_percent=TRAINING_SPLIT, + ) + + worker = SupervisedTrainingWorker(worker_config) + worker.wandb_config = wandb_config + ######### SET LOG + log = LogFixture() + worker.log_signal.connect(log.print_and_log) + worker.warn_signal.connect(log.warn) + worker.error_signal.connect(log.error) + + results = [] + for result in worker.train(): + results.append(result) + print("Training finished") + + +if __name__ == "__main__": + results = remote_training() diff --git a/napari_cellseg3d/dev_scripts/thread_test.py b/napari_cellseg3d/dev_scripts/thread_test.py index 82782ef8..cdaa368e 100644 --- a/napari_cellseg3d/dev_scripts/thread_test.py +++ b/napari_cellseg3d/dev_scripts/thread_test.py @@ -23,11 +23,11 @@ @thread_worker def two_way_communication_with_args(start, end): """Both sends and receives values to & from the main thread. + Accepts arguments, puts them on the worker object. Receives values from main thread with ``incoming = yield`` - Optionally returns a value at the end + Optionally returns a value at the end. """ - # do computationally intensive work here i = start while i < end: @@ -43,7 +43,10 @@ def two_way_communication_with_args(start, end): class Controller(QWidget): + """Widget that controls a function running in another thread.""" + def __init__(self, viewer): + """Build the widget.""" super().__init__() self.viewer = viewer diff --git a/napari_cellseg3d/dev_scripts/whole_brain_utils.py b/napari_cellseg3d/dev_scripts/whole_brain_utils.py new file mode 100644 index 00000000..e36be7cf --- /dev/null +++ b/napari_cellseg3d/dev_scripts/whole_brain_utils.py @@ -0,0 +1,50 @@ +"""Utilities to improve whole-brain regions segmentation.""" +import numpy as np +from skimage.measure import label +from skimage.segmentation import find_boundaries + + +def extract_continuous_region(image): + """Extract continuous region from image.""" + image = np.where(image > 0, 1, 0) + return label(image) + + +def get_boundaries(image_regions, num_iters=1): + """Obtain boundaries from image regions.""" + boundaries = np.zeros_like(image_regions) + label_values = np.unique(image_regions) + iter_n = 0 + new_labels = image_regions + while iter_n < num_iters: + for i in label_values: + if i == 0: + continue + boundary = find_boundaries(new_labels == i) + boundaries += np.where(boundary > 0, i, 0) + new_labels = np.where(boundary > 0, 0, new_labels) + iter_n += 1 + return boundaries + + +def remove_boundaries_from_segmentation( + image_segmentation, image_labels=None, image=None, thickness_num_iters=1 +): + """Remove boundaries from segmentation. + + Args: + image_segmentation (np.ndarray): 3D image segmentation. + image_labels (np.ndarray): 3D integer labels of image segmentation. Use output from extract_continuous_region. + image (np.ndarray): Additional 3D image used to extract continuous region. + thickness_num_iters (int): Number of iterations to remove boundaries. A greater number will remove more boundary pixels. + """ + if image_labels is None: + image_regions = extract_continuous_region(image_segmentation) + elif image is not None: + image_regions = extract_continuous_region(image) + else: + image_regions = image_labels + boundaries = get_boundaries(image_regions, num_iters=thickness_num_iters) + + seg_in = np.where(image_regions > 0, image_segmentation, 0) + return np.where(boundaries > 0, 0, seg_in) diff --git a/napari_cellseg3d/interface.py b/napari_cellseg3d/interface.py index 6f832e23..05baf64c 100644 --- a/napari_cellseg3d/interface.py +++ b/napari_cellseg3d/interface.py @@ -1,3 +1,4 @@ +"""User interface functions and aliases.""" import threading from functools import partial from typing import List, Optional @@ -36,10 +37,6 @@ # Local from napari_cellseg3d import utils -""" -User interface functions and aliases""" - - ############### # show debug tooltips SHOW_LABELS_DEBUG_TOOLTIP = False @@ -79,19 +76,15 @@ class QWidgetSingleton(type(QObject)): - """ - To be used as a metaclass when making a singleton QWidget, - meaning only one instance exists at a time. - Avoids unnecessary memory overhead and keeps user parameters even when a widget is closed + """To be used as a metaclass when making a singleton QWidget, meaning only one instance exists at a time. + + Avoids unnecessary memory overhead and keeps user parameters even when a widget is closed. """ _instances = {} def __call__(cls, *args, **kwargs): - """ - Ensure only one instance of a QWidget with QWidgetSingleton as a metaclass exists at a time - - """ + """Ensure only one instance of a QWidget with QWidgetSingleton as a metaclass exists at a time.""" if cls not in cls._instances: cls._instances[cls] = super(QWidgetSingleton, cls).__call__( *args, **kwargs @@ -105,8 +98,7 @@ def __call__(cls, *args, **kwargs): def handle_adjust_errors(widget, warning_type, context, msg: str): - """Qt message handler that attempts to react to errors when setting the window size - and resizes the main window""" + """Qt message handler that attempts to react to errors when setting the window size and resizes the main window.""" pass # head = msg.split(": ")[0] # if warning_type == QtWarningMsg and head == "QWindowsWindow::setGeometry": @@ -129,7 +121,7 @@ def handle_adjust_errors(widget, warning_type, context, msg: str): def handle_adjust_errors_wrapper(widget): - """Returns a callable that can be used with qInstallMessageHandler directly""" + """Returns a callable that can be used with qInstallMessageHandler directly.""" return partial(handle_adjust_errors, widget) @@ -144,7 +136,7 @@ class UtilsDropdown(metaclass=utils.Singleton): caller_widget = None def dropdown_menu_call(self, widget, event): - """Calls the utility dropdown menu at the location of a CTRL+right-click""" + """Calls the utility dropdown menu at the location of a CTRL+right-click.""" # ### DEBUG ### # # print(event.modifiers) # print("menu call") @@ -176,8 +168,8 @@ def dropdown_menu_call(self, widget, event): # print(f"blocked widget {widget} from opening utils") def show_utils_menu(self, widget, event): - """ - Shows the context menu for utilities. Use with dropdown_menu_call. + """Shows the context menu for utilities. Use with dropdown_menu_call. + Args: widget: widget to show context menu in event: mouse press event @@ -212,7 +204,7 @@ class Log(QTextEdit): """Class to implement a log for important user info. Should be thread-safe.""" def __init__(self, parent=None): - """Creates a log with a lock for multithreading + """Creates a log with a lock for multithreading. Args: parent (QWidget): parent widget to add Log instance to. @@ -227,8 +219,8 @@ def __init__(self, parent=None): # def receive_log(self, text): # self.print_and_log(text) def write(self, message): - """ - Write message to log in a thread-safe manner + """Write message to log in a thread-safe manner. + Args: message: string to be printed """ @@ -254,7 +246,11 @@ def write(self, message): @QtCore.Slot(str) def replace_last_line(self, text): - """Replace last line. For use in progress bar""" + """Replace last line. For use in progress bar. + + Args: + text: string to be printed + """ self.lock.acquire() try: cursor = self.textCursor() @@ -268,8 +264,7 @@ def replace_last_line(self, text): self.lock.release() def print_and_log(self, text, printing=True): - """Utility used to both print to terminal and log text to a QTextEdit - item in a thread-safe manner. Use only for important user info. + """Utility used to both print to terminal and log text to a QTextEdit item in a thread-safe manner. Use only for important user info. Args: text (str): Text to be printed and logged @@ -290,7 +285,11 @@ def print_and_log(self, text, printing=True): self.lock.release() def warn(self, warning): - """Show logger.warning from another thread""" + """Show logger.warning from another thread. + + Args: + warning: warning to be printed + """ self.lock.acquire() try: logger.warning(warning) @@ -298,7 +297,12 @@ def warn(self, warning): self.lock.release() def error(self, error, msg=None): - """Show exception and message from another thread""" + """Show exception and message from another thread. + + Args: + error: error to be printed + msg: message to be printed + """ self.lock.acquire() try: logger.error(error, exc_info=True) @@ -306,7 +310,7 @@ def error(self, error, msg=None): self.print_and_log(f"{msg} : {error}", printing=False) else: self.print_and_log( - f"Excepetion caught in another thread : {error}", + f"Exception caught in another thread : {error}", printing=False, ) raise error @@ -330,17 +334,27 @@ def toggle_visibility(checkbox, widget): def add_label(widget, label, label_before=True, horizontal=True): + """Adds a label to a widget. + + Args: + widget: The widget to add the label to + label: The label to add + label_before: If True, the label is added before the widget. If False, the label is added after the widget + horizontal: If True, the label and widget are added horizontally. If False, they are added vertically + """ if label_before: return combine_blocks(widget, label, horizontal=horizontal) return combine_blocks(label, widget, horizontal=horizontal) class ContainerWidget(QWidget): + """Class for a container widget that can contain other widgets.""" + def __init__( self, l=0, t=0, r=1, b=11, vertical=True, parent=None, fixed=True ): - """ - Creates a container widget that can contain other widgets + """Creates a container widget that can contain other widgets. + Args: l: left margin in pixels t: top margin in pixels @@ -350,7 +364,6 @@ def __init__( parent: parent QWidget fixed: uses QLayout.SetFixedSize if True """ - super().__init__(parent) self.layout = None @@ -365,7 +378,10 @@ def __init__( class RadioButton(QRadioButton): + """Class for a radio button with a title and connected to a function when clicked. Inherits from QRadioButton.""" + def __init__(self, text: str = None, parent=None): + """Creates a radio button with a title and a function to execute when toggled.""" super().__init__(text, parent) @@ -387,6 +403,7 @@ def __init__( parent: Optional[QWidget] = None, fixed: Optional[bool] = True, ): + """Creates a button with a title and a function to execute when clicked.""" super().__init__(parent) if title is not None: self.setText(title) @@ -398,12 +415,12 @@ def __init__( self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) def visibility_condition(self, checkbox): - """Provide a QCheckBox to use to determine whether to show the button or not""" + """Provide a QCheckBox to use to determine whether to show the button or not.""" toggle_visibility(checkbox, self) class DropdownMenu(QComboBox): - """Creates a dropdown menu with a title and adds specified entries to it""" + """Creates a dropdown menu with a title and adds specified entries to it.""" def __init__( self, @@ -412,11 +429,13 @@ def __init__( text_label: Optional[str] = None, fixed: Optional[bool] = True, ): - """Args: - entries (array(str)): Entries to add to the dropdown menu. Defaults to None, no entries if None - parent (QWidget): parent QWidget to add dropdown menu to. Defaults to None, no parent is set if None - text_label (str) : if not None, creates a QLabel with the contents of 'label', and returns the label as well - fixed (bool): if True, will set the size policy of the dropdown menu to Fixed in h and w. Defaults to True. + """Creates a dropdown menu with a title and adds specified entries to it. + + Args: + entries (array(str)): Entries to add to the dropdown menu. Defaults to None, no entries if None + parent (QWidget): parent QWidget to add dropdown menu to. Defaults to None, no parent is set if None + text_label (str) : if not None, creates a QLabel with the contents of 'label', and returns the label as well + fixed (bool): if True, will set the size policy of the dropdown menu to Fixed in h and w. Defaults to True. """ super().__init__(parent) self.label = None @@ -428,11 +447,12 @@ def __init__( self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) def get_items(self): + """Returns the items in the dropdown menu.""" return [self.itemText(i) for i in range(self.count())] class CheckBox(QCheckBox): - """Shortcut class for creating QCheckBox with a title and a function""" + """Shortcut class for creating QCheckBox with a title and a function.""" def __init__( self, @@ -441,7 +461,8 @@ def __init__( parent: Optional[QWidget] = None, fixed: Optional[bool] = True, ): - """ + """Creates a checkbox with a title and a function to execute when toggled. + Args: title (str-like): title of the checkbox. Defaults to None, if None no title is set func (callable): function to execute when checkbox is toggled. Defaults to None, no binding is made if None @@ -456,7 +477,7 @@ def __init__( class Slider(QSlider): - """Shortcut class to create a Slider widget""" + """Shortcut class to create a Slider widget.""" def __init__( self, @@ -469,6 +490,7 @@ def __init__( orientation=Qt.Horizontal, text_label: str = None, ): + """Creates a slider to select a value between lower and upper, with a step.""" super().__init__(orientation, parent) if upper <= lower: @@ -527,6 +549,7 @@ def __init__( self._build_container() def set_visibility(self, visible: bool): + """Sets the visibility of the slider and its label.""" self.container.setVisible(visible) self.setVisible(visible) self.label.setVisible(visible) @@ -552,7 +575,7 @@ def _warn_outside_bounds(self, default): ) def _update_slider(self): - """Update slider when value is changed""" + """Update slider when value is changed.""" try: if self._value_label.text() == "": return @@ -571,7 +594,7 @@ def _update_slider(self): logger.error(e) def _update_value_label(self): - """Update label, to connect to when slider is dragged""" + """Update label, to connect to when slider is dragged.""" try: self._value_label.setText(str(self.value_text)) except Exception as e: @@ -579,10 +602,12 @@ def _update_value_label(self): @property def tooltips(self): + """Get the tooltip of the slider.""" return self.toolTip() @tooltips.setter def tooltips(self, tooltip: str): + """Set the tooltip of the slider and label.""" self.setToolTip(tooltip) self._value_label.setToolTip(tooltip) @@ -591,25 +616,24 @@ def tooltips(self, tooltip: str): @property def slider_value(self): - """Get value of the slider divided by self._divide_factor to implement floats in Slider""" + """Get value of the slider divided by self._divide_factor to implement floats in Slider.""" if self._divide_factor == 1.0: return self.value() try: return self.value() / self._divide_factor except ZeroDivisionError as e: - raise ZeroDivisionError from ( - f"Divide factor cannot be 0 for Slider : {e}" - ) + logger.error(f"Divide factor cannot be 0 for Slider : {e}") + raise ZeroDivisionError from (e) @property def value_text(self): - """Get value of the slide bar as string""" + """Get value of the slide bar as string.""" return str(self.slider_value) @slider_value.setter def slider_value(self, value: int): - """Set a value (int) divided by self._divide_factor""" + """Set a value (int) divided by self._divide_factor.""" if value < self.minimum() or value > self.maximum(): logger.error( ValueError( @@ -629,9 +653,12 @@ def slider_value(self, value: int): class AnisotropyWidgets(QWidget): - """Class that creates widgets for anisotropy handling. Includes : - - A checkbox to hides or shows the controls - - Three spinboxes to enter resolution for each dimension""" + """Class that creates widgets for anisotropy handling. + + Includes : + A checkbox to hides or shows the controls + Three spinboxes to enter resolution for each dimension. + """ def __init__( self, @@ -642,12 +669,15 @@ def __init__( always_visible: Optional[bool] = False, use_integer_counter: Optional[bool] = False, ): - """Creates an instance of AnisotropyWidgets + """Creates an instance of AnisotropyWidgets. + Args: - - parent: parent QWidget - - default_x: default resolution to use for x axis in microns - - default_y: default resolution to use for y axis in microns - - default_z: default resolution to use for z axis in microns + parent: parent QWidget + default_x: default resolution to use for x axis in microns + default_y: default resolution to use for y axis in microns + default_z: default resolution to use for z axis in microns + always_visible: if True, the checkbox is hidden and the spinboxes are always visible + use_integer_counter: if True, the spinboxes are QSpinBoxes instead of QDoubleSpinBoxes """ super().__init__(parent) @@ -697,13 +727,11 @@ def __init__( self._toggle_permanent_visibility() def _toggle_display_aniso(self): - """Shows the choices for correcting anisotropy - when viewing results depending on whether :py:attr:`self.checkbox` is checked - """ + """Shows the choices for correcting anisotropy when viewing results depending on whether :py:attr:`self.checkbox` is checked.""" toggle_visibility(self.checkbox, self.container) def build(self): - """Builds the layout of the widget""" + """Builds the layout of the widget.""" [ self.container.layout.addWidget(widget, alignment=HCENTER_AL) for widgets in zip(self.box_widgets_lbl, self.box_widgets) @@ -717,50 +745,52 @@ def build(self): self.setLayout(self._layout) def resolution_xyz(self): - """The resolution selected for each of the three dimensions. XYZ order (for MONAI)""" + """The resolution selected for each of the three dimensions. XYZ order (for MONAI).""" return [w.value() for w in self.box_widgets] def scaling_xyz(self): - """The scaling factors for each of the three dimensions. XYZ order (for MONAI)""" + """The scaling factors for each of the three dimensions. XYZ order (for MONAI).""" return self.anisotropy_zoom_factor(self.resolution_xyz()) def resolution_zyx(self): - """The resolution selected for each of the three dimensions. ZYX order (for napari)""" + """The resolution selected for each of the three dimensions. ZYX order (for napari).""" res = self.resolution_xyz() return [res[2], res[1], res[0]] def scaling_zyx(self): - """The scaling factors for each of the three dimensions. ZYX order (for napari)""" + """The scaling factors for each of the three dimensions. ZYX order (for napari).""" return self.anisotropy_zoom_factor(self.resolution_zyx()) @staticmethod def anisotropy_zoom_factor(aniso_res): - """Computes a zoom factor to correct anisotropy, based on anisotropy resolutions + """Computes a zoom factor to correct anisotropy, based on anisotropy resolutions. - Args: - aniso_res: array for anisotropic resolution (float) in microns for each axis + Args: + aniso_res: array for anisotropic resolution (float) in microns for each axis Returns: an array with the corresponding zoom factors for each axis (all values divided by min) """ - base = min(aniso_res) return [base / res for res in aniso_res] def enabled(self): - """Returns : whether anisotropy correction has been enabled or not""" + """Returns : whether anisotropy correction has been enabled or not.""" return self.checkbox.isChecked() def _toggle_permanent_visibility(self): - """Hides the checkbox and always display resolution spinboxes""" + """Hides the checkbox and always display resolution spinboxes.""" self.checkbox.toggle() self.checkbox.setVisible(False) class LayerSelecter(ContainerWidget): + """Class that creates a dropdown menu to select a layer from a napari viewer.""" + def __init__( self, viewer, name="Layer", layer_type=napari.layers.Layer, parent=None ): + """Creates an instance of LayerSelecter.""" super().__init__(parent=parent, fixed=False) self._viewer = viewer self.layer_type = layer_type @@ -821,31 +851,38 @@ def _remove_layer(self, event): self.layer_list.removeItem(index) def set_layer_type(self, layer_type): # no @property due to Qt constraint + """Sets the layer type to be selected in the dropdown menu.""" self.layer_type = layer_type [self.layer_list.removeItem(i) for i in range(self.layer_list.count())] self._check_for_layers() def layer(self): + """Returns the layer selected in the dropdown menu.""" try: return self._viewer.layers[self.layer_name()] except ValueError: return None def layer_name(self): + """Returns the name of the layer selected in the dropdown menu.""" return self.layer_list.currentText() def layer_data(self): + """Returns the data of the layer selected in the dropdown menu.""" if self.layer_list.count() < 1: - logger.warning("Please select a valid layer !") + logger.debug("Layer list is empty") return None return self.layer().data class FilePathWidget(QWidget): # TODO include load as folder - """Widget to handle the choice of file paths for data throughout the plugin. Provides the following elements : - - An "Open" button to show a file dialog (defined externally) - - A QLineEdit in read only to display the chosen path/file""" + """Widget to handle the choice of file paths for data throughout the plugin. + + Provides the following elements : + An "Open" button to show a file dialog (defined externally) + A QLineEdit in read only to display the chosen path/file + """ def __init__( self, @@ -856,11 +893,13 @@ def __init__( default: Optional[str] = None, ): """Creates a FilePathWidget. + Args: description (str): Initial text to add to the text box file_function (callable): Function to handle the file dialog parent (Optional[QWidget]): parent QWidget required (Optional[bool]): if True, field will be highlighted in red if empty. Defaults to False. + default (Optional[str]): default path to use. Defaults to None. """ super().__init__(parent) self._layout = QHBoxLayout() @@ -883,7 +922,7 @@ def __init__( self.text_field.textChanged.connect(self.check_ready) def build(self): - """Builds the layout of the widget""" + """Builds the layout of the widget.""" add_widgets( self._layout, [combine_blocks(self.button, self.text_field, min_spacing=5, b=0)], @@ -893,32 +932,34 @@ def build(self): @property def tooltips(self): + """Get the tooltip of the text field and button.""" return self._text_field.toolTip() @tooltips.setter def tooltips(self, tooltip: str): + """Set the tooltip of the text field and button.""" self._text_field.setToolTip(tooltip) self._button.setToolTip(tooltip) @property def text_field(self): - """Get text field with file path""" + """Get text field with file path.""" return self._text_field @text_field.setter def text_field(self, text: str): - """Sets the initial description in the text field, makes it the new default path""" + """Sets the initial description in the text field, makes it the new default path.""" self._initial_desc = text self.tooltips = text self._text_field.setText(text) @property def button(self): - """Get "Open" button""" + """Get "Open" button.""" return self._button def check_ready(self): - """Check if a path is correctly set""" + """Check if a path is correctly set.""" if ( self.text_field.text() in ["", self._initial_desc] and self.required @@ -932,16 +973,17 @@ def check_ready(self): @property def required(self): + """Get whether the field is required or not.""" return self._required @required.setter def required(self, is_required): - """If set to True, will be colored red if incorrectly set""" + """If set to True, will be colored red if incorrectly set.""" self.check_ready() self._required = is_required def update_field_color(self, color: str): - """Updates the background of the text field""" + """Updates the background of the text field.""" self.text_field.setStyleSheet(f"background-color : {color}") self.text_field.style().unpolish(self.text_field) self.text_field.style().polish(self.text_field) @@ -958,13 +1000,14 @@ def __init__( base_wh: Optional[List[int]] = None, parent: Optional[QWidget] = None, ): - """ + """Initializes a QScrollArea and sets it up, then adds the contained_layout to it. + Args: - contained_layout (QLayout): the layout of widgets to be made scrollable - min_wh (Optional[List[int]]): array of two ints for respectively the minimum width and minimum height of the scrollable area. Defaults to None, lets Qt decide if None - max_wh (Optional[List[int]]): array of two ints for respectively the maximum width and maximum height of the scrollable area. Defaults to None, lets Qt decide if None - base_wh (Optional[List[int]]): array of two ints for respectively the initial width and initial height of the scrollable area. Defaults to None, lets Qt decide if None - parent (Optional[QWidget]): array of two ints for respectively the initial width and initial height of the scrollable area. Defaults to None, lets Qt decide if None + contained_layout (QLayout): the layout of widgets to be made scrollable + min_wh (Optional[List[int]]): array of two ints for respectively the minimum width and minimum height of the scrollable area. Defaults to None, lets Qt decide if None + max_wh (Optional[List[int]]): array of two ints for respectively the maximum width and maximum height of the scrollable area. Defaults to None, lets Qt decide if None + base_wh (Optional[List[int]]): array of two ints for respectively the initial width and initial height of the scrollable area. Defaults to None, lets Qt decide if None + parent (Optional[QWidget]): array of two ints for respectively the initial width and initial height of the scrollable area. Defaults to None, lets Qt decide if None """ super().__init__(parent) @@ -1004,15 +1047,15 @@ def make_scrollable( max_wh: Optional[List[int]] = None, base_wh: Optional[List[int]] = None, ): - """Factory method to create a scroll area in a widget + """Factory method to create a scroll area in a widget. + Args: - contained_layout (QLayout): the widget to be made scrollable - parent (QWidget): the parent widget to add the resulting scroll area in - min_wh (Optional[List[int]]): array of two ints for respectively the minimum width and minimum height of the scrollable area. Defaults to None, lets Qt decide if None - max_wh (Optional[List[int]]): array of two ints for respectively the maximum width and maximum height of the scrollable area. Defaults to None, lets Qt decide if None - base_wh (Optional[List[int]]): array of two ints for respectively the initial width and initial height of the scrollable area. Defaults to None, lets Qt decide if None + contained_layout (QLayout): the widget to be made scrollable + parent (QWidget): the parent widget to add the resulting scroll area in + min_wh (Optional[List[int]]): array of two ints for respectively the minimum width and minimum height of the scrollable area. Defaults to None, lets Qt decide if None + max_wh (Optional[List[int]]): array of two ints for respectively the maximum width and maximum height of the scrollable area. Defaults to None, lets Qt decide if None + base_wh (Optional[List[int]]): array of two ints for respectively the initial width and initial height of the scrollable area. Defaults to None, lets Qt decide if None """ - scroll = cls(contained_layout, min_wh, max_wh, base_wh) layout = QVBoxLayout(parent) # layout.setContentsMargins(0,0,1,1) @@ -1029,14 +1072,16 @@ def set_spinbox( step=1, fixed: Optional[bool] = True, ): - """Args: - box : QSpinBox or QDoubleSpinBox - min_value : minimum value, defaults to 0 - max_value : maximum value, defaults to 10 - default : default value, defaults to 0 - step : step value, defaults to 1 - fixed (bool): if True, sets the QSizePolicy of the spinbox to Fixed""" + """Sets the parameters of a QSpinBox or QDoubleSpinBox. + Args: + box : QSpinBox or QDoubleSpinBox + min_value : minimum value, defaults to 0 + max_value : maximum value, defaults to 10 + default : default value, defaults to 0 + step : step value, defaults to 1 + fixed (bool): if True, sets the QSizePolicy of the spinbox to Fixed + """ box.setMinimum(min_value) box.setMaximum(max_value) box.setSingleStep(step) @@ -1056,7 +1101,7 @@ def make_n_spinboxes( parent: Optional[QWidget] = None, fixed: Optional[bool] = True, ): - """Creates n increment counters with the specified parameters : + """Creates n increment counters with the specified parameters. Args: class_ : QSpinBox or QDoubleSpinbox @@ -1091,16 +1136,17 @@ def __init__( fixed: Optional[bool] = True, text_label: Optional[str] = None, ): - """Args: - lower (Optional[float]): minimum value, defaults to 0 - upper (Optional[float]): maximum value, defaults to 10 - default (Optional[float]): default value, defaults to 0 - step (Optional[float]): step value, defaults to 1 - parent: parent widget, defaults to None - fixed (bool): if True, sets the QSizePolicy of the spinbox to Fixed - text_label (Optional[str]): if provided, creates a label with the chosen title to use with the counter - """ + """Creates a DoubleIncrementCounter. + Args: + lower (Optional[float]): minimum value, defaults to 0 + upper (Optional[float]): maximum value, defaults to 10 + default (Optional[float]): default value, defaults to 0 + step (Optional[float]): step value, defaults to 1 + parent: parent widget, defaults to None + fixed (bool): if True, sets the QSizePolicy of the spinbox to Fixed + text_label (Optional[str]): if provided, creates a label with the chosen title to use with the counter + """ super().__init__(parent) set_spinbox(self, lower, upper, default, step, fixed) @@ -1119,22 +1165,24 @@ def __init__( @property def tooltips(self): + """Gets the tooltip of both the DoubleIncrementCounter and its label.""" return self.toolTip() @tooltips.setter def tooltips(self, tooltip: str): - """Sets the tooltip of both the DoubleIncrementCounter and its label""" + """Sets the tooltip of both the DoubleIncrementCounter and its label.""" self.setToolTip(tooltip) if self.label is not None: self.label.setToolTip(tooltip) @property def precision(self): + """Get current precision of the box.""" return self.decimals() @precision.setter def precision(self, decimals: int): - """Sets the precision of the box to the specified number of decimals""" + """Sets the precision of the box to the specified number of decimals.""" self.setDecimals(decimals) @classmethod @@ -1148,11 +1196,13 @@ def make_n( parent: Optional[QWidget] = None, fixed: Optional[bool] = True, ): + """Creates n increment counters with the specified parameters.""" return make_n_spinboxes( cls, n, lower, upper, default, step, parent, fixed ) def set_visibility(self, visible: bool): + """Sets the visibility of the counter and its label.""" self.setVisible(visible) self.label.setVisible(visible) @@ -1170,14 +1220,17 @@ def __init__( fixed: Optional[bool] = True, text_label: Optional[str] = None, ): - """Args: - lower (Optional[int]): minimum value, defaults to 0 - upper (Optional[int]): maximum value, defaults to 10 - default (Optional[int]): default value, defaults to 0 - step (Optional[int]): step value, defaults to 1 - parent: parent widget, defaults to None - fixed (bool): if True, sets the QSizePolicy of the spinbox to Fixed""" + """Creates an IntIncrementCounter. + Args: + lower (Optional[int]): minimum value, defaults to 0 + upper (Optional[int]): maximum value, defaults to 10 + default (Optional[int]): default value, defaults to 0 + step (Optional[int]): step value, defaults to 1 + parent: parent widget, defaults to None + fixed (bool): if True, sets the QSizePolicy of the spinbox to Fixed + text_label (Optional[str]): if provided, creates a label with the chosen title to use with the counter + """ super().__init__(parent) set_spinbox(self, lower, upper, default, step, fixed) @@ -1189,10 +1242,12 @@ def __init__( @property def tooltips(self): + """Gets the tooltip of both the IntIncrementCounter and its label.""" return self.toolTip() @tooltips.setter def tooltips(self, tooltip): + """Sets the tooltip of both the IntIncrementCounter and its label.""" self.setToolTip(tooltip) self.label.setToolTip(tooltip) @@ -1207,14 +1262,14 @@ def make_n( parent: Optional[QWidget] = None, fixed: Optional[bool] = True, ): + """Creates n increment counters with the specified parameters.""" return make_n_spinboxes( cls, n, lower, upper, default, step, parent, fixed ) def add_blank(widget, layout=None): - """ - Adds a space between consecutive buttons/labels in a layout when building a widget + """Adds a space between consecutive buttons/labels in a layout when building a widget. Args: widget (QWidget): widget to add blank in @@ -1243,8 +1298,9 @@ def open_file_dialog( load_as_folder (bool): Whether to open a folder or a single file. If True, will allow opening folder as a single file (2D stack interpreted as 3D) file_extension (str): The description and file extension to load (format : ``"Description (*.example1 *.example2)"``). Default ``"Image file (*.tif *.tiff)"`` + Returns: + str : chosen file path """ - default_path = utils.parse_default_path(possible_paths) return QFileDialog.getOpenFileName( @@ -1256,6 +1312,16 @@ def open_folder_dialog( widget, possible_paths: list = (), ): + """Opens a window to choose a directory using QFileDialog. + + Args: + widget (QWidget): Widget to display file dialog in + possible_paths (str): Paths that may have been chosen before, can be a string + or an array of strings containing the paths + + Returns: + str : chosen directory path + """ default_path = utils.parse_default_path(possible_paths) logger.debug(f"Default : {default_path}") @@ -1265,7 +1331,7 @@ def open_folder_dialog( def make_label(name, parent=None): # TODO update to child class - """Creates a QLabel + """Creates a QLabel. Args: name: string with name @@ -1286,7 +1352,8 @@ def make_label(name, parent=None): # TODO update to child class def make_group(title, l=7, t=20, r=7, b=11, parent=None): - """Creates a group widget and layout, with a header (`title`) and content margins for top/left/right/bottom `L, T, R, B` (in pixels) + """Creates a group widget and layout, with a header (`title`) and content margins for top/left/right/bottom `L, T, R, B` (in pixels). + Group widget and layout returned will have a Fixed size policy. Args: @@ -1304,9 +1371,10 @@ def make_group(title, l=7, t=20, r=7, b=11, parent=None): class GroupedWidget(QGroupBox): - """Subclass of QGroupBox designed to easily group widgets belonging to a same category""" + """Subclass of QGroupBox designed to easily group widgets belonging to a same category.""" def __init__(self, title, l=7, t=20, r=7, b=11, parent=None): + """Creates a GroupedWidget.""" super().__init__(title, parent) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) @@ -1315,7 +1383,8 @@ def __init__(self, title, l=7, t=20, r=7, b=11, parent=None): self.layout.setContentsMargins(l, t, r, b) self.layout.setSizeConstraint(QLayout.SetFixedSize) - def set_layout(self): + def _set_layout(self): + """Sets the layout of the widget.""" self.setLayout(self.layout) @classmethod @@ -1330,6 +1399,7 @@ def create_single_widget_group( b=11, alignment=LEFT_AL, ): + """Creates a group with a single widget in it.""" group = cls(title, l, t, r, b) group.layout.addWidget(widget, alignment=alignment) group.setLayout(group.layout) @@ -1339,7 +1409,9 @@ def create_single_widget_group( def add_widgets(layout, widgets, alignment=LEFT_AL): """Adds all widgets in the list to layout, with the specified alignment. + If alignment is None, no alignment is set. + Args: layout: layout to add widgets in widgets: list of QWidgets to add to layout @@ -1363,14 +1435,15 @@ def combine_blocks( # TODO FIXME PLEASE this is a horrible design r=11, b=11, ): - """Combines two QWidget objects and puts them side by side (first on the left/top and second on the right/bottom depending on "horizontal") - Weird argument names due the initial implementation of it. # TODO maybe fix arg names or refactor + """Combines two QWidget objects and puts them side by side (first on the left/top and second on the right/bottom depending on "horizontal"). + + Weird argument names due the initial implementation of it. # TODO maybe fix arg names or refactor. Args: left_or_above (QWidget): First widget, to be added on the left/above of "second" right_or_below (QWidget): Second widget, to be displayed right/below of "first" min_spacing (int): Minimum spacing between the two widgets (from the start of label to the start of button) - horizontal (bool): whether to stack widgets vertically (False) or horizontally (True) + horizontal (bool): whether to stack widgets vertically (False) or horizontally (True) l (int): left spacing in pixels t (int): top spacing in pixels r (int): right spacing in pixels diff --git a/napari_cellseg3d/plugins.py b/napari_cellseg3d/plugins.py index f0d74386..74d867c7 100644 --- a/napari_cellseg3d/plugins.py +++ b/napari_cellseg3d/plugins.py @@ -1,3 +1,7 @@ +"""napari-cellseg3d: napari plugin for 3D cell segmentation. + +Main plugins menu for napari-cellseg3d. +""" from napari_cellseg3d.code_plugins.plugin_helper import Helper from napari_cellseg3d.code_plugins.plugin_model_inference import Inferer from napari_cellseg3d.code_plugins.plugin_model_training import Trainer diff --git a/napari_cellseg3d/utils.py b/napari_cellseg3d/utils.py index dfd6866e..f665230f 100644 --- a/napari_cellseg3d/utils.py +++ b/napari_cellseg3d/utils.py @@ -1,3 +1,4 @@ +"""Utilities functions, classes, and variables.""" import logging import math from datetime import datetime @@ -31,14 +32,14 @@ def save_folder( results_path, folder_name, images, image_paths, exist_ok=False ): - """ - Saves a list of images in a folder + """Saves a list of images in a folder. Args: results_path: Path to the folder containing results folder_name: Name of the folder containing results images: List of images to save image_paths: list of filenames of images + exist_ok: whether to check for existing files. If False, will raise an error if the folder already exists. """ results_folder = results_path / Path(folder_name) results_folder.mkdir(exist_ok=exist_ok, parents=True) @@ -54,8 +55,7 @@ def save_folder( def save_layer(results_path, image_name, image): - """ - Saves an image layer at the specified path + """Saves an image layer at the specified path. Args: results_path: path to folder containing result @@ -76,14 +76,15 @@ def show_result( existing_layer: napari.layers.Layer = None, colormap="bop orange", ) -> napari.layers.Layer: - """ - Adds layers to a viewer to show result to user + """Adds layers to a viewer to show result to user. Args: viewer: viewer to add layer in layer: original layer the operation was run on, to determine whether it should be an Image or Labels layer image: the data array containing the image name: name of the added layer + existing_layer: existing layer to update, if any + colormap: colormap to use for the layer Returns: napari.layers.Layer: the layer added to the viewer @@ -118,22 +119,25 @@ def show_result( class Singleton(type): - """ - Singleton class that can only be instantiated once at a time, - with said unique instance always being accessed on call. - Should be used as a metaclass for classes without inheritance (object type) + """Singleton class that can only be instantiated once at a time, with said unique instance always being accessed on call. + + Should be used as a metaclass for classes without inheritance (object type). """ _instances = {} def __call__(cls, *args, **kwargs): + """Call method for Singleton class. + + Ensures that only one instance of the class is created at a time, and that it is always the same instance that is returned. + """ if cls not in cls._instances: cls._instances[cls] = super().__call__(*args, **kwargs) return cls._instances[cls] def normalize_x(image): - """Normalizes the values of an image array to be between [-1;1] rather than [0;255] + """Normalizes the values of an image array to be between [-1;1] rather than [0;255]. Args: image (array): Image to process @@ -145,11 +149,12 @@ def normalize_x(image): def mkdir_from_str(path: str, exist_ok=True, parents=True): + """Creates a directory from a string path.""" Path(path).resolve().mkdir(exist_ok=exist_ok, parents=parents) def normalize_y(image): - """Normalizes the values of an image array to be between [0;1] rather than [0;255] + """Normalizes the values of an image array to be between [0;1] rather than [0;255]. Args: image (array): Image to process @@ -161,7 +166,7 @@ def normalize_y(image): def sphericity_volume_area(volume, surface_area): - """Computes the sphericity from volume and area + r"""Computes the sphericity from volume and area. .. math:: sphericity =\\frac {\\pi^\\frac{1}{3} (6 V_{p})^\\frac{2}{3}} {A_p} @@ -171,7 +176,7 @@ def sphericity_volume_area(volume, surface_area): def sphericity_axis(semi_major, semi_minor): - """Computes the sphericity from volume semi major (a) and semi minor (b) axes. + r"""Computes the sphericity from volume semi major (a) and semi minor (b) axes. .. math:: sphericity = \\frac {2 \\sqrt[3]{ab^2}} {a+ \\frac {b^2} {\\sqrt{a^2-b^2}}ln( \\frac {a+ \\sqrt{a^2-b^2}} {b} )} @@ -188,14 +193,16 @@ def sphericity_axis(semi_major, semi_minor): / (a + (b**2) / root * np.log((a + root) / b)) ) except ZeroDivisionError: - print("Zero division in sphericity calculation was replaced by 0") + LOGGER.warning( + "Zero division in sphericity calculation was replaced by 0" + ) result = 0 except ValueError as e: - print(f"Error encountered in calculation : {e}") + LOGGER.warning(f"Error encountered in calculation : {e}") result = "Error in calculation" if math.isnan(result): - print("NaN in sphericity calculation was replaced by 0") + LOGGER.warning("NaN in sphericity calculation was replaced by 0") result = 0 return result @@ -206,11 +213,14 @@ def dice_coeff( y_pred: Union[torch.Tensor, np.ndarray], smooth: float = 1.0, ) -> Union[torch.Tensor, np.float64]: - """Compute Dice-Sorensen coefficient between two numpy arrays + """Compute Dice-Sorensen coefficient between two numpy arrays. + Args: y_true: Ground truth label y_pred: Prediction label - Returns: dice coefficient + smooth: Smoothing factor to avoid division by zero + + Returns: dice coefficient. """ if isinstance(y_true, np.ndarray) and isinstance(y_pred, np.ndarray): sum_tensor = np.sum @@ -230,12 +240,12 @@ def dice_coeff( def seek_best_dice_coeff_channel(y_pred, y_true) -> torch.Tensor: - """Compute Dice-Sorensen coefficient between unsupervised model output and ground truth labels; - returns the channel with the highest dice coefficient. + """Compute Dice-Sorensen coefficient between unsupervised model output and ground truth labels; returns the channel with the highest dice coefficient. + Args: y_true: Ground truth label y_pred: Prediction label - Returns: best Dice coefficient channel + Returns: best Dice coefficient channel. """ dices = [] # Find in which channel the labels are (to avoid background) @@ -253,13 +263,13 @@ def seek_best_dice_coeff_channel(y_pred, y_true) -> torch.Tensor: def correct_rotation(image): - """Rotates the exes 0 and 2 in [DHW] section of image array""" + """Rotates the axes 0 and 2 in [DHW] section of image array.""" extra_dims = len(image.shape) - 3 return np.swapaxes(image, 0 + extra_dims, 2 + extra_dims) def normalize_max(image): - """Normalizes an image using the max and min value""" + """Normalizes an image using the max and min value.""" shape = image.shape image = image.flatten() image = (image - image.min()) / (image.max() - image.min()) @@ -274,7 +284,7 @@ def remap_image( prev_max=None, prev_min=None, ): - """Normalizes a numpy array or Tensor using the max and min value""" + """Normalizes a numpy array or Tensor using the max and min value.""" shape = image.shape image = image.flatten() im_max = prev_max if prev_max is not None else image.max() @@ -286,6 +296,7 @@ def remap_image( def resize(image, zoom_factors): + """Resizes an image using the zoom_factors.""" isotropic_image = Zoom( zoom_factors, keep_size=False, @@ -296,6 +307,7 @@ def resize(image, zoom_factors): def align_array_sizes(array_shape, target_shape): + """Aligns the sizes of two arrays by adding zeros to the smaller one.""" index_differences = [] for i in range(len(target_shape)): if target_shape[i] != array_shape[i]: @@ -303,7 +315,7 @@ def align_array_sizes(array_shape, target_shape): if array_shape[i] == target_shape[j] and j != i: index_differences.append({"origin": i, "target": j}) - # print(index_differences) + # LOGGER.debug(index_differences) if len(index_differences) == 0: return [0, 1, 2], [-3, -2, -1] @@ -319,7 +331,7 @@ def align_array_sizes(array_shape, target_shape): targets[i] = reverse_mapping[targets[i]] infos = np.unique(origins, return_index=True, return_counts=True) {"origins": infos[0], "index": infos[1], "counts": infos[2]} - # print(info_dict) + # LOGGER.debug(info_dict) final_orig = [] final_targ = [] @@ -327,19 +339,19 @@ def align_array_sizes(array_shape, target_shape): if infos[2][i] == 1: final_orig.append(infos[0][i]) final_targ.append(targets[infos[1][i]]) - # print(final_orig, final_targ) + # LOGGER.debug(final_orig, final_targ) return final_orig, final_targ def time_difference(time_start, time_finish, as_string=True): - """ + """Computes the time difference between two datetime objects. + Args: - time_start (datetime): time to subtract to time_finish - time_finish (datetime): time to add to subtract time_start to - as_string (bool): if True, returns a string with the full time diff. Otherwise, returns as a list [hours,minutes,seconds] + time_start (datetime): time to subtract to time_finish + time_finish (datetime): time to add to subtract time_start to + as_string (bool): if True, returns a string with the full time diff. Otherwise, returns as a list [hours,minutes,seconds]. """ - time_taken = time_finish - time_start days = divmod(time_taken.total_seconds(), 86400) # Get days (without [0]!) hours = divmod(days[1], 3600) # Use remainder of days to calc hours @@ -358,13 +370,14 @@ def time_difference(time_start, time_finish, as_string=True): def get_padding_dim(image_shape, anisotropy_factor=None): - """ - Finds the nearest and superior power of two for each image dimension to zero-pad it for CNN processing, - accepts either 2D or 3D images shapes. E.g. an image size of 30x40x100 will result in a padding of 32x64x128. + """Finds the nearest and superior power of two for each image dimension to zero-pad it for CNN processing. + + Accepts either 2D or 3D images shapes. E.g. an image size of 30x40x100 will result in a padding of 32x64x128. Shows a warning if the padding dimensions are very large. Args: image_shape (torch.size): an array of the dimensions of the image in D/H/W if 3D or H/W if 2D + anisotropy_factor (list): anisotropy factor for each dimension Returns: array(int): padding value for each dim @@ -409,7 +422,7 @@ def get_padding_dim(image_shape, anisotropy_factor=None): def denormalize_y(image): - """De-normalizes the values of an image array to be between [0;255] rather than [0;1] + """De-normalizes the values of an image array to be between [0;255] rather than [0;1]. Args: image (array): Image to process @@ -422,7 +435,8 @@ def denormalize_y(image): def fill_list_in_between(lst, n, fill_value): """Fills a list with n * elem between each member of list. - Example with list = [1,2,3], n=2, elem='&' : returns [1, &, &,2,&,&,3,&,&] + + Example with list = [1,2,3], n=2, elem='&' : returns [1, &, &,2,&,&,3,&,&]. Args: lst: list to fill @@ -452,6 +466,7 @@ def parse_default_path(possible_paths, check_existence=True): Args: possible_paths: array of paths + check_existence: whether to check if the path exists. Returns: the chosen default path @@ -476,25 +491,24 @@ def parse_default_path(possible_paths, check_existence=True): def get_date_time(): - """Get date and time in the following format : year_month_day_hour_minute_second""" + """Get date and time in the following format : year_month_day_hour_minute_second.""" return f"{datetime.now():%Y_%m_%d_%H_%M_%S}" def get_time(): - """Get time in the following format : hour:minute:second. NOT COMPATIBLE with file paths (saving with ":" is invalid)""" + """Get time in the following format : hour:minute:second. NOT COMPATIBLE with file paths (saving with ":" is invalid).""" return f"{datetime.now():%H:%M:%S}" def get_time_filepath(): - """Get time in the following format : hour_minute_second. Compatible with saving""" + """Get time in the following format : hour_minute_second. Compatible with saving.""" return f"{datetime.now():%H_%M_%S}" def load_images(dir_or_path, filetype="", as_folder: bool = False): - """Loads the images in ``directory``, with different behaviour depending on ``filetype`` and ``as_folder`` + """Loads the images in ``directory``, with different behaviour depending on ``filetype`` and ``as_folder``. * If ``as_folder`` is **False**, will load the path as a single 3D **.tif** image. - * If **True**, it will try to load a folder as stack of images. In this case ``filetype`` must be specified. If **True** : @@ -512,22 +526,9 @@ def load_images(dir_or_path, filetype="", as_folder: bool = False): Returns: np.array: array with loaded images """ - # if not as_folder: filename_pattern_original = Path(dir_or_path) return imread(str(filename_pattern_original)) # tifffile imread - # print(filename_pattern_original) - # elif as_folder and filetype != "": - # filename_pattern_original = Path(dir_or_path + "/*" + filetype) - # print(filename_pattern_original) - # else: - # raise ValueError("If loading as a folder, filetype must be specified") - - # if as_folder: - # raise NotImplementedError( - # "Loading as folder not implemented yet. Use napari to load as folder" - # images_original = dask_imread(filename_pattern_original) - # ) def quantile_normalization( @@ -535,7 +536,7 @@ def quantile_normalization( quantile_high=0.99, quantile_low=0.01, ): - """Normalizes an image using the quantiles""" + """Normalizes an image using the quantiles.""" if quantile_high < quantile_low: raise ValueError( f"quantile_high must be greater than quantile_low, got {quantile_high} and {quantile_low}" @@ -560,7 +561,7 @@ def quantile_normalization( def channels_fraction_above_threshold(volume: np.array, threshold=0.5) -> list: - """Computes the fraction of pixels above a certain value in a 4D volume for each channel + """Computes the fraction of pixels above a certain value in a 4D volume for each channel. Args: volume (np.ndarray): Array of shape (C, H, W, D) containing the input volume @@ -569,7 +570,7 @@ def channels_fraction_above_threshold(volume: np.array, threshold=0.5) -> list: Returns: list: List of length C containing the fraction of pixels above the threshold for each channel """ - if volume.shape != 4: + if len(volume.shape) != 4: raise ValueError( f"Volume shape {volume.shape} is not 4D. Expecting CxHxWxD." ) @@ -582,11 +583,11 @@ def channels_fraction_above_threshold(volume: np.array, threshold=0.5) -> list: def fraction_above_threshold(volume: np.array, threshold=0.5) -> float: - """ - Computes the fraction of pixels above a certain value in a volume + """Computes the fraction of pixels above a certain value in a volume. + Args: volume (np.ndarray): Array containing the input volume - threshold (float): Threshold value to use for the computation + threshold (float): Threshold value to use for the computation. Returns: float: Fraction of pixels above the threshold diff --git a/pyproject.toml b/pyproject.toml index 094166fb..2be8ce1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,7 @@ select = [ "E", "F", "W", "A", "B", + "D", "G", "I", "PT", @@ -84,6 +85,7 @@ select = [ ] # Never enforce `E501` (line length violations) and 'E741' (ambiguous variable names) # and 'G004' (do not use f-strings in logging) +# and 'A003' (Shadowing python builtins) ignore = ["E501", "E741", "G004", "A003"] exclude = [ ".bzr", @@ -111,6 +113,9 @@ exclude = [ "napari_cellseg3d/_tests/conftest.py", ] +[tool.ruff.pydocstyle] +convention = "google" + [tool.black] line-length = 79 @@ -139,12 +144,10 @@ dev = [ "ruff", "pre-commit", "tuna", + "twine", ] docs = [ - "sphinx", - "sphinx_autodoc_typehints", - "sphinx_rtd_theme", - "twine", + "jupyter-book", ] test = [ "pytest", diff --git a/requirements.txt b/requirements.txt index ada03ae4..3f8e64ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,11 +3,9 @@ coverage imageio-ffmpeg>=0.4.5 isort itk +jupyter-book pytest pytest-qt -sphinx -sphinx-autodoc-typehints -sphinx-rtd-theme tox twine numpy