This page describes the internal architecture, deployment workflow, plugin system, and extension mechanisms used by SAMLab.
Explore recordings
Open WAV files, navigate by time, zoom by frequency, adjust dynamic range, and play segments directly from the interface.
Annotate events
Select regions in time and frequency, assign categories, edit or delete annotations, and save deployment-level annotation CSV files.
Run analyses
Choose one or more automatic analysis plugins, view detected events, and export deployment indicators and detected event tables.
How SAMLab is structured
SAMLab is structured around a PySide6 graphical interface, reusable processing modules, and an extensible plugin system. Computational work is moved into Qt worker threads so the interface remains responsive while plugins run.
Main application
samlab.py defines the MainWindow class and coordinates the main application workflow, including: menu actions, spectrogram visualisation, deployment navigation, event browsing, audio playback, plugin execution, and manual annotation tools.
The graphical interface integrates matplotlib visualisation widgets with PySide6 controls to provide interactive exploration of large underwater acoustic recordings.
Core modules
The modules/ package contains the reusable components used throughout the application, including: graphical dialogs, spectrogram and navigation drawing routines, deployment analysis workflows, shared data models, plugin selection interfaces, status and progress windows, and multithreaded worker classes.
Workers Threads
Long-running computational tasks are executed in Qt worker threads to prevent the graphical interface from freezing during deployment analyses or plugin execution. Worker classes are responsible for:
executing plugins asynchronously, updating progress windows, handling cancellation requests, and returning detected events and indicators back to the main application thread.
This architecture allows SAMLab to process large deployments while maintaining an interactive user experience.
SAMLab user Workflow
1 Open audio
Use File → Open File… or double click in the Deployment Navigation Graph of a deployment to load a WAV file into SAMLab.
2 Inspect
Move through time, zoom into a frequency band of the spectrogram representation, adjust FFT size, dynamic range, etc.
3 Analyze
Use Analyze → Analyze current File… or Analyze Deployment…, choose specific plugins for acoustic event detection, and review automatically detected events.
4 Annotate
Use manual annotation tools to draw time-frequency boxes, classify acoustic events, and save annotations.
Deployment Analysis workflow
Deployment analysis loads deployment_info.mat, scans all *.WAV files within a deployment directory1, executes the selected analysis plugins on each recording, exports deployment indicators to deployment_indicators.csv, and stores detected events in the HDF5 file detected_events.h5.
The workflow also supports:
- interrupted-analysis recovery,
- partial reprocessing,
- resumable deployment analyses,
- deployment-level visualisation of extracted indicators.
Deployment indicators can later be visualised through the deployment navigation interface for rapid inspection of long-term acoustic trends.
Plugin architecture
Analysis plugins are located in the analysis_plugins/ package and are dynamically discovered through:
plugin_loader.discover_plugins(analysis_plugins)
Each plugin exposes metadata such as:
- plugin name,
- description,
- version,
- author,
- and exported indicators.
This metadata is used to automatically populate the plugin selection interface and integrate plugin outputs into deployment analyses and event visualisation workflows.
Plugins can operate either on:
- individual recordings,
- or complete deployment processing pipelines.
Plugins always return Detected Events and Indicators. Indicators consist of summarized event information, such as the number of events of a given type, and are used for graphical navigation through the deployment in the Deployment Navigation Graph.
Adding a new analysis plugin
A SAMLab analysis plugin is a Python class with metadata and an analyze() method. The method receives the audio array, sampling rate, DSP calibration, band calibration, and a verbosity flag. It returns two objects: detected events and file-level indicators.
1. Create a new file
Place your plugin in the analysis_plugins/ package, for example:
analysis_plugins/my_detector.py
2. Implement the plugin class
import numpy as np
import pandas as pd
import time
class MyDetector:
name = "My Detector"
description = "Detects a custom acoustic event and reports one indicator."
version = "1.0.0"
indtag = ["MyDetector_Count [#]"] # one indicator.
# Creates one column in the CSV per returned indicator.
# The text between [] is used for units
evtype='MDE' # Compact label for event type
evtag='My Detector Event' # Human-readable event type in spectrogram view
def analyze(self, x, fs, dsp, bands, verbose=False):
"""
Parameters
----------
x : np.ndarray
Audio samples, normally as float64 counts.
fs : int or float
Sampling frequency in Hz.
dsp : DSP or dict-like
Recorder calibration/gain information.
bands : Bands or dict-like
Frequency-band calibration information.
verbose : bool
Print progress messages when True.
Returns
-------
events : pandas.DataFrame
Rows describing detected events, or an empty DataFrame.
indicators : list[float]
File-level values matching the plugin's indtag list.
"""
start_time = time.time()
if verbose:
print("Running My Detector...")
# Example placeholder algorithm: detect samples above a threshold.
x = np.asarray(x, dtype=float)
threshold = np.mean(np.abs(x)) + 4 * np.std(x)
hits = np.flatnonzero(np.abs(x) > threshold)
events = []
if hits.size:
start = int(hits[0])
end = int(hits[-1])
events.append({
"start": start,
"end": end,
"fmin": 0.0,
"fmax": fs / 2,
"f0": np.nan,
"BW": np.nan,
"ICI": np.nan,
"SPL": np.nan,
"score": 1,
"user": np.nan,
"type": "MyDetector",
"tag": "MYD",
"Tdata": np.nan,
"Fdata": np.nan,
})
if verbose:
print(f"Analysis finished in {time.time()-start_time:.2f} s")
return pd.DataFrame(events), [float(len(events))]
3. Pandas “detected event” fields expected by SAMLab
| Field | Meaning |
start, end | Event limits in samples, not seconds. |
fmin, fmax | Frequency bounds in Hz. |
f0, BW, ICI, SPL | Event central frequency, Bandwidth, Inter Event Interval, and Sound Pressure level (used by the miniature event navigation graph and combo box). |
score | Detection score or confidence value. |
,evtype | Human-readable event tag to be drawn on the spectrogram view, and compact event label for event reference. |
Tdata, Fdata | Optional contour points for time-frequency tracks; use np.nan if not applicable. |
4. Match returned indicators to indtag elements
If your plugin declares two indicator tags indtag = ["Number of events A [#]", "Number of events B [#]"], return exactly two indicator values, for example [value_a, value_b]. These values become extra columns in deployment_indicators.csv.
5. Test the plugin
Import test
Start SAMLab and check that your plugin appears in the selector with the right name, description, and version.
Single file
Run it on a short WAV file and confirm that the event list, spectrogram boxes, and indicators look correct.
Deployment
Run it on a small deployment folder and check CSV/HDF5 outputs.
Interrupt/resume
For long analyses, verify that interrupted deployment analysis resumes without corrupting results.
Plugin programming rules
- Do not modify
xin place unless you intentionally want downstream plugins to see the modified signal. Preferx = np.asarray(x, dtype=float). - Return an empty
DataFramerather thanNonewhen no events are found. - Keep long loops interrupt-friendly where possible; SAMLab can request interruption between plugins and files.
- Use printed progress messages sparingly; they appear in the status window when verbose mode is enabled.
- Keep metadata stable. Changing
nameortagaffects resume logic and CSV compatibility.
GPLv3 licensing
Open-source distribution
SAMLab can be distributed under the GNU General Public License v3. This means users may run, study, share, and modify the software under the GPLv3 terms.
Commercial licensing
The source headers also mention that commercial licenses are available. Keep that notice if you distribute a dual-licensed version.
This page is not legal advice. Before public release, include a complete LICENSE file containing the GPLv3 text, preserve copyright notices, and decide whether plugins are distributed as GPLv3 code, separate optional extensions, or dual-licensed modules.
SAMLab — Submarine Acoustic Monitoring Laboratory
Copyright © 2026 Universitat Politècnica de València and contributors.
- Deployment requirement: a deployment folder should contain
deployment_info.matplus WAV files named with date and time, for exampleXXX_N_1_YYYYMMDD_HHMMSS.WAV. ↩︎