Skip to content
Snippets Groups Projects
Commit 57609a42 authored by Brian Groenke's avatar Brian Groenke
Browse files

Add more utility functions and tests

parent 39184908
No related branches found
No related tags found
1 merge request!70Add piecewise linear parameter mapping
......@@ -14,12 +14,12 @@ import CryoGrid
import ExprTools
import ForwardDiff
export @xu_str, @Float_str, @Real_str, @Number_str, @UFloat_str, @UT_str, @setscalar, @threaded
export @xu_str, @Float_str, @Real_str, @Number_str, @UFloat_str, @UT_str, @setscalar, @threaded, @sym_str
include("macros.jl")
export DistUnit, DistQuantity, TempUnit, TempQuantity, TimeUnit, TimeQuantity
export dustrip, duconvert, applyunit
export structiterate, getscalar, tuplejoin, convert_tspan
export structiterate, getscalar, tuplejoin, convert_t, convert_tspan
export Params
# Convenience constants for units
......@@ -84,17 +84,25 @@ Base.iterate(p::Params, state) = structiterate(p,state)
getscalar(x::Number) = x
getscalar(x::Number, i) = x
getscalar(a::AbstractArray) = a[1]
getscalar(a::AbstractArray) = begin @assert length(a) == 1; a[1] end
getscalar(a::AbstractArray, i) = a[i]
"""
convert_t(t::DateTime)
convert_t(t::Float64)
Convenience method for converting between `Dates.DateTime` and solver time.
"""
convert_t(t::DateTime) = Dates.datetime2epochms(t) / 1000
convert_t(t::Float64) = Dates.epochms2datetime(1000t)
"""
convert_tspan(tspan::Tuple{DateTime,DateTime})
convert_tspan(tspan::Tuple{Float64,Float64})
Convenience method for converting between `Dates.DateTime` and solver time.
"""
convert_tspan(tspan::NTuple{2,DateTime}) = Dates.datetime2epochms.(tspan) ./ 1000.0
convert_tspan(tspan::NTuple{2,Float64}) = Dates.epochms2datetime.(tspan.*1000.0)
convert_tspan(tspan::NTuple{2,DateTime}) = convert_t.(tspan)
convert_tspan(tspan::NTuple{2,Float64}) = convert_t.(tspan)
"""
argnames(f, choosefn=first)
......
using CryoGrid.Utils: ffill!
using CryoGrid
using Dates
using Test
struct TestCallable end
(::TestCallable)(x,y,z) = nothing
@testset "Utils" begin
@testset "argnames" begin
f(x) = nothing
g(x,y) = nothing
h(x,y,args...) = nothing
@test Utils.argnames(f) == [:x,]
@test Utils.argnames(g) == [:x,:y]
@test Utils.argnames(h) == [:x,:y,:args]
@test Utils.argnames(TestCallable()) == [:x,:y,:z]
end
@testset "convert time" begin
epoch_date = Dates.epochms2datetime(0.0)
# solver time is seconds since epoch, so we check that the conversion function does it correctly
@test convert_t(epoch_date + Hour(1)) Dates.value(convert(Second, Hour(1)))
@test convert_t(convert_t(epoch_date + Hour(1))) == epoch_date + Hour(1)
@test all(convert_tspan((epoch_date, epoch_date + Hour(1))) . (0.0, Dates.value(convert(Second, Hour(1)))))
@test all(convert_tspan(convert_tspan((epoch_date, epoch_date + Hour(1)))) .== (epoch_date, epoch_date + Hour(1)))
end
@testset "ffill!" begin
X = [missing, 1.0, 1.0, missing, missing, missing, 2.0, missing, 3.0, missing]
ffill!(X)
Utils.ffill!(X)
@test ismissing(X[1])
@test X[2:end] == [1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0]
end
@testset "getscalar" begin
@test getscalar([1.0]) == 1.0
@test getscalar(1.0) == 1.0
@test getscalar([1.0,2.0], 2) == 2.0
@test_throws AssertionError getscalar([1.0,2.0])
end
@testset "tuplejoin" begin
@test tuplejoin(()) == ()
@test tuplejoin((),(1,)) == (1,)
@test tuplejoin(1,2,3) == (1,2,3)
@test tuplejoin((1,),(2,),(3,)) == (1,2,3)
@test tuplejoin((1,2,3),(4,5)) == (1,2,3,4,5)
# should not flatten nested tuples
@test tuplejoin((1,2,(3,)),(4,)) == (1,2,(3,),4)
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment