From 6587c6c4e54923d2cddddb857a5740ded3a3709b Mon Sep 17 00:00:00 2001 From: mbsantiago Date: Wed, 6 May 2026 14:32:51 +0100 Subject: [PATCH] feat: rename CLI inference command to process --- README.md | 4 +- docs/source/getting_started.md | 26 ++++++------ .../how_to/choose-an-inference-input-mode.md | 27 +++++++----- .../how_to/configure-audio-preprocessing.md | 12 +++--- docs/source/how_to/run-batch-predictions.md | 25 ++++++----- ...predictions-in-different-output-formats.md | 31 +++++++++----- .../source/how_to/tune-detection-threshold.md | 13 +++--- docs/source/how_to/tune-inference-clipping.md | 34 +++++++++------ docs/source/index.md | 28 +++++-------- docs/source/legacy/cli-detect.md | 10 +++-- docs/source/legacy/index.md | 9 ++-- docs/source/legacy/migration-guide.md | 41 +++++++++++------- docs/source/reference/cli/detect_legacy.rst | 4 +- docs/source/reference/cli/index.md | 8 ++-- docs/source/reference/cli/predict.rst | 8 ++-- .../tutorials/run-inference-on-folder.md | 31 ++++++++------ src/batdetect2/cli/__init__.py | 4 +- src/batdetect2/cli/base.py | 19 +++++---- src/batdetect2/cli/compat.py | 11 ++++- src/batdetect2/cli/inference.py | 28 ++++++------- tests/test_cli/test_predict.py | 42 +++++++++---------- 21 files changed, 237 insertions(+), 178 deletions(-) diff --git a/README.md b/README.md index 24ac15f..d421875 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ src/batdetect2/models/checkpoints/Net2DFast_UK_same.pth.tar Example command: ```bash -batdetect2 predict directory \ +batdetect2 process directory \ src/batdetect2/models/checkpoints/Net2DFast_UK_same.pth.tar \ example_data/audio \ outputs @@ -145,7 +145,7 @@ The remainder of this section is legacy reference material. The commands below describe the legacy CLI workflow. -For new work, prefer the current docs and `batdetect2 predict`. +For new work, prefer the current docs and `batdetect2 process`. You can run the model by opening the command line and typing: ```bash diff --git a/docs/source/getting_started.md b/docs/source/getting_started.md index 8e36bd1..ccce3b0 100644 --- a/docs/source/getting_started.md +++ b/docs/source/getting_started.md @@ -1,19 +1,20 @@ # Getting started -If you want to run BatDetect2 on your recordings, -start with the command-line route below. +If you want to run BatDetect2 on your recordings, start with the command-line +route below. You do not need to write Python code for a standard first run. -BatDetect2 also has a Python interface, -but that is mainly for users writing their own analysis scripts. +BatDetect2 also has a Python interface, but that is mainly for users writing +their own analysis scripts. -- Use the command-line route if you want to run an existing model or train your own model by typing commands in a terminal window. +- Use the command-line route if you want to run an existing model or train your + own model by typing commands in a terminal window. - Use the Python route only if you already want to work in scripts or notebooks. ```{note} If you are looking for the previous BatDetect2 workflow based on `batdetect2 detect` or `batdetect2.api`, go to {doc}`legacy/index`. -New docs default to the current `predict` CLI and `BatDetect2API` workflow. +New docs default to the current `process` CLI and `BatDetect2API` workflow. ``` If you want to try BatDetect2 before installing anything locally: @@ -27,15 +28,14 @@ If you want to try BatDetect2 before installing anything locally: 2. Use a model checkpoint. 3. Run the first tutorial on a folder of recordings. -If that is what you want, -you can ignore the Python sections for now. +If that is what you want, you can ignore the Python sections for now. ## Install BatDetect2 We recommend `uv` for both workflows. -`uv` is a tool that helps install Python software cleanly, -without mixing it into the rest of your machine. +`uv` is a tool that helps install Python software cleanly, without mixing it +into the rest of your machine. - Use `uv tool` to install the CLI. - Use `uv add` to add `batdetect2` as a dependency in a Python project. @@ -70,7 +70,8 @@ Go to {doc}`tutorials/run-inference-on-folder` for a complete first run. ## Choose a model checkpoint -The current command-line and Python workflows expect an explicit checkpoint path. +The current command-line and Python workflows expect an explicit checkpoint +path. A checkpoint is the saved model file that BatDetect2 will use for prediction. @@ -85,7 +86,8 @@ In this repository checkout, an example pretrained checkpoint is available at: src/batdetect2/models/checkpoints/Net2DFast_UK_same.pth.tar ``` -Use that path in the tutorial commands if you want a concrete starting point from this source tree. +Use that path in the tutorial commands if you want a concrete starting point +from this source tree. ## Python route for users writing code diff --git a/docs/source/how_to/choose-an-inference-input-mode.md b/docs/source/how_to/choose-an-inference-input-mode.md index ec89a72..38b0c5a 100644 --- a/docs/source/how_to/choose-an-inference-input-mode.md +++ b/docs/source/how_to/choose-an-inference-input-mode.md @@ -1,8 +1,9 @@ # How to choose an inference input mode -Use this guide to decide whether `predict directory`, `predict file_list`, or `predict dataset` is the right entry point for your run. +Use this guide to decide whether `process directory`, `process file_list`, or +`process dataset` is the right entry point for your run. -## Use `predict directory` when the recordings already live together +## Use `process directory` when the recordings already live together This is the simplest choice. @@ -13,13 +14,13 @@ Use it when: - you are doing a first pass over a folder of recordings. ```bash -batdetect2 predict directory \ +batdetect2 process directory \ path/to/model.ckpt \ path/to/audio_dir \ path/to/outputs ``` -## Use `predict file_list` when you need explicit control over the file set +## Use `process file_list` when you need explicit control over the file set Use it when: @@ -30,13 +31,13 @@ Use it when: The list file should contain one path per line. ```bash -batdetect2 predict file_list \ +batdetect2 process file_list \ path/to/model.ckpt \ path/to/audio_files.txt \ path/to/outputs ``` -## Use `predict dataset` when your workflow is already annotation-set driven +## Use `process dataset` when your workflow is already annotation-set driven Use it when: @@ -45,13 +46,14 @@ Use it when: - you want BatDetect2 to resolve recording paths from the annotation set. ```bash -batdetect2 predict dataset \ +batdetect2 process dataset \ path/to/model.ckpt \ path/to/annotation_set.json \ path/to/outputs ``` -The dataset command reads a `soundevent` annotation set and extracts unique recording paths before inference. +The dataset command reads a `soundevent` annotation set and extracts unique +recording paths before inference. ## Rule of thumb @@ -61,6 +63,9 @@ The dataset command reads a `soundevent` annotation set and extracts unique reco ## Related pages -- Run batch predictions: {doc}`run-batch-predictions` -- Tune inference clipping: {doc}`tune-inference-clipping` -- Predict command reference: {doc}`../reference/cli/predict` +- Run batch predictions: + {doc}`run-batch-predictions` +- Tune inference clipping: + {doc}`tune-inference-clipping` +- Process command reference: + {doc}`../reference/cli/predict` diff --git a/docs/source/how_to/configure-audio-preprocessing.md b/docs/source/how_to/configure-audio-preprocessing.md index bf1ca41..f59123c 100644 --- a/docs/source/how_to/configure-audio-preprocessing.md +++ b/docs/source/how_to/configure-audio-preprocessing.md @@ -46,7 +46,7 @@ Available built-ins: For CLI inference/evaluation, use `--audio-config`. ```bash -batdetect2 predict directory \ +batdetect2 process directory \ path/to/model.ckpt \ path/to/audio_dir \ path/to/outputs \ @@ -55,10 +55,12 @@ batdetect2 predict directory \ ## 4) Verify quickly on a small subset -Run on a small folder first and confirm that outputs and runtime are as -expected before full-batch runs. +Run on a small folder first and confirm that outputs and runtime are as expected +before full-batch runs. ## Related pages -- Spectrogram settings: {doc}`configure-spectrogram-preprocessing` -- Preprocessing config reference: {doc}`../reference/preprocessing-config` +- Spectrogram settings: + {doc}`configure-spectrogram-preprocessing` +- Preprocessing config reference: + {doc}`../reference/preprocessing-config` diff --git a/docs/source/how_to/run-batch-predictions.md b/docs/source/how_to/run-batch-predictions.md index 5d2d68c..515b74e 100644 --- a/docs/source/how_to/run-batch-predictions.md +++ b/docs/source/how_to/run-batch-predictions.md @@ -1,14 +1,15 @@ -# How to run batch predictions +# How to run batch processing This guide shows practical command patterns for directory-based and file-list -prediction runs. +processing runs. -Use it after you already know which input mode you want and need concrete command templates for a repeatable batch run. +Use it after you already know which input mode you want and need concrete +command templates for a repeatable batch run. -## Predict from a directory +## Process a directory ```bash -batdetect2 predict directory \ +batdetect2 process directory \ path/to/model.ckpt \ path/to/audio_dir \ path/to/outputs @@ -16,27 +17,29 @@ batdetect2 predict directory \ Use this when BatDetect2 should discover the audio files for you. -## Predict from a file list +## Process a file list ```bash -batdetect2 predict file_list \ +batdetect2 process file_list \ path/to/model.ckpt \ path/to/audio_files.txt \ path/to/outputs ``` -Use this when another part of your workflow already produced the exact recording list to process. +Use this when another part of your workflow already produced the exact recording +list to process. -## Predict from a dataset config +## Process a dataset config ```bash -batdetect2 predict dataset \ +batdetect2 process dataset \ path/to/model.ckpt \ path/to/annotation_set.json \ path/to/outputs ``` -Use this when your project already has a `soundevent` annotation set and you want to extract unique recording paths from it. +Use this when your project already has a `soundevent` annotation set and you +want to extract unique recording paths from it. ## Useful options diff --git a/docs/source/how_to/save-predictions-in-different-output-formats.md b/docs/source/how_to/save-predictions-in-different-output-formats.md index c354243..820728a 100644 --- a/docs/source/how_to/save-predictions-in-different-output-formats.md +++ b/docs/source/how_to/save-predictions-in-different-output-formats.md @@ -1,22 +1,27 @@ # How to save predictions in different output formats -Use this guide when you need BatDetect2 outputs in a specific representation for downstream tools. +Use this guide when you need BatDetect2 outputs in a specific representation for +downstream tools. ## Choose the format that matches the job Current built-in output formats include: -- `raw`: one NetCDF file per clip, best for rich structured outputs, -- `parquet`: tabular storage for data analysis workflows, -- `soundevent`: prediction-set JSON for soundevent-style tooling, -- `batdetect2`: legacy per-recording JSON output. +- `raw`: + one NetCDF file per clip, best for rich structured outputs, +- `parquet`: + tabular storage for data analysis workflows, +- `soundevent`: + prediction-set JSON for soundevent-style tooling, +- `batdetect2`: + legacy per-recording JSON output. ## Select a format from the CLI Use `--format` for quick experiments. ```bash -batdetect2 predict directory \ +batdetect2 process directory \ path/to/model.ckpt \ path/to/audio_dir \ path/to/outputs \ @@ -25,7 +30,8 @@ batdetect2 predict directory \ ## Use an outputs config for repeatable runs -Use an outputs config when you want reproducible control over format and transforms. +Use an outputs config when you want reproducible control over format and +transforms. Example: @@ -43,7 +49,7 @@ transform: Run with: ```bash -batdetect2 predict directory \ +batdetect2 process directory \ path/to/model.ckpt \ path/to/audio_dir \ path/to/outputs \ @@ -59,6 +65,9 @@ batdetect2 predict directory \ ## Related pages -- Outputs config reference: {doc}`../reference/outputs-config` -- Output formats reference: {doc}`../reference/output-formats` -- Output transforms reference: {doc}`../reference/output-transforms` +- Outputs config reference: + {doc}`../reference/outputs-config` +- Output formats reference: + {doc}`../reference/output-formats` +- Output transforms reference: + {doc}`../reference/output-transforms` diff --git a/docs/source/how_to/tune-detection-threshold.md b/docs/source/how_to/tune-detection-threshold.md index 2229c9c..8bdd4c7 100644 --- a/docs/source/how_to/tune-detection-threshold.md +++ b/docs/source/how_to/tune-detection-threshold.md @@ -4,7 +4,8 @@ Use this guide to compare detection outputs at different threshold values. The goal is not to find a universal threshold. -The goal is to choose a threshold that fits your reviewed local data and the project trade-off between missed calls and false positives. +The goal is to choose a threshold that fits your reviewed local data and the +project trade-off between missed calls and false positives. ## 1) Start with a baseline run @@ -12,12 +13,12 @@ Run an initial prediction workflow and keep outputs in a dedicated folder. ## 2) Sweep threshold values -Run `predict` multiple times with different thresholds (for example `0.1`, +Run `process` multiple times with different thresholds (for example `0.1`, `0.3`, `0.5`) and compare output counts and quality on the same validation subset. ```bash -batdetect2 predict directory \ +batdetect2 process directory \ path/to/model.ckpt \ path/to/audio_dir \ path/to/outputs_thr_03 \ @@ -26,7 +27,8 @@ batdetect2 predict directory \ Keep each threshold run in a separate output directory. -That makes it easier to compare counts and inspect example files without mixing results. +That makes it easier to compare counts and inspect example files without mixing +results. ## 3) Validate against known calls @@ -38,7 +40,8 @@ Check both: - obvious false positives, - obvious missed calls. -If class interpretation matters downstream, inspect class ranking behavior as well, not just detection counts. +If class interpretation matters downstream, inspect class ranking behavior as +well, not just detection counts. ## 4) Record your chosen setting diff --git a/docs/source/how_to/tune-inference-clipping.md b/docs/source/how_to/tune-inference-clipping.md index 3e3d164..a12999f 100644 --- a/docs/source/how_to/tune-inference-clipping.md +++ b/docs/source/how_to/tune-inference-clipping.md @@ -1,6 +1,7 @@ # How to tune inference clipping -Use this guide when long recordings need to be split into smaller clips during inference. +Use this guide when long recordings need to be split into smaller clips during +inference. ## What clipping controls @@ -8,14 +9,19 @@ Use this guide when long recordings need to be split into smaller clips during i Key fields are: -- `duration`: clip duration in seconds, -- `overlap`: overlap between adjacent clips, -- `max_empty`: how much empty padding is allowed, -- `discard_empty`: whether empty clips are dropped. +- `duration`: + clip duration in seconds, +- `overlap`: + overlap between adjacent clips, +- `max_empty`: + how much empty padding is allowed, +- `discard_empty`: + whether empty clips are dropped. ## Start from the defaults -Use the built-in clipping behavior first unless you already know you need something else. +Use the built-in clipping behavior first unless you already know you need +something else. Only tune clipping when: @@ -25,7 +31,7 @@ Only tune clipping when: ## Override clipping with an inference config -Create an inference config file and pass it to `predict` or `evaluate`. +Create an inference config file and pass it to `process` or `evaluate`. Example: @@ -43,7 +49,7 @@ loader: Run with: ```bash -batdetect2 predict directory \ +batdetect2 process directory \ path/to/model.ckpt \ path/to/audio_dir \ path/to/outputs \ @@ -52,12 +58,16 @@ batdetect2 predict directory \ ## Validate clipping changes on a small reviewed subset -Changing clipping changes what the model sees per batch and can change how events near clip boundaries behave. +Changing clipping changes what the model sees per batch and can change how +events near clip boundaries behave. Check a reviewed subset before applying clipping changes to a full project. ## Related pages -- Inference config reference: {doc}`../reference/inference-config` -- Run batch predictions: {doc}`run-batch-predictions` -- Understanding the pipeline: {doc}`../explanation/pipeline-overview` +- Inference config reference: + {doc}`../reference/inference-config` +- Run batch predictions: + {doc}`run-batch-predictions` +- Understanding the pipeline: + {doc}`../explanation/pipeline-overview` diff --git a/docs/source/index.md b/docs/source/index.md index c676128..98f0213 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -6,25 +6,20 @@ Welcome to the BatDetect2 documentation. `batdetect2` detects bat echolocation calls in audio recordings. -It can help you screen large collections of recordings, -find files that need expert review, -and support ecology and conservation work where manual review alone would be slow. +It can help you screen large collections of recordings, find files that need +expert review, and support ecology and conservation work where manual review +alone would be slow. -In practice, -BatDetect2 takes recordings, -looks for likely bat calls, -draws a box around each detected event, -and scores the most likely class for that event. +In practice, BatDetect2 takes recordings, looks for likely bat calls, draws a +box around each detected event, and scores the most likely class for that event. The current default model is trained for 17 UK species. -The library also supports custom training, -fine-tuning, -evaluation, -and more advanced use from Python. +The library also supports custom training, fine-tuning, evaluation, and more +advanced use from Python. For details on the underlying approach, see the pre-print: -[Towards a General Approach for Bat Echolocation Detection and Classification](https://www.biorxiv.org/content/10.1101/2022.12.14.520490v1) +[Towards a General Approach for Bat Echolocation Detection and Classification](https://www.biorxiv.org/content/10.1101/2022.12.14.520490v1) ## A good first use for BatDetect2 @@ -56,7 +51,7 @@ Always validate on reviewed local data before using results for ecological infer ```{note} Looking for the previous BatDetect2 workflow? See {doc}`legacy/index`. -The legacy docs are still available, but new workflows should use `batdetect2 predict` and `BatDetect2API`. +The legacy docs are still available, but new workflows should use `batdetect2 process` and `BatDetect2API`. ``` ## How to use this site @@ -65,8 +60,7 @@ Start with {doc}`getting_started` if you are new. Then choose the section that matches what you need. -If you are here mainly to run the model on recordings, -start with Tutorials. +If you are here mainly to run the model on recordings, start with Tutorials. | Section | Best for | Start here | | --- | --- | --- | @@ -81,7 +75,7 @@ start with Tutorials. - GitHub repository: [macaodha/batdetect2](https://github.com/macaodha/batdetect2) - Questions, bug reports, and feature requests: - [GitHub Issues](https://github.com/macaodha/batdetect2/issues) + [GitHub Issues](https://github.com/macaodha/batdetect2/issues) - Common questions: {doc}`faq` - Want to contribute? diff --git a/docs/source/legacy/cli-detect.md b/docs/source/legacy/cli-detect.md index 3667078..c22e77e 100644 --- a/docs/source/legacy/cli-detect.md +++ b/docs/source/legacy/cli-detect.md @@ -4,7 +4,7 @@ This page documents the previous CLI workflow based on `batdetect2 detect`. ```{warning} This is legacy documentation. -For new workflows, use `batdetect2 predict directory` instead. +For new workflows, use `batdetect2 process directory` instead. If you are migrating, start with {doc}`migration-guide`. ``` @@ -27,7 +27,7 @@ Common legacy options included: The closest current CLI entry point is: ```bash -batdetect2 predict directory \ +batdetect2 process directory \ path/to/model.ckpt \ path/to/audio_dir \ path/to/outputs @@ -35,5 +35,7 @@ batdetect2 predict directory \ ## Related pages -- Migration guide: {doc}`migration-guide` -- Current predict docs: {doc}`../reference/cli/predict` +- Migration guide: + {doc}`migration-guide` +- Current process docs: + {doc}`../reference/cli/predict` diff --git a/docs/source/legacy/index.md b/docs/source/legacy/index.md index 9f21a7c..226adf1 100644 --- a/docs/source/legacy/index.md +++ b/docs/source/legacy/index.md @@ -2,12 +2,15 @@ This section documents the previous BatDetect2 workflow. -Use these pages if you need to keep working with the older `batdetect2 detect` command or the older `batdetect2.api` interface. +Use these pages if you need to keep working with the older `batdetect2 detect` +command or the older `batdetect2.api` interface. For new projects, we recommend the current workflow: -- CLI: `batdetect2 predict` -- Python: `batdetect2.api_v2.BatDetect2API` +- CLI: + `batdetect2 process` +- Python: + `batdetect2.api_v2.BatDetect2API` If you are moving from the older workflow, start with {doc}`migration-guide`. diff --git a/docs/source/legacy/migration-guide.md b/docs/source/legacy/migration-guide.md index 89dfe40..2dbd8b4 100644 --- a/docs/source/legacy/migration-guide.md +++ b/docs/source/legacy/migration-guide.md @@ -1,6 +1,7 @@ # Migration guide: legacy to current workflows -Use this guide when moving from the previous BatDetect2 workflow to the current CLI and API. +Use this guide when moving from the previous BatDetect2 workflow to the current +CLI and API. ## Who should migrate now @@ -9,31 +10,37 @@ You should migrate if: - you are starting a new workflow, - you want the current docs path, - you want the newer CLI and API surface, -- you are maintaining code that does not depend on the exact legacy JSON or feature outputs. +- you are maintaining code that does not depend on the exact legacy JSON or + feature outputs. You may need the legacy workflow a bit longer if: - downstream tooling depends on the exact old output structure, - you rely on older notebooks built around `batdetect2.api`, -- you depend on legacy feature extraction outputs without a validated replacement yet. +- you depend on legacy feature extraction outputs without a validated + replacement yet. ## CLI mapping -- `batdetect2 detect AUDIO_DIR ANN_DIR DETECTION_THRESHOLD` - -> `batdetect2 predict directory MODEL_PATH AUDIO_DIR OUTPUT_PATH --detection-threshold ...` +- `batdetect2 detect AUDIO_DIR ANN_DIR DETECTION_THRESHOLD` -> `batdetect2 + process directory MODEL_PATH AUDIO_DIR OUTPUT_PATH --detection-threshold ...` Main changes: -- the model path is now a positional argument on the `predict` subcommand, -- the current workflow expects an explicit checkpoint path rather than silently relying on the old default CLI behavior, +- the model path is now a positional argument on the `process` subcommand, +- the current workflow expects an explicit checkpoint path rather than silently + relying on the old default CLI behavior, - output formatting is configurable, - threshold override is an option rather than a required positional argument, -- there are separate subcommands for directory, file-list, and dataset-driven inference. +- there are separate subcommands for directory, file-list, and dataset-driven + inference. ## Python API mapping -- old: `import batdetect2.api as api` -- current: `from batdetect2.api_v2 import BatDetect2API` +- old: + `import batdetect2.api as api` +- current: + `from batdetect2.api_v2 import BatDetect2API` Typical migration shape: @@ -51,7 +58,7 @@ Useful replacements: - legacy `process_file` -> current `BatDetect2API.process_file` - legacy `process_audio` -> current `BatDetect2API.process_audio` - legacy `process_spectrogram` -> current `BatDetect2API.process_spectrogram` -- legacy one-off batch loops -> current `process_files` or CLI `predict` +- legacy one-off batch loops -> current `process_files` or CLI `process` ## Output and terminology changes @@ -78,7 +85,8 @@ Before replacing a legacy workflow in production or research analysis, validate: - that outputs are being saved in the right format, - that downstream code reads the new outputs correctly, - that feature-related assumptions still hold, -- that evaluation and ecological interpretation are unchanged only where you have actually verified that. +- that evaluation and ecological interpretation are unchanged only where you + have actually verified that. ## Migration checklist @@ -91,6 +99,9 @@ Before replacing a legacy workflow in production or research analysis, validate: ## Related pages -- Current getting started: {doc}`../getting_started` -- Current tutorials: {doc}`../tutorials/index` -- Current API reference: {doc}`../reference/api` +- Current getting started: + {doc}`../getting_started` +- Current tutorials: + {doc}`../tutorials/index` +- Current API reference: + {doc}`../reference/api` diff --git a/docs/source/reference/cli/detect_legacy.rst b/docs/source/reference/cli/detect_legacy.rst index c3d15de..2571a1b 100644 --- a/docs/source/reference/cli/detect_legacy.rst +++ b/docs/source/reference/cli/detect_legacy.rst @@ -4,13 +4,13 @@ Legacy detect command .. warning:: ``batdetect2 detect`` is a legacy compatibility command. - Prefer ``batdetect2 predict directory`` for new workflows. + Prefer ``batdetect2 process directory`` for new workflows. Migration at a glance --------------------- - Legacy: ``batdetect2 detect AUDIO_DIR ANN_DIR DETECTION_THRESHOLD`` -- Current: ``batdetect2 predict directory MODEL_PATH AUDIO_DIR OUTPUT_PATH`` +- Current: ``batdetect2 process directory MODEL_PATH AUDIO_DIR OUTPUT_PATH`` with optional ``--detection-threshold`` .. click:: batdetect2.cli.compat:detect diff --git a/docs/source/reference/cli/index.md b/docs/source/reference/cli/index.md index e7e06e5..1ca9064 100644 --- a/docs/source/reference/cli/index.md +++ b/docs/source/reference/cli/index.md @@ -7,7 +7,7 @@ for the full option list. | Command | Use it for | Required positional args | | --- | --- | --- | -| `batdetect2 predict` | Run prediction on audio | Depends on subcommand (`directory`, `file_list`, `dataset`) | +| `batdetect2 process` | Run inference on audio | Depends on subcommand (`directory`, `file_list`, `dataset`) | | `batdetect2 data` | Inspect and convert dataset configs | Depends on subcommand (`summary`, `convert`) | | `batdetect2 train` | Train or fine-tune models | `TRAIN_DATASET` | | `batdetect2 finetune` | Fine-tune a checkpoint on new targets | `TRAIN_DATASET` plus `--targets` | @@ -19,13 +19,13 @@ for the full option list. - Global CLI options are documented in {doc}`base`. - Paths with spaces should be wrapped in quotes. - Input audio is expected to be mono. -- `predict` uses the optional `--detection-threshold` override. +- `process` uses the optional `--detection-threshold` override. - `finetune` defaults to the bundled `uk_same` checkpoint if `--model` is not provided. ```{warning} `batdetect2 detect` is a legacy command. -Prefer `batdetect2 predict directory` for new workflows. +Prefer `batdetect2 process directory` for new workflows. ``` ## Related pages @@ -39,7 +39,7 @@ Prefer `batdetect2 predict directory` for new workflows. :maxdepth: 1 Base command and global options -Predict command group +Process command group Data command group Train command Finetune command diff --git a/docs/source/reference/cli/predict.rst b/docs/source/reference/cli/predict.rst index 0027ff0..080ab4a 100644 --- a/docs/source/reference/cli/predict.rst +++ b/docs/source/reference/cli/predict.rst @@ -1,7 +1,7 @@ -Predict command +Process command =============== -Use ``batdetect2 predict`` to run prediction on audio. +Use ``batdetect2 process`` to run inference on audio. Choose a subcommand based on how you want to provide the input: @@ -12,6 +12,6 @@ Choose a subcommand based on how you want to provide the input: Use ``--detection-threshold`` when you want to override the configured threshold for one run. -.. click:: batdetect2.cli.inference:predict - :prog: batdetect2 predict +.. click:: batdetect2.cli.inference:process + :prog: batdetect2 process :nested: full diff --git a/docs/source/tutorials/run-inference-on-folder.md b/docs/source/tutorials/run-inference-on-folder.md index cff78b7..2f2834a 100644 --- a/docs/source/tutorials/run-inference-on-folder.md +++ b/docs/source/tutorials/run-inference-on-folder.md @@ -4,7 +4,8 @@ This tutorial walks through a first end-to-end inference run with the CLI. It is the default starting point for new users. -Use it when you want to run an existing model on a folder of recordings and quickly check what BatDetect2 found. +Use it when you want to run an existing model on a folder of recordings and +quickly check what BatDetect2 found. ## Before you start @@ -24,7 +25,7 @@ src/batdetect2/models/checkpoints/Net2DFast_UK_same.pth.tar By the end of this tutorial you will have: -- run `batdetect2 predict directory`, +- run `batdetect2 process directory`, - saved predictions to disk, - checked that BatDetect2 wrote output files, - identified the next pages to use for tuning or customization. @@ -48,12 +49,13 @@ project/ outputs/ ``` -## 2. Run prediction on the directory +## 2. Run processing on the directory -Use this command when you want BatDetect2 to scan a folder of recordings automatically. +Use this command when you want BatDetect2 to scan a folder of recordings +automatically. ```bash -batdetect2 predict directory \ +batdetect2 process directory \ path/to/model.pth.tar \ path/to/audio_dir \ path/to/outputs @@ -70,8 +72,7 @@ What this does: After the command completes, inspect the output directory. -For a first run, -the important check is simple: +For a first run, the important check is simple: - did BatDetect2 create result files, - are they in the output directory you expected, @@ -81,8 +82,8 @@ Different workflows can save results in different file formats. You do not need to learn those details for the first run. -If you later need to choose a specific output format, -go to {doc}`../how_to/save-predictions-in-different-output-formats`. +If you later need to choose a specific output format, go to +{doc}`../how_to/save-predictions-in-different-output-formats`. ## 4. Inspect predictions @@ -103,13 +104,17 @@ Validation comes next. ## 5. Tune only after you have a baseline -If the first run is too noisy or misses obvious calls, tune thresholds on a reviewed subset rather than changing settings blindly across the full dataset. +If the first run is too noisy or misses obvious calls, tune thresholds on a +reviewed subset rather than changing settings blindly across the full dataset. Use {doc}`../how_to/tune-detection-threshold` for that process. ## What to do next -- If you need a different input mode, use {doc}`../how_to/choose-an-inference-input-mode`. -- If you want to tune sensitivity, use {doc}`../how_to/tune-detection-threshold`. -- If you already write code and want more control from Python, use {doc}`integrate-with-a-python-pipeline`. +- If you need a different input mode, use + {doc}`../how_to/choose-an-inference-input-mode`. +- If you want to tune sensitivity, use + {doc}`../how_to/tune-detection-threshold`. +- If you already write code and want more control from Python, use + {doc}`integrate-with-a-python-pipeline`. - If you need full command details, use {doc}`../reference/cli/predict`. diff --git a/src/batdetect2/cli/__init__.py b/src/batdetect2/cli/__init__.py index eadc98f..69d75d7 100644 --- a/src/batdetect2/cli/__init__.py +++ b/src/batdetect2/cli/__init__.py @@ -3,7 +3,7 @@ from batdetect2.cli.compat import detect from batdetect2.cli.data import data from batdetect2.cli.evaluate import evaluate_command from batdetect2.cli.finetune import finetune_command -from batdetect2.cli.inference import predict +from batdetect2.cli.inference import process from batdetect2.cli.train import train_command __all__ = [ @@ -13,7 +13,7 @@ __all__ = [ "train_command", "finetune_command", "evaluate_command", - "predict", + "process", ] diff --git a/src/batdetect2/cli/base.py b/src/batdetect2/cli/base.py index ee99afb..9a991e5 100644 --- a/src/batdetect2/cli/base.py +++ b/src/batdetect2/cli/base.py @@ -2,6 +2,8 @@ import click +from batdetect2.cli.ascii import BATDETECT_ASCII_ART + __all__ = [ "cli", ] @@ -9,29 +11,30 @@ __all__ = [ INFO_STR = """ BatDetect2 - Input audio should be mono. Wrap paths that contain spaces in quotes. - For long recordings, split audio into shorter files before running - prediction. """ -@click.group() +@click.group(invoke_without_command=True) @click.option( "-v", "--verbose", count=True, help="Increase verbosity. -v for INFO, -vv for DEBUG.", ) -def cli(verbose: int = 0): +@click.pass_context +def cli(ctx: click.Context, verbose: int = 0): """Run the BatDetect2 CLI. - Use subcommands to run prediction, training, evaluation, and dataset + Use subcommands to run processing, training, evaluation, and dataset utilities. """ - click.echo(INFO_STR) + + if ctx.invoked_subcommand is None: + click.echo(BATDETECT_ASCII_ART) + click.echo(ctx.get_help()) + ctx.exit() from batdetect2.logging import enable_logging enable_logging(verbose) - # click.echo(BATDETECT_ASCII_ART) diff --git a/src/batdetect2/cli/compat.py b/src/batdetect2/cli/compat.py index c8934fe..dad391c 100644 --- a/src/batdetect2/cli/compat.py +++ b/src/batdetect2/cli/compat.py @@ -1,4 +1,5 @@ import os +import warnings import click @@ -15,7 +16,7 @@ DEFAULT_MODEL_PATH = os.path.join( @cli.command( short_help="Legacy detection command.", epilog=( - "Deprecated workflow. Prefer `batdetect2 predict directory` for " + "Deprecated workflow. Prefer `batdetect2 process directory` for " "new analyses." ), ) @@ -91,11 +92,17 @@ def detect( Note ---- This command is kept for backwards compatibility. Prefer - `batdetect2 predict directory` for new workflows. + `batdetect2 process directory` for new workflows. """ from batdetect2 import api from batdetect2.utils.detector_utils import save_results_to_file + message = ( + "The `batdetect2 detect` command is deprecated. Prefer " + "`batdetect2 process directory` for new analyses." + ) + click.secho(f"WARNING: {message}", fg="yellow", err=True) + click.echo(f"Loading model: {args['model_path']}") model, params = api.load_model(args["model_path"]) diff --git a/src/batdetect2/cli/inference.py b/src/batdetect2/cli/inference.py index 41f6622..84985e6 100644 --- a/src/batdetect2/cli/inference.py +++ b/src/batdetect2/cli/inference.py @@ -13,11 +13,11 @@ if TYPE_CHECKING: from batdetect2.inference import InferenceConfig from batdetect2.outputs import OutputsConfig -__all__ = ["predict"] +__all__ = ["process"] -@cli.group(name="predict", short_help="Run prediction workflows.") -def predict() -> None: +@cli.group(name="process", short_help="Run processing workflows.") +def process() -> None: """Run model inference on audio. Choose a subcommand based on how you want to provide input audio. @@ -25,7 +25,7 @@ def predict() -> None: def common_predict_options(func): - """Attach options shared by all ``predict`` subcommands.""" + """Attach options shared by all ``process`` subcommands.""" @click.option( "--audio-config", @@ -186,9 +186,9 @@ def _run_prediction( ) -@predict.command( +@process.command( name="directory", - short_help="Predict on audio files in a directory.", + short_help="Process audio files in a directory.", ) @click.argument("model_path", type=str) @click.argument("audio_dir", type=click.Path(exists=True)) @@ -207,9 +207,9 @@ def predict_directory_command( format_name: str | None, detection_threshold: float | None, ) -> None: - """Run prediction on all supported audio files in a directory. + """Run processing on all supported audio files in a directory. - This command scans ``audio_dir`` for audio files, runs prediction, and + This command scans ``audio_dir`` for audio files, runs processing, and saves the results to ``output_path``. """ from soundevent.audio.files import get_audio_files @@ -230,9 +230,9 @@ def predict_directory_command( ) -@predict.command( +@process.command( name="file_list", - short_help="Predict on paths listed in a text file.", + short_help="Process paths listed in a text file.", ) @click.argument("model_path", type=str) @click.argument("file_list", type=click.Path(exists=True)) @@ -251,7 +251,7 @@ def predict_file_list_command( format_name: str | None, detection_threshold: float | None, ) -> None: - """Run prediction on audio files listed in a text file. + """Run processing on audio files listed in a text file. The text file should contain one audio path per line. Empty lines are ignored. @@ -278,9 +278,9 @@ def predict_file_list_command( ) -@predict.command( +@process.command( name="dataset", - short_help="Predict on recordings from a dataset config.", + short_help="Process recordings from a dataset config.", ) @click.argument("model_path", type=str) @click.argument("dataset_path", type=click.Path(exists=True)) @@ -299,7 +299,7 @@ def predict_dataset_command( format_name: str | None, detection_threshold: float | None, ) -> None: - """Run prediction on recordings referenced in a dataset file. + """Run processing on recordings referenced in a dataset file. Recording paths are read from the dataset and each recording is processed once. diff --git a/tests/test_cli/test_predict.py b/tests/test_cli/test_predict.py index 23f92dc..0fdc91f 100644 --- a/tests/test_cli/test_predict.py +++ b/tests/test_cli/test_predict.py @@ -1,4 +1,4 @@ -"""Behavior tests for predict CLI workflows.""" +"""Behavior tests for process CLI workflows.""" from pathlib import Path @@ -9,10 +9,10 @@ from soundevent import data, io from batdetect2.cli import cli -def test_cli_predict_help() -> None: - """User story: discover available predict modes.""" +def test_cli_process_help() -> None: + """User story: discover available process modes.""" - result = CliRunner().invoke(cli, ["predict", "--help"]) + result = CliRunner().invoke(cli, ["process", "--help"]) assert result.exit_code == 0 assert "directory" in result.output @@ -21,19 +21,19 @@ def test_cli_predict_help() -> None: @pytest.mark.slow -def test_cli_predict_directory_runs_on_real_audio( +def test_cli_process_directory_runs_on_real_audio( tmp_path: Path, tiny_checkpoint_path: Path, single_audio_dir: Path, ) -> None: - """User story: run prediction for all files in a directory.""" + """User story: process all files in a directory.""" output_path = tmp_path / "predictions" result = CliRunner().invoke( cli, [ - "predict", + "process", "directory", str(tiny_checkpoint_path), str(single_audio_dir), @@ -52,12 +52,12 @@ def test_cli_predict_directory_runs_on_real_audio( assert len(list(output_path.glob("*.json"))) == 1 -def test_cli_predict_file_list_runs_on_real_audio( +def test_cli_process_file_list_runs_on_real_audio( tmp_path: Path, tiny_checkpoint_path: Path, single_audio_dir: Path, ) -> None: - """User story: run prediction from an explicit list of files.""" + """User story: process an explicit list of files.""" audio_file = next(single_audio_dir.glob("*.wav")) file_list = tmp_path / "files.txt" @@ -68,7 +68,7 @@ def test_cli_predict_file_list_runs_on_real_audio( result = CliRunner().invoke( cli, [ - "predict", + "process", "file_list", str(tiny_checkpoint_path), str(file_list), @@ -87,12 +87,12 @@ def test_cli_predict_file_list_runs_on_real_audio( assert len(list(output_path.glob("*.json"))) == 1 -def test_cli_predict_dataset_runs_on_aoef_metadata( +def test_cli_process_dataset_runs_on_aoef_metadata( tmp_path: Path, tiny_checkpoint_path: Path, single_audio_dir: Path, ) -> None: - """User story: predict from AOEF dataset metadata file.""" + """User story: process from AOEF dataset metadata file.""" audio_file = next(single_audio_dir.glob("*.wav")) recording = data.Recording.from_file(audio_file) @@ -103,7 +103,7 @@ def test_cli_predict_dataset_runs_on_aoef_metadata( ) annotation_set = data.AnnotationSet( name="test", - description="predict dataset test", + description="process dataset test", clip_annotations=[data.ClipAnnotation(clip=clip, sound_events=[])], ) @@ -115,7 +115,7 @@ def test_cli_predict_dataset_runs_on_aoef_metadata( result = CliRunner().invoke( cli, [ - "predict", + "process", "dataset", str(tiny_checkpoint_path), str(dataset_path), @@ -142,7 +142,7 @@ def test_cli_predict_dataset_runs_on_aoef_metadata( ("soundevent", "*.json", True), ], ) -def test_cli_predict_directory_supports_output_format_override( +def test_cli_process_directory_supports_output_format_override( tmp_path: Path, tiny_checkpoint_path: Path, single_audio_dir: Path, @@ -157,7 +157,7 @@ def test_cli_predict_directory_supports_output_format_override( result = CliRunner().invoke( cli, [ - "predict", + "process", "directory", str(tiny_checkpoint_path), str(single_audio_dir), @@ -180,12 +180,12 @@ def test_cli_predict_directory_supports_output_format_override( assert len(list(output_path.glob(expected_pattern))) >= 1 -def test_cli_predict_dataset_deduplicates_recordings( +def test_cli_process_dataset_deduplicates_recordings( tmp_path: Path, tiny_checkpoint_path: Path, single_audio_dir: Path, ) -> None: - """User story: duplicated recording entries are predicted once.""" + """User story: duplicated recording entries are processed once.""" audio_file = next(single_audio_dir.glob("*.wav")) recording = data.Recording.from_file(audio_file) @@ -215,7 +215,7 @@ def test_cli_predict_dataset_deduplicates_recordings( result = CliRunner().invoke( cli, [ - "predict", + "process", "dataset", str(tiny_checkpoint_path), str(dataset_path), @@ -234,7 +234,7 @@ def test_cli_predict_dataset_deduplicates_recordings( assert len(list(output_path.glob("*.nc"))) == 1 -def test_cli_predict_rejects_unknown_output_format( +def test_cli_process_rejects_unknown_output_format( tmp_path: Path, tiny_checkpoint_path: Path, single_audio_dir: Path, @@ -245,7 +245,7 @@ def test_cli_predict_rejects_unknown_output_format( result = CliRunner().invoke( cli, [ - "predict", + "process", "directory", str(tiny_checkpoint_path), str(single_audio_dir),