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..747ffb7 --- /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 + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..386cb86 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,49 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "batdetect2" +copyright = "2025, Oisin Mac Aodha, Santiago Martinez Balvanera" +author = "Oisin Mac Aodha, Santiago Martinez Balvanera" +release = "1.1.1" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", + "numpydoc", + "myst_parser", + "sphinx_autodoc_typehints", +] + +templates_path = ["_templates"] +exclude_patterns = [] + +source_suffix = { + ".rst": "restructuredtext", + ".txt": "markdown", + ".md": "markdown", +} + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "sphinx_book_theme" +html_static_path = ["_static"] + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "soundevent": ("https://mbsantiago.github.io/soundevent/", None), + "pydantic": ("https://docs.pydantic.dev/latest/", None), +} + +# -- Options for autodoc ------------------------------------------------------ +autosummary_generate = True +autosummary_imported_members = True diff --git a/docs/source/index.md b/docs/source/index.md new file mode 100644 index 0000000..17afddc --- /dev/null +++ b/docs/source/index.md @@ -0,0 +1,11 @@ +# batdetect2 documentation + +Hi! + +```{toctree} +:maxdepth: 1 +:caption: Contents: + +targets/index +reference/index +``` diff --git a/docs/source/reference/configs.md b/docs/source/reference/configs.md new file mode 100644 index 0000000..52bf13b --- /dev/null +++ b/docs/source/reference/configs.md @@ -0,0 +1,7 @@ +# Config Reference + +```{eval-rst} +.. automodule:: batdetect2.configs + :members: + :inherited-members: pydantic.BaseModel +``` diff --git a/docs/source/reference/index.md b/docs/source/reference/index.md new file mode 100644 index 0000000..87d0647 --- /dev/null +++ b/docs/source/reference/index.md @@ -0,0 +1,10 @@ +# Reference documentation + +```{eval-rst} +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + configs + targets +``` diff --git a/docs/source/reference/targets.md b/docs/source/reference/targets.md new file mode 100644 index 0000000..b6607a0 --- /dev/null +++ b/docs/source/reference/targets.md @@ -0,0 +1,6 @@ +# Targets Reference + +```{eval-rst} +.. automodule:: batdetect2.targets + :members: +``` diff --git a/docs/targets/classes.md b/docs/source/targets/classes.md similarity index 96% rename from docs/targets/classes.md rename to docs/source/targets/classes.md index f5dc3cd..5b0aa37 100644 --- a/docs/targets/classes.md +++ b/docs/source/targets/classes.md @@ -1,6 +1,6 @@ -## Step 4: Defining Target Classes for Training +# Step 4: Defining Target Classes for Training -### Purpose and Context +## Purpose and Context You've prepared your data by defining your annotation vocabulary (Step 1: Terms), removing irrelevant sounds (Step 2: Filtering), and potentially cleaning up or modifying tags (Step 3: Transforming Tags). Now, it's time to tell `batdetect2` **exactly what categories (classes) your model should learn to identify**. @@ -9,13 +9,13 @@ This step involves defining rules that map the final tags on your sound event an These class names are the labels the machine learning model will be trained to predict. Getting this definition right is essential for successful model training. -### How it Works: Defining Classes with Rules +## How it Works: Defining Classes with Rules You define your target classes in your main configuration file (e.g., your `.yaml` training config), typically under a section named `classes`. This section contains a **list** of class definitions. Each item in the list defines one specific class your model should learn. -### Defining a Single Class +## Defining a Single Class Each class definition rule requires a few key pieces of information: @@ -77,7 +77,7 @@ classes: value: Pipistrellus nathusii ``` -### Handling Overlap: Priority Order Matters! +## Handling Overlap: Priority Order Matters Sometimes, an annotation might have tags that match the rules for _more than one_ class definition. For example, an annotation tagged `species: Pipistrellus pipistrellus` would match both a specific `'pippip'` class rule and a broader `'pipistrelle'` genus rule (like the examples above) if both were defined. @@ -121,7 +121,7 @@ It would not be assigned `noise`, even though it also matches the second conditi Okay, that's a very important clarification about how BatDetect2 handles sounds that don't match specific class definitions. Let's refine that section to accurately reflect this behavior. -### What if No Class Matches? (The Generic "Bat" Class) +## What if No Class Matches? It's important to understand what happens if a sound event annotation passes through the filtering (Step 2) and transformation (Step 3) steps, but its final set of tags doesn't match _any_ of the specific class definitions you've listed in this section. @@ -142,7 +142,7 @@ The goal is generally that all relevant bat echolocation calls that pass the ini **Crucially:** If you want certain types of sounds (even if they are bat calls) to be **completely excluded** from the training process altogether (not even included in the generic "Bat" class), you **must remove them using rules in the Filtering step (Step 2)**. Any sound annotation that makes it past filtering _will_ be used in training, either under one of your specific classes or the generic one. -### Outcome +## Outcome By defining this list of prioritized class rules, you provide `batdetect2` with a clear procedure to assign a specific target label (your class `name`) to each relevant sound event annotation based on its tags. This labelled data is exactly what the model needs for training (Step 5). diff --git a/docs/targets/filtering.md b/docs/source/targets/filtering.md similarity index 96% rename from docs/targets/filtering.md rename to docs/source/targets/filtering.md index c1a0811..8839b85 100644 --- a/docs/targets/filtering.md +++ b/docs/source/targets/filtering.md @@ -1,6 +1,6 @@ -## Filtering Sound Events for Training +# Step 2: Filtering Sound Events -### Purpose +## Purpose When preparing your annotated audio data for training a `batdetect2` model, you often want to select only specific sound events. For example, you might want to: @@ -12,14 +12,14 @@ For example, you might want to: This filtering module allows you to define rules based on the **tags** associated with each sound event annotation. Only the events that pass _all_ your defined rules will be kept for further processing and training. -### How it Works: Rules +## How it Works: Rules Filtering is controlled by a list of **rules**. Each rule defines a condition based on the tags attached to a sound event. An event must satisfy **all** the rules you define in your configuration to be included. If an event fails even one rule, it is discarded. -### Defining Rules in Configuration +## Defining Rules in Configuration You define these rules within your main configuration file (usually a `.yaml` file) under a specific section (the exact name might depend on the main training config, but let's assume it's called `filtering`). @@ -48,7 +48,7 @@ filtering: # ... add more rules as needed ``` -### Understanding `match_type` +## Understanding `match_type` This determines _how_ the list of `tags` in the rule is used to check a sound event. There are four types: @@ -76,12 +76,12 @@ There are four types: - The sound event **passes** this rule only if its set of tags is _exactly identical_ to the list of `tags` provided in the rule (no more, no less). - _Note:_ This is very strict and usually less useful than `all` or `any`. -### Combining Rules +## Combining Rules Remember: A sound event must **pass every single rule** defined in the `rules` list to be kept. The rules are checked one by one, and if an event fails any rule, it's immediately excluded from further consideration. -### Examples +## Examples **Example 1: Keep good quality echolocation calls** @@ -135,7 +135,7 @@ _Explanation:_ An event is kept only if it passes ALL three rules: 2. It has the `Project ID: Project Alpha` tag. 3. It does _not_ have an `ID Certainty: Low` tag AND it does _not_ have an `ID Certainty: Maybe` tag. -### Usage +## Usage You will typically specify the path to the configuration file containing these `filtering` rules when you set up your data processing or training pipeline in `batdetect2`. The tool will then automatically load these rules and apply them to your annotated sound events. diff --git a/docs/source/targets/index.md b/docs/source/targets/index.md new file mode 100644 index 0000000..ab23fb6 --- /dev/null +++ b/docs/source/targets/index.md @@ -0,0 +1,14 @@ +# Selecting Targets + +Hi! + +```{toctree} +:maxdepth: 1 +:caption: Contents: + +tags_and_terms +filtering +transform +classes +labels +``` diff --git a/docs/targets/labels.md b/docs/source/targets/labels.md similarity index 96% rename from docs/targets/labels.md rename to docs/source/targets/labels.md index c9f15f1..18d8c6b 100644 --- a/docs/targets/labels.md +++ b/docs/source/targets/labels.md @@ -1,13 +1,13 @@ -## Step 5: Generating Training Targets (Heatmaps) +# Step 5: Generating Training Targets -### Purpose and Context +## Purpose and Context Following the previous steps of defining terms, filtering events, transforming tags, and defining specific class rules, this final stage focuses on **generating the ground truth data** used directly for training the BatDetect2 model. This involves converting the refined annotation information for each audio clip into specific **heatmap formats** required by the underlying neural network architecture. This step essentially translates your structured annotations into the precise "answer key" the model learns to replicate during training. -### What are Heatmaps? +## What are Heatmaps? Heatmaps, in this context, are multi-dimensional arrays, often visualized as images aligned with the input spectrogram, where the values at different time-frequency coordinates represent specific information about the sound events. For BatDetect2 training, three primary heatmaps are generated: @@ -31,7 +31,7 @@ For BatDetect2 training, three primary heatmaps are generated: - **Structure:** A 3D array with dimensions for size-dimension ('width', 'height'), time, and frequency. At the reference location of each detected sound event, this heatmap stores two numerical values corresponding to the scaled width and height derived from the event's bounding box. -### How Heatmaps are Created (The Process) +## How Heatmaps are Created The generation of these heatmaps is an automated process within `batdetect2`, driven by your configurations from all previous steps. For each audio clip and its corresponding spectrogram in the training dataset: @@ -46,7 +46,7 @@ For each audio clip and its corresponding spectrogram in the training dataset: - If an annotation received a specific class name, a signal is placed on the corresponding layer of the **Class Heatmap** at the reference location. 6. Finally, Gaussian smoothing (a blurring effect) is typically applied to the Detection and Class heatmaps to create spatially smoother targets, which often aids model training stability and performance. -### Configurable Settings for Heatmap Generation +## Configurable Settings for Heatmap Generation While the content of the heatmaps is primarily determined by the previous configuration steps, a few parameters specific to the heatmap drawing process itself can be adjusted. These are usually set in your main configuration file under a section like `labelling`: @@ -70,7 +70,7 @@ labelling: frequency_scale: 0.00116 # Example: Scales Hz relative to ~860 Hz (model specific!) ``` -### Outcome: Final Training Targets +## Outcome: Final Training Targets Executing this step for all training data yields the complete set of target heatmaps (Detection, Class, Size) for each corresponding input spectrogram. These arrays constitute the ground truth data that the BatDetect2 model directly compares its predictions against during the training phase, guiding its learning process. diff --git a/docs/targets/tags_and_terms.md b/docs/source/targets/tags_and_terms.md similarity index 97% rename from docs/targets/tags_and_terms.md rename to docs/source/targets/tags_and_terms.md index 9575190..bd2f994 100644 --- a/docs/targets/tags_and_terms.md +++ b/docs/source/targets/tags_and_terms.md @@ -1,6 +1,6 @@ -## Managing Annotation Vocabulary: Terms and Tags +# Step 1: Managing Annotation Vocabulary -### Purpose +## Purpose To train `batdetect2`, you will need sound events that have been carefully annotated. We annotate sound events using **tags**. A tag is simply a piece of information attached to an annotation, often describing what the sound is or its characteristics. Common examples include `Species: Myotis daubentonii` or `Quality: Good`. @@ -19,7 +19,7 @@ This `terms` module is designed to help manage these definitions effectively: 2. It lets you **define your own custom terms** if you need concepts specific to your project. 3. Crucially, it allows you to use simple **"keys"** (like shortcuts) in your configuration files to refer to these potentially complex term definitions, making configuration much easier and less error-prone. -### The Problem: Why We Need Defined Terms (and Why It Gets Complicated) +## The Problem: Why We Need Defined Terms Imagine you have a tag that simply says `"Myomyo"`. If you created this tag, you might know it's a shortcut for the species _Myotis myotis_. @@ -41,7 +41,7 @@ Using standard Terms whenever possible makes your data clearer, easier for other **But here's the practical problem:** While using standard, well-defined Terms is important for clarity and reusability, writing out full definitions or long standard names (like `dwc:scientificName` or "Scientific Name according to Darwin Core standard") every single time you need to refer to a species tag in a configuration file would be extremely tedious and prone to typing errors. -### The Solution: Keys (Shortcuts) and the Registry +## The Solution: Keys (Shortcuts) and the Registry This module uses a central **Registry** that stores the full definitions of various Terms. Each Term in the registry is assigned a unique, short **key** (a simple string). @@ -57,7 +57,7 @@ The system automatically looks up the full definition in the registry using the - **Key:** `species` - **In Config:** You just write `species`. -### Available Keys +## Available Keys The registry comes pre-loaded with keys for many standard terms used in bioacoustics, including those from the `soundevent` package and some specific to `batdetect2`. This means you can often use these common concepts without needing to define them yourself. @@ -77,7 +77,7 @@ This is not an exhaustive list. To discover all the term keys currently availabl Okay, let's refine the "Defining Your Own Terms" section to incorporate the explanation about namespacing within the `name` field description, keeping the style clear and researcher-focused. -### Defining Your Own Terms +## Defining Your Own Terms While many common terms have pre-defined keys, you might need a term specific to your project or data that isn't already available (e.g., "Recording Setup", "Weather Condition", "Project Phase", "Noise Source"). You can easily define these custom terms directly within a configuration file (usually your main `.yaml` file). @@ -119,7 +119,7 @@ terms: When `batdetect2` loads your configuration, it reads this `terms` section and adds your custom definitions (linked to their unique keys) to the central registry. These keys (`weather`, `setup_id`, etc.) are then ready to be used in other parts of your configuration, like defining filters or target classes. -### Using Keys to Specify Tags (in Filters, Class Definitions, etc.) +## Using Keys to Specify Tags (in Filters, Class Definitions, etc.) Now that you have keys for all the terms you need (both pre-defined and custom), you can easily refer to specific **tags** in other parts of your configuration, such as: @@ -155,7 +155,7 @@ rules: value: Good ``` -### Summary +## Summary - Annotations have **tags** (Term + Value). - This module uses short **keys** as shortcuts for Term definitions, stored in a **registry**. diff --git a/docs/targets/transform.md b/docs/source/targets/transform.md similarity index 97% rename from docs/targets/transform.md rename to docs/source/targets/transform.md index e2bb89c..a46c561 100644 --- a/docs/targets/transform.md +++ b/docs/source/targets/transform.md @@ -1,6 +1,6 @@ -## Step 3: Transforming Annotation Tags (Optional) +# Step 3: Transforming Annotation Tags (Optional) -### Purpose and Context +## Purpose and Context After defining your vocabulary (Step 1: Terms) and filtering out irrelevant sound events (Step 2: Filtering), you have a dataset of annotations ready for the next stages. Before you select the final target classes for training (Step 4), you might want or need to **modify the tags** associated with your annotations. @@ -15,7 +15,7 @@ This optional step allows you to clean up, standardize, or derive new informatio This step uses the `batdetect2.targets.transform` module to apply these changes based on rules you define. -### How it Works: Transformation Rules +## How it Works: Transformation Rules You control how tags are transformed by defining a list of **rules** in your configuration file (e.g., your main `.yaml` file, often under a section named `transform`). @@ -24,7 +24,7 @@ Importantly, the rules are applied **sequentially**, in the exact order they app The output annotation from one rule becomes the input for the next rule in the list. This means the order can matter! -### Types of Transformation Rules +## Types of Transformation Rules Here are the main types of rules you can define: @@ -106,13 +106,13 @@ Here are the main types of rules you can define: keep_source: false # Replace the original species tag ``` -### Rule Order Matters! +## Rule Order Matters Remember that rules are applied one after another. If you have multiple rules, make sure they are ordered correctly to achieve the desired outcome. For instance, you might want to standardize species names _before_ deriving the genus from them. -### Outcome +## Outcome After applying all the transformation rules you've defined, the annotations will proceed to the next step (Step 4: Select Target Tags & Define Classes) with their tags potentially cleaned, standardized, or augmented based on your configuration. If you don't define any rules, the tags simply pass through this step unchanged. diff --git a/pyproject.toml b/pyproject.toml index eef243a..109a3a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,11 @@ dev-dependencies = [ "ipykernel>=6.29.4", "setuptools>=69.5.1", "pyright>=1.1.399", + "myst-parser>=3.0.1", + "sphinx-autobuild>=2024.10.3", + "numpydoc>=1.8.0", + "sphinx-autodoc-typehints>=2.3.0", + "sphinx-book-theme>=1.1.4", ] [tool.ruff]