using Skraak
using Test
using DataFrames, Dates
@testset "Skraak.jl" begin
@testset "make_clips functon" begin
@testset "function Skraak.assert_not_empty" begin
# Empty dataframe should throw an error
df1 = DataFrames.DataFrame()
@test_throws MethodError Skraak.assert_not_empty(df1, "/abc/def")
# Non-empty dataframe should return the same dataframe
df2 = DataFrames.DataFrame(A = [1, 2, 3], B = [4, 5, 6])
@test Skraak.assert_not_empty(df2, "/abc/def") ==
DataFrames.DataFrame(A = [1, 2, 3], B = [4, 5, 6])
end
@testset "function Skraak.rename_column!" begin
# Should do nothing if col does not exist
df1 = DataFrames.DataFrame(A = [1, 2], B = [3, 4])
@test Skraak.rename_column!(df1, "C", "D") ==
DataFrames.DataFrame(A = [1, 2], B = [3, 4])
# existing column should be renamed
df2 = DataFrames.DataFrame(A = [1, 2], B = [1, 2])
@test Skraak.rename_column!(df2, "B", "C") ==
DataFrames.DataFrame(A = [1, 2], C = [1, 2])
end
@testset "function Skraak.assert_detections_present" begin
# should return the same dataframe
df1 = DataFrames.DataFrame(loc = ["Auckland"], kiwi = [1.0])
@test Skraak.assert_detections_present(df1, "location", "trip date") ==
DataFrames.DataFrame(loc = ["Auckland"], kiwi = [1.0])
# no detections so throws error to shortcicuit the pipe
df2 = DataFrames.DataFrame(loc = ["Wellington", "Auckland"], kiwi = [0.0, 0.0])
@test_throws MethodError Skraak.assert_detections_present(
df2,
"location",
"trip_date",
)
end
@testset "function filter_positives!" begin
# All positives
@test Skraak.filter_positives!(
DataFrames.DataFrame(kiwi = [1.0, 1.0, 1.0]),
"kiwi",
) == DataFrames.DataFrame(kiwi = [1.0, 1.0, 1.0])
# Mix of positive and negative
@test Skraak.filter_positives!(
DataFrames.DataFrame(kiwi = [1.0, 0.0, 1.0]),
"kiwi",
) == DataFrames.DataFrame(kiwi = [1.0, 1.0])
# All negatives
@test Skraak.filter_positives!(
DataFrames.DataFrame(kiwi = [0.0, 0.0, 0.0]),
"kiwi",
) == DataFrames.DataFrame(kiwi = [])
end
@testset "function filename_to_datetime!" begin
@testset "DateTime from yyyymmdd_HHMMSS format" begin
# Test with valid filename
@test Skraak.filename_to_datetime!("./20230328_213000.WAV") ==
DateTime(2023, 3, 28, 21, 30, 0)
# Test with invalid filename
@test_throws ArgumentError Skraak.filename_to_datetime!(
"./20230328_2130.WAV",
)
end
@testset "DateTime from ddmmyyyy_HHMMSS format" begin
# Test with valid filename
@test Skraak.filename_to_datetime!("./280323_213000.wav") ==
DateTime(2023, 3, 28, 21, 30, 0)
# Test with invalid filename (does not throw, not sure why)
#@test_throws ArgumentError Skraak.filename_to_datetime!("./280323_2130.WAV")
@test_throws ArgumentError Skraak.filename_to_datetime!(
"./28323_213000.WAV",
)
end
end
@testset "function insert_datetime_column!" begin
df =
DataFrames.DataFrame(file = ["./20220101_120000.WV", "./011122_124500.wav"])
@test Skraak.insert_datetime_column!(df) == DataFrames.DataFrame(
file = ["./20220101_120000.WV", "./011122_124500.wav"],
DateTime = [
DateTime(2022, 1, 1, 12, 0, 0),
DateTime(2022, 11, 1, 12, 45, 0),
],
)
end
@testset "functions construct_dawn_dusk_dict, night and exclude_daytime!" begin
dict = Skraak.construct_dawn_dusk_dict("../../dawn_dusk.csv")
# construct_dawn_dusk_dict
@test length(keys(dict)) >= 2557
@test haskey(dict, Date(2019, 1, 1))
@test haskey(dict, Date(2024, 12, 31))
@test dict[Date(2019, 1, 1)] ==
(DateTime("2019-01-01T06:03:03"), DateTime("2019-01-01T21:43:33"))
@test dict[Date(2024, 12, 31)] ==
(DateTime("2024-12-31T06:02:38"), DateTime("2024-12-31T21:43:30"))
# night
@test Skraak.night(DateTime("2019-01-01T00:00:00"), dict) == true
@test Skraak.night(DateTime("2019-01-01T09:03:03"), dict) == false
@test Skraak.night(DateTime("2021-11-02T04:00:00"), dict) == true
@test Skraak.night(DateTime("2021-11-02T20:00:00"), dict) == false
# exclude_daytime!
df = DataFrames.DataFrame(
DateTime = [
DateTime("2021-08-01T00:00:00"),
DateTime("2021-08-01T06:00:00"),
DateTime("2021-08-01T12:00:00"),
DateTime("2021-08-01T16:00:00"),
],
)
Skraak.exclude_daytime!(df, dict)
@test df == DataFrames.DataFrame(
DateTime = [
DateTime("2021-08-01T00:00:00"),
DateTime("2021-08-01T06:00:00"),
],
)
end
@testset "cluster_detections" begin
detections = [
100.0,
102.5,
105.0,
107.5,
110.0,
112.5,
115.0,
117.5,
120.0,
122.5,
125.0,
127.5,
130.0,
132.5,
135.0,
137.5,
140.0,
685.0,
687.5,
690.0,
692.5,
695.0,
697.5,
700.0,
702.5,
705.0,
707.5,
710.0,
712.5,
717.5,
720.0,
890.0,
]
@test Skraak.cluster_detections(detections) == [
[
100.0,
102.5,
105.0,
107.5,
110.0,
112.5,
115.0,
117.5,
120.0,
122.5,
125.0,
127.5,
130.0,
132.5,
135.0,
137.5,
140.0,
],
[
685.0,
687.5,
690.0,
692.5,
695.0,
697.5,
700.0,
702.5,
705.0,
707.5,
710.0,
712.5,
717.5,
720.0,
],
]
@test Skraak.cluster_detections([100.0]) == []
@test_throws BoundsError Skraak.cluster_detections(Float64[])
end
@testset "function calculate_clip_start_end" begin
# assumes it is operating on 5 second clips
freq = 16000.0f0
signal_length = Int(895 * freq)
# good long detection
detection = [
100.0,
102.5,
105.0,
107.5,
110.0,
112.5,
115.0,
117.5,
120.0,
122.5,
125.0,
127.5,
130.0,
132.5,
135.0,
137.5,
140.0,
]
@test Skraak.calculate_clip_start_end(detection, freq, signal_length) ==
(1.6e6, 2.32e6)
@test Skraak.calculate_clip_start_end(detection[1:2], freq, signal_length) ==
(1.6e6, 1.72e6)
# needs at least 2 detections
@test_throws MethodError Skraak.calculate_clip_start_end(
detection[1],
freq,
signal_length,
)
# first detection at 0
first = [0.0, 2.5]
@test Skraak.calculate_clip_start_end(first, freq, signal_length) ==
(1.0, 120000.0)
# last detection within 5s of last sample
last = [890.0, 892.5, 895.0]
@test Skraak.calculate_clip_start_end(last, freq, signal_length) ==
(1.424e7, 1.432e7)
@test Skraak.calculate_clip_start_end(last[1:2], freq, signal_length) ==
(1.424e7, 1.432e7)
end
end
end