Skip to content

Commit ac3132a

Browse files
authored
Merge pull request #1 from simmsa/acoustics-standardization
Acoustics Module Standardization
2 parents 8b3ac90 + 536d37a commit ac3132a

29 files changed

Lines changed: 1939 additions & 566 deletions

examples/acoustics_example.html

Lines changed: 622 additions & 0 deletions
Large diffs are not rendered by default.

examples/acoustics_example.m

Lines changed: 213 additions & 103 deletions
Large diffs are not rendered by default.

examples/acoustics_example.mlx

-44.2 KB
Binary file not shown.
Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,47 @@
11
function spsd_cal = apply_calibration(spsd,sensitivity_curve, fill_value)
22

3-
% Applies custom calibration to spectral density values.
4-
%
3+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4+
%
5+
% Apply custom calibration to spectral density values
6+
%
57
% Parameters
6-
% ----------
7-
% spsd: struct
8-
% Mean square sound pressure spectral density in V^2/Hz.
9-
% sensitivity_curve: matrix
10-
% Calibrated sensitivity curve in units of dB rel 1 V^2/uPa^2.
11-
% First column should be frequency, second column should be calibration values.
12-
% fill_value: float or int
13-
% Value with which to fill missing values from the calibration curve,
14-
% in units of dB rel 1 V^2/uPa^2.
15-
%
8+
% ------------
9+
% spsd: struct
10+
% Mean square sound pressure spectral density in V^2/Hz
11+
% spsd.data : Spectral density data [V^2/Hz]
12+
% spsd.freq : Frequency vector [Hz]
13+
% spsd.time : Time vector (if time series)
14+
% sensitivity_curve: matrix
15+
% Calibrated sensitivity curve in units of dB rel 1 V^2/uPa^2
16+
% First column should be frequency, second column should be calibration values
17+
% fill_value: float
18+
% Value with which to fill missing values from the calibration curve [dB rel 1 V^2/uPa^2]
19+
%
1620
% Returns
17-
% -------
18-
% spsd_calibrated: struct
19-
% Spectral density in Pa^2/Hz, indexed by time and frequency.
21+
% ---------
22+
% spsd_cal: struct
23+
% Calibrated spectral density in Pa^2/Hz, indexed by time and frequency
24+
% spsd_cal.data : Calibrated spectral density data [Pa^2/Hz]
25+
% spsd_cal.freq : Frequency vector [Hz]
26+
% spsd_cal.time : Time vector (if time series)
27+
% spsd_cal.name : Data name
28+
% spsd_cal.units : Data units
29+
%
30+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2031

2132
arguments (Input)
2233
spsd struct
23-
sensitivity_curve
24-
fill_value {mustBeNumeric}
34+
sensitivity_curve {mustBeNumeric, mustBeFinite}
35+
fill_value {mustBeNumeric, mustBeFinite}
2536
end
2637

2738
arguments (Output)
2839
spsd_cal struct
2940
end
3041

31-
% check if sensitivity_curve is a matrix
32-
if ~ismatrix(sensitivity_curve) || size(sensitivity_curve,2) ~= 2
33-
error('sensitivity_curve must be a matrix with two columns!')
34-
end
35-
36-
% check if 'freq' exists in spsd
37-
if ~isfield(spsd, "freq")
38-
error('"freq" is missing in spsd!')
39-
end
42+
% Validate spsd structure
43+
validate_spsd_struct(spsd, 'apply_calibration', ...
44+
'required_fields', {{'freq'}});
4045

4146
spsd_cal = spsd;
4247

@@ -55,4 +60,4 @@
5560
spsd_cal.name = "Calibrated Sound Pressure Spectral Density";
5661
spsd_cal.units = "Pa^2/Hz";
5762

58-
end
63+
end

mhkit/acoustics/analysis/band_aggregate.m

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,41 @@
11
function out = band_aggregate(spsdl, octave, fmin, fmax, method)
22

3-
% Reorganizes spectral density level frequency tensor into
4-
% fractional octave bands and applies a function to them.
5-
%
3+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4+
%
5+
% Reorganize spectral density level frequency tensor into fractional octave bands and applies a function to them
6+
%
67
% Parameters
7-
% ----------
8-
% spsdl: struct
9-
% Mean square sound pressure spectral density level in dB rel 1 uPa^2/Hz
10-
% octave: [int, int]
11-
% Octave and octave base to subdivide spectral density level by. Set to
12-
% octave base to 2 for the true octave band; set to base 10 for
13-
% the decidecade octave band.
14-
% Default = [3, 2] (true third octave)
15-
% fmin: int
16-
% Lower frequency band limit (lower limit of the hydrophone). Default: 10 Hz
17-
% fmax: int
18-
% Upper frequency band limit (Nyquist frequency). Default: 100000 Hz
19-
% method:
20-
% Method to run on the binned data. Can be a string (e.g., "median") or a dict
21-
% where the key is the method and the value is its argument (e.g., {"quantile": 0.25}).
22-
% Options: [median, mean, min, max, sum, quantile, std, var, count, map]
23-
%
8+
% ------------
9+
% spsdl: struct
10+
% Mean square sound pressure spectral density level in dB rel 1 uPa^2/Hz
11+
% spsdl.data : Spectral density level data [dB rel 1 uPa^2/Hz]
12+
% spsdl.freq : Frequency vector [Hz]
13+
% spsdl.time : Time vector
14+
% spsdl.fs : Sampling frequency [Hz]
15+
% octave: (1,2) vector
16+
% Octave and octave base to subdivide spectral density level by
17+
% Set octave base to 2 for true octave band; set to base 10 for decidecade octave band
18+
% Default = [3, 2] (true third octave)
19+
% fmin: float
20+
% Lower frequency band limit (lower limit of the hydrophone) [Hz]
21+
% fmax: float
22+
% Upper frequency band limit (Nyquist frequency) [Hz]
23+
% method: string or cell
24+
% Method to run on the binned data. Can be a string (e.g., "median") or a cell
25+
% where the first element is the method and the second is its argument
26+
% Options: [median, mean, min, max, sum, quantile, std, var, count, map]
27+
%
2428
% Returns
25-
% -------
26-
% out: struct
27-
% Frequency band-averaged sound pressure spectral density level [dB re 1 uPa^2/Hz]
28-
% indexed by time and frequency
29+
% ---------
30+
% out: struct
31+
% Frequency band-averaged sound pressure spectral density level
32+
% out.data : Band-averaged spectral density level [dB re 1 uPa^2/Hz]
33+
% out.freq : Center frequencies of bands [Hz]
34+
% out.time : Time vector
35+
% out.name : Data name
36+
% out.units : Data units
37+
%
38+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2939

3040

3141
arguments (Input)
@@ -40,17 +50,21 @@
4050
out struct
4151
end
4252

53+
% Validate spsdl structure
54+
validate_spsdl_struct(spsdl, 'band_aggregate', ...
55+
'required_fields', {{'data', 'freq', 'time', 'name', 'units', 'fs'}});
56+
4357
if ~isnumeric(octave) || numel(octave) ~= 2
44-
error("'octave' must be a vector of two positive integers.");
58+
error('MHKiT:acoustics:band_aggregate:InvalidOctave', 'octave must be a vector of two positive integers');
4559
end
4660
if any(octave <= 0)
47-
error("'octave' must contain positive integers.");
61+
error('MHKiT:acoustics:band_aggregate:InvalidOctave', 'octave must contain positive integers');
4862
end
4963
if ~isnumeric(fmin) || fmin <= 0
50-
error("'fmin' must be a positive integer.");
64+
error('MHKiT:acoustics:band_aggregate:InvalidFrequency', 'fmin must be a positive number');
5165
end
5266
if ~isnumeric(fmax) || fmax <= fmin
53-
error("'fmax' must be greater than 'fmin'.");
67+
error('MHKiT:acoustics:band_aggregate:InvalidFrequency', 'fmax must be greater than fmin');
5468
end
5569

5670
fmax = fmax_warning(spsdl.fs/2, fmax);
@@ -81,4 +95,4 @@
8195
out.name = spsdl.name;
8296
out.units = spsdl.units;
8397

84-
end
98+
end

mhkit/acoustics/analysis/band_sound_pressure_level.m

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,35 @@
11
function mspl = band_sound_pressure_level(spsd, octave, base, fmin, fmax)
22

3-
% Calculates band-averaged sound pressure levels from the
4-
% mean square sound pressure spectral density (SPSD).
5-
%
3+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4+
%
5+
% Calculate band-averaged sound pressure levels from the mean square sound pressure spectral density (SPSD)
6+
%
67
% Parameters
7-
% ----------
8-
% spsd: struct
9-
% Mean square sound pressure spectral density in [Pa^2/Hz]
10-
% octave: int
11-
% Octave subdivision (1 = full octave, 3 = third-octave, etc.)
12-
% base: int
13-
% Octave base subdivision (2 = true octave, 10 = decade octave, etc.)
14-
% fmin : int, optional
15-
% Lower frequency band limit (lower limit of the hydrophone).
16-
% Default is 10 Hz.
17-
% fmax : int, optional
18-
% Upper frequency band limit (Nyquist frequency).
19-
% Default is 100,000 Hz.
20-
%
8+
% ------------
9+
% spsd: struct
10+
% Mean square sound pressure spectral density in [Pa^2/Hz]
11+
% spsd.data : Spectral density data [Pa^2/Hz]
12+
% spsd.freq : Frequency vector [Hz]
13+
% spsd.time : Time vector
14+
% spsd.fs : Sampling frequency [Hz]
15+
% octave: float
16+
% Octave subdivision (1 = full octave, 3 = third-octave, etc.)
17+
% base: float
18+
% Octave base subdivision (2 = true octave, 10 = decade octave, etc.)
19+
% fmin: float
20+
% Lower frequency band limit (lower limit of the hydrophone) [Hz]
21+
% fmax: float
22+
% Upper frequency band limit (Nyquist frequency) [Hz]
23+
%
2124
% Returns
22-
% -------
23-
% mspl: struct
24-
% Sound pressure level [dB re 1 uPa] indexed by time and frequency of specified bandwidth
25+
% ---------
26+
% mspl: struct
27+
% Sound pressure level [dB re 1 uPa] indexed by time and frequency of specified bandwidth
28+
% mspl.data : Sound pressure level data [dB re 1 uPa]
29+
% mspl.freq : Center frequencies of bands [Hz]
30+
% mspl.time : Time vector
31+
%
32+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2533

2634
arguments (Input)
2735
spsd struct
@@ -35,6 +43,10 @@
3543
mspl struct
3644
end
3745

46+
% Validate spsd structure
47+
validate_spsd_struct(spsd, 'band_sound_pressure_level', ...
48+
'required_fields', {{'freq', 'time', 'fs'}});
49+
3850
reference = 1e-12; % Pa^2, = 1 uPa^2
3951

4052
fmax = fmax_warning(spsd.fs/2, fmax);
@@ -66,4 +78,4 @@
6678
mspl.freq = band.center_freq;
6779
mspl.time = spsd.time;
6880

69-
end
81+
end
Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,43 @@
11
function [octave_bins, band] = create_frequency_bands(octave, base, fmin, fmax)
22

3-
% Calculates frequency bands based on the specified octave, minimum and
4-
% maximum frequency limits.
3+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4+
%
5+
% Calculate frequency bands based on the specified octave, minimum and maximum frequency limits
56
%
67
% Parameters
7-
% ----------
8-
% octave: int
9-
% Octave to subdivide spectral density level by.
10-
% base : int, optional
11-
% Octave base. Set to 2 for the true octave band; set to base 10 for
12-
% the decidecade octave band. Default: 2
13-
% fmin : int, optional
14-
% Lower frequency band limit (lower limit of the hydrophone). Default is 10 Hz.
15-
% fmax : int, optional
16-
% Upper frequency band limit (Nyquist frequency). Default is 100,000 Hz.
8+
% ------------
9+
% octave: double
10+
% Octave to subdivide spectral density level by
11+
% base: double, optional
12+
% Octave base. Set to 2 for the true octave band; set to base 10 for
13+
% the decidecade octave band. Default: 2
14+
% fmin: double, optional
15+
% Lower frequency band limit (lower limit of the hydrophone). Default is 10 Hz
16+
% fmax: double, optional
17+
% Upper frequency band limit (Nyquist frequency). Default is 100,000 Hz
1718
%
1819
% Returns
19-
% -------
20-
% octave_bins: array
21-
% Array of octave bin edges
22-
% band: struct
23-
% Struct containing the frequency band edges and center frequency
20+
% ---------
21+
% octave_bins: array
22+
% Array of octave bin edges
23+
% band: structure
24+
% band.center_freq : Center frequencies [Hz]
25+
% band.lower_limit : Lower frequency limits [Hz]
26+
% band.upper_limit : Upper frequency limits [Hz]
27+
%
28+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29+
30+
arguments (Input)
31+
octave double {mustBeFinite, mustBePositive}
32+
base double {mustBeFinite, mustBePositive} = 2
33+
fmin double {mustBeFinite, mustBePositive} = 10
34+
fmax double {mustBeFinite, mustBePositive} = 100000
35+
end
36+
37+
arguments (Output)
38+
octave_bins double
39+
band struct
40+
end
2441

2542
bandwidth = base^(1 / octave);
2643
half_bandwidth = base^(1 / (octave * 2));
@@ -40,4 +57,4 @@
4057
band.lower_limit = lower_limit;
4158
band.upper_limit = upper_limit;
4259

43-
end
60+
end

0 commit comments

Comments
 (0)