diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..7379318 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,20 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 1 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/source/conf.py + +# Optionally set the version of Python and requirements required to build your docs +python: + version: 3.8 + install: + - requirements: docs/requirements.txt diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..6fcf05b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..df6335e --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,6 @@ +Babel==2.9.1 +imagesize==1.3.0 +readme-renderer>=32.0 +sphinx==4.2.0 +sphinx_rtd_theme==1.0.0 +readthedocs-sphinx-search==0.1.1 \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..7192c73 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,76 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# 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. +# +from os.path import dirname +import os +import sys + +current_dir = os.getcwd() +path = dirname(dirname(current_dir)) +sys.path.append(path) +sys.path.append(os.path.join(path, 'sklearn')) +sys.path.insert(0, os.path.abspath('../../')) +sys.path.insert(0, os.path.abspath('sphinxext')) + + +# -- Project information ----------------------------------------------------- + +project = 'MontePython' +copyright = '2022, Montgomery Flora' +author = 'Montgomery Flora' + +# The full version, including alpha/beta/rc tags +release = '1.1.851-py3.8' + + +# -- General configuration --------------------------------------------------- + +# 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.autodoc', + 'sphinx.ext.coverage', + 'sphinx.ext.napoleon', + "sphinx.ext.intersphinx", + "sphinx.ext.mathjax", + "sphinx.ext.viewcode", + ] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# 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 = 'Python' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_tile=project + +# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +# 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 = ['_static'] \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..8326bbb --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,40 @@ +.. MontePython documentation master file, created by + sphinx-quickstart on Fri Mar 11 21:19:45 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to MontePython's documentation! +======================================= + +Methods for Object-based and Neighborhood Threat Evaluation in Python (MontePython) is a Python module for meteorological-based image segementation, matching, and tracking. This package was originally built for `NOAA's Warn-on-Forecast System `_ (WoFS). + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + +Install +================== + +MontePython is not available through PyPi at the moment. To install it, +require cloning the environment and then when the parent directory, +using the setup.py to install it. + + git clone https://github.com/WarnOnForecast/MontePython + + python setup.py install + + +Content +=========== + +.. toctree:: + :maxdepth: 2 + + Object Identification + Object Quality Control + Object Matching + Object Tracking + Storm Mode Classification + + diff --git a/docs/source/object_id.rst b/docs/source/object_id.rst new file mode 100644 index 0000000..be30edc --- /dev/null +++ b/docs/source/object_id.rst @@ -0,0 +1,18 @@ +.. currentmodule:: monte_python + +Object Identification +========================= + +.. automodule:: monte_python.object_identification + :members: + +.. toctree:: + :maxdepth: 1 + +.. automodule:: monte_python.EnhancedWatershedSegmenter + :members: + +.. toctree:: + :maxdepth: 1 + + \ No newline at end of file diff --git a/docs/source/object_matching.rst b/docs/source/object_matching.rst new file mode 100644 index 0000000..7a2d29e --- /dev/null +++ b/docs/source/object_matching.rst @@ -0,0 +1,11 @@ +.. currentmodule:: monte_python + + +Object Matching +========================= + +.. automodule:: monte_python.object_matching + :members: + +.. toctree:: + :maxdepth: 2 diff --git a/docs/source/object_qc.rst b/docs/source/object_qc.rst new file mode 100644 index 0000000..17b52c6 --- /dev/null +++ b/docs/source/object_qc.rst @@ -0,0 +1,12 @@ +.. currentmodule:: monte_python + +Object Quality Control +========================= + + +.. automodule:: monte_python.object_quality_control + :members: + +.. toctree:: + :maxdepth: 2 + diff --git a/docs/source/object_tracking.rst b/docs/source/object_tracking.rst new file mode 100644 index 0000000..b618204 --- /dev/null +++ b/docs/source/object_tracking.rst @@ -0,0 +1,10 @@ +.. currentmodule:: monte_python + +Object Tracking +========================= + +.. automodule:: monte_python.object_tracking + :members: + +.. toctree:: + :maxdepth: 2 diff --git a/docs/source/storm_mode.rst b/docs/source/storm_mode.rst new file mode 100644 index 0000000..9313f7c --- /dev/null +++ b/docs/source/storm_mode.rst @@ -0,0 +1,11 @@ +.. currentmodule:: monte_python + +Storm Segmentation and Mode Classification +============================================== + +.. automodule:: monte_python.storm_mode_classification + :members: + +.. toctree:: + :maxdepth: 2 + diff --git a/monte_python/object_identification.py b/monte_python/object_identification.py index 5fa7ef7..b68fb52 100644 --- a/monte_python/object_identification.py +++ b/monte_python/object_identification.py @@ -24,9 +24,9 @@ def label(input_data, params, method='watershed', return_object_properties=True) method [1]_ [2]_ [3]_ [4]_. .. note :: - The enhanced and iterative watershed algoritms are a powerful tools for image segementation, but - they require significant parameter tuning. We recommend exploring the single - threshold method first. + The enhanced and iterative watershed algoritms are a powerful tools for image segementation + ,but they require significant parameter tuning. We recommend exploring the single + threshold method first. Parameters ---------- @@ -369,13 +369,13 @@ def grow_objects(self, previous_region_props, previous_data_to_label, previous_l labelled region with new points. BUT remove the point so it is not further considered. - Args: + Parameters ------------------ regionprops, skimage object original_data, 2D numpy array of the data to be labelled labelled_data, 2D numpy array of labelled regions in original_data - Returns: + Returns --------------- labelled_array, 2D numpy array of labelled regions """ @@ -408,13 +408,13 @@ def grow_objects_recursive(self, labelled region with new points. BUT remove the point so it is not further considered. - Args: + Parameters ------------------ regionprops, skimage object original_data, 2D numpy array of the data to be labelled labelled_data, 2D numpy array of labelled regions in original_data - Returns: + Returns --------------- labelled_array, 2D numpy array of labelled regions """ diff --git a/monte_python/object_tracking.py b/monte_python/object_tracking.py index 0a758bb..76837fd 100755 --- a/monte_python/object_tracking.py +++ b/monte_python/object_tracking.py @@ -282,10 +282,12 @@ def relabel(self, data): def match(self, data_a, data_b): """ Match two set of data valid at a single or multiple times. - Args: + Parameters + ------------- object_set_a, 2D array or list of 2D arrays, object labels at a single or multiple times object_set_b, 2D array or list of 2D arrays, object labels at a single or multiple times - Returns: + Returns + ------------- Lists of matched labels in set a, matched labels in set b, and tuples of y- and x- components of centroid displacement of matched pairs """ @@ -327,10 +329,13 @@ def percent_intersection(self, region_a, region_b): def find_possible_matches(self, data_a, data_b): """ Finds matches based on amount of intersection between data at time = t and time = t+1. - Args: + Parameters + ----------- regionprops_set_a, skimage.measure.regionprops for object_set_a regionprops_set_b, skimage.measure.regionprops for object_set_b - Returns: + + Returns + ---------- Dictionary of tuples of possible matched object pairs associated with their total interest score Dictionary of y- and x-component of centroid displacement of possible matched object pairs """ diff --git a/monte_python/storm_mode_classification.py b/monte_python/storm_mode_classification.py index 01d35ea..9b4d851 100644 --- a/monte_python/storm_mode_classification.py +++ b/monte_python/storm_mode_classification.py @@ -29,7 +29,7 @@ class StormModeClassifier: Authors: Corey Potvin (NOAA NSSL), Montgomery Flora (OU/CIWRO) - Attributes: + Parameters ---------------- dbz_thresh, float Threshold used for the initial composite reflectivity object identification. @@ -108,7 +108,7 @@ def classify(self, dbz_vals, rot_vals=None, label_embedded=True): 7-mode scheme. Optionally, it can include mid-level rotation to aid in the classification. - Parameters: + Parameters --------------------- dbz_vals, array-like with shape (NY, NX) Composite reflectivity field at single time to identify and classify. @@ -123,7 +123,7 @@ def classify(self, dbz_vals, rot_vals=None, label_embedded=True): If True, then embedded storms are identified and classified. Otherwise, storm modes are only based on a 3-mode scheme. - Returns: + Returns --------------------- results : dict Keys, @@ -239,7 +239,7 @@ def get_storm_modes(self, dbz_data, rot_data=None,): Example : rot_data = (uh, rot_labels, rot_props) - Returns: + Returns ------------------- storm_modes : list of strings, of len(dbz_props) Storm types for each object in the dbz_props, (i.e., one for each reflectivity object) @@ -324,7 +324,7 @@ def get_constituent_storms(self, data_dict): Description: Identify reflectivity objects with a progressively higher threshold. Helps to identify embedded storms. - Parameters: + Parameters ------------------- data_dict : dict keys include @@ -333,7 +333,7 @@ def get_constituent_storms(self, data_dict): 'dbz_props' 'rot_labels' 'rot_props' - Returns: + Returns ------------------- """ dbz_vals, init_dbz_labels, init_dbz_props = data_dict['dbz_vals'], data_dict['dbz_labels'], data_dict['dbz_props'] @@ -433,10 +433,10 @@ def final_qc(self, storm_modes, storm_embs, dbz_labels, dbz_props,): contains the parent type of each child object new_storm_depths is later used to process objects in order of their generation. - Parameters: + Parameters ----------------------- - Returns: + Returns ----------------------- """