From ea08fead0746f80b0082b0f58b7beadc600fa591 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Laurent?= <francois.laurent@posteo.net>
Date: Fri, 27 May 2022 14:47:28 +0200
Subject: [PATCH] fixes #42

---
 Project.toml       |  2 ++
 src/LarvaTagger.jl |  2 ++
 src/controllers.jl | 10 ++++++++--
 src/models.jl      | 16 ++++++++++++++++
 src/plots.jl       |  4 ++--
 5 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/Project.toml b/Project.toml
index d3f21fb..7ba527d 100644
--- a/Project.toml
+++ b/Project.toml
@@ -9,6 +9,7 @@ Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
 Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0"
 JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
 JSServe = "824d6782-a2ef-11e9-3a09-e5662e0c26f9"
+LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
 Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
 Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
 Meshes = "eacbb407-ea5a-433e-ab97-5258b1ca43fa"
@@ -16,6 +17,7 @@ Observables = "510215fc-4207-5dde-b226-833fc4488ee2"
 ObservationPolicies = "6317928a-6b1a-42e8-b853-b8e2fc3e9ca3"
 OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
 PlanarLarvae = "c2615984-ef14-4d40-b148-916c85b43307"
+Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
 StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
 Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
 TidyObservables = "c8131bbd-73a8-4254-a42d-d5d4c5febb31"
diff --git a/src/LarvaTagger.jl b/src/LarvaTagger.jl
index a242337..d605d97 100644
--- a/src/LarvaTagger.jl
+++ b/src/LarvaTagger.jl
@@ -16,6 +16,8 @@ using Meshes
 using Logging
 import Dates
 using OrderedCollections
+using Random
+using LinearAlgebra
 
 export larvaviewer, larvaeditor
 
diff --git a/src/controllers.jl b/src/controllers.jl
index 489616d..1f2671f 100644
--- a/src/controllers.jl
+++ b/src/controllers.jl
@@ -173,6 +173,7 @@ struct LarvaController
     player::AbstractAnimator
     # could make LarvaController mutable instead...
     boundingbox::Ref{<:NTuple{4, <:AbstractFloat}}
+    medianlarvasize::AbstractFloat
 end
 
 function LarvaController(main::ControllerHub,
@@ -181,7 +182,8 @@ function LarvaController(main::ControllerHub,
         player::AbstractAnimator)
     activelarva = Observable{ActiveLarva}(nothing)
     boundingbox = Ref((0.0, 10.0, 0.0, 10.0))
-    LarvaController(main, model, tag_lut, activelarva, player, boundingbox)
+    mediansize = medianlarvasize(model)
+    LarvaController(main, model, tag_lut, activelarva, player, boundingbox, mediansize)
 end
 
 function LarvaController(main::ControllerHub,
@@ -211,6 +213,9 @@ getlarva(c, id) = getlarvae(c)[id]
 setboundingbox!(c, bb) = setboundingbox!(gethub(c)[:larva], bb)
 setboundingbox!(c::LarvaController, bb) = (c.boundingbox[] = bb)
 
+getmedianlarvasize(c) = getmedianlarvasize(gethub(c)[:larva])
+getmedianlarvasize(c::LarvaController) = c.medianlarvasize
+
 getplayer(c::LarvaController) = c.player
 getplayer(c) = getplayer(gethub(c))
 getplayer(hub::ControllerHub) = haskey(hub, :player) ? hub[:player] : getplayer(hub[:larva])
@@ -327,7 +332,8 @@ function slave(master::LarvaController,
                     tag_lut,
                     master.activelarva,
                     player,
-                    master.boundingbox)
+                    master.boundingbox,
+                    master.medianlarvasize)
 end
 
 stop!(controller::LarvaController) = stop!(controller.player)
diff --git a/src/models.jl b/src/models.jl
index fc0f7e3..065687f 100644
--- a/src/models.jl
+++ b/src/models.jl
@@ -254,3 +254,19 @@ function downsample(timestamps::Vector{Int}, path::PathOrOutline; step::Int=20)
     start = mod1(timestamps[1], step)
     (timestamps[start:step:end], path[start:step:end])
 end
+
+medianlarvasize(larvae::Dict; n::Int=100) = medianlarvasize(collect(values(larvae)); n=n)
+
+function medianlarvasize(larvae::Vector{LarvaModel}; n::Int=100)
+    larvae = Random.shuffle(larvae)
+    sizes = Float64[]
+    sizehint!(sizes, n)
+    for k in 1:n
+        larva = larvae[mod1(k, length(larvae))]
+        _, state = larva.fullstates[rand(1:length(larva.fullstates))]
+        spine = state[:spine]
+        size = sum(norm.(diff(spine.vertices)))
+        push!(sizes, size)
+    end
+    return median(sizes)
+end
diff --git a/src/plots.jl b/src/plots.jl
index c2233d8..a424f66 100644
--- a/src/plots.jl
+++ b/src/plots.jl
@@ -299,8 +299,6 @@ function assign_tag_to_segment!(larvaview, firststep)
     flag_active_larva_as_edited(controller)
 end
 
-const reference_larva_size = 2.25
-
 function setmouseevents!(scene, larva::SingleLarvaView; blocking=true, priority=Int8(10), kwargs...)
     # WGLMakie does not support addmouseevents! with plots as additional input args
     mouseevents = Makie.addmouseevents!(scene; priority=priority)
@@ -311,6 +309,8 @@ function setmouseevents!(scene, larva::SingleLarvaView; blocking=true, priority=
         return Consume(false)
     end
 
+    reference_larva_size = getmedianlarvasize(larva.controller)
+
     # dead code
     modifier_active() = ispressed(scene, Keyboard.left_shift)
 
-- 
GitLab