-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkooguTableToDetection.m
More file actions
112 lines (102 loc) · 3.6 KB
/
Copy pathkooguTableToDetection.m
File metadata and controls
112 lines (102 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
function t = kooguTableToDetection(ravenFile,soundFolder,siteCode,classification)
%t = ravenTableToStruct(ravenFile,soundFolder,siteCode,classification)
% Load a Raven Selection table of annotations, and convert this into a
% Matlab struct, 'a', with some basic metadata for an acoustic detection.
% The metadata in Raven Selection Tables is highly variable, and here we
% assume that each Selection Table contains the following columns/fields:
% Begin Date Time,
% Delta Time (s),
% Low Freq (Hz),
% High Freq (Hz)
% To make the detection data structure a bit more useful, we optionally add
% a siteCode to identify the recording, optionally link each detection to a
% soundFolder to facilitate loading acoustic data, and optionally add a
% classification code.
if nargin < 4
classification = '';
end
if nargin < 3
siteCode = '';
end
if nargin < 2
soundFolder = '';
end
warning('off','MATLAB:table:ModifiedVarnames');
if istable(ravenFile)
t = ravenFile;
else
t = readtable(ravenFile,'delimiter','\t');
if width(t) < 4 % Something is wrong if less than 4 columns,
% try a different delimiter
t = readtable(ravenFile,'delimiter',',');
end
end
parforThreshold = 20e3; % Use parfor if height(t) > this many detections
nDetect = height(t);
if (nDetect == 0)
return;
end
%% Create XBAT-like fields to facilitate compatibility with XBAT 'events'
if strcmp(t.Properties.VariableNames,'Channel')
t.channel = t.Channel;
else
t.channel = ones(height(t),1);
end
try % First Check soundFolders
t0 = zeros(height(t),1);
wavInfo = wavFolderInfo(soundFolder);
fnames = {wavInfo.fname};
startDates = [wavInfo.startDate];
offsets = [t.FileOffset_s_];
beginFile = t.BeginFile;
if height(t) > parforThreshold
parfor i = 1:height(t)
ix = contains(fnames,beginFile(i));
t0(i) = startDates(ix)+offsets(i)/86400;
end
else
for i = 1:height(t)
ix = contains(fnames,beginFile(i));
t0(i) = startDates(ix)+offsets(i)/86400;
end
end
t.t0 = t0;
catch
try % If soundFolder are problematic try getting startDates from
% BeginFile
startDates = cellfun(@guessFileNameTimestamp,t.BeginFile);
offsets = [t.FileOffset_s_];
t.t0 = startDates+offsets/86400;
catch
% TODO: add some graceful error handling above for situation where
% t contains detections outside of soundFolder
keyboard
end
end
t.DeltaTime_s_ = t.EndTime_s_ - t.BeginTime_s_;
t.tEnd = t.t0+t.DeltaTime_s_/86400; % Matlab datenum
t.duration = (t.tEnd-t.t0)*86400; % Duration in seconds
% Older versions of Koogu
if any(strcmpi(t.Properties.VariableNames,'LowFrequency_Hz_'))
t.fLow = t.LowFrequency_Hz_;
else % Newer versions of Koogu
t.fLow = t.LowFreq_Hz_;
end
if any(strcmpi(t.Properties.VariableNames,'HighFrequency_Hz_'))
t.fHigh= t.HighFrequency_Hz_;
else
t.fHigh= t.HighFreq_Hz_;
end
t.freq = [t.fLow t.fHigh]; % Frequency vector in Hz
t.soundFolder = cellstr(repmat(soundFolder,nDetect,1)); % Location of audio files for this detection
t.siteCode = cellstr(repmat(siteCode,nDetect,1)); % Append site to data structure
if isempty(classification)
if any(strcmp('Tags', t.Properties.VariableNames))
t.classification = cellstr(string(t.Tags)); % per-row passthrough
else
t.classification = repmat({'none'}, nDetect, 1); % no Tags column to fall back on
end
else
t.classification = cellstr(repmat(classification,nDetect,1)); % explicit value, unchanged behavior
end
t = sortrows(t,'t0');