Skip to content

Commit c442c9d

Browse files
Major restructure of pgmatlab for v2
- Move code into object-oriented structure, whilst keeeping loadPamguardBinaryFile, loadPamguardBinaryFolder and loadPamguardMultiFile the same. - Add a testing suite to compare the new v2 code with the 'legacy' v1 code. - Integrate the testing suite into GitHub actions for an automated testing and distribution workflow.
1 parent cca40bc commit c442c9d

File tree

231 files changed

+2962
-204
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

231 files changed

+2962
-204
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# This workflow will automatically create a ZIP file
2+
# of the distribution files, and add them to a GitHub
3+
# release. It only runs, on creation of the GitHub
4+
# release.
5+
6+
name: Build Package
7+
8+
on:
9+
release:
10+
types: [published]
11+
12+
permissions:
13+
contents: write
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Zip code to distribute
24+
run: |
25+
zip -r "pgmatlab-${{ github.event.release.tag_name }}.zip" pgmatlab/* LICENSE README.md
26+
27+
- name: Upload code to distribute
28+
uses: actions/upload-artifact@v4
29+
with:
30+
name: dist-files
31+
path: "pgmatlab-${{ github.event.release.tag_name }}.zip"
32+
33+
- name: Append distribution code to release
34+
uses: softprops/action-gh-release@v2
35+
with:
36+
files: "pgmatlab-${{ github.event.release.tag_name }}.zip"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: MATLAB Testing
2+
3+
# Controls when the workflow will run
4+
on:
5+
# Triggers the workflow on push or pull request events but only for the "main" branch
6+
push:
7+
branches: [ "dev" ]
8+
pull_request:
9+
branches: [ "dev" ]
10+
11+
# Allows you to run this workflow manually from the Actions tab
12+
workflow_dispatch:
13+
14+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
15+
jobs:
16+
# This workflow contains a single job called "build"
17+
build:
18+
# The type of runner that the job will run on
19+
runs-on: ${{ matrix.os }}
20+
strategy:
21+
matrix:
22+
matlab-version: [r2020a, r2021a, r2022a, r2023a, r2025a]
23+
os: [ubuntu-latest, windows-latest, macos-latest]
24+
25+
26+
steps:
27+
- name: Check out repository
28+
uses: actions/checkout@v4
29+
30+
- name: Set up MATLAB
31+
uses: matlab-actions/setup-matlab@v2.1.2
32+
with:
33+
version: ${{ matrix.matlab-version }}
34+
35+
- name: Run MATLAB Tests
36+
uses: matlab-actions/run-tests@v2.1.2
37+
with:
38+
select-by-folder: tests

pgmatlab/.MATLABDriveTag

Lines changed: 0 additions & 1 deletion
This file was deleted.

pgmatlab/Array/.MATLABDriveTag

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
classdef BeamFormer < StandardAnnotation
3+
methods
4+
function obj = BeamFormer(); end
5+
function [data, selState] = read(obj, fid, data, fileInfo, anLength, anVersion);
6+
[data, selState] = read@StandardAnnotation(obj, fid, data, fileInfo, anLength, anVersion);
7+
8+
data.hydrophones = fread(fid, 1, 'uint32');
9+
data.arrayType = fread(fid, 1, 'int16');
10+
data.localisationContent = fread( fid, 1, 'uint32');
11+
data.nAngles = fread(fid, 1, 'int16');
12+
data.angles = fread(fid, data.nAngles, 'float32');
13+
end
14+
end
15+
end
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
classdef Bearing < StandardAnnotation
3+
methods
4+
function obj = Bearing(); end
5+
function [data, selState] = read(obj, fid, data, fileInfo, anLength, anVersion);
6+
[data, selState] = read@StandardAnnotation(obj, fid, data, fileInfo, anLength, anVersion);
7+
8+
data.algorithmName = readJavaUTFString(fid);
9+
data.version = annotationVersion;
10+
data.hydrophones = fread(fid, 1, 'uint32');
11+
data.arrayType = fread(fid, 1, 'int16');
12+
data.localisationContent = fread( fid, 1, 'uint32');
13+
data.nAngles = fread(fid, 1, 'int16');
14+
data.angles = fread(fid, data.nAngles, 'float32');
15+
data.nErrors = fread(fid, 1, 'int16');
16+
data.errors = fread(fid, data.nErrors, 'float32');
17+
if (annotationVersion >= 2)
18+
nAng = fread(fid, 1, 'int16');
19+
data.refAngles = fread(fid, nAng, 'float32')
20+
end
21+
end
22+
end
23+
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
classdef ClickClsFr < StandardAnnotation
2+
methods
3+
function obj = ClickClsFr(); end
4+
function [data, selState] = read(obj, fid, data, fileInfo, anLength, anVersion);
5+
[data, selState] = read@StandardAnnotation(obj, fid, data, fileInfo, anLength, anVersion);
6+
7+
nclassifications = fread(fid, 1, 'int16');
8+
for i = 1:nclassifications
9+
data.classify_set(i) = fread(fid, 1, 'int16');
10+
end
11+
end
12+
end
13+
end
14+

pgmatlab/core/annotations/@DL/DL.m

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
classdef DL < StandardAnnotation
2+
properties
3+
name = 'dlclassification';
4+
end
5+
6+
methods (Access = private)
7+
function modeldata = readModelData(~, fid)
8+
9+
modeltype = fread(fid, 1, 'char'); % bye in Java
10+
11+
isbinary = fread(fid, 1, 'char'); % bye in Java
12+
isbinary = isbinary~=0; % boolean is stored as byte in Java
13+
scale = fread(fid, 1, 'float'); % the scale for prediciton results - short in Java
14+
nspecies = fread(fid, 1, 'int16'); % the scale for prediciton results - short in Java
15+
16+
% read prediciton results
17+
tempdata=-1*ones(length(nspecies),1);
18+
for j=1:nspecies
19+
tempdata(j) = fread(fid, 1, 'int16')/scale;
20+
end
21+
22+
% get the class name IDs
23+
nclass = fread(fid, 1, 'int16'); % the number of class names.classnames
24+
classnames=-1*ones(length(nclass),1);
25+
for j=1:nclass
26+
classnames(j) = fread(fid, 1, 'int16');
27+
end
28+
29+
switch (modeltype)
30+
31+
case 0 % generic deep learning annotation
32+
modeldata.predictions = tempdata;
33+
modeldata.classID = classnames;
34+
modeldata.isbinary = isbinary;
35+
modeldata.type = modeltype;
36+
case 1 % Sound Spot classifier.
37+
% Sound spot
38+
modeldata.predictions = tempdata;
39+
modeldata.classID = classnames;
40+
modeldata.isbinary = isbinary;
41+
modeldata.type = modeltype;
42+
43+
case 2 % dummy result
44+
modeldata.predictions = [];
45+
modeldata.type = 'dummy';
46+
end
47+
end
48+
end
49+
50+
methods
51+
function obj = DL(); end
52+
function [data, selState] = read(obj, fid, fileInfo, anLength, anVersion);
53+
nummodels = fread(fid, 1, 'int16'); % short in Java
54+
55+
% disp(['Num models: ' num2str(nummodels)])
56+
% read the data from each model.
57+
% data = zeros(1, nummodels);
58+
for i=1:nummodels
59+
data(i) = obj.readModelData(fid);
60+
end
61+
end
62+
end
63+
end
64+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
classdef MatchCls < StandardAnnotation
2+
methods
3+
function obj = MatchCls(); end
4+
function [data, selState] = read(obj, fid, data, fileInfo, anLength, anVersion);
5+
[data, selState] = read@StandardAnnotation(obj, fid, data, fileInfo, anLength, anVersion);
6+
7+
if (anVersion==1)
8+
%the threshold value. This is used to classify the clicks.
9+
threshold = fread(fid, 1, 'double');
10+
11+
%the maximum correlation between the match template and the click
12+
matchcorr = fread(fid, 1, 'double');
13+
14+
%the max correlation value between the reject template and the click.
15+
rejectcorr = fread(fid, 1, 'double');
16+
17+
data = [threshold matchcorr rejectcorr];
18+
19+
end
20+
21+
% new version with multiple templates.
22+
if (anVersion==2)
23+
%read the number of templates there are
24+
ntemplates = fread(fid, 1, 'int16'); % short in Java
25+
26+
n=1;
27+
data=zeros(ntemplates,3); % pre allocate the data array,
28+
for i=1:ntemplates
29+
30+
%the threshold value. This is used to classify the clicks.
31+
threshold = fread(fid, 1, 'double');
32+
33+
%the maximum correlation between the match template and the click
34+
matchcorr = fread(fid, 1, 'double');
35+
36+
%the max correlation value between the reject template and the click.
37+
rejectcorr = fread(fid, 1, 'double');
38+
39+
data(n,1) = threshold;
40+
data(n,2) = matchcorr;
41+
data(n,3) = rejectcorr;
42+
n=n+1;
43+
44+
end
45+
end
46+
end
47+
end
48+
end
49+
50+
51+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
classdef RWUDP < StandardAnnotation
2+
methods
3+
function obj = RWUDP(); end
4+
function [data, selState] = read(obj, fid, data, fileInfo, anLength, anVersion);
5+
[data, selState] = read@StandardAnnotation(obj, fid, data, fileInfo, anLength, anVersion);
6+
7+
data.label = readJavaUTFString(fid);
8+
data.method = readJavaUTFString(fid);
9+
data.score = fread(fid, 1, 'float32');
10+
end
11+
end
12+
end
13+
14+
15+

0 commit comments

Comments
 (0)