Commit 67fedf6b authored by François  LAURENT's avatar François LAURENT
Browse files

support for FIMTrack csv files

parent 238e7af4
Pipeline #81529 passed with stage
in 3 minutes and 55 seconds
......@@ -29,3 +29,11 @@ lazy = true
[[sample_labels_small.download]]
url = "https://gitlab.pasteur.fr/nyx/artefacts/-/raw/master/PlanarLarvae/labels_small.tgz?inline=false"
sha256 = "b6be8a281644726f09ef7ebd0ac3976c388e042838e7258a1d407d1f48abec53"
[sample_fimtrack_tables]
git-tree-sha1 = "6a1bb0b1ced44ae1add848156c7cc9ad367972fb"
lazy = true
[[sample_fimtrack_tables.download]]
url = "https://gitlab.pasteur.fr/nyx/artefacts/-/raw/master/PlanarLarvae/fimtrack_sample_tables.tgz?inline=false"
sha256 = "6163685cb6b23b74be61a786abf6a8f85996b6885dc42a68801d2ad2c9361cbe"
module Datasets
using ..LarvaBase: LarvaID
using ..LarvaBase: LarvaBase, LarvaID
using OrderedCollections: OrderedDict
using StructTypes
import JSON3
......@@ -846,4 +846,19 @@ function labels_encoded(run::Run, attrname::Symbol=:labels)
return true
end
# conversion utilities
asnamedtuple(states, i) = NamedTuple(key=>val[i] for (key, val) in pairs(states))
function astimeseries(track::Track)
firststate = asnamedtuple(track.states, 1)
timeseries = LarvaBase.TimeSeries{typeof(firststate)}()
for (i, t) in enumerate(track.timestamps)
push!(timeseries, (t, asnamedtuple(track.states, i)))
end
return timeseries
end
LarvaBase.eachtimeseries(tracks::Vector{Track}) = astimeseries.(tracks)
end
......@@ -92,7 +92,7 @@ function read_outline(::Type{Vector{Point2}}, head, spinepoints, radii, tail)
for (i, curr) in enumerate(spinepoints)
next = i < length(spinepoints) ? spinepoints[i+1] : tail
radius = radii[i]
0 < radius || @info "null radius"
0 < radius || @debug "null radius"
v1 = norm(prev - curr)
v2 = norm(curr - next)
x3, y3 = norm(v1 + v2)
......@@ -136,7 +136,7 @@ end
function astracks(larva_specs, features; fps=nothing)
tracks = Track[]
for (id, t0, t1) in larva_specs
t0, t1 = Time(t0), Time(t1)
t0, t1 = Time(t0-1), Time(t1-1)
larva_times = collect(isnothing(fps) ? (t0:t1) : (t0/fps:1/fps:t1/fps))
larva_features = OrderedDict(ftrname => ftrdata[id]
for (ftrname, ftrdata) in pairs(features)
......
......@@ -372,7 +372,7 @@ eachtimeseries(f::Function, sample::Runs) = (f(track)
for tracks in values(sample)
for track in values(tracks)
)
# fallback implementations
# fallback implementations; high risk of StackOverflowError
eachtimeseries(f::Function, collection) = Iterators.map(f, eachtimeseries(collection))
eachtimeseries(collection) = eachtimeseries(identity, collection)
......@@ -540,6 +540,7 @@ function centroid(snapshot::NamedTuple)
end
larvatrack(ts::Vector{Tuple{T,S}}) where {T,S} = [centroid(state) for (_, state) in ts]
larvatrack(ts::Vector) = centroid.(ts)
vertices′(::Type{P}, v::AbstractVector{<:P}) where {P} = v
vertices′(T, c::Chain) = vertices′(T, c.vertices)
......
......@@ -33,6 +33,12 @@ function make_test_data(target="chore_sample_outline")
elseif target == "sample_labels_file_nyx_small"
artefact = artifact"sample_labels_small"
filename = "maggotuba.labels"
elseif target == "sample_collision_dataset"
artefact = artifact"sample_fimtrack_tables"
filename = "collision_sample_table.csv"
elseif target == "sample_fimtrack_table"
artefact = artifact"sample_fimtrack_tables"
filename = "embl_sample_table.csv"
else
throw(DomainError("unknown artefact: " * target))
end
......
......@@ -512,3 +512,41 @@ with metadata: OrderedDict{Symbol, Any} with 3 entries:
end
end
if all_tests || "FIMTrack" in ARGS
@testset "FIMTrack.jl" begin
using PlanarLarvae.FIMTrack
csvtable = make_test_data("sample_collision_dataset")
tracks= read_fimtrack(csvtable)
@test [track.id for track in tracks] == UInt16[14, 18]
track = tracks[1]
@test collect(keys(track.states)) == [:mom, :area, :perimeter, :head, :spinepoint, :tail, :radius, :in_collision]
@test track.timestamps == 0:113
spine = track[:spinepoint]
@test length(spine) == 114 && spine isa Vector{PointSeries{Float32}}
@test spine[1] == [Point2f(238, 237), Point2f(239, 221), Point2f(237, 206), Point2f(236, 191), Point2f(234, 175)]
@test track[:in_collision] isa Vector{Bool}
csvtable = make_test_data("sample_fimtrack_table")
tracks = read_fimtrack((:spine=>Spine, :outline=>Outline), csvtable; fps=30)
@test [track.id for track in tracks] == UInt16.(0:31)
@test tracks[end-1].timestamps[end] == 1807 / 30
track = tracks[end]
@test collect(keys(track.states)) == [:spine, :outline]
@test track.timestamps == 1735 / 30 : 1 / 30 : 1781 / 30
spine = track[:spine, 1781 / 30]
@test spine isa Chain{2,Float64} && spine.vertices == [Point(1061, 50), Point(1054, 49), Point(1048, 49), Point(1042, 48), Point(1040, 45)]
tracks = read_fimtrack(csvtable)
track = tracks[1]
@test collect(keys(track.states)) == [:mom, :mom_dst, :acc_dst, :dst_to_origin, :area, :perimeter, :spine_length, :bending, :head, :spinepoint, :tail, :radius, :is_coiled, :is_well_oriented, :go_phase, :left_bended, :right_bended, :mov_direction, :velocity, :acceleration]
@test all(ftr -> track[ftr] isa Vector{Bool},
(:is_coiled, :is_well_oriented, :left_bended, :right_bended))
@test all(ftr -> track[ftr] isa Vector{Union{Missing, Bool}}, (:go_phase,))
end
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment