Remove stale load functions

This commit is contained in:
mbsantiago 2026-03-18 19:43:54 +00:00
parent 22a3d18d45
commit 2f03abe8f6
18 changed files with 35 additions and 197 deletions

View File

@ -43,11 +43,11 @@ def evaluate_command(
from batdetect2.api_v2 import BatDetect2API from batdetect2.api_v2 import BatDetect2API
from batdetect2.audio import AudioConfig from batdetect2.audio import AudioConfig
from batdetect2.data import load_dataset_from_config from batdetect2.data import load_dataset_from_config
from batdetect2.evaluate import load_evaluation_config from batdetect2.evaluate import EvaluationConfig
from batdetect2.inference import InferenceConfig from batdetect2.inference import InferenceConfig
from batdetect2.logging import load_logging_config from batdetect2.logging import AppLoggingConfig
from batdetect2.outputs import OutputsConfig from batdetect2.outputs import OutputsConfig
from batdetect2.targets import load_target_config from batdetect2.targets import TargetConfig
logger.info("Initiating evaluation process...") logger.info("Initiating evaluation process...")
@ -62,7 +62,7 @@ def evaluate_command(
) )
target_conf = ( target_conf = (
load_target_config(targets_config) TargetConfig.load(targets_config)
if targets_config is not None if targets_config is not None
else None else None
) )
@ -70,7 +70,7 @@ def evaluate_command(
AudioConfig.load(audio_config) if audio_config is not None else None AudioConfig.load(audio_config) if audio_config is not None else None
) )
eval_conf = ( eval_conf = (
load_evaluation_config(evaluation_config) EvaluationConfig.load(evaluation_config)
if evaluation_config is not None if evaluation_config is not None
else None else None
) )
@ -85,7 +85,7 @@ def evaluate_command(
else None else None
) )
logging_conf = ( logging_conf = (
load_logging_config(logging_config) AppLoggingConfig.load(logging_config)
if logging_config is not None if logging_config is not None
else None else None
) )

View File

@ -53,19 +53,19 @@ def train_command(
from batdetect2.audio import AudioConfig from batdetect2.audio import AudioConfig
from batdetect2.config import BatDetect2Config from batdetect2.config import BatDetect2Config
from batdetect2.data import load_dataset_from_config from batdetect2.data import load_dataset_from_config
from batdetect2.evaluate import load_evaluation_config from batdetect2.evaluate import EvaluationConfig
from batdetect2.inference import InferenceConfig from batdetect2.inference import InferenceConfig
from batdetect2.logging import load_logging_config from batdetect2.logging import AppLoggingConfig
from batdetect2.models import ModelConfig from batdetect2.models import ModelConfig
from batdetect2.outputs import OutputsConfig from batdetect2.outputs import OutputsConfig
from batdetect2.targets import load_target_config from batdetect2.targets import TargetConfig
from batdetect2.train import load_train_config from batdetect2.train import TrainingConfig
logger.info("Initiating training process...") logger.info("Initiating training process...")
logger.info("Loading configuration...") logger.info("Loading configuration...")
target_conf = ( target_conf = (
load_target_config(targets_config) TargetConfig.load(targets_config)
if targets_config is not None if targets_config is not None
else None else None
) )
@ -73,7 +73,7 @@ def train_command(
ModelConfig.load(model_config) if model_config is not None else None ModelConfig.load(model_config) if model_config is not None else None
) )
train_conf = ( train_conf = (
load_train_config(training_config) TrainingConfig.load(training_config)
if training_config is not None if training_config is not None
else None else None
) )
@ -81,7 +81,7 @@ def train_command(
AudioConfig.load(audio_config) if audio_config is not None else None AudioConfig.load(audio_config) if audio_config is not None else None
) )
eval_conf = ( eval_conf = (
load_evaluation_config(evaluation_config) EvaluationConfig.load(evaluation_config)
if evaluation_config is not None if evaluation_config is not None
else None else None
) )
@ -96,7 +96,7 @@ def train_command(
else None else None
) )
logging_conf = ( logging_conf = (
load_logging_config(logging_config) AppLoggingConfig.load(logging_config)
if logging_config is not None if logging_config is not None
else None else None
) )

View File

@ -1,10 +1,9 @@
from typing import Literal from typing import Literal
from pydantic import Field from pydantic import Field
from soundevent.data import PathLike
from batdetect2.audio import AudioConfig from batdetect2.audio import AudioConfig
from batdetect2.core.configs import BaseConfig, load_config from batdetect2.core.configs import BaseConfig
from batdetect2.evaluate.config import ( from batdetect2.evaluate.config import (
EvaluationConfig, EvaluationConfig,
get_default_eval_config, get_default_eval_config,
@ -17,7 +16,6 @@ from batdetect2.train.config import TrainingConfig
__all__ = [ __all__ = [
"BatDetect2Config", "BatDetect2Config",
"load_full_config",
"validate_config", "validate_config",
] ]
@ -41,10 +39,3 @@ def validate_config(config: dict | None) -> BatDetect2Config:
return BatDetect2Config() return BatDetect2Config()
return BatDetect2Config.model_validate(config) return BatDetect2Config.model_validate(config)
def load_full_config(
path: PathLike,
field: str | None = None,
) -> BatDetect2Config:
return load_config(path, schema=BatDetect2Config, field=field)

View File

@ -1,4 +1,4 @@
from batdetect2.evaluate.config import EvaluationConfig, load_evaluation_config from batdetect2.evaluate.config import EvaluationConfig
from batdetect2.evaluate.evaluate import DEFAULT_EVAL_DIR, run_evaluate from batdetect2.evaluate.evaluate import DEFAULT_EVAL_DIR, run_evaluate
from batdetect2.evaluate.evaluator import Evaluator, build_evaluator from batdetect2.evaluate.evaluator import Evaluator, build_evaluator
from batdetect2.evaluate.results import save_evaluation_results from batdetect2.evaluate.results import save_evaluation_results
@ -27,7 +27,6 @@ __all__ = [
"TaskConfig", "TaskConfig",
"build_evaluator", "build_evaluator",
"build_task", "build_task",
"load_evaluation_config",
"run_evaluate", "run_evaluate",
"save_evaluation_results", "save_evaluation_results",
] ]

View File

@ -1,16 +1,14 @@
from typing import List from typing import List
from pydantic import Field from pydantic import Field
from soundevent import data
from batdetect2.core.configs import BaseConfig, load_config from batdetect2.core.configs import BaseConfig
from batdetect2.evaluate.tasks import TaskConfig from batdetect2.evaluate.tasks import TaskConfig
from batdetect2.evaluate.tasks.classification import ClassificationTaskConfig from batdetect2.evaluate.tasks.classification import ClassificationTaskConfig
from batdetect2.evaluate.tasks.detection import DetectionTaskConfig from batdetect2.evaluate.tasks.detection import DetectionTaskConfig
__all__ = [ __all__ = [
"EvaluationConfig", "EvaluationConfig",
"load_evaluation_config",
] ]
@ -43,10 +41,3 @@ def get_default_eval_config() -> EvaluationConfig:
] ]
} }
) )
def load_evaluation_config(
path: data.PathLike,
field: str | None = None,
) -> EvaluationConfig:
return load_config(path, schema=EvaluationConfig, field=field)

View File

@ -26,7 +26,7 @@ from matplotlib.figure import Figure
from pydantic import Field from pydantic import Field
from soundevent import data from soundevent import data
from batdetect2.core.configs import BaseConfig, load_config from batdetect2.core.configs import BaseConfig
DEFAULT_LOGS_DIR: Path = Path("outputs") / "logs" DEFAULT_LOGS_DIR: Path = Path("outputs") / "logs"
@ -43,7 +43,6 @@ __all__ = [
"enable_logging", "enable_logging",
"get_image_logger", "get_image_logger",
"get_table_logger", "get_table_logger",
"load_logging_config",
] ]
@ -106,13 +105,6 @@ class AppLoggingConfig(BaseConfig):
inference: LoggerConfig = Field(default_factory=CSVLoggerConfig) inference: LoggerConfig = Field(default_factory=CSVLoggerConfig)
def load_logging_config(
path: data.PathLike,
field: str | None = None,
) -> AppLoggingConfig:
return load_config(path, schema=AppLoggingConfig, field=field)
T = TypeVar("T", bound=LoggerConfig, contravariant=True) T = TypeVar("T", bound=LoggerConfig, contravariant=True)

View File

@ -1,9 +1,6 @@
"""Main entry point for the BatDetect2 Postprocessing pipeline.""" """Main entry point for the BatDetect2 Postprocessing pipeline."""
from batdetect2.postprocess.config import ( from batdetect2.postprocess.config import PostprocessConfig
PostprocessConfig,
load_postprocess_config,
)
from batdetect2.postprocess.nms import non_max_suppression from batdetect2.postprocess.nms import non_max_suppression
from batdetect2.postprocess.postprocessor import ( from batdetect2.postprocess.postprocessor import (
Postprocessor, Postprocessor,
@ -30,6 +27,5 @@ __all__ = [
"Postprocessor", "Postprocessor",
"PostprocessorProtocol", "PostprocessorProtocol",
"build_postprocessor", "build_postprocessor",
"load_postprocess_config",
"non_max_suppression", "non_max_suppression",
] ]

View File

@ -1,12 +1,10 @@
from pydantic import Field from pydantic import Field
from soundevent import data
from batdetect2.core.configs import BaseConfig, load_config from batdetect2.core.configs import BaseConfig
from batdetect2.postprocess.nms import NMS_KERNEL_SIZE from batdetect2.postprocess.nms import NMS_KERNEL_SIZE
__all__ = [ __all__ = [
"PostprocessConfig", "PostprocessConfig",
"load_postprocess_config",
] ]
DEFAULT_DETECTION_THRESHOLD = 0.01 DEFAULT_DETECTION_THRESHOLD = 0.01
@ -51,42 +49,3 @@ class PostprocessConfig(BaseConfig):
ge=0, ge=0,
) )
top_k_per_sec: int = Field(default=TOP_K_PER_SEC, gt=0) top_k_per_sec: int = Field(default=TOP_K_PER_SEC, gt=0)
def load_postprocess_config(
path: data.PathLike,
field: str | None = None,
) -> PostprocessConfig:
"""Load the postprocessing configuration from a file.
Reads a configuration file (YAML) and validates it against the
`PostprocessConfig` schema, potentially extracting data from a nested
field.
Parameters
----------
path : PathLike
Path to the configuration file.
field : str, optional
Dot-separated path to a nested section within the file containing the
postprocessing configuration (e.g., "inference.postprocessing").
If None, the entire file content is used.
Returns
-------
PostprocessConfig
The loaded and validated postprocessing configuration object.
Raises
------
FileNotFoundError
If the config file path does not exist.
yaml.YAMLError
If the file content is not valid YAML.
pydantic.ValidationError
If the loaded configuration data does not conform to the
`PostprocessConfig` schema.
KeyError, TypeError
If `field` specifies an invalid path within the loaded data.
"""
return load_config(path, schema=PostprocessConfig, field=field)

View File

@ -1,10 +1,7 @@
"""Main entry point for the BatDetect2 preprocessing subsystem.""" """Main entry point for the BatDetect2 preprocessing subsystem."""
from batdetect2.audio import TARGET_SAMPLERATE_HZ from batdetect2.audio import TARGET_SAMPLERATE_HZ
from batdetect2.preprocess.config import ( from batdetect2.preprocess.config import PreprocessingConfig
PreprocessingConfig,
load_preprocessing_config,
)
from batdetect2.preprocess.preprocessor import Preprocessor, build_preprocessor from batdetect2.preprocess.preprocessor import Preprocessor, build_preprocessor
from batdetect2.preprocess.spectrogram import MAX_FREQ, MIN_FREQ from batdetect2.preprocess.spectrogram import MAX_FREQ, MIN_FREQ
from batdetect2.preprocess.types import PreprocessorProtocol from batdetect2.preprocess.types import PreprocessorProtocol
@ -17,5 +14,4 @@ __all__ = [
"Preprocessor", "Preprocessor",
"TARGET_SAMPLERATE_HZ", "TARGET_SAMPLERATE_HZ",
"build_preprocessor", "build_preprocessor",
"load_preprocessing_config",
] ]

View File

@ -8,9 +8,8 @@ spectrogram ready for the detection model.
from typing import List from typing import List
from pydantic import Field from pydantic import Field
from soundevent.data import PathLike
from batdetect2.core.configs import BaseConfig, load_config from batdetect2.core.configs import BaseConfig
from batdetect2.preprocess.audio import AudioTransform from batdetect2.preprocess.audio import AudioTransform
from batdetect2.preprocess.spectrogram import ( from batdetect2.preprocess.spectrogram import (
FrequencyConfig, FrequencyConfig,
@ -22,7 +21,6 @@ from batdetect2.preprocess.spectrogram import (
) )
__all__ = [ __all__ = [
"load_preprocessing_config",
"AudioTransform", "AudioTransform",
"PreprocessingConfig", "PreprocessingConfig",
] ]
@ -71,26 +69,3 @@ class PreprocessingConfig(BaseConfig):
frequencies: FrequencyConfig = Field(default_factory=FrequencyConfig) frequencies: FrequencyConfig = Field(default_factory=FrequencyConfig)
size: ResizeConfig = Field(default_factory=ResizeConfig) size: ResizeConfig = Field(default_factory=ResizeConfig)
def load_preprocessing_config(
path: PathLike,
field: str | None = None,
) -> PreprocessingConfig:
"""Load a ``PreprocessingConfig`` from a YAML file.
Parameters
----------
path : PathLike
Path to the YAML configuration file.
field : str, optional
If provided, read the config from a nested field within the
YAML document (e.g. ``"preprocessing"`` to read from a top-level
``preprocessing:`` key).
Returns
-------
PreprocessingConfig
The deserialised preprocessing configuration.
"""
return load_config(path, schema=PreprocessingConfig, field=field)

View File

@ -6,7 +6,7 @@ from batdetect2.targets.classes import (
build_sound_event_encoder, build_sound_event_encoder,
get_class_names_from_config, get_class_names_from_config,
) )
from batdetect2.targets.config import TargetConfig, load_target_config from batdetect2.targets.config import TargetConfig
from batdetect2.targets.rois import ( from batdetect2.targets.rois import (
AnchorBBoxMapperConfig, AnchorBBoxMapperConfig,
ROIMapperConfig, ROIMapperConfig,
@ -56,6 +56,5 @@ __all__ = [
"get_class_names_from_config", "get_class_names_from_config",
"individual", "individual",
"iterate_encoded_sound_events", "iterate_encoded_sound_events",
"load_target_config",
"load_targets", "load_targets",
] ]

View File

@ -2,9 +2,8 @@ from collections import Counter
from typing import List from typing import List
from pydantic import Field, field_validator from pydantic import Field, field_validator
from soundevent import data
from batdetect2.core.configs import BaseConfig, load_config from batdetect2.core.configs import BaseConfig
from batdetect2.targets.classes import ( from batdetect2.targets.classes import (
DEFAULT_CLASSES, DEFAULT_CLASSES,
DEFAULT_DETECTION_CLASS, DEFAULT_DETECTION_CLASS,
@ -14,7 +13,6 @@ from batdetect2.targets.rois import AnchorBBoxMapperConfig, ROIMapperConfig
__all__ = [ __all__ = [
"TargetConfig", "TargetConfig",
"load_target_config",
] ]
@ -44,41 +42,3 @@ class TargetConfig(BaseConfig):
f"{', '.join(duplicates)}" f"{', '.join(duplicates)}"
) )
return v return v
def load_target_config(
path: data.PathLike,
field: str | None = None,
) -> TargetConfig:
"""Load the unified target configuration from a file.
Reads a configuration file (typically YAML) and validates it against the
`TargetConfig` schema, potentially extracting data from a nested field.
Parameters
----------
path : data.PathLike
Path to the configuration file.
field : str, optional
Dot-separated path to a nested section within the file containing the
target configuration. If None, the entire file content is used.
Returns
-------
TargetConfig
The loaded and validated unified target configuration object.
Raises
------
FileNotFoundError
If the config file path does not exist.
yaml.YAMLError
If the file content is not valid YAML.
pydantic.ValidationError
If the loaded configuration data does not conform to the
`TargetConfig` schema (including validation within nested configs
like `ClassesConfig`).
KeyError, TypeError
If `field` specifies an invalid path within the loaded data.
"""
return load_config(path=path, schema=TargetConfig, field=field)

View File

@ -11,7 +11,7 @@ from batdetect2.targets.classes import (
build_sound_event_encoder, build_sound_event_encoder,
get_class_names_from_config, get_class_names_from_config,
) )
from batdetect2.targets.config import TargetConfig, load_target_config from batdetect2.targets.config import TargetConfig
from batdetect2.targets.rois import ( from batdetect2.targets.rois import (
AnchorBBoxMapperConfig, AnchorBBoxMapperConfig,
build_roi_mapper, build_roi_mapper,
@ -276,13 +276,13 @@ def load_targets(
------ ------
FileNotFoundError, yaml.YAMLError, pydantic.ValidationError, KeyError, FileNotFoundError, yaml.YAMLError, pydantic.ValidationError, KeyError,
TypeError TypeError
Errors raised during file loading, validation, or extraction via Errors raised during file loading or validation via
`load_target_config`. ``TargetConfig.load``.
KeyError, ImportError, AttributeError, TypeError KeyError, ImportError, AttributeError, TypeError
Errors raised during the build process by `Targets.from_config` Errors raised during the build process by `Targets.from_config`
(e.g., missing keys in registries, failed imports). (e.g., missing keys in registries, failed imports).
""" """
config = load_target_config( config = TargetConfig.load(
config_path, config_path,
field=field, field=field,
) )

View File

@ -1,5 +1,5 @@
from batdetect2.train.checkpoints import DEFAULT_CHECKPOINT_DIR from batdetect2.train.checkpoints import DEFAULT_CHECKPOINT_DIR
from batdetect2.train.config import TrainingConfig, load_train_config from batdetect2.train.config import TrainingConfig
from batdetect2.train.lightning import ( from batdetect2.train.lightning import (
TrainingModule, TrainingModule,
load_model_from_checkpoint, load_model_from_checkpoint,
@ -12,6 +12,5 @@ __all__ = [
"TrainingModule", "TrainingModule",
"build_trainer", "build_trainer",
"load_model_from_checkpoint", "load_model_from_checkpoint",
"load_train_config",
"run_train", "run_train",
] ]

View File

@ -15,7 +15,7 @@ from batdetect2.audio.clips import get_subclip_annotation
from batdetect2.audio.loader import TARGET_SAMPLERATE_HZ from batdetect2.audio.loader import TARGET_SAMPLERATE_HZ
from batdetect2.audio.types import AudioLoader from batdetect2.audio.types import AudioLoader
from batdetect2.core.arrays import adjust_width from batdetect2.core.arrays import adjust_width
from batdetect2.core.configs import BaseConfig, load_config from batdetect2.core.configs import BaseConfig
from batdetect2.core.registries import ( from batdetect2.core.registries import (
ImportConfig, ImportConfig,
Registry, Registry,
@ -38,7 +38,6 @@ __all__ = [
"WarpConfig", "WarpConfig",
"add_echo", "add_echo",
"build_augmentations", "build_augmentations",
"load_augmentation_config",
"mask_frequency", "mask_frequency",
"mask_time", "mask_time",
"mix_audio", "mix_audio",
@ -686,13 +685,6 @@ def build_augmentations(
return audio_augmentation, spectrogram_augmentation return audio_augmentation, spectrogram_augmentation
def load_augmentation_config(
path: data.PathLike, field: str | None = None
) -> AugmentationsConfig:
"""Load the augmentations configuration from a file."""
return load_config(path, schema=AugmentationsConfig, field=field)
class RandomAudioSource: class RandomAudioSource:
def __init__( def __init__(
self, self,

View File

@ -1,7 +1,6 @@
from pydantic import Field from pydantic import Field
from soundevent import data
from batdetect2.core.configs import BaseConfig, load_config from batdetect2.core.configs import BaseConfig
from batdetect2.evaluate.config import EvaluationConfig from batdetect2.evaluate.config import EvaluationConfig
from batdetect2.train.checkpoints import CheckpointConfig from batdetect2.train.checkpoints import CheckpointConfig
from batdetect2.train.dataset import TrainLoaderConfig, ValLoaderConfig from batdetect2.train.dataset import TrainLoaderConfig, ValLoaderConfig
@ -15,7 +14,6 @@ from batdetect2.train.schedulers import (
__all__ = [ __all__ = [
"TrainingConfig", "TrainingConfig",
"load_train_config",
] ]
@ -52,10 +50,3 @@ class TrainingConfig(BaseConfig):
labels: LabelConfig = Field(default_factory=LabelConfig) labels: LabelConfig = Field(default_factory=LabelConfig)
validation: EvaluationConfig = Field(default_factory=EvaluationConfig) validation: EvaluationConfig = Field(default_factory=EvaluationConfig)
checkpoints: CheckpointConfig = Field(default_factory=CheckpointConfig) checkpoints: CheckpointConfig = Field(default_factory=CheckpointConfig)
def load_train_config(
path: data.PathLike,
field: str | None = None,
) -> TrainingConfig:
return load_config(path, schema=TrainingConfig, field=field)

View File

@ -177,8 +177,6 @@ def test_preprocessor_with_fix_duration_audio_transform():
def test_preprocessor_yaml_roundtrip(tmp_path: pathlib.Path): def test_preprocessor_yaml_roundtrip(tmp_path: pathlib.Path):
"""PreprocessingConfig serialised to YAML and reloaded should produce """PreprocessingConfig serialised to YAML and reloaded should produce
a functionally identical preprocessor.""" a functionally identical preprocessor."""
from batdetect2.preprocess.config import load_preprocessing_config
config = PreprocessingConfig( config = PreprocessingConfig(
stft=STFTConfig(window_duration=0.002, window_overlap=0.75), stft=STFTConfig(window_duration=0.002, window_overlap=0.75),
frequencies=FrequencyConfig(min_freq=10_000, max_freq=120_000), frequencies=FrequencyConfig(min_freq=10_000, max_freq=120_000),
@ -188,7 +186,7 @@ def test_preprocessor_yaml_roundtrip(tmp_path: pathlib.Path):
yaml_path = tmp_path / "preprocess_config.yaml" yaml_path = tmp_path / "preprocess_config.yaml"
yaml_path.write_text(config.to_yaml_string()) yaml_path.write_text(config.to_yaml_string())
loaded_config = load_preprocessing_config(yaml_path) loaded_config = PreprocessingConfig.load(yaml_path)
preprocessor = build_preprocessor( preprocessor = build_preprocessor(
loaded_config, input_samplerate=SAMPLERATE loaded_config, input_samplerate=SAMPLERATE

View File

@ -3,7 +3,7 @@ from pathlib import Path
from soundevent import data, terms from soundevent import data, terms
from batdetect2.targets import build_targets, load_target_config from batdetect2.targets import TargetConfig, build_targets
def test_can_override_default_roi_mapper_per_class( def test_can_override_default_roi_mapper_per_class(
@ -42,7 +42,7 @@ def test_can_override_default_roi_mapper_per_class(
""" """
config_path = create_temp_yaml(yaml_content) config_path = create_temp_yaml(yaml_content)
config = load_target_config(config_path) config = TargetConfig.load(config_path)
targets = build_targets(config) targets = build_targets(config)
geometry = data.BoundingBox(coordinates=[0.1, 12_000, 0.2, 18_000]) geometry = data.BoundingBox(coordinates=[0.1, 12_000, 0.2, 18_000])
@ -105,7 +105,7 @@ def test_roi_is_recovered_roundtrip_even_with_overriders(
""" """
config_path = create_temp_yaml(yaml_content) config_path = create_temp_yaml(yaml_content)
config = load_target_config(config_path) config = TargetConfig.load(config_path)
targets = build_targets(config) targets = build_targets(config)
geometry = data.BoundingBox(coordinates=[0.1, 12_000, 0.2, 18_000]) geometry = data.BoundingBox(coordinates=[0.1, 12_000, 0.2, 18_000])