diff --git a/Project.toml b/Project.toml index 697fc32..b77f158 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "EDF" uuid = "ccffbfc1-f56e-50fb-a33b-53d1781b2825" authors = ["Beacon Biosignals, Inc."] -version = "0.5.1" +version = "0.6.0" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" diff --git a/src/types.jl b/src/types.jl index 4185b46..30150d8 100644 --- a/src/types.jl +++ b/src/types.jl @@ -82,6 +82,12 @@ const ANNOTATIONS_SIGNAL_LABEL = "EDF Annotations" A type representing a time-stamped annotations list (TAL). +Note that this type's constructor may attempt to round given `onset_in_seconds` and +`duration_in_seconds` arguments to their nearest representable values in accordance +with the EDF+ specification, which a) represents these values as ASCII, b) constrains +these values to an 8 character limit, and c) does not allow the use of scientific +notation for these fields. + See EDF+ specification for details. # Fields @@ -94,6 +100,17 @@ struct TimestampedAnnotationList onset_in_seconds::Float64 duration_in_seconds::Union{Float64,Nothing} annotations::Vector{String} + function TimestampedAnnotationList(onset_in_seconds, duration_in_seconds, annotations) + onset_in_seconds = _nearest_representable_edf_time_value(onset_in_seconds) + duration_in_seconds = _nearest_representable_edf_time_value(duration_in_seconds) + return new(onset_in_seconds, duration_in_seconds, annotations) + end +end + +_nearest_representable_edf_time_value(::Nothing) = nothing + +function _nearest_representable_edf_time_value(x) + return round(x; digits=(8 - (ndigits(floor(Int, x)) + signbit(x) + isinteger(x)))) end function Base.:(==)(a::TimestampedAnnotationList, b::TimestampedAnnotationList) diff --git a/test/runtests.jl b/test/runtests.jl index c6b2608..921cb0b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -107,6 +107,13 @@ const DATADIR = joinpath(@__DIR__, "data") @test eof(io) end + @test EDF._edf_repr(EDF._nearest_representable_edf_time_value(-0.0023405432)) == "-0.00234" + @test EDF._edf_repr(EDF._nearest_representable_edf_time_value(0.0023405432)) == "0.002340" + @test EDF._edf_repr(EDF._nearest_representable_edf_time_value(1.002343)) == "1.002343" + @test EDF._edf_repr(EDF._nearest_representable_edf_time_value(1011.05432)) == "1011.054" + @test EDF._edf_repr(EDF._nearest_representable_edf_time_value(-1011.05432)) == "-1011.05" + @test EDF._edf_repr(EDF._nearest_representable_edf_time_value(-1013441.5)) == "-1013442" + @test EDF._edf_repr(EDF._nearest_representable_edf_time_value(-1013441.3)) == "-1013441" @test EDF._edf_repr(34577777) == "34577777" @test EDF._edf_repr(0.0345) == "0.034500" @test EDF._edf_repr(-0.02) == "-0.02000"