diff --git a/scripts/larvatagger-gui.jl b/scripts/larvatagger-gui.jl index 1bc01e8db4d536ee67bbd9cdbfb5144ce6954b03..8cadce79670ac92b648fccb5e093f32ec6ffa402 100755 --- a/scripts/larvatagger-gui.jl +++ b/scripts/larvatagger-gui.jl @@ -9,7 +9,7 @@ fi FLAGS= if [ "$1" = "--sysimage" -o "$1" = "-J" ]; then FLAGS="--sysimage $2 "; shift 2; fi if [ "${1:0:2}" = "-J" ]; then FLAGS="$1 "; shift; fi -if [ -n "$1" -a -f "$1" ]; then FLAGS="$FLAGS -iq "; fi +if [ -n "$1" -a -f "$1" -o "$1" = "blank" ]; then FLAGS="$FLAGS -iq "; fi if [ -z "$JULIA" ]; then JULIA=julia; fi exec $JULIA --project="$PROJECT_DIR" --color=yes --startup-file=no $FLAGS\ "${BASH_SOURCE[0]}" "$@" diff --git a/src/cli_open.jl b/src/cli_open.jl index 28bd83a8d5d4677ac3c4f6bd2aa7b3f92628d123..c72ecf9bea881fd7afd4f1699b87d3abd3da1fb3 100644 --- a/src/cli_open.jl +++ b/src/cli_open.jl @@ -47,7 +47,9 @@ function main(args=ARGS; exit_on_error=false) verbose = !parsed_args["--quiet"] infile = parsed_args["<file-path>"] - if !isfile(infile) + if infile == "blank" + infile = nothing + elseif !isfile(infile) @error "File not found; did you specify a file path?" infile exit() end diff --git a/src/models.jl b/src/models.jl index 2c537415dc328090bbf2133ac7e5b982be09c88c..9910a28cadded6c41161031c487c93d567b6fc9e 100644 --- a/src/models.jl +++ b/src/models.jl @@ -310,7 +310,8 @@ end medianlarvasize(larvae::Dict; n::Int=100) = medianlarvasize(collect(values(larvae)); n=n) -function medianlarvasize(larvae::Vector{LarvaModel}; n::Int=100) +function medianlarvasize(larvae::Vector{LarvaModel}; n::Int=100)::Float32 + isempty(larvae) && return 0.0f0 larvae = Random.shuffle(larvae) sizes = Float64[] sizehint!(sizes, n) @@ -324,7 +325,8 @@ function medianlarvasize(larvae::Vector{LarvaModel}; n::Int=100) return median(sizes) end -function simultaneouslarvae(larvae) +function simultaneouslarvae(larvae)::Int + isempty(larvae) && return 0 laststep = maximum([larva.alignedsteps[end] for larva in values(larvae)]) n = 0 for step in 1:20:laststep diff --git a/src/plots.jl b/src/plots.jl index e3bbceda9e7f2fe27c8495e4055a65d4fe04eab5..4a76a07e37abd5b8b02ec19cc83924fb95b49504 100644 --- a/src/plots.jl +++ b/src/plots.jl @@ -588,12 +588,19 @@ function DecoratedLarvae(larvae::Vector{DecoratedLarva}) end end end - center = Meshes.coordinates ∘ Meshes.centroid - centers = cat((center(larva.activearea) for larva in larvae)...; dims=2) - norm2 = sum(centers .* centers, dims=1) + centers = zeros(Float32, (2, 0)) + norm2 = zeros(Float32, (1, 0)) + if ~isempty(larvae) + center = Meshes.coordinates ∘ Meshes.centroid + centers = cat((center(larva.activearea) for larva in larvae)...; dims=2) + norm2 = sum(centers .* centers, dims=1) + end DecoratedLarvae(larvae, centers, norm2, hovered_larva, hovering_active) end +Base.isempty(larvae::DecoratedLarvae) = isempty(larvae.larvae) +Base.length(larvae::DecoratedLarvae) = length(larvae.larvae) + function find(larvae::DecoratedLarvae, position) pos = Vector(position)' p2 = pos * pos' @@ -630,7 +637,13 @@ end Meshes.boundingbox(larva::StatefulLarva) = Meshes.boundingbox(larva.model) Meshes.boundingbox(larva::DecoratedLarva) = Meshes.boundingbox(larva.larva) -Meshes.boundingbox(larvae::DecoratedLarvae) = Meshes.boundingbox(map(Meshes.boundingbox, larvae.larvae)) +function Meshes.boundingbox(larvae::DecoratedLarvae) + if isempty(larvae) + Meshes.Box(Meshes.Point(0.0, 1.0), Meshes.Point(0.0, 1.0)) + else + Meshes.boundingbox(map(Meshes.boundingbox, larvae.larvae)) + end +end function setmouseevents!(scene, plot::DecoratedLarvae, ctrl; consume=false) on(events(scene).mousebutton) do mb diff --git a/src/viewer.jl b/src/viewer.jl index 4175e5fa695a84ba1e712a025e6f389a263d5cef..b2344b44c0937f0cb60ae6270712619a7ce975aa 100644 --- a/src/viewer.jl +++ b/src/viewer.jl @@ -1,45 +1,52 @@ struct ViewerView assayplot::AssayViewer - trackplot::TrackViewer + trackplot::Union{Nothing, TrackViewer} end function Bonito.jsrender(session::Session, vv::ViewerView) - controller = vv.trackplot.plot.controller delayed_controller = vv.assayplot.plot.controller - assaydom = r(session, vv.assayplot) - trackdom = r(session, vv.trackplot) - - on(session, larvaevents(controller).activated) do _ - vv.assayplot.visible[] = false - evaljs(session, - js""" - const assayviewer = $(assaydom); - const trackviewer = $(trackdom); - assayviewer.style.display = "none"; - trackviewer.style.display = "block"; - """) - end - on(session, larvaevents(controller).deactivated) do _ - vv.assayplot.visible[] = true - evaljs(session, - js""" - const assayviewer = $(assaydom); - const trackviewer = $(trackdom); - trackviewer.style.display = "none"; - assayviewer.style.display = "block"; - """) - end - on(session.on_close) do closed if closed pause(delayed_controller.player) end end - r(session, - DOM.div(Bonito.TailwindCSS, assaydom, trackdom; class="flex flex-row")) + assaydom = r(session, vv.assayplot) + trackdom = nothing + + if !isnothing(vv.trackplot) + controller = vv.trackplot.plot.controller + trackdom = r(session, vv.trackplot) + + on(session, larvaevents(controller).activated) do _ + vv.assayplot.visible[] = false + evaljs(session, + js""" + const assayviewer = $(assaydom); + const trackviewer = $(trackdom); + assayviewer.style.display = "none"; + trackviewer.style.display = "block"; + """) + end + on(session, larvaevents(controller).deactivated) do _ + vv.assayplot.visible[] = true + evaljs(session, + js""" + const assayviewer = $(assaydom); + const trackviewer = $(trackdom); + trackviewer.style.display = "none"; + assayviewer.style.display = "block"; + """) + end + + r(session, + DOM.div(Bonito.TailwindCSS, assaydom, trackdom; class="flex flex-row")) + + else + r(session, DOM.div(Bonito.TailwindCSS, assaydom)) + end end function larvaviewer(path::String; allow_multiple_tags::Union{Nothing, Bool}=false, @@ -68,9 +75,14 @@ function larvaviewer(controller; multipletags::Union{Nothing, Bool}=false, viewfactor::Real=1, ) - model = getlarvae(controller) - times = gettimes(controller) - tag_lut = gettags(controller) + model = LarvaModel[] + times = PlanarLarvae.Time[0.0, 1.0] + tag_lut = Observable(TagLUT()) + if haskey(controller, :larva) + model = getlarvae(controller) + times = gettimes(controller) + tag_lut = gettags(controller) + end controller[:player] = player = timecontroller(times) controller[:larva] = larva = LarvaController(controller, model, tag_lut, player) diff --git a/src/wgl.jl b/src/wgl.jl index 69984ede68c42d00af023633e122816b22dab1df..c21d40fc2d8abf281f35b0a8be23e0374dcfbc00 100644 --- a/src/wgl.jl +++ b/src/wgl.jl @@ -90,9 +90,11 @@ function AssayPlot(ctrl, larvae::DecoratedLarvae; size=FIGSIZE) ax = Axis(fig.layout[1, 1], aspect=DataAspect(), xgridwidth=width, ygridwidth=width, xgridcolor=color, ygridcolor=color) autosize!(ax, size) - plot = larvaplot!(ax, larvae) - setkeyboardevents!(plot.parent, getplayer(ctrl)) - setbounds!(ax, ctrl, larvae) + if !isempty(larvae) + plot = larvaplot!(ax, larvae) + setkeyboardevents!(plot.parent, getplayer(ctrl)) + setbounds!(ax, ctrl, larvae) + end button = homebutton() on(button) do _ setbounds!(ax, ctrl, larvae) @@ -845,6 +847,7 @@ function trackviewer(controller; kwargs... ) model = getlarvae(controller) + isempty(model) && return nothing plot = trackplot(model, controller; editabletags=editabletags, kwargs...) play = player(controller) sele = tagselector(controller; editabletags=editabletags, multipletags=multipletags)